diff options
author | Matt Fleming <matt.fleming@intel.com> | 2013-09-05 14:55:00 -0400 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2013-09-05 14:55:00 -0400 |
commit | 9efff3899b90e5ead9e676af9736e891ee23ce41 (patch) | |
tree | 9a07ec52e822200704c8af9efea9a8971545cc98 | |
parent | 6f9dd30c22da4e48c4b7b837e9641f072e673161 (diff) | |
parent | 258f6fd738221766b512cd8c7120563b78d62829 (diff) |
Merge branch 'arm/efi-stub' into next
-rw-r--r-- | arch/ia64/include/asm/io.h | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/efi.c | 54 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi.c | 126 | ||||
-rw-r--r-- | drivers/firmware/efi/efi.c | 140 | ||||
-rw-r--r-- | include/linux/efi.h | 8 |
5 files changed, 170 insertions, 159 deletions
diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h index 74a7cc3293bc..0d2bcb37ec35 100644 --- a/arch/ia64/include/asm/io.h +++ b/arch/ia64/include/asm/io.h | |||
@@ -424,6 +424,7 @@ extern void __iomem * ioremap(unsigned long offset, unsigned long size); | |||
424 | extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size); | 424 | extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size); |
425 | extern void iounmap (volatile void __iomem *addr); | 425 | extern void iounmap (volatile void __iomem *addr); |
426 | extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size); | 426 | extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size); |
427 | #define early_memremap(phys_addr, size) early_ioremap(phys_addr, size) | ||
427 | extern void early_iounmap (volatile void __iomem *addr, unsigned long size); | 428 | extern void early_iounmap (volatile void __iomem *addr, unsigned long size); |
428 | static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size) | 429 | static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size) |
429 | { | 430 | { |
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 51bce594eb83..da5b462e6de6 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c | |||
@@ -44,10 +44,15 @@ | |||
44 | 44 | ||
45 | #define EFI_DEBUG 0 | 45 | #define EFI_DEBUG 0 |
46 | 46 | ||
47 | static __initdata unsigned long palo_phys; | ||
48 | |||
49 | static __initdata efi_config_table_type_t arch_tables[] = { | ||
50 | {PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID, "PALO", &palo_phys}, | ||
51 | {NULL_GUID, NULL, 0}, | ||
52 | }; | ||
53 | |||
47 | extern efi_status_t efi_call_phys (void *, ...); | 54 | extern efi_status_t efi_call_phys (void *, ...); |
48 | 55 | ||
49 | struct efi efi; | ||
50 | EXPORT_SYMBOL(efi); | ||
51 | static efi_runtime_services_t *runtime; | 56 | static efi_runtime_services_t *runtime; |
52 | static u64 mem_limit = ~0UL, max_addr = ~0UL, min_addr = 0UL; | 57 | static u64 mem_limit = ~0UL, max_addr = ~0UL, min_addr = 0UL; |
53 | 58 | ||
@@ -423,9 +428,9 @@ static u8 __init palo_checksum(u8 *buffer, u32 length) | |||
423 | * Parse and handle PALO table which is published at: | 428 | * Parse and handle PALO table which is published at: |
424 | * http://www.dig64.org/home/DIG64_PALO_R1_0.pdf | 429 | * http://www.dig64.org/home/DIG64_PALO_R1_0.pdf |
425 | */ | 430 | */ |
426 | static void __init handle_palo(unsigned long palo_phys) | 431 | static void __init handle_palo(unsigned long phys_addr) |
427 | { | 432 | { |
428 | struct palo_table *palo = __va(palo_phys); | 433 | struct palo_table *palo = __va(phys_addr); |
429 | u8 checksum; | 434 | u8 checksum; |
430 | 435 | ||
431 | if (strncmp(palo->signature, PALO_SIG, sizeof(PALO_SIG) - 1)) { | 436 | if (strncmp(palo->signature, PALO_SIG, sizeof(PALO_SIG) - 1)) { |
@@ -467,12 +472,10 @@ void __init | |||
467 | efi_init (void) | 472 | efi_init (void) |
468 | { | 473 | { |
469 | void *efi_map_start, *efi_map_end; | 474 | void *efi_map_start, *efi_map_end; |
470 | efi_config_table_t *config_tables; | ||
471 | efi_char16_t *c16; | 475 | efi_char16_t *c16; |
472 | u64 efi_desc_size; | 476 | u64 efi_desc_size; |
473 | char *cp, vendor[100] = "unknown"; | 477 | char *cp, vendor[100] = "unknown"; |
474 | int i; | 478 | int i; |
475 | unsigned long palo_phys; | ||
476 | 479 | ||
477 | /* | 480 | /* |
478 | * It's too early to be able to use the standard kernel command line | 481 | * It's too early to be able to use the standard kernel command line |
@@ -514,8 +517,6 @@ efi_init (void) | |||
514 | efi.systab->hdr.revision >> 16, | 517 | efi.systab->hdr.revision >> 16, |
515 | efi.systab->hdr.revision & 0xffff); | 518 | efi.systab->hdr.revision & 0xffff); |
516 | 519 | ||
517 | config_tables = __va(efi.systab->tables); | ||
518 | |||
519 | /* Show what we know for posterity */ | 520 | /* Show what we know for posterity */ |
520 | c16 = __va(efi.systab->fw_vendor); | 521 | c16 = __va(efi.systab->fw_vendor); |
521 | if (c16) { | 522 | if (c16) { |
@@ -528,43 +529,10 @@ efi_init (void) | |||
528 | efi.systab->hdr.revision >> 16, | 529 | efi.systab->hdr.revision >> 16, |
529 | efi.systab->hdr.revision & 0xffff, vendor); | 530 | efi.systab->hdr.revision & 0xffff, vendor); |
530 | 531 | ||
531 | efi.mps = EFI_INVALID_TABLE_ADDR; | ||
532 | efi.acpi = EFI_INVALID_TABLE_ADDR; | ||
533 | efi.acpi20 = EFI_INVALID_TABLE_ADDR; | ||
534 | efi.smbios = EFI_INVALID_TABLE_ADDR; | ||
535 | efi.sal_systab = EFI_INVALID_TABLE_ADDR; | ||
536 | efi.boot_info = EFI_INVALID_TABLE_ADDR; | ||
537 | efi.hcdp = EFI_INVALID_TABLE_ADDR; | ||
538 | efi.uga = EFI_INVALID_TABLE_ADDR; | ||
539 | |||
540 | palo_phys = EFI_INVALID_TABLE_ADDR; | 532 | palo_phys = EFI_INVALID_TABLE_ADDR; |
541 | 533 | ||
542 | for (i = 0; i < (int) efi.systab->nr_tables; i++) { | 534 | if (efi_config_init(arch_tables) != 0) |
543 | if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) { | 535 | return; |
544 | efi.mps = config_tables[i].table; | ||
545 | printk(" MPS=0x%lx", config_tables[i].table); | ||
546 | } else if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) { | ||
547 | efi.acpi20 = config_tables[i].table; | ||
548 | printk(" ACPI 2.0=0x%lx", config_tables[i].table); | ||
549 | } else if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) { | ||
550 | efi.acpi = config_tables[i].table; | ||
551 | printk(" ACPI=0x%lx", config_tables[i].table); | ||
552 | } else if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) { | ||
553 | efi.smbios = config_tables[i].table; | ||
554 | printk(" SMBIOS=0x%lx", config_tables[i].table); | ||
555 | } else if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) == 0) { | ||
556 | efi.sal_systab = config_tables[i].table; | ||
557 | printk(" SALsystab=0x%lx", config_tables[i].table); | ||
558 | } else if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) { | ||
559 | efi.hcdp = config_tables[i].table; | ||
560 | printk(" HCDP=0x%lx", config_tables[i].table); | ||
561 | } else if (efi_guidcmp(config_tables[i].guid, | ||
562 | PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID) == 0) { | ||
563 | palo_phys = config_tables[i].table; | ||
564 | printk(" PALO=0x%lx", config_tables[i].table); | ||
565 | } | ||
566 | } | ||
567 | printk("\n"); | ||
568 | 536 | ||
569 | if (palo_phys != EFI_INVALID_TABLE_ADDR) | 537 | if (palo_phys != EFI_INVALID_TABLE_ADDR) |
570 | handle_palo(palo_phys); | 538 | handle_palo(palo_phys); |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 90f6ed127096..fbc1d70188f8 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -60,19 +60,6 @@ | |||
60 | 60 | ||
61 | static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; | 61 | static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; |
62 | 62 | ||
63 | struct efi __read_mostly efi = { | ||
64 | .mps = EFI_INVALID_TABLE_ADDR, | ||
65 | .acpi = EFI_INVALID_TABLE_ADDR, | ||
66 | .acpi20 = EFI_INVALID_TABLE_ADDR, | ||
67 | .smbios = EFI_INVALID_TABLE_ADDR, | ||
68 | .sal_systab = EFI_INVALID_TABLE_ADDR, | ||
69 | .boot_info = EFI_INVALID_TABLE_ADDR, | ||
70 | .hcdp = EFI_INVALID_TABLE_ADDR, | ||
71 | .uga = EFI_INVALID_TABLE_ADDR, | ||
72 | .uv_systab = EFI_INVALID_TABLE_ADDR, | ||
73 | }; | ||
74 | EXPORT_SYMBOL(efi); | ||
75 | |||
76 | struct efi_memory_map memmap; | 63 | struct efi_memory_map memmap; |
77 | 64 | ||
78 | static struct efi efi_phys __initdata; | 65 | static struct efi efi_phys __initdata; |
@@ -80,6 +67,13 @@ static efi_system_table_t efi_systab __initdata; | |||
80 | 67 | ||
81 | unsigned long x86_efi_facility; | 68 | unsigned long x86_efi_facility; |
82 | 69 | ||
70 | static __initdata efi_config_table_type_t arch_tables[] = { | ||
71 | #ifdef CONFIG_X86_UV | ||
72 | {UV_SYSTEM_TABLE_GUID, "UVsystab", &efi.uv_systab}, | ||
73 | #endif | ||
74 | {NULL_GUID, NULL, 0}, | ||
75 | }; | ||
76 | |||
83 | /* | 77 | /* |
84 | * Returns 1 if 'facility' is enabled, 0 otherwise. | 78 | * Returns 1 if 'facility' is enabled, 0 otherwise. |
85 | */ | 79 | */ |
@@ -399,6 +393,8 @@ int __init efi_memblock_x86_reserve_range(void) | |||
399 | 393 | ||
400 | memblock_reserve(pmap, memmap.nr_map * memmap.desc_size); | 394 | memblock_reserve(pmap, memmap.nr_map * memmap.desc_size); |
401 | 395 | ||
396 | efi.memmap = &memmap; | ||
397 | |||
402 | return 0; | 398 | return 0; |
403 | } | 399 | } |
404 | 400 | ||
@@ -578,80 +574,6 @@ static int __init efi_systab_init(void *phys) | |||
578 | return 0; | 574 | return 0; |
579 | } | 575 | } |
580 | 576 | ||
581 | static int __init efi_config_init(u64 tables, int nr_tables) | ||
582 | { | ||
583 | void *config_tables, *tablep; | ||
584 | int i, sz; | ||
585 | |||
586 | if (efi_enabled(EFI_64BIT)) | ||
587 | sz = sizeof(efi_config_table_64_t); | ||
588 | else | ||
589 | sz = sizeof(efi_config_table_32_t); | ||
590 | |||
591 | /* | ||
592 | * Let's see what config tables the firmware passed to us. | ||
593 | */ | ||
594 | config_tables = early_ioremap(tables, nr_tables * sz); | ||
595 | if (config_tables == NULL) { | ||
596 | pr_err("Could not map Configuration table!\n"); | ||
597 | return -ENOMEM; | ||
598 | } | ||
599 | |||
600 | tablep = config_tables; | ||
601 | pr_info(""); | ||
602 | for (i = 0; i < efi.systab->nr_tables; i++) { | ||
603 | efi_guid_t guid; | ||
604 | unsigned long table; | ||
605 | |||
606 | if (efi_enabled(EFI_64BIT)) { | ||
607 | u64 table64; | ||
608 | guid = ((efi_config_table_64_t *)tablep)->guid; | ||
609 | table64 = ((efi_config_table_64_t *)tablep)->table; | ||
610 | table = table64; | ||
611 | #ifdef CONFIG_X86_32 | ||
612 | if (table64 >> 32) { | ||
613 | pr_cont("\n"); | ||
614 | pr_err("Table located above 4GB, disabling EFI.\n"); | ||
615 | early_iounmap(config_tables, | ||
616 | efi.systab->nr_tables * sz); | ||
617 | return -EINVAL; | ||
618 | } | ||
619 | #endif | ||
620 | } else { | ||
621 | guid = ((efi_config_table_32_t *)tablep)->guid; | ||
622 | table = ((efi_config_table_32_t *)tablep)->table; | ||
623 | } | ||
624 | if (!efi_guidcmp(guid, MPS_TABLE_GUID)) { | ||
625 | efi.mps = table; | ||
626 | pr_cont(" MPS=0x%lx ", table); | ||
627 | } else if (!efi_guidcmp(guid, ACPI_20_TABLE_GUID)) { | ||
628 | efi.acpi20 = table; | ||
629 | pr_cont(" ACPI 2.0=0x%lx ", table); | ||
630 | } else if (!efi_guidcmp(guid, ACPI_TABLE_GUID)) { | ||
631 | efi.acpi = table; | ||
632 | pr_cont(" ACPI=0x%lx ", table); | ||
633 | } else if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID)) { | ||
634 | efi.smbios = table; | ||
635 | pr_cont(" SMBIOS=0x%lx ", table); | ||
636 | #ifdef CONFIG_X86_UV | ||
637 | } else if (!efi_guidcmp(guid, UV_SYSTEM_TABLE_GUID)) { | ||
638 | efi.uv_systab = table; | ||
639 | pr_cont(" UVsystab=0x%lx ", table); | ||
640 | #endif | ||
641 | } else if (!efi_guidcmp(guid, HCDP_TABLE_GUID)) { | ||
642 | efi.hcdp = table; | ||
643 | pr_cont(" HCDP=0x%lx ", table); | ||
644 | } else if (!efi_guidcmp(guid, UGA_IO_PROTOCOL_GUID)) { | ||
645 | efi.uga = table; | ||
646 | pr_cont(" UGA=0x%lx ", table); | ||
647 | } | ||
648 | tablep += sz; | ||
649 | } | ||
650 | pr_cont("\n"); | ||
651 | early_iounmap(config_tables, efi.systab->nr_tables * sz); | ||
652 | return 0; | ||
653 | } | ||
654 | |||
655 | static int __init efi_runtime_init(void) | 577 | static int __init efi_runtime_init(void) |
656 | { | 578 | { |
657 | efi_runtime_services_t *runtime; | 579 | efi_runtime_services_t *runtime; |
@@ -745,7 +667,7 @@ void __init efi_init(void) | |||
745 | efi.systab->hdr.revision >> 16, | 667 | efi.systab->hdr.revision >> 16, |
746 | efi.systab->hdr.revision & 0xffff, vendor); | 668 | efi.systab->hdr.revision & 0xffff, vendor); |
747 | 669 | ||
748 | if (efi_config_init(efi.systab->tables, efi.systab->nr_tables)) | 670 | if (efi_config_init(arch_tables)) |
749 | return; | 671 | return; |
750 | 672 | ||
751 | set_bit(EFI_CONFIG_TABLES, &x86_efi_facility); | 673 | set_bit(EFI_CONFIG_TABLES, &x86_efi_facility); |
@@ -816,34 +738,6 @@ static void __init runtime_code_page_mkexec(void) | |||
816 | } | 738 | } |
817 | } | 739 | } |
818 | 740 | ||
819 | /* | ||
820 | * We can't ioremap data in EFI boot services RAM, because we've already mapped | ||
821 | * it as RAM. So, look it up in the existing EFI memory map instead. Only | ||
822 | * callable after efi_enter_virtual_mode and before efi_free_boot_services. | ||
823 | */ | ||
824 | void __iomem *efi_lookup_mapped_addr(u64 phys_addr) | ||
825 | { | ||
826 | void *p; | ||
827 | if (WARN_ON(!memmap.map)) | ||
828 | return NULL; | ||
829 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
830 | efi_memory_desc_t *md = p; | ||
831 | u64 size = md->num_pages << EFI_PAGE_SHIFT; | ||
832 | u64 end = md->phys_addr + size; | ||
833 | if (!(md->attribute & EFI_MEMORY_RUNTIME) && | ||
834 | md->type != EFI_BOOT_SERVICES_CODE && | ||
835 | md->type != EFI_BOOT_SERVICES_DATA) | ||
836 | continue; | ||
837 | if (!md->virt_addr) | ||
838 | continue; | ||
839 | if (phys_addr >= md->phys_addr && phys_addr < end) { | ||
840 | phys_addr += md->virt_addr - md->phys_addr; | ||
841 | return (__force void __iomem *)(unsigned long)phys_addr; | ||
842 | } | ||
843 | } | ||
844 | return NULL; | ||
845 | } | ||
846 | |||
847 | void efi_memory_uc(u64 addr, unsigned long size) | 741 | void efi_memory_uc(u64 addr, unsigned long size) |
848 | { | 742 | { |
849 | unsigned long page_shift = 1UL << EFI_PAGE_SHIFT; | 743 | unsigned long page_shift = 1UL << EFI_PAGE_SHIFT; |
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 5145fa344ad5..2e2fbdec0845 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c | |||
@@ -13,11 +13,27 @@ | |||
13 | * This file is released under the GPLv2. | 13 | * This file is released under the GPLv2. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
17 | |||
16 | #include <linux/kobject.h> | 18 | #include <linux/kobject.h> |
17 | #include <linux/module.h> | 19 | #include <linux/module.h> |
18 | #include <linux/init.h> | 20 | #include <linux/init.h> |
19 | #include <linux/device.h> | 21 | #include <linux/device.h> |
20 | #include <linux/efi.h> | 22 | #include <linux/efi.h> |
23 | #include <linux/io.h> | ||
24 | |||
25 | struct efi __read_mostly efi = { | ||
26 | .mps = EFI_INVALID_TABLE_ADDR, | ||
27 | .acpi = EFI_INVALID_TABLE_ADDR, | ||
28 | .acpi20 = EFI_INVALID_TABLE_ADDR, | ||
29 | .smbios = EFI_INVALID_TABLE_ADDR, | ||
30 | .sal_systab = EFI_INVALID_TABLE_ADDR, | ||
31 | .boot_info = EFI_INVALID_TABLE_ADDR, | ||
32 | .hcdp = EFI_INVALID_TABLE_ADDR, | ||
33 | .uga = EFI_INVALID_TABLE_ADDR, | ||
34 | .uv_systab = EFI_INVALID_TABLE_ADDR, | ||
35 | }; | ||
36 | EXPORT_SYMBOL(efi); | ||
21 | 37 | ||
22 | static struct kobject *efi_kobj; | 38 | static struct kobject *efi_kobj; |
23 | static struct kobject *efivars_kobj; | 39 | static struct kobject *efivars_kobj; |
@@ -132,3 +148,127 @@ err_put: | |||
132 | } | 148 | } |
133 | 149 | ||
134 | subsys_initcall(efisubsys_init); | 150 | subsys_initcall(efisubsys_init); |
151 | |||
152 | |||
153 | /* | ||
154 | * We can't ioremap data in EFI boot services RAM, because we've already mapped | ||
155 | * it as RAM. So, look it up in the existing EFI memory map instead. Only | ||
156 | * callable after efi_enter_virtual_mode and before efi_free_boot_services. | ||
157 | */ | ||
158 | void __iomem *efi_lookup_mapped_addr(u64 phys_addr) | ||
159 | { | ||
160 | struct efi_memory_map *map; | ||
161 | void *p; | ||
162 | map = efi.memmap; | ||
163 | if (!map) | ||
164 | return NULL; | ||
165 | if (WARN_ON(!map->map)) | ||
166 | return NULL; | ||
167 | for (p = map->map; p < map->map_end; p += map->desc_size) { | ||
168 | efi_memory_desc_t *md = p; | ||
169 | u64 size = md->num_pages << EFI_PAGE_SHIFT; | ||
170 | u64 end = md->phys_addr + size; | ||
171 | if (!(md->attribute & EFI_MEMORY_RUNTIME) && | ||
172 | md->type != EFI_BOOT_SERVICES_CODE && | ||
173 | md->type != EFI_BOOT_SERVICES_DATA) | ||
174 | continue; | ||
175 | if (!md->virt_addr) | ||
176 | continue; | ||
177 | if (phys_addr >= md->phys_addr && phys_addr < end) { | ||
178 | phys_addr += md->virt_addr - md->phys_addr; | ||
179 | return (__force void __iomem *)(unsigned long)phys_addr; | ||
180 | } | ||
181 | } | ||
182 | return NULL; | ||
183 | } | ||
184 | |||
185 | static __initdata efi_config_table_type_t common_tables[] = { | ||
186 | {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20}, | ||
187 | {ACPI_TABLE_GUID, "ACPI", &efi.acpi}, | ||
188 | {HCDP_TABLE_GUID, "HCDP", &efi.hcdp}, | ||
189 | {MPS_TABLE_GUID, "MPS", &efi.mps}, | ||
190 | {SAL_SYSTEM_TABLE_GUID, "SALsystab", &efi.sal_systab}, | ||
191 | {SMBIOS_TABLE_GUID, "SMBIOS", &efi.smbios}, | ||
192 | {UGA_IO_PROTOCOL_GUID, "UGA", &efi.uga}, | ||
193 | {NULL_GUID, NULL, 0}, | ||
194 | }; | ||
195 | |||
196 | static __init int match_config_table(efi_guid_t *guid, | ||
197 | unsigned long table, | ||
198 | efi_config_table_type_t *table_types) | ||
199 | { | ||
200 | u8 str[EFI_VARIABLE_GUID_LEN + 1]; | ||
201 | int i; | ||
202 | |||
203 | if (table_types) { | ||
204 | efi_guid_unparse(guid, str); | ||
205 | |||
206 | for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) { | ||
207 | efi_guid_unparse(&table_types[i].guid, str); | ||
208 | |||
209 | if (!efi_guidcmp(*guid, table_types[i].guid)) { | ||
210 | *(table_types[i].ptr) = table; | ||
211 | pr_cont(" %s=0x%lx ", | ||
212 | table_types[i].name, table); | ||
213 | return 1; | ||
214 | } | ||
215 | } | ||
216 | } | ||
217 | |||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | int __init efi_config_init(efi_config_table_type_t *arch_tables) | ||
222 | { | ||
223 | void *config_tables, *tablep; | ||
224 | int i, sz; | ||
225 | |||
226 | if (efi_enabled(EFI_64BIT)) | ||
227 | sz = sizeof(efi_config_table_64_t); | ||
228 | else | ||
229 | sz = sizeof(efi_config_table_32_t); | ||
230 | |||
231 | /* | ||
232 | * Let's see what config tables the firmware passed to us. | ||
233 | */ | ||
234 | config_tables = early_memremap(efi.systab->tables, | ||
235 | efi.systab->nr_tables * sz); | ||
236 | if (config_tables == NULL) { | ||
237 | pr_err("Could not map Configuration table!\n"); | ||
238 | return -ENOMEM; | ||
239 | } | ||
240 | |||
241 | tablep = config_tables; | ||
242 | pr_info(""); | ||
243 | for (i = 0; i < efi.systab->nr_tables; i++) { | ||
244 | efi_guid_t guid; | ||
245 | unsigned long table; | ||
246 | |||
247 | if (efi_enabled(EFI_64BIT)) { | ||
248 | u64 table64; | ||
249 | guid = ((efi_config_table_64_t *)tablep)->guid; | ||
250 | table64 = ((efi_config_table_64_t *)tablep)->table; | ||
251 | table = table64; | ||
252 | #ifndef CONFIG_64BIT | ||
253 | if (table64 >> 32) { | ||
254 | pr_cont("\n"); | ||
255 | pr_err("Table located above 4GB, disabling EFI.\n"); | ||
256 | early_iounmap(config_tables, | ||
257 | efi.systab->nr_tables * sz); | ||
258 | return -EINVAL; | ||
259 | } | ||
260 | #endif | ||
261 | } else { | ||
262 | guid = ((efi_config_table_32_t *)tablep)->guid; | ||
263 | table = ((efi_config_table_32_t *)tablep)->table; | ||
264 | } | ||
265 | |||
266 | if (!match_config_table(&guid, table, common_tables)) | ||
267 | match_config_table(&guid, table, arch_tables); | ||
268 | |||
269 | tablep += sz; | ||
270 | } | ||
271 | pr_cont("\n"); | ||
272 | early_iounmap(config_tables, efi.systab->nr_tables * sz); | ||
273 | return 0; | ||
274 | } | ||
diff --git a/include/linux/efi.h b/include/linux/efi.h index 5f8f176154f7..c084b6d942c3 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h | |||
@@ -404,6 +404,12 @@ typedef struct { | |||
404 | unsigned long table; | 404 | unsigned long table; |
405 | } efi_config_table_t; | 405 | } efi_config_table_t; |
406 | 406 | ||
407 | typedef struct { | ||
408 | efi_guid_t guid; | ||
409 | const char *name; | ||
410 | unsigned long *ptr; | ||
411 | } efi_config_table_type_t; | ||
412 | |||
407 | #define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL) | 413 | #define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL) |
408 | 414 | ||
409 | #define EFI_2_30_SYSTEM_TABLE_REVISION ((2 << 16) | (30)) | 415 | #define EFI_2_30_SYSTEM_TABLE_REVISION ((2 << 16) | (30)) |
@@ -552,6 +558,7 @@ extern struct efi { | |||
552 | efi_get_next_high_mono_count_t *get_next_high_mono_count; | 558 | efi_get_next_high_mono_count_t *get_next_high_mono_count; |
553 | efi_reset_system_t *reset_system; | 559 | efi_reset_system_t *reset_system; |
554 | efi_set_virtual_address_map_t *set_virtual_address_map; | 560 | efi_set_virtual_address_map_t *set_virtual_address_map; |
561 | struct efi_memory_map *memmap; | ||
555 | } efi; | 562 | } efi; |
556 | 563 | ||
557 | static inline int | 564 | static inline int |
@@ -587,6 +594,7 @@ static inline efi_status_t efi_query_variable_store(u32 attributes, unsigned lon | |||
587 | } | 594 | } |
588 | #endif | 595 | #endif |
589 | extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr); | 596 | extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr); |
597 | extern int efi_config_init(efi_config_table_type_t *arch_tables); | ||
590 | extern u64 efi_get_iobase (void); | 598 | extern u64 efi_get_iobase (void); |
591 | extern u32 efi_mem_type (unsigned long phys_addr); | 599 | extern u32 efi_mem_type (unsigned long phys_addr); |
592 | extern u64 efi_mem_attributes (unsigned long phys_addr); | 600 | extern u64 efi_mem_attributes (unsigned long phys_addr); |