]> xenbits.xensource.com Git - seabios.git/commitdiff
serialio: Support for mmap serial ports
authorRicardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Tue, 20 Dec 2016 18:03:58 +0000 (19:03 +0100)
committerKevin O'Connor <kevin@koconnor.net>
Fri, 30 Dec 2016 16:29:08 +0000 (11:29 -0500)
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.

Tested-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
src/Kconfig
src/hw/serialio.c

index e767be1351c349d6755bc18b1e09cba3e516c753..457d082c15123174b851bf3856c4a3312c702edc 100644 (file)
@@ -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
index 6486fc086b1cd753da5c53a2f2944840a4c6f51e..319a85c16bfc9b6426c52f966879b224fb28c03d 100644 (file)
 
 #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;