Hi all, Am Do., 18. März 2021 um 23:08 Uhr schrieb Benjamin Herrenschmidt < benh@kernel.crashing.org>: > This adds the ability for the driver to access UARTs via MMIO instead > of PIO selectively at runtime, and exposes a new function to add an > MMIO port. > I had a couple of sleepless nights trying to find out why this didn't work for my MMIO UART (Intel Cannon Lake PCH Intel C246), so I thought I would share my findings with others in a similar situation. (See below.) > diff --git a/grub-core/term/ns8250.c b/grub-core/term/ns8250.c > index 39809d042..183e14b3b 100644 > --- a/grub-core/term/ns8250.c > +++ b/grub-core/term/ns8250.c > @@ -44,6 +44,24 @@ static int dead_ports = 0; > #define DEFAULT_BASE_CLOCK 115200 > #endif > > +static inline unsigned char > +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)); > + return grub_inb (port->port + reg); > +} > + > +static inline void > +ns8250_reg_write (struct grub_serial_port *port, unsigned char value, > grub_addr_t reg) > +{ > + asm volatile("" : : : "memory"); > + if (port->mmio) > + *((volatile char *)(port->mmio_base + reg)) = value; > + else > + grub_outb (value, port->port + reg); > +} > This code assumes that the registers are only 8 bit wide. Apparently for my chipset they are 32 bits wide, so it only (finally) worked when I rewrote this code to address and write full grub_uint32_t values, like this: ------ volatile grub_uint32_t* p = (void*)(port->mmio_base); *(p + reg) = (grub_uint32_t)(value); ------ Cheers Sven