aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/platform/efi/efi.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/platform/efi/efi.c')
-rw-r--r--arch/x86/platform/efi/efi.c133
1 files changed, 62 insertions, 71 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 994a7df84a7b..f93545e7dc54 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -54,10 +54,6 @@
54#include <asm/rtc.h> 54#include <asm/rtc.h>
55#include <asm/uv/uv.h> 55#include <asm/uv/uv.h>
56 56
57#define EFI_DEBUG
58
59struct efi_memory_map memmap;
60
61static struct efi efi_phys __initdata; 57static struct efi efi_phys __initdata;
62static efi_system_table_t efi_systab __initdata; 58static efi_system_table_t efi_systab __initdata;
63 59
@@ -119,11 +115,10 @@ void efi_get_time(struct timespec *now)
119 115
120void __init efi_find_mirror(void) 116void __init efi_find_mirror(void)
121{ 117{
122 void *p; 118 efi_memory_desc_t *md;
123 u64 mirror_size = 0, total_size = 0; 119 u64 mirror_size = 0, total_size = 0;
124 120
125 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { 121 for_each_efi_memory_desc(md) {
126 efi_memory_desc_t *md = p;
127 unsigned long long start = md->phys_addr; 122 unsigned long long start = md->phys_addr;
128 unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; 123 unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;
129 124
@@ -146,10 +141,9 @@ void __init efi_find_mirror(void)
146 141
147static void __init do_add_efi_memmap(void) 142static void __init do_add_efi_memmap(void)
148{ 143{
149 void *p; 144 efi_memory_desc_t *md;
150 145
151 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { 146 for_each_efi_memory_desc(md) {
152 efi_memory_desc_t *md = p;
153 unsigned long long start = md->phys_addr; 147 unsigned long long start = md->phys_addr;
154 unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; 148 unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;
155 int e820_type; 149 int e820_type;
@@ -209,47 +203,47 @@ int __init efi_memblock_x86_reserve_range(void)
209#else 203#else
210 pmap = (e->efi_memmap | ((__u64)e->efi_memmap_hi << 32)); 204 pmap = (e->efi_memmap | ((__u64)e->efi_memmap_hi << 32));
211#endif 205#endif
212 memmap.phys_map = pmap; 206 efi.memmap.phys_map = pmap;
213 memmap.nr_map = e->efi_memmap_size / 207 efi.memmap.nr_map = e->efi_memmap_size /
214 e->efi_memdesc_size; 208 e->efi_memdesc_size;
215 memmap.desc_size = e->efi_memdesc_size; 209 efi.memmap.desc_size = e->efi_memdesc_size;
216 memmap.desc_version = e->efi_memdesc_version; 210 efi.memmap.desc_version = e->efi_memdesc_version;
217 211
218 memblock_reserve(pmap, memmap.nr_map * memmap.desc_size); 212 WARN(efi.memmap.desc_version != 1,
213 "Unexpected EFI_MEMORY_DESCRIPTOR version %ld",
214 efi.memmap.desc_version);
219 215
220 efi.memmap = &memmap; 216 memblock_reserve(pmap, efi.memmap.nr_map * efi.memmap.desc_size);
221 217
222 return 0; 218 return 0;
223} 219}
224 220
225void __init efi_print_memmap(void) 221void __init efi_print_memmap(void)
226{ 222{
227#ifdef EFI_DEBUG
228 efi_memory_desc_t *md; 223 efi_memory_desc_t *md;
229 void *p; 224 int i = 0;
230 int i;
231 225
232 for (p = memmap.map, i = 0; 226 for_each_efi_memory_desc(md) {
233 p < memmap.map_end;
234 p += memmap.desc_size, i++) {
235 char buf[64]; 227 char buf[64];
236 228
237 md = p;
238 pr_info("mem%02u: %s range=[0x%016llx-0x%016llx] (%lluMB)\n", 229 pr_info("mem%02u: %s range=[0x%016llx-0x%016llx] (%lluMB)\n",
239 i, efi_md_typeattr_format(buf, sizeof(buf), md), 230 i++, efi_md_typeattr_format(buf, sizeof(buf), md),
240 md->phys_addr, 231 md->phys_addr,
241 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1, 232 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1,
242 (md->num_pages >> (20 - EFI_PAGE_SHIFT))); 233 (md->num_pages >> (20 - EFI_PAGE_SHIFT)));
243 } 234 }
244#endif /* EFI_DEBUG */
245} 235}
246 236
247void __init efi_unmap_memmap(void) 237void __init efi_unmap_memmap(void)
248{ 238{
239 unsigned long size;
240
249 clear_bit(EFI_MEMMAP, &efi.flags); 241 clear_bit(EFI_MEMMAP, &efi.flags);
250 if (memmap.map) { 242
251 early_memunmap(memmap.map, memmap.nr_map * memmap.desc_size); 243 size = efi.memmap.nr_map * efi.memmap.desc_size;
252 memmap.map = NULL; 244 if (efi.memmap.map) {
245 early_memunmap(efi.memmap.map, size);
246 efi.memmap.map = NULL;
253 } 247 }
254} 248}
255 249
@@ -352,8 +346,6 @@ static int __init efi_systab_init(void *phys)
352 efi.systab->hdr.revision >> 16, 346 efi.systab->hdr.revision >> 16,
353 efi.systab->hdr.revision & 0xffff); 347 efi.systab->hdr.revision & 0xffff);
354 348
355 set_bit(EFI_SYSTEM_TABLES, &efi.flags);
356
357 return 0; 349 return 0;
358} 350}
359 351
@@ -440,17 +432,22 @@ static int __init efi_runtime_init(void)
440 432
441static int __init efi_memmap_init(void) 433static int __init efi_memmap_init(void)
442{ 434{
435 unsigned long addr, size;
436
443 if (efi_enabled(EFI_PARAVIRT)) 437 if (efi_enabled(EFI_PARAVIRT))
444 return 0; 438 return 0;
445 439
446 /* Map the EFI memory map */ 440 /* Map the EFI memory map */
447 memmap.map = early_memremap((unsigned long)memmap.phys_map, 441 size = efi.memmap.nr_map * efi.memmap.desc_size;
448 memmap.nr_map * memmap.desc_size); 442 addr = (unsigned long)efi.memmap.phys_map;
449 if (memmap.map == NULL) { 443
444 efi.memmap.map = early_memremap(addr, size);
445 if (efi.memmap.map == NULL) {
450 pr_err("Could not map the memory map!\n"); 446 pr_err("Could not map the memory map!\n");
451 return -ENOMEM; 447 return -ENOMEM;
452 } 448 }
453 memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size); 449
450 efi.memmap.map_end = efi.memmap.map + size;
454 451
455 if (add_efi_memmap) 452 if (add_efi_memmap)
456 do_add_efi_memmap(); 453 do_add_efi_memmap();
@@ -552,12 +549,9 @@ void __init efi_set_executable(efi_memory_desc_t *md, bool executable)
552void __init runtime_code_page_mkexec(void) 549void __init runtime_code_page_mkexec(void)
553{ 550{
554 efi_memory_desc_t *md; 551 efi_memory_desc_t *md;
555 void *p;
556 552
557 /* Make EFI runtime service code area executable */ 553 /* Make EFI runtime service code area executable */
558 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { 554 for_each_efi_memory_desc(md) {
559 md = p;
560
561 if (md->type != EFI_RUNTIME_SERVICES_CODE) 555 if (md->type != EFI_RUNTIME_SERVICES_CODE)
562 continue; 556 continue;
563 557
@@ -604,12 +598,10 @@ void __init old_map_region(efi_memory_desc_t *md)
604/* Merge contiguous regions of the same type and attribute */ 598/* Merge contiguous regions of the same type and attribute */
605static void __init efi_merge_regions(void) 599static void __init efi_merge_regions(void)
606{ 600{
607 void *p;
608 efi_memory_desc_t *md, *prev_md = NULL; 601 efi_memory_desc_t *md, *prev_md = NULL;
609 602
610 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { 603 for_each_efi_memory_desc(md) {
611 u64 prev_size; 604 u64 prev_size;
612 md = p;
613 605
614 if (!prev_md) { 606 if (!prev_md) {
615 prev_md = md; 607 prev_md = md;
@@ -651,30 +643,31 @@ static void __init get_systab_virt_addr(efi_memory_desc_t *md)
651static void __init save_runtime_map(void) 643static void __init save_runtime_map(void)
652{ 644{
653#ifdef CONFIG_KEXEC_CORE 645#ifdef CONFIG_KEXEC_CORE
646 unsigned long desc_size;
654 efi_memory_desc_t *md; 647 efi_memory_desc_t *md;
655 void *tmp, *p, *q = NULL; 648 void *tmp, *q = NULL;
656 int count = 0; 649 int count = 0;
657 650
658 if (efi_enabled(EFI_OLD_MEMMAP)) 651 if (efi_enabled(EFI_OLD_MEMMAP))
659 return; 652 return;
660 653
661 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { 654 desc_size = efi.memmap.desc_size;
662 md = p;
663 655
656 for_each_efi_memory_desc(md) {
664 if (!(md->attribute & EFI_MEMORY_RUNTIME) || 657 if (!(md->attribute & EFI_MEMORY_RUNTIME) ||
665 (md->type == EFI_BOOT_SERVICES_CODE) || 658 (md->type == EFI_BOOT_SERVICES_CODE) ||
666 (md->type == EFI_BOOT_SERVICES_DATA)) 659 (md->type == EFI_BOOT_SERVICES_DATA))
667 continue; 660 continue;
668 tmp = krealloc(q, (count + 1) * memmap.desc_size, GFP_KERNEL); 661 tmp = krealloc(q, (count + 1) * desc_size, GFP_KERNEL);
669 if (!tmp) 662 if (!tmp)
670 goto out; 663 goto out;
671 q = tmp; 664 q = tmp;
672 665
673 memcpy(q + count * memmap.desc_size, md, memmap.desc_size); 666 memcpy(q + count * desc_size, md, desc_size);
674 count++; 667 count++;
675 } 668 }
676 669
677 efi_runtime_map_setup(q, count, memmap.desc_size); 670 efi_runtime_map_setup(q, count, desc_size);
678 return; 671 return;
679 672
680out: 673out:
@@ -714,10 +707,10 @@ static inline void *efi_map_next_entry_reverse(void *entry)
714{ 707{
715 /* Initial call */ 708 /* Initial call */
716 if (!entry) 709 if (!entry)
717 return memmap.map_end - memmap.desc_size; 710 return efi.memmap.map_end - efi.memmap.desc_size;
718 711
719 entry -= memmap.desc_size; 712 entry -= efi.memmap.desc_size;
720 if (entry < memmap.map) 713 if (entry < efi.memmap.map)
721 return NULL; 714 return NULL;
722 715
723 return entry; 716 return entry;
@@ -759,10 +752,10 @@ static void *efi_map_next_entry(void *entry)
759 752
760 /* Initial call */ 753 /* Initial call */
761 if (!entry) 754 if (!entry)
762 return memmap.map; 755 return efi.memmap.map;
763 756
764 entry += memmap.desc_size; 757 entry += efi.memmap.desc_size;
765 if (entry >= memmap.map_end) 758 if (entry >= efi.memmap.map_end)
766 return NULL; 759 return NULL;
767 760
768 return entry; 761 return entry;
@@ -776,8 +769,11 @@ static void * __init efi_map_regions(int *count, int *pg_shift)
776{ 769{
777 void *p, *new_memmap = NULL; 770 void *p, *new_memmap = NULL;
778 unsigned long left = 0; 771 unsigned long left = 0;
772 unsigned long desc_size;
779 efi_memory_desc_t *md; 773 efi_memory_desc_t *md;
780 774
775 desc_size = efi.memmap.desc_size;
776
781 p = NULL; 777 p = NULL;
782 while ((p = efi_map_next_entry(p))) { 778 while ((p = efi_map_next_entry(p))) {
783 md = p; 779 md = p;
@@ -792,7 +788,7 @@ static void * __init efi_map_regions(int *count, int *pg_shift)
792 efi_map_region(md); 788 efi_map_region(md);
793 get_systab_virt_addr(md); 789 get_systab_virt_addr(md);
794 790
795 if (left < memmap.desc_size) { 791 if (left < desc_size) {
796 new_memmap = realloc_pages(new_memmap, *pg_shift); 792 new_memmap = realloc_pages(new_memmap, *pg_shift);
797 if (!new_memmap) 793 if (!new_memmap)
798 return NULL; 794 return NULL;
@@ -801,10 +797,9 @@ static void * __init efi_map_regions(int *count, int *pg_shift)
801 (*pg_shift)++; 797 (*pg_shift)++;
802 } 798 }
803 799
804 memcpy(new_memmap + (*count * memmap.desc_size), md, 800 memcpy(new_memmap + (*count * desc_size), md, desc_size);
805 memmap.desc_size);
806 801
807 left -= memmap.desc_size; 802 left -= desc_size;
808 (*count)++; 803 (*count)++;
809 } 804 }
810 805
@@ -816,7 +811,6 @@ static void __init kexec_enter_virtual_mode(void)
816#ifdef CONFIG_KEXEC_CORE 811#ifdef CONFIG_KEXEC_CORE
817 efi_memory_desc_t *md; 812 efi_memory_desc_t *md;
818 unsigned int num_pages; 813 unsigned int num_pages;
819 void *p;
820 814
821 efi.systab = NULL; 815 efi.systab = NULL;
822 816
@@ -840,8 +834,7 @@ static void __init kexec_enter_virtual_mode(void)
840 * Map efi regions which were passed via setup_data. The virt_addr is a 834 * Map efi regions which were passed via setup_data. The virt_addr is a
841 * fixed addr which was used in first kernel of a kexec boot. 835 * fixed addr which was used in first kernel of a kexec boot.
842 */ 836 */
843 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { 837 for_each_efi_memory_desc(md) {
844 md = p;
845 efi_map_region_fixed(md); /* FIXME: add error handling */ 838 efi_map_region_fixed(md); /* FIXME: add error handling */
846 get_systab_virt_addr(md); 839 get_systab_virt_addr(md);
847 } 840 }
@@ -850,10 +843,10 @@ static void __init kexec_enter_virtual_mode(void)
850 843
851 BUG_ON(!efi.systab); 844 BUG_ON(!efi.systab);
852 845
853 num_pages = ALIGN(memmap.nr_map * memmap.desc_size, PAGE_SIZE); 846 num_pages = ALIGN(efi.memmap.nr_map * efi.memmap.desc_size, PAGE_SIZE);
854 num_pages >>= PAGE_SHIFT; 847 num_pages >>= PAGE_SHIFT;
855 848
856 if (efi_setup_page_tables(memmap.phys_map, num_pages)) { 849 if (efi_setup_page_tables(efi.memmap.phys_map, num_pages)) {
857 clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); 850 clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
858 return; 851 return;
859 } 852 }
@@ -937,16 +930,16 @@ static void __init __efi_enter_virtual_mode(void)
937 930
938 if (efi_is_native()) { 931 if (efi_is_native()) {
939 status = phys_efi_set_virtual_address_map( 932 status = phys_efi_set_virtual_address_map(
940 memmap.desc_size * count, 933 efi.memmap.desc_size * count,
941 memmap.desc_size, 934 efi.memmap.desc_size,
942 memmap.desc_version, 935 efi.memmap.desc_version,
943 (efi_memory_desc_t *)__pa(new_memmap)); 936 (efi_memory_desc_t *)__pa(new_memmap));
944 } else { 937 } else {
945 status = efi_thunk_set_virtual_address_map( 938 status = efi_thunk_set_virtual_address_map(
946 efi_phys.set_virtual_address_map, 939 efi_phys.set_virtual_address_map,
947 memmap.desc_size * count, 940 efi.memmap.desc_size * count,
948 memmap.desc_size, 941 efi.memmap.desc_size,
949 memmap.desc_version, 942 efi.memmap.desc_version,
950 (efi_memory_desc_t *)__pa(new_memmap)); 943 (efi_memory_desc_t *)__pa(new_memmap));
951 } 944 }
952 945
@@ -1011,13 +1004,11 @@ void __init efi_enter_virtual_mode(void)
1011u32 efi_mem_type(unsigned long phys_addr) 1004u32 efi_mem_type(unsigned long phys_addr)
1012{ 1005{
1013 efi_memory_desc_t *md; 1006 efi_memory_desc_t *md;
1014 void *p;
1015 1007
1016 if (!efi_enabled(EFI_MEMMAP)) 1008 if (!efi_enabled(EFI_MEMMAP))
1017 return 0; 1009 return 0;
1018 1010
1019 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { 1011 for_each_efi_memory_desc(md) {
1020 md = p;
1021 if ((md->phys_addr <= phys_addr) && 1012 if ((md->phys_addr <= phys_addr) &&
1022 (phys_addr < (md->phys_addr + 1013 (phys_addr < (md->phys_addr +
1023 (md->num_pages << EFI_PAGE_SHIFT)))) 1014 (md->num_pages << EFI_PAGE_SHIFT))))