diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/firmware/pcdp.c | 24 | ||||
-rw-r--r-- | drivers/firmware/pcdp.h | 33 |
2 files changed, 50 insertions, 7 deletions
diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c index 839b44a..53c95c0 100644 --- a/drivers/firmware/pcdp.c +++ b/drivers/firmware/pcdp.c @@ -16,6 +16,7 @@ #include <linux/console.h> #include <linux/efi.h> #include <linux/serial.h> +#include <asm/vga.h> #include "pcdp.h" static int __init @@ -40,10 +41,27 @@ setup_serial_console(struct pcdp_uart *uart) } static int __init -setup_vga_console(struct pcdp_vga *vga) +setup_vga_console(struct pcdp_device *dev) { #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) - if (efi_mem_type(0xA0000) == EFI_CONVENTIONAL_MEMORY) { + u8 *if_ptr; + + if_ptr = ((u8 *)dev + sizeof(struct pcdp_device)); + if (if_ptr[0] == PCDP_IF_PCI) { + struct pcdp_if_pci if_pci; + + /* struct copy since ifptr might not be correctly aligned */ + + memcpy(&if_pci, if_ptr, sizeof(if_pci)); + + if (if_pci.trans & PCDP_PCI_TRANS_IOPORT) + vga_console_iobase = if_pci.ioport_tra; + + if (if_pci.trans & PCDP_PCI_TRANS_MMIO) + vga_console_membase = if_pci.mmio_tra; + } + + if (efi_mem_type(vga_console_membase + 0xA0000) == EFI_CONVENTIONAL_MEMORY) { printk(KERN_ERR "PCDP: VGA selected, but frame buffer is not MMIO!\n"); return -ENODEV; } @@ -95,7 +113,7 @@ efi_setup_pcdp_console(char *cmdline) dev = (struct pcdp_device *) ((u8 *) dev + dev->length)) { if (dev->flags & PCDP_PRIMARY_CONSOLE) { if (dev->type == PCDP_CONSOLE_VGA) { - return setup_vga_console((struct pcdp_vga *) dev); + return setup_vga_console(dev); } } } diff --git a/drivers/firmware/pcdp.h b/drivers/firmware/pcdp.h index 1dc7c88..e72cc47 100644 --- a/drivers/firmware/pcdp.h +++ b/drivers/firmware/pcdp.h @@ -52,11 +52,34 @@ struct pcdp_uart { u32 clock_rate; u8 pci_prog_intfc; u8 flags; -}; +} __attribute__((packed)); + +#define PCDP_IF_PCI 1 + +/* pcdp_if_pci.trans */ +#define PCDP_PCI_TRANS_IOPORT 0x02 +#define PCDP_PCI_TRANS_MMIO 0x01 + +struct pcdp_if_pci { + u8 interconnect; + u8 reserved; + u16 length; + u8 segment; + u8 bus; + u8 dev; + u8 fun; + u16 dev_id; + u16 vendor_id; + u32 acpi_interrupt; + u64 mmio_tra; + u64 ioport_tra; + u8 flags; + u8 trans; +} __attribute__((packed)); struct pcdp_vga { u8 count; /* address space descriptors */ -}; +} __attribute__((packed)); /* pcdp_device.flags */ #define PCDP_PRIMARY_CONSOLE 1 @@ -66,7 +89,9 @@ struct pcdp_device { u8 flags; u16 length; u16 efi_index; -}; + /* next data is pcdp_if_pci or pcdp_if_acpi (not yet supported) */ + /* next data is device specific type (currently only pcdp_vga) */ +} __attribute__((packed)); struct pcdp { u8 signature[4]; @@ -81,4 +106,4 @@ struct pcdp { u32 num_uarts; struct pcdp_uart uart[0]; /* actual size is num_uarts */ /* remainder of table is pcdp_device structures */ -}; +} __attribute__((packed)); |