diff options
Diffstat (limited to 'arch/x86/platform/efi/efi.c')
-rw-r--r-- | arch/x86/platform/efi/efi.c | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index aded2a91162a..ad4439145f85 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -70,11 +70,15 @@ EXPORT_SYMBOL(efi); | |||
70 | struct efi_memory_map memmap; | 70 | struct efi_memory_map memmap; |
71 | 71 | ||
72 | bool efi_64bit; | 72 | bool efi_64bit; |
73 | static bool efi_native; | ||
74 | 73 | ||
75 | static struct efi efi_phys __initdata; | 74 | static struct efi efi_phys __initdata; |
76 | static efi_system_table_t efi_systab __initdata; | 75 | static efi_system_table_t efi_systab __initdata; |
77 | 76 | ||
77 | static inline bool efi_is_native(void) | ||
78 | { | ||
79 | return IS_ENABLED(CONFIG_X86_64) == efi_64bit; | ||
80 | } | ||
81 | |||
78 | static int __init setup_noefi(char *arg) | 82 | static int __init setup_noefi(char *arg) |
79 | { | 83 | { |
80 | efi_enabled = 0; | 84 | efi_enabled = 0; |
@@ -420,7 +424,7 @@ void __init efi_reserve_boot_services(void) | |||
420 | } | 424 | } |
421 | } | 425 | } |
422 | 426 | ||
423 | static void __init efi_unmap_memmap(void) | 427 | void __init efi_unmap_memmap(void) |
424 | { | 428 | { |
425 | if (memmap.map) { | 429 | if (memmap.map) { |
426 | early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); | 430 | early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); |
@@ -432,7 +436,7 @@ void __init efi_free_boot_services(void) | |||
432 | { | 436 | { |
433 | void *p; | 437 | void *p; |
434 | 438 | ||
435 | if (!efi_native) | 439 | if (!efi_is_native()) |
436 | return; | 440 | return; |
437 | 441 | ||
438 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | 442 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
@@ -684,12 +688,10 @@ void __init efi_init(void) | |||
684 | return; | 688 | return; |
685 | } | 689 | } |
686 | efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab; | 690 | efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab; |
687 | efi_native = !efi_64bit; | ||
688 | #else | 691 | #else |
689 | efi_phys.systab = (efi_system_table_t *) | 692 | efi_phys.systab = (efi_system_table_t *) |
690 | (boot_params.efi_info.efi_systab | | 693 | (boot_params.efi_info.efi_systab | |
691 | ((__u64)boot_params.efi_info.efi_systab_hi<<32)); | 694 | ((__u64)boot_params.efi_info.efi_systab_hi<<32)); |
692 | efi_native = efi_64bit; | ||
693 | #endif | 695 | #endif |
694 | 696 | ||
695 | if (efi_systab_init(efi_phys.systab)) { | 697 | if (efi_systab_init(efi_phys.systab)) { |
@@ -723,7 +725,7 @@ void __init efi_init(void) | |||
723 | * that doesn't match the kernel 32/64-bit mode. | 725 | * that doesn't match the kernel 32/64-bit mode. |
724 | */ | 726 | */ |
725 | 727 | ||
726 | if (!efi_native) | 728 | if (!efi_is_native()) |
727 | pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); | 729 | pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); |
728 | else if (efi_runtime_init()) { | 730 | else if (efi_runtime_init()) { |
729 | efi_enabled = 0; | 731 | efi_enabled = 0; |
@@ -735,7 +737,7 @@ void __init efi_init(void) | |||
735 | return; | 737 | return; |
736 | } | 738 | } |
737 | #ifdef CONFIG_X86_32 | 739 | #ifdef CONFIG_X86_32 |
738 | if (efi_native) { | 740 | if (efi_is_native()) { |
739 | x86_platform.get_wallclock = efi_get_time; | 741 | x86_platform.get_wallclock = efi_get_time; |
740 | x86_platform.set_wallclock = efi_set_rtc_mmss; | 742 | x86_platform.set_wallclock = efi_set_rtc_mmss; |
741 | } | 743 | } |
@@ -810,6 +812,16 @@ void __iomem *efi_lookup_mapped_addr(u64 phys_addr) | |||
810 | return NULL; | 812 | return NULL; |
811 | } | 813 | } |
812 | 814 | ||
815 | void efi_memory_uc(u64 addr, unsigned long size) | ||
816 | { | ||
817 | unsigned long page_shift = 1UL << EFI_PAGE_SHIFT; | ||
818 | u64 npages; | ||
819 | |||
820 | npages = round_up(size, page_shift) / page_shift; | ||
821 | memrange_efi_to_native(&addr, &npages); | ||
822 | set_memory_uc(addr, npages); | ||
823 | } | ||
824 | |||
813 | /* | 825 | /* |
814 | * This function will switch the EFI runtime services to virtual mode. | 826 | * This function will switch the EFI runtime services to virtual mode. |
815 | * Essentially, look through the EFI memmap and map every region that | 827 | * Essentially, look through the EFI memmap and map every region that |
@@ -823,7 +835,7 @@ void __init efi_enter_virtual_mode(void) | |||
823 | efi_memory_desc_t *md, *prev_md = NULL; | 835 | efi_memory_desc_t *md, *prev_md = NULL; |
824 | efi_status_t status; | 836 | efi_status_t status; |
825 | unsigned long size; | 837 | unsigned long size; |
826 | u64 end, systab, addr, npages, end_pfn; | 838 | u64 end, systab, end_pfn; |
827 | void *p, *va, *new_memmap = NULL; | 839 | void *p, *va, *new_memmap = NULL; |
828 | int count = 0; | 840 | int count = 0; |
829 | 841 | ||
@@ -834,7 +846,7 @@ void __init efi_enter_virtual_mode(void) | |||
834 | * non-native EFI | 846 | * non-native EFI |
835 | */ | 847 | */ |
836 | 848 | ||
837 | if (!efi_native) { | 849 | if (!efi_is_native()) { |
838 | efi_unmap_memmap(); | 850 | efi_unmap_memmap(); |
839 | return; | 851 | return; |
840 | } | 852 | } |
@@ -879,10 +891,14 @@ void __init efi_enter_virtual_mode(void) | |||
879 | end_pfn = PFN_UP(end); | 891 | end_pfn = PFN_UP(end); |
880 | if (end_pfn <= max_low_pfn_mapped | 892 | if (end_pfn <= max_low_pfn_mapped |
881 | || (end_pfn > (1UL << (32 - PAGE_SHIFT)) | 893 | || (end_pfn > (1UL << (32 - PAGE_SHIFT)) |
882 | && end_pfn <= max_pfn_mapped)) | 894 | && end_pfn <= max_pfn_mapped)) { |
883 | va = __va(md->phys_addr); | 895 | va = __va(md->phys_addr); |
884 | else | 896 | |
885 | va = efi_ioremap(md->phys_addr, size, md->type); | 897 | if (!(md->attribute & EFI_MEMORY_WB)) |
898 | efi_memory_uc((u64)(unsigned long)va, size); | ||
899 | } else | ||
900 | va = efi_ioremap(md->phys_addr, size, | ||
901 | md->type, md->attribute); | ||
886 | 902 | ||
887 | md->virt_addr = (u64) (unsigned long) va; | 903 | md->virt_addr = (u64) (unsigned long) va; |
888 | 904 | ||
@@ -892,13 +908,6 @@ void __init efi_enter_virtual_mode(void) | |||
892 | continue; | 908 | continue; |
893 | } | 909 | } |
894 | 910 | ||
895 | if (!(md->attribute & EFI_MEMORY_WB)) { | ||
896 | addr = md->virt_addr; | ||
897 | npages = md->num_pages; | ||
898 | memrange_efi_to_native(&addr, &npages); | ||
899 | set_memory_uc(addr, npages); | ||
900 | } | ||
901 | |||
902 | systab = (u64) (unsigned long) efi_phys.systab; | 911 | systab = (u64) (unsigned long) efi_phys.systab; |
903 | if (md->phys_addr <= systab && systab < end) { | 912 | if (md->phys_addr <= systab && systab < end) { |
904 | systab += md->virt_addr - md->phys_addr; | 913 | systab += md->virt_addr - md->phys_addr; |