mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-28 10:10:29 +00:00
term/ns8250: Support more MMIO access sizes
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> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
1 parent
7b192ec4cd
commit
f5e1d23a18
3 files changed
+60
-6
No files matched your search
+50
-3
@@ -42,7 +42,31 @@ ns8250_reg_read (struct grub_serial_port *port, grub_addr_t reg)
|
||||
{
|
||||
asm volatile("" : : : "memory");
|
||||
if (port->mmio == true)
|
||||
return *((volatile grub_uint8_t *) (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:
|
||||
/* ACPI tables occasionally uses "0" (legacy) as equivalent to "1" (byte). */
|
||||
case 1:
|
||||
return *((volatile grub_uint8_t *) (port->mmio_base + reg));
|
||||
case 2:
|
||||
return grub_le_to_cpu16 (*((volatile grub_uint16_t *) (port->mmio_base + (reg << 1))));
|
||||
case 3:
|
||||
return grub_le_to_cpu32 (*((volatile grub_uint32_t *) (port->mmio_base + (reg << 2))));
|
||||
case 4:
|
||||
/*
|
||||
* This will only work properly on 64-bit systems since 64-bit
|
||||
* accessors aren't atomic on 32-bit hardware. Thankfully the
|
||||
* case of a UART with a 64-bit register spacing on 32-bit
|
||||
* also probably doesn't exist.
|
||||
*/
|
||||
return grub_le_to_cpu64 (*((volatile grub_uint64_t *) (port->mmio_base + (reg << 3))));
|
||||
}
|
||||
}
|
||||
return grub_inb (port->port + reg);
|
||||
}
|
||||
|
||||
@@ -51,7 +75,26 @@ ns8250_reg_write (struct grub_serial_port *port, grub_uint8_t value, grub_addr_t
|
||||
{
|
||||
asm volatile("" : : : "memory");
|
||||
if (port->mmio == true)
|
||||
*((volatile grub_uint8_t *) (port->mmio_base + reg)) = value;
|
||||
{
|
||||
switch(port->access_size)
|
||||
{
|
||||
default:
|
||||
/* ACPI tables occasionally uses "0" (legacy) as equivalent to "1" (byte). */
|
||||
case 1:
|
||||
*((volatile grub_uint8_t *) (port->mmio_base + reg)) = value;
|
||||
break;
|
||||
case 2:
|
||||
*((volatile grub_uint16_t *) (port->mmio_base + (reg << 1))) = grub_cpu_to_le16 (value);
|
||||
break;
|
||||
case 3:
|
||||
*((volatile grub_uint32_t *) (port->mmio_base + (reg << 2))) = grub_cpu_to_le32 (value);
|
||||
break;
|
||||
case 4:
|
||||
/* See commment in ns8250_reg_read(). */
|
||||
*((volatile grub_uint64_t *) (port->mmio_base + (reg << 3))) = grub_cpu_to_le64 (value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
grub_outb (value, port->port + reg);
|
||||
}
|
||||
@@ -286,6 +329,7 @@ grub_ns8250_init (void)
|
||||
grub_print_error ();
|
||||
|
||||
grub_serial_register (&com_ports[i]);
|
||||
com_ports[i].access_size = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,6 +384,7 @@ grub_serial_ns8250_add_port (grub_port_t port, struct grub_serial_config *config
|
||||
p->driver = &grub_ns8250_driver;
|
||||
p->mmio = false;
|
||||
p->port = port;
|
||||
p->access_size = 1;
|
||||
if (config != NULL)
|
||||
grub_serial_port_configure (p, config);
|
||||
else
|
||||
@@ -350,7 +395,8 @@ 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;
|
||||
@@ -375,6 +421,7 @@ grub_serial_ns8250_add_mmio (grub_addr_t addr, struct grub_serial_config *config
|
||||
p->driver = &grub_ns8250_driver;
|
||||
p->mmio = true;
|
||||
p->mmio_base = addr;
|
||||
p->access_size = acc_size;
|
||||
if (config != NULL)
|
||||
grub_serial_port_configure (p, config);
|
||||
else
|
||||
|
||||
Reference in new issue
Block a user