See patch -- Stefan Reinauer Google Inc.
add support for OXPCIe 952 card and clean up debug abstraction layer
Signed-off-by: Stefan Reinauer <[email protected]> diff --git a/src/Kconfig b/src/Kconfig index fca73e4..38eb5d8 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -343,6 +343,13 @@ menu "Debugging" help Send debugging information to serial port. + config DEBUG_SERIAL_OXFORD + depends on DEBUG_LEVEL != 0 + bool "OXPCIe 952 serial port debugging" + default n + help + Send debugging information to serial port. + config SCREEN_AND_DEBUG depends on DEBUG_LEVEL != 0 bool "Show screen writes on debug ports" diff --git a/src/boot.c b/src/boot.c index 1cd4126..df11b8e 100644 --- a/src/boot.c +++ b/src/boot.c @@ -629,7 +629,7 @@ do_boot(u16 seq_nr) void VISIBLE32FLAT handle_18(void) { - debug_serial_setup(); + debug_setup(); debug_enter(NULL, DEBUG_HDL_18); u16 ebda_seg = get_ebda_seg(); u16 seq = GET_EBDA2(ebda_seg, boot_sequence) + 1; @@ -641,7 +641,7 @@ handle_18(void) void VISIBLE32FLAT handle_19(void) { - debug_serial_setup(); + debug_setup(); debug_enter(NULL, DEBUG_HDL_19); SET_EBDA(boot_sequence, 0); do_boot(0); diff --git a/src/optionroms.c b/src/optionroms.c index a94b46c..42cea88 100644 --- a/src/optionroms.c +++ b/src/optionroms.c @@ -99,7 +99,7 @@ __callrom(struct rom_header *rom, u16 offset, u16 bdf) call16big(&br); finish_preempt(); - debug_serial_setup(); + debug_setup(); } // Execute a given option rom at the standard entry vector. diff --git a/src/output.c b/src/output.c index 4c9f95b..f27bdb9 100644 --- a/src/output.c +++ b/src/output.c @@ -11,6 +11,7 @@ #include "bregs.h" // struct bregs #include "config.h" // CONFIG_* #include "biosvar.h" // GET_GLOBAL +#include "pci.h" // pci_find_device struct putcinfo { void (*func)(struct putcinfo *info, char c); @@ -24,7 +25,10 @@ struct putcinfo { #define DEBUG_PORT PORT_SERIAL1 #define DEBUG_TIMEOUT 100000 -void +#define OXPCIE_COM1 (oxpcie_bar + 0x1000) +u32 oxpcie_bar VAR16VISIBLE; + +static void debug_serial_setup(void) { if (!CONFIG_DEBUG_SERIAL) @@ -70,29 +74,114 @@ debug_serial_flush(void) return; } +static void +debug_serial_oxford_setup(void) +{ + if (!CONFIG_DEBUG_SERIAL_OXFORD) + return; + + int oxpcie_bdf; + oxpcie_bar = 0; + oxpcie_bdf = pci_find_device(0x1415, 0xc158); + if (oxpcie_bdf != -1) + oxpcie_bar = pci_config_readl(oxpcie_bdf, 0x10); + if (!oxpcie_bar) + return; + // setup for serial logging: 8N1 + u8 oldparam, newparam = 0x03; + oldparam = readb((void *)OXPCIE_COM1+SEROFF_LCR); + writeb((void *)OXPCIE_COM1+SEROFF_LCR, newparam); + // Disable irqs + u8 oldier, newier = 0; + oldier = readb((void *)OXPCIE_COM1+SEROFF_IER); + writeb((void *)OXPCIE_COM1+SEROFF_IER, newier); + + if (oldparam != newparam || oldier != newier) + dprintf(1, "Changing serial settings was %x/%x now %x/%x\n" + , oldparam, oldier, newparam, newier); +} + +// Write a character to the serial port. +static void +debug_serial_oxford(char c) +{ + if (!CONFIG_DEBUG_SERIAL_OXFORD) + return; + if (!oxpcie_bar) + return; + + int timeout = DEBUG_TIMEOUT; + while ((readb((void *)OXPCIE_COM1+SEROFF_LSR) & 0x60) != 0x60) + if (!timeout--) + // Ran out of time. + return; + writeb((void *)OXPCIE_COM1+SEROFF_DATA, c); +} + +// Make sure all serial port writes have been completely sent. +static void +debug_serial_oxford_flush(void) +{ + if (!CONFIG_DEBUG_SERIAL_OXFORD) + return; + if (!oxpcie_bar) + return; + int timeout = DEBUG_TIMEOUT; + + while ((readb((void *)OXPCIE_COM1+SEROFF_LSR) & 0x40) != 0x40) + if (!timeout--) + // Ran out of time. + return; +} + +void +debug_setup(void) +{ + if (! CONFIG_DEBUG_LEVEL) + return; + if (CONFIG_DEBUG_SERIAL) + debug_serial_setup(); + if (CONFIG_DEBUG_SERIAL_OXFORD) + debug_serial_oxford_setup(); +} + // Write a character to debug port(s). static void -putc_debug(struct putcinfo *action, char c) +debug_putc(struct putcinfo *action, char c) { if (! CONFIG_DEBUG_LEVEL) return; + if (c == '\n') + debug_putc(action, '\r'); if (! CONFIG_COREBOOT) // Send character to debug port. outb(c, PORT_BIOS_DEBUG); - if (c == '\n') - debug_serial('\r'); - debug_serial(c); + if (CONFIG_DEBUG_SERIAL) + debug_serial(c); + if (CONFIG_DEBUG_SERIAL_OXFORD) + debug_serial_oxford(c); +} + +static void +debug_flush(void) +{ + if (! CONFIG_DEBUG_LEVEL) + return; + if (CONFIG_DEBUG_SERIAL) + debug_serial_flush(); + if (CONFIG_DEBUG_SERIAL_OXFORD) + debug_serial_oxford_flush(); } -// In segmented mode just need a dummy variable (putc_debug is always +// In segmented mode just need a dummy variable (debug_putc is always // used anyway), and in 32bit flat mode need a pointer to the 32bit -// instance of putc_debug(). +// instance of debug_putc(). #if MODE16 static struct putcinfo debuginfo VAR16; #elif MODESEGMENT static struct putcinfo debuginfo VAR32SEG; #else -static struct putcinfo debuginfo = { putc_debug }; +static struct putcinfo debuginfo = { debug_putc }; #endif @@ -117,7 +206,7 @@ static void putc_screen(struct putcinfo *action, char c) { if (CONFIG_SCREEN_AND_DEBUG) - putc_debug(&debuginfo, c); + debug_putc(&debuginfo, c); if (c == '\n') screenc('\r'); screenc(c); @@ -136,7 +225,7 @@ putc(struct putcinfo *action, char c) { if (MODESEGMENT) { // Only debugging output supported in segmented mode. - putc_debug(action, c); + debug_putc(action, c); return; } @@ -325,7 +414,7 @@ panic(const char *fmt, ...) va_start(args, fmt); bvprintf(&debuginfo, fmt, args); va_end(args); - debug_serial_flush(); + debug_flush(); } // XXX - use PANIC PORT. @@ -342,10 +431,10 @@ __dprintf(const char *fmt, ...) struct thread_info *cur = getCurThread(); if (cur != &MainThread) { // Show "thread id" for this debug message. - putc_debug(&debuginfo, '|'); + debug_putc(&debuginfo, '|'); puthex(&debuginfo, (u32)cur, 8, 0); - putc_debug(&debuginfo, '|'); - putc_debug(&debuginfo, ' '); + debug_putc(&debuginfo, '|'); + debug_putc(&debuginfo, ' '); } } @@ -353,7 +442,7 @@ __dprintf(const char *fmt, ...) va_start(args, fmt); bvprintf(&debuginfo, fmt, args); va_end(args); - debug_serial_flush(); + debug_flush(); } void @@ -365,7 +454,7 @@ printf(const char *fmt, ...) bvprintf(&screeninfo, fmt, args); va_end(args); if (CONFIG_SCREEN_AND_DEBUG) - debug_serial_flush(); + debug_flush(); } @@ -456,7 +545,7 @@ hexdump(const void *d, int len) d+=4; } putc(&debuginfo, '\n'); - debug_serial_flush(); + debug_flush(); } static void @@ -480,7 +569,7 @@ __debug_isr(const char *fname) { puts_cs(&debuginfo, fname); putc(&debuginfo, '\n'); - debug_serial_flush(); + debug_flush(); } // Function called on handler startup. diff --git a/src/post.c b/src/post.c index 7d2b5f2..f39d862 100644 --- a/src/post.c +++ b/src/post.c @@ -373,7 +373,7 @@ _start(void) { init_dma(); - debug_serial_setup(); + debug_setup(); dprintf(1, "Start bios (version %s)\n", VERSION); if (HaveRunPost) diff --git a/src/resume.c b/src/resume.c index 20e2e3d..dacb889 100644 --- a/src/resume.c +++ b/src/resume.c @@ -30,7 +30,7 @@ handle_resume(u8 status) { init_dma(); - debug_serial_setup(); + debug_setup(); dprintf(1, "In resume (status=%d)\n", status); switch (status) { diff --git a/src/util.h b/src/util.h index 2160b37..5a0eb96 100644 --- a/src/util.h +++ b/src/util.h @@ -231,7 +231,7 @@ int wait_preempt(void); void check_preempt(void); // output.c -void debug_serial_setup(void); +void debug_setup(void); void panic(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))) __noreturn; void printf(const char *fmt, ...)
_______________________________________________ SeaBIOS mailing list [email protected] http://www.seabios.org/mailman/listinfo/seabios
