aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2006-03-26 04:37:08 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-26 11:56:54 -0500
commitb2c99e3c70d77fb194df5aa1642030080d28ea48 (patch)
tree65f2a173e49b3e15e90b8cabf45b7dd4f3691e29 /drivers/firmware
parent27d8e3d15bcf9d7cd99bf6ca910ea9e34328c7fb (diff)
[PATCH] EFI: keep physical table addresses in efi structure
Almost all users of the table addresses from the EFI system table want physical addresses. So rather than doing the pa->va->pa conversion, just keep physical addresses in struct efi. This fixes a DMI bug: the efi structure contained the physical SMBIOS address on x86 but the virtual address on ia64, so dmi_scan_machine() used ioremap() on a virtual address on ia64. This is essentially the same as an earlier patch by Matt Tolentino: http://marc.theaimsgroup.com/?l=linux-kernel&m=112130292316281&w=2 except that this changes all table addresses, not just ACPI addresses. Matt's original patch was backed out because it caused MCAs on HP sx1000 systems. That problem is resolved by the ioremap() attribute checking added for ia64. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Cc: Matt Domsch <Matt_Domsch@dell.com> Cc: "Tolentino, Matthew E" <matthew.e.tolentino@intel.com> Cc: "Brown, Len" <len.brown@intel.com> Cc: Andi Kleen <ak@muc.de> Acked-by: "Luck, Tony" <tony.luck@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/efivars.c28
-rw-r--r--drivers/firmware/pcdp.c19
2 files changed, 26 insertions, 21 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 343379f23a53..9b7e4d52ffd4 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -568,20 +568,20 @@ systab_read(struct subsystem *entry, char *buf)
568 if (!entry || !buf) 568 if (!entry || !buf)
569 return -EINVAL; 569 return -EINVAL;
570 570
571 if (efi.mps) 571 if (efi.mps != EFI_INVALID_TABLE_ADDR)
572 str += sprintf(str, "MPS=0x%lx\n", __pa(efi.mps)); 572 str += sprintf(str, "MPS=0x%lx\n", efi.mps);
573 if (efi.acpi20) 573 if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
574 str += sprintf(str, "ACPI20=0x%lx\n", __pa(efi.acpi20)); 574 str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20);
575 if (efi.acpi) 575 if (efi.acpi != EFI_INVALID_TABLE_ADDR)
576 str += sprintf(str, "ACPI=0x%lx\n", __pa(efi.acpi)); 576 str += sprintf(str, "ACPI=0x%lx\n", efi.acpi);
577 if (efi.smbios) 577 if (efi.smbios != EFI_INVALID_TABLE_ADDR)
578 str += sprintf(str, "SMBIOS=0x%lx\n", __pa(efi.smbios)); 578 str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
579 if (efi.hcdp) 579 if (efi.hcdp != EFI_INVALID_TABLE_ADDR)
580 str += sprintf(str, "HCDP=0x%lx\n", __pa(efi.hcdp)); 580 str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp);
581 if (efi.boot_info) 581 if (efi.boot_info != EFI_INVALID_TABLE_ADDR)
582 str += sprintf(str, "BOOTINFO=0x%lx\n", __pa(efi.boot_info)); 582 str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info);
583 if (efi.uga) 583 if (efi.uga != EFI_INVALID_TABLE_ADDR)
584 str += sprintf(str, "UGA=0x%lx\n", __pa(efi.uga)); 584 str += sprintf(str, "UGA=0x%lx\n", efi.uga);
585 585
586 return str - buf; 586 return str - buf;
587} 587}
diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c
index ae1fb45dbb40..c37baf9448bc 100644
--- a/drivers/firmware/pcdp.c
+++ b/drivers/firmware/pcdp.c
@@ -89,19 +89,20 @@ efi_setup_pcdp_console(char *cmdline)
89 struct pcdp_uart *uart; 89 struct pcdp_uart *uart;
90 struct pcdp_device *dev, *end; 90 struct pcdp_device *dev, *end;
91 int i, serial = 0; 91 int i, serial = 0;
92 int rc = -ENODEV;
92 93
93 pcdp = efi.hcdp; 94 if (efi.hcdp == EFI_INVALID_TABLE_ADDR)
94 if (!pcdp)
95 return -ENODEV; 95 return -ENODEV;
96 96
97 printk(KERN_INFO "PCDP: v%d at 0x%lx\n", pcdp->rev, __pa(pcdp)); 97 pcdp = ioremap(efi.hcdp, 4096);
98 printk(KERN_INFO "PCDP: v%d at 0x%lx\n", pcdp->rev, efi.hcdp);
98 99
99 if (strstr(cmdline, "console=hcdp")) { 100 if (strstr(cmdline, "console=hcdp")) {
100 if (pcdp->rev < 3) 101 if (pcdp->rev < 3)
101 serial = 1; 102 serial = 1;
102 } else if (strstr(cmdline, "console=")) { 103 } else if (strstr(cmdline, "console=")) {
103 printk(KERN_INFO "Explicit \"console=\"; ignoring PCDP\n"); 104 printk(KERN_INFO "Explicit \"console=\"; ignoring PCDP\n");
104 return -ENODEV; 105 goto out;
105 } 106 }
106 107
107 if (pcdp->rev < 3 && efi_uart_console_only()) 108 if (pcdp->rev < 3 && efi_uart_console_only())
@@ -110,7 +111,8 @@ efi_setup_pcdp_console(char *cmdline)
110 for (i = 0, uart = pcdp->uart; i < pcdp->num_uarts; i++, uart++) { 111 for (i = 0, uart = pcdp->uart; i < pcdp->num_uarts; i++, uart++) {
111 if (uart->flags & PCDP_UART_PRIMARY_CONSOLE || serial) { 112 if (uart->flags & PCDP_UART_PRIMARY_CONSOLE || serial) {
112 if (uart->type == PCDP_CONSOLE_UART) { 113 if (uart->type == PCDP_CONSOLE_UART) {
113 return setup_serial_console(uart); 114 rc = setup_serial_console(uart);
115 goto out;
114 } 116 }
115 } 117 }
116 } 118 }
@@ -121,10 +123,13 @@ efi_setup_pcdp_console(char *cmdline)
121 dev = (struct pcdp_device *) ((u8 *) dev + dev->length)) { 123 dev = (struct pcdp_device *) ((u8 *) dev + dev->length)) {
122 if (dev->flags & PCDP_PRIMARY_CONSOLE) { 124 if (dev->flags & PCDP_PRIMARY_CONSOLE) {
123 if (dev->type == PCDP_CONSOLE_VGA) { 125 if (dev->type == PCDP_CONSOLE_VGA) {
124 return setup_vga_console(dev); 126 rc = setup_vga_console(dev);
127 goto out;
125 } 128 }
126 } 129 }
127 } 130 }
128 131
129 return -ENODEV; 132out:
133 iounmap(pcdp);
134 return rc;
130} 135}