[SeaBIOS] [RFC PATCH] Add support for Intel Quark UART.

David Woodhouse dwmw2 at infradead.org
Fri Nov 29 15:02:02 CET 2013


This provides basic debug output on the Quark system, assuming that
*something* (i.e. coreboot or UEFI) has set it up in advance for us.

Signed-off-by: David Woodhouse <David.Woodhouse at intel.com>
---
I looked briefly at making this part of the CONFIG_DEBUG_SERIAL code,
and making that generic enough to handle I/O access *or* MMIO access
depending on what's present... but in fact that's probably overkill.

This isn't really limited to Quark; it would work with any 16550 device
wired up as MMIO32. But we can expand it as required, I think. No point
in starting off with the same functionality as the 5000-odd lines of the
Linux kernel's 8250_pci.c.

What do I need to do if called in 32-bit segmented mode? I'm guessing
that's not going to work right now...

 src/Kconfig  |  5 +++++
 src/fw/csm.c |  2 ++
 src/output.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)

diff --git a/src/Kconfig b/src/Kconfig
index a42ab2d..bdc2602 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -472,6 +472,11 @@ menu "Debugging"
 
             Set to zero to disable debugging.
 
+    config DEBUG_QUARK_UART
+        depends on DEBUG_LEVEL != 0
+        bool "Debug to Quark UART #1"
+        default n
+
     config DEBUG_SERIAL
         depends on DEBUG_LEVEL != 0
         bool "Serial port debugging"
diff --git a/src/fw/csm.c b/src/fw/csm.c
index dfb0d12..afd7ffe 100644
--- a/src/fw/csm.c
+++ b/src/fw/csm.c
@@ -280,6 +280,8 @@ handle_csm(struct bregs *regs)
     if (!CONFIG_CSM)
         return;
 
+    debug_serial_preinit();
+
     dprintf(3, "handle_csm regs %p AX=%04x\n", regs, regs->ax);
 
     pic_irqmask_write(PICMask);
diff --git a/src/output.c b/src/output.c
index b47625f..a90d350 100644
--- a/src/output.c
+++ b/src/output.c
@@ -17,6 +17,8 @@
 #include "stacks.h" // call16_int
 #include "string.h" // memset
 #include "util.h" // ScreenAndDebug
+#include "hw/pci_regs.h" // PCI_VENDOR_ID, PCI_BASE_ADDRESS_0
+#include "hw/pci.h" // pci_config_readl
 
 struct putcinfo {
     void (*func)(struct putcinfo *info, char c);
@@ -31,9 +33,59 @@ struct putcinfo {
 
 u16 DebugOutputPort VARFSEG = 0x402;
 
+static volatile u32 *quark_uart_addr = 0;
+
+extern void _cfunc32flat_quark_uart_preinit(void);
+extern void _cfunc32flat_quark_uart_putc(void);
+extern void _cfunc32flat_quark_uart_flush(void);
+
+void quark_uart_preinit(void)
+{
+    // debug port is bus 0, device 0x14, function 5.
+    u16 uart_bdf = pci_to_bdf(0, 0x14, 5);
+
+    // If it isn't a Quark UART...
+    if (pci_config_readl(uart_bdf, PCI_VENDOR_ID) != 0x09368086)
+        return;
+
+    u32 bar0 = pci_config_readl(uart_bdf, PCI_BASE_ADDRESS_0);
+    if (!(bar0 & 0xf))
+        quark_uart_addr = (void *)bar0;
+}
+
+void quark_uart_putc(char c)
+{
+    if (!quark_uart_addr)
+        return;
+
+    int timeout = DEBUG_TIMEOUT;
+    while ((quark_uart_addr[SEROFF_LSR] & 0x20) != 0x20)
+        if (!timeout--)
+            // Ran out of time.
+            return;
+    quark_uart_addr[SEROFF_DATA] = c;
+}
+
+void quark_uart_flush(void)
+{
+    if (!quark_uart_addr)
+        return;
+    int timeout = DEBUG_TIMEOUT;
+    while ((quark_uart_addr[SEROFF_LSR] & 0x60) != 0x60)
+        if (!timeout--)
+            // Ran out of time.
+            return;
+}
+
 void
 debug_serial_preinit(void)
 {
+    if (CONFIG_DEBUG_QUARK_UART) {
+	    if (MODE16)
+		    call32(_cfunc32flat_quark_uart_preinit, 0, 0);
+	    else
+		    quark_uart_preinit();
+    }
     if (!CONFIG_DEBUG_SERIAL)
         return;
     // setup for serial logging: 8N1
@@ -54,6 +106,12 @@ debug_serial_preinit(void)
 static void
 debug_serial(char c)
 {
+    if (CONFIG_DEBUG_QUARK_UART) {
+	    if (MODE16)
+		    call32(_cfunc32flat_quark_uart_putc, c, 0);
+	    else
+		    quark_uart_putc(c);
+    }
     if (!CONFIG_DEBUG_SERIAL)
         return;
     int timeout = DEBUG_TIMEOUT;
@@ -68,6 +126,12 @@ debug_serial(char c)
 static void
 debug_serial_flush(void)
 {
+    if (CONFIG_DEBUG_QUARK_UART) {
+	    if (MODE16)
+		    call32(_cfunc32flat_quark_uart_flush, 0, 0);
+	    else
+		    quark_uart_flush();
+    }
     if (!CONFIG_DEBUG_SERIAL)
         return;
     int timeout = DEBUG_TIMEOUT;
-- 
1.8.3.1


-- 
dwmw2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5745 bytes
Desc: not available
URL: <http://www.seabios.org/pipermail/seabios/attachments/20131129/7f37dd7c/attachment.bin>


More information about the SeaBIOS mailing list