Hi all,

Am Do., 18. März 2021 um 23:08 Uhr schrieb Benjamin Herrenschmidt <
b...@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
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to