[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 6/7] ns8250: Support more MMIO access sizes
From: |
Benjamin Herrenschmidt |
Subject: |
[PATCH 6/7] ns8250: Support more MMIO access sizes |
Date: |
Fri, 2 Dec 2022 10:05:25 +1100 |
From: Benjamin Herrenschmidt <benh@amazon.com>
It is common for PCI based UARTs to use larger than one byte access
sizes. This adds support for this and uses the information present
in SPCR accordingly.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
grub-core/term/ns8250-spcr.c | 3 ++-
grub-core/term/ns8250.c | 45 +++++++++++++++++++++++++++++++++---
include/grub/serial.h | 9 ++++++--
3 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/grub-core/term/ns8250-spcr.c b/grub-core/term/ns8250-spcr.c
index 0786aee1b..dd589af60 100644
--- a/grub-core/term/ns8250-spcr.c
+++ b/grub-core/term/ns8250-spcr.c
@@ -73,7 +73,8 @@ grub_ns8250_spcr_init (void)
switch (spcr->base_addr.space_id)
{
case GRUB_ACPI_GENADDR_MEM_SPACE:
- return grub_serial_ns8250_add_mmio(spcr->base_addr.addr, &config);
+ return grub_serial_ns8250_add_mmio(spcr->base_addr.addr,
+ spcr->base_addr.access_size,
&config);
case GRUB_ACPI_GENADDR_IO_SPACE:
return grub_serial_ns8250_add_port(spcr->base_addr.addr, &config);
default:
diff --git a/grub-core/term/ns8250.c b/grub-core/term/ns8250.c
index 08dfb99da..76f68c037 100644
--- a/grub-core/term/ns8250.c
+++ b/grub-core/term/ns8250.c
@@ -48,7 +48,26 @@ ns8250_reg_read (struct grub_serial_port *port, grub_addr_t
reg)
{
asm volatile("" : : : "memory");
if (port->mmio)
- return *((volatile unsigned char *)(port->mmio_base + reg));
+ {
+ /* Note: we assume MMIO UARTs are little endian. This is not true of all
+ * embedded platforms but will do for now
+ */
+ switch(port->access_size)
+ {
+ default:
+ case 1:
+ return *((volatile unsigned char *)(port->mmio_base + reg));
+ case 2:
+ return grub_le_to_cpu16(*((volatile unsigned short
*)(port->mmio_base + (reg << 1))));
+ case 3:
+ return grub_le_to_cpu32(*((volatile unsigned long *)(port->mmio_base
+ (reg << 2))));
+ case 4:
+ /* This will only work properly on 64-bit systems, thankfully it
+ * also probably doesn't exist
+ */
+ return grub_le_to_cpu64(*((volatile unsigned long long
*)(port->mmio_base + (reg << 3))));
+ }
+ }
return grub_inb (port->port + reg);
}
@@ -57,7 +76,24 @@ ns8250_reg_write (struct grub_serial_port *port, unsigned
char value, grub_addr_
{
asm volatile("" : : : "memory");
if (port->mmio)
- *((volatile char *)(port->mmio_base + reg)) = value;
+ {
+ switch(port->access_size)
+ {
+ default:
+ case 1:
+ *((volatile unsigned char *)(port->mmio_base + reg)) = value;
+ break;
+ case 2:
+ *((volatile unsigned short *)(port->mmio_base + (reg << 1))) =
grub_cpu_to_le16(value);
+ break;
+ case 3:
+ *((volatile unsigned long *)(port->mmio_base + (reg << 2))) =
grub_cpu_to_le32(value);
+ break;
+ case 4:
+ *((volatile unsigned long long *)(port->mmio_base + (reg << 3))) =
grub_cpu_to_le64(value);
+ break;
+ }
+ }
else
grub_outb (value, port->port + reg);
}
@@ -285,6 +321,7 @@ grub_ns8250_init (void)
grub_print_error ();
grub_serial_register (&com_ports[i]);
+ com_ports[i].access_size = 1;
}
}
@@ -338,6 +375,7 @@ grub_serial_ns8250_add_port (grub_port_t port, struct
grub_serial_config *config
p->driver = &grub_ns8250_driver;
p->mmio = 0;
p->port = port;
+ p->access_size = 1;
if (config)
grub_serial_port_configure (p, config);
else
@@ -348,7 +386,7 @@ grub_serial_ns8250_add_port (grub_port_t port, struct
grub_serial_config *config
}
char *
-grub_serial_ns8250_add_mmio(grub_addr_t addr, struct grub_serial_config
*config)
+grub_serial_ns8250_add_mmio(grub_addr_t addr, unsigned int acc_size, struct
grub_serial_config *config)
{
struct grub_serial_port *p;
unsigned i;
@@ -372,6 +410,7 @@ grub_serial_ns8250_add_mmio(grub_addr_t addr, struct
grub_serial_config *config)
p->driver = &grub_ns8250_driver;
p->mmio = 1;
p->mmio_base = addr;
+ p->access_size = acc_size;
if (config)
grub_serial_port_configure (p, config);
else
diff --git a/include/grub/serial.h b/include/grub/serial.h
index 646bdf1bb..8875eaf82 100644
--- a/include/grub/serial.h
+++ b/include/grub/serial.h
@@ -94,7 +94,12 @@ struct grub_serial_port
#if defined(__mips__) || defined (__i386__) || defined (__x86_64__)
grub_port_t port;
#endif
- grub_addr_t mmio_base;
+ struct
+ {
+ grub_addr_t mmio_base;
+ /* Access size uses ACPI definition */
+ unsigned int access_size;
+ };
};
};
struct
@@ -187,7 +192,7 @@ grub_serial_config_defaults (struct grub_serial_port *port)
void grub_ns8250_init (void);
char * grub_ns8250_spcr_init (void);
char *grub_serial_ns8250_add_port (grub_port_t port, struct grub_serial_config
*config);
-char *grub_serial_ns8250_add_mmio(grub_addr_t addr, struct grub_serial_config
*config);
+char *grub_serial_ns8250_add_mmio(grub_addr_t addr, unsigned int acc_size,
struct grub_serial_config *config);
#endif
#ifdef GRUB_MACHINE_IEEE1275
void grub_ofserial_init (void);
--
2.34.1
- [RESEND PATCH 0/7] serial: Add MMIO & SPCR support, Benjamin Herrenschmidt, 2022/12/01
- [PATCH 1/7] acpi: Export a generic grub_acpi_find_table, Benjamin Herrenschmidt, 2022/12/01
- [PATCH 2/7] acpi: Add SPCR and generic address definitions, Benjamin Herrenschmidt, 2022/12/01
- [PATCH 3/7] ns8250: Add base support for MMIO UARTs, Benjamin Herrenschmidt, 2022/12/01
- [PATCH 4/7] ns8250: Add configuration parameter when adding ports, Benjamin Herrenschmidt, 2022/12/01
- [PATCH 5/7] ns8250: Use ACPI SPCR table when available to configure serial, Benjamin Herrenschmidt, 2022/12/01
- [PATCH 6/7] ns8250: Support more MMIO access sizes,
Benjamin Herrenschmidt <=
- [PATCH 7/7] serial: Add ability to specify MMIO ports via 'serial', Benjamin Herrenschmidt, 2022/12/01
- Re: [RESEND PATCH 0/7] serial: Add MMIO & SPCR support, Daniel Kiper, 2022/12/21