diff -u -r -X /home/helgaas/exclude linux-2.4.18-ia64-020719/Documentation/Configure.help 10_early_printk/Documentation/Configure.help --- linux-2.4.18-ia64-020719/Documentation/Configure.help Sun Jul 21 03:03:28 2002 +++ 10_early_printk/Documentation/Configure.help Sun Jul 21 03:03:31 2002 @@ -23866,12 +23866,29 @@ and restore instructions. It's useful for tracking down spinlock problems, but slow! If you're unsure, select N. -Early printk support (requires VGA!) +Early printk support CONFIG_IA64_EARLY_PRINTK - Selecting this option uses the VGA screen for printk() output before - the consoles are initialised. It is useful for debugging problems - early in the boot process, but only if you have a VGA screen - attached. If you're unsure, select N. + Selecting this option uses a UART or VGA screen (or both) for + printk() output before the consoles are initialised. It is useful + for debugging problems early in the boot process, but only if you + have a serial terminal or a VGA screen attached. If you're unsure, + select N. + +Early printk on serial port +CONFIG_IA64_EARLY_PRINTK_UART + Select this option to use a serial port for early printk() output. + You must either select CONFIG_SERIAL_HCDP (to locate the UART + using the EFI HCDP table) or set the UART address explicitly + with CONFIG_IA64_EARLY_PRINTK_UART_BASE. + +UART base address +CONFIG_IA64_EARLY_PRINTK_UART_BASE + The physical MMIO address of the UART to use for early printk(). + This overrides any UART located using the EFI HCDP table. + +Early printk on VGA +CONFIG_IA64_EARLY_PRINTK_VGA + Select this option to use VGA for early printk() output. Print possible IA64 hazards to console CONFIG_IA64_PRINT_HAZARDS diff -u -r -X /home/helgaas/exclude linux-2.4.18-ia64-020719/arch/ia64/config.in 10_early_printk/arch/ia64/config.in --- linux-2.4.18-ia64-020719/arch/ia64/config.in Sun Jul 21 03:03:28 2002 +++ 10_early_printk/arch/ia64/config.in Sun Jul 21 03:03:31 2002 @@ -294,7 +294,14 @@ bool ' Disable VHPT' CONFIG_DISABLE_VHPT bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ - bool ' Early printk support (requires VGA!)' CONFIG_IA64_EARLY_PRINTK + bool ' Early printk support' CONFIG_IA64_EARLY_PRINTK + if [ "$CONFIG_IA64_EARLY_PRINTK" != "n" ]; then + bool ' Early printk on MMIO serial port' CONFIG_IA64_EARLY_PRINTK_UART + if [ "$CONFIG_IA64_EARLY_PRINTK_UART" != "n" ]; then + hex ' UART MMIO base address' CONFIG_IA64_EARLY_PRINTK_UART_BASE 0 + fi + bool ' Early printk on VGA' CONFIG_IA64_EARLY_PRINTK_VGA + fi bool ' Debug memory allocations' CONFIG_DEBUG_SLAB bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK bool ' Turn on compare-and-exchange bug checking (slow!)' CONFIG_IA64_DEBUG_CMPXCHG diff -u -r -X /home/helgaas/exclude linux-2.4.18-ia64-020719/drivers/char/hcdp_serial.c 10_early_printk/drivers/char/hcdp_serial.c --- linux-2.4.18-ia64-020719/drivers/char/hcdp_serial.c Sun Jul 21 03:03:29 2002 +++ 10_early_printk/drivers/char/hcdp_serial.c Mon Jul 22 05:07:15 2002 @@ -219,3 +219,41 @@ printk("Leaving setup_serial_hcdp()\n"); #endif } + +#ifdef CONFIG_IA64_EARLY_PRINTK_UART +unsigned long hcdp_early_uart(void) +{ + efi_system_table_t *systab; + efi_config_table_t *config_tables; + hcdp_t *hcdp = 0; + hcdp_dev_t *dev; + int i; + + systab = (efi_system_table_t *) ia64_boot_param->efi_systab; + if (!systab) + return 0; + systab = __va(systab); + + config_tables = (efi_config_table_t *) systab->tables; + if (!config_tables) + return 0; + config_tables = __va(config_tables); + + for (i = 0; i < systab->nr_tables; i++) { + if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) { + hcdp = (hcdp_t *) config_tables[i].table; + break; + } + } + if (!hcdp) + return 0; + hcdp = __va(hcdp); + + for (i = 0, dev = hcdp->hcdp_dev; i < hcdp->num_entries; i++, dev++) { + if (dev->type == HCDP_DEV_CONSOLE) + return (u64) dev->base_addr.addrhi << 32 + | dev->base_addr.addrlo; + } + return 0; +} +#endif diff -u -r -X /home/helgaas/exclude linux-2.4.18-ia64-020719/kernel/printk.c 10_early_printk/kernel/printk.c --- linux-2.4.18-ia64-020719/kernel/printk.c Sun Jul 21 03:03:30 2002 +++ 10_early_printk/kernel/printk.c Mon Jul 22 05:05:47 2002 @@ -694,6 +694,47 @@ #ifdef CONFIG_IA64_EARLY_PRINTK +#ifdef CONFIG_IA64_EARLY_PRINTK_UART + +#include +#include + +static void early_printk_uart(const char *str, size_t len) +{ + static char *uart = 0; + unsigned long uart_base; + char c; + + if (!uart) { +#ifdef CONFIG_SERIAL_HCDP + extern unsigned long hcdp_early_uart(void); + uart_base = hcdp_early_uart(); +#endif +#if CONFIG_IA64_EARLY_PRINTK_UART_BASE + uart_base = CONFIG_IA64_EARLY_PRINTK_UART_BASE; +#endif + if (uart_base) + uart = ioremap(uart_base, 64); + } + + if (!uart) + return; + + while (len-- > 0) { + c = *str++; + while (!(UART_LSR_TEMT & readb(uart + UART_LSR))) + ; /* spin */ + + writeb(c, uart + UART_TX); + + if (c == '\n') + writeb('\r', uart + UART_TX); + } +} +#endif /* CONFIG_IA64_EARLY_PRINTK_UART */ + +#ifdef CONFIG_IA64_EARLY_PRINTK_VGA + #include #define VGABASE ((char *)0xc0000000000b8000) @@ -702,8 +743,7 @@ static int current_ypos = VGALINES, current_xpos = 0; -void -early_printk (const char *str, size_t len) +static void early_printk_vga(const char *str, size_t len) { char c; int i, k, j; @@ -735,6 +775,17 @@ } } } +} +#endif /* CONFIG_IA64_EARLY_PRINTK_VGA */ + +void early_printk(const char *str, size_t len) +{ +#ifdef CONFIG_IA64_EARLY_PRINTK_UART + early_printk_uart(str, len); +#endif +#ifdef CONFIG_IA64_EARLY_PRINTK_VGA + early_printk_vga(str, len); +#endif } #endif /* CONFIG_IA64_EARLY_PRINTK */