pcdp.c revision 97d3a00f77fa527886d53dd943017654ce142186
1/* 2 * Parse the EFI PCDP table to locate the console device. 3 * 4 * (c) Copyright 2002, 2003, 2004 Hewlett-Packard Development Company, L.P. 5 * Khalid Aziz <khalid.aziz@hp.com> 6 * Alex Williamson <alex.williamson@hp.com> 7 * Bjorn Helgaas <bjorn.helgaas@hp.com> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 */ 13 14#include <linux/config.h> 15#include <linux/acpi.h> 16#include <linux/console.h> 17#include <linux/efi.h> 18#include <linux/serial.h> 19#include "pcdp.h" 20 21static int __init 22setup_serial_console(struct pcdp_uart *uart) 23{ 24#ifdef CONFIG_SERIAL_8250_CONSOLE 25 int mmio; 26 static char options[64]; 27 28 mmio = (uart->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY); 29 snprintf(options, sizeof(options), "console=uart,%s,0x%lx,%lun%d", 30 mmio ? "mmio" : "io", uart->addr.address, uart->baud, 31 uart->bits ? uart->bits : 8); 32 33 return early_serial_console_init(options); 34#else 35 return -ENODEV; 36#endif 37} 38 39static int __init 40setup_vga_console(struct pcdp_vga *vga) 41{ 42#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) 43 if (efi_mem_type(0xA0000) == EFI_CONVENTIONAL_MEMORY) { 44 printk(KERN_ERR "PCDP: VGA selected, but frame buffer is not MMIO!\n"); 45 return -ENODEV; 46 } 47 48 conswitchp = &vga_con; 49 printk(KERN_INFO "PCDP: VGA console\n"); 50 return 0; 51#else 52 return -ENODEV; 53#endif 54} 55 56int __init 57efi_setup_pcdp_console(char *cmdline) 58{ 59 struct pcdp *pcdp; 60 struct pcdp_uart *uart; 61 struct pcdp_device *dev, *end; 62 int i, serial = 0; 63 64 pcdp = efi.hcdp; 65 if (!pcdp) 66 return -ENODEV; 67 68 printk(KERN_INFO "PCDP: v%d at 0x%lx\n", pcdp->rev, __pa(pcdp)); 69 70 if (strstr(cmdline, "console=hcdp")) { 71 if (pcdp->rev < 3) 72 serial = 1; 73 } else if (strstr(cmdline, "console=")) { 74 printk(KERN_INFO "Explicit \"console=\"; ignoring PCDP\n"); 75 return -ENODEV; 76 } 77 78 if (pcdp->rev < 3 && efi_uart_console_only()) 79 serial = 1; 80 81 for (i = 0, uart = pcdp->uart; i < pcdp->num_uarts; i++, uart++) { 82 if (uart->flags & PCDP_UART_PRIMARY_CONSOLE || serial) { 83 if (uart->type == PCDP_CONSOLE_UART) { 84 return setup_serial_console(uart); 85 } 86 } 87 } 88 89 end = (struct pcdp_device *) ((u8 *) pcdp + pcdp->length); 90 for (dev = (struct pcdp_device *) (pcdp->uart + pcdp->num_uarts); 91 dev < end; 92 dev = (struct pcdp_device *) ((u8 *) dev + dev->length)) { 93 if (dev->flags & PCDP_PRIMARY_CONSOLE) { 94 if (dev->type == PCDP_CONSOLE_VGA) { 95 return setup_vga_console((struct pcdp_vga *) dev); 96 } 97 } 98 } 99 100 return -ENODEV; 101} 102