On Tue, Dec 20, 2016 at 07:03:58PM +0100, Ricardo Ribalda Delgado wrote: > Some chipsets have memory mapped serial ports. The protocol is the same > as an standard uart, but with memory read/write instead of inb/outb. > > Signed-off-by: Ricardo Ribalda Delgado <[email protected]> > --- > v2: Fix typos > > Suggested by: Kevin O'Connor <[email protected]>: > > -Only operate in 32bit mode if !MODESEGMENT > > src/Kconfig | 3 +++ > src/hw/serialio.c | 32 +++++++++++++++++++++++++------- > src/serial.c | 2 +- > 3 files changed, 29 insertions(+), 8 deletions(-) > > diff --git a/src/Kconfig b/src/Kconfig > index e767be1351c3..e53713f2c527 100644 > --- a/src/Kconfig > +++ b/src/Kconfig > @@ -532,6 +532,9 @@ menu "Debugging" > default 0x3f8 > help > Base port for serial - generally 0x3f8, 0x2f8, 0x3e8, or 0x2e8. > + On some chipsets the serial port is memory mapped, in those cases > + provide the 32 bit address. E.g. 0xFEDC6000 for the AMD Kern > + (a.k.a Hudson UART).
Thanks. I'm a little concerned about overloading the meaning of CONFIG_DEBUG_SERIAL_PORT to mean either port or memory address. How about the modified patch below instead? -Kevin >From 9968b2ef2bbfaf7271cd2d27302161e141200738 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado <[email protected]> Date: Tue, 20 Dec 2016 19:03:58 +0100 Subject: [PATCH] serialio: Support for mmap serial ports Some chipsets have memory mapped serial ports. The protocol is the same as an standard uart, but with memory read/write instead of inb/outb. Signed-off-by: Ricardo Ribalda Delgado <[email protected]> Signed-off-by: Kevin O'Connor <[email protected]> --- src/Kconfig | 13 +++++++++++++ src/hw/serialio.c | 44 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/Kconfig b/src/Kconfig index e767be1..457d082 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -532,6 +532,19 @@ menu "Debugging" default 0x3f8 help Base port for serial - generally 0x3f8, 0x2f8, 0x3e8, or 0x2e8. + config DEBUG_SERIAL_MMIO + depends on DEBUG_LEVEL != 0 && !DEBUG_SERIAL + bool "Serial port debugging via memory mapped IO" + default n + help + Send debugging information to serial port mapped in memory. + config DEBUG_SERIAL_MEM_ADDRESS + depends on DEBUG_SERIAL_MMIO + hex "Serial port memory mapped IO address" + help + On some chipsets the serial port is memory mapped, in those cases + provide the 32 bit address. E.g. 0xFEDC6000 for the AMD Kern + (a.k.a Hudson UART). config DEBUG_IO depends on QEMU_HARDWARE && DEBUG_LEVEL != 0 diff --git a/src/hw/serialio.c b/src/hw/serialio.c index 6486fc0..319a85c 100644 --- a/src/hw/serialio.c +++ b/src/hw/serialio.c @@ -17,20 +17,44 @@ #define DEBUG_TIMEOUT 100000 +// Write to a serial port register +static void +serial_debug_write(u8 offset, u8 val) +{ + if (CONFIG_DEBUG_SERIAL) { + outb(val, CONFIG_DEBUG_SERIAL_PORT + offset); + } else if (CONFIG_DEBUG_SERIAL_MMIO) { + ASSERT32FLAT(); + writeb((void*)CONFIG_DEBUG_SERIAL_MEM_ADDRESS + 4*offset, val); + } +} + +// Read from a serial port register +static u8 +serial_debug_read(u8 offset) +{ + if (CONFIG_DEBUG_SERIAL) + return inb(CONFIG_DEBUG_SERIAL_PORT + offset); + if (CONFIG_DEBUG_SERIAL_MMIO) { + ASSERT32FLAT(); + return readb((void*)CONFIG_DEBUG_SERIAL_MEM_ADDRESS + 4*offset); + } +} + // Setup the debug serial port for output. void serial_debug_preinit(void) { - if (!CONFIG_DEBUG_SERIAL) + if (!CONFIG_DEBUG_SERIAL && (!CONFIG_DEBUG_SERIAL_MMIO || MODESEGMENT)) return; // setup for serial logging: 8N1 u8 oldparam, newparam = 0x03; - oldparam = inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_LCR); - outb(newparam, CONFIG_DEBUG_SERIAL_PORT+SEROFF_LCR); + oldparam = serial_debug_read(SEROFF_LCR); + serial_debug_write(SEROFF_LCR, newparam); // Disable irqs u8 oldier, newier = 0; - oldier = inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_IER); - outb(newier, CONFIG_DEBUG_SERIAL_PORT+SEROFF_IER); + oldier = serial_debug_read(SEROFF_IER); + serial_debug_write(SEROFF_IER, newier); if (oldparam != newparam || oldier != newier) dprintf(1, "Changing serial settings was %x/%x now %x/%x\n" @@ -41,14 +65,14 @@ serial_debug_preinit(void) static void serial_debug(char c) { - if (!CONFIG_DEBUG_SERIAL) + if (!CONFIG_DEBUG_SERIAL && (!CONFIG_DEBUG_SERIAL_MMIO || MODESEGMENT)) return; int timeout = DEBUG_TIMEOUT; - while ((inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_LSR) & 0x20) != 0x20) + while ((serial_debug_read(SEROFF_LSR) & 0x20) != 0x20) if (!timeout--) // Ran out of time. return; - outb(c, CONFIG_DEBUG_SERIAL_PORT+SEROFF_DATA); + serial_debug_write(SEROFF_DATA, c); } void @@ -63,10 +87,10 @@ serial_debug_putc(char c) void serial_debug_flush(void) { - if (!CONFIG_DEBUG_SERIAL) + if (!CONFIG_DEBUG_SERIAL && (!CONFIG_DEBUG_SERIAL_MMIO || MODESEGMENT)) return; int timeout = DEBUG_TIMEOUT; - while ((inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_LSR) & 0x60) != 0x60) + while ((serial_debug_read(SEROFF_LSR) & 0x60) != 0x60) if (!timeout--) // Ran out of time. return; -- 2.5.5 _______________________________________________ SeaBIOS mailing list [email protected] https://www.coreboot.org/mailman/listinfo/seabios
