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.c158
1 files changed, 102 insertions, 56 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 45d4f7674678..43e7cf6c6111 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -453,9 +453,6 @@ void __init efi_free_boot_services(void)
453{ 453{
454 void *p; 454 void *p;
455 455
456 if (!efi_is_native())
457 return;
458
459 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { 456 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
460 efi_memory_desc_t *md = p; 457 efi_memory_desc_t *md = p;
461 unsigned long long start = md->phys_addr; 458 unsigned long long start = md->phys_addr;
@@ -579,37 +576,85 @@ static int __init efi_systab_init(void *phys)
579 return 0; 576 return 0;
580} 577}
581 578
582static int __init efi_runtime_init(void) 579static int __init efi_runtime_init32(void)
583{ 580{
584 efi_runtime_services_t *runtime; 581 efi_runtime_services_32_t *runtime;
582
583 runtime = early_ioremap((unsigned long)efi.systab->runtime,
584 sizeof(efi_runtime_services_32_t));
585 if (!runtime) {
586 pr_err("Could not map the runtime service table!\n");
587 return -ENOMEM;
588 }
585 589
586 /* 590 /*
587 * Check out the runtime services table. We need to map 591 * We will only need *early* access to the following two
588 * the runtime services table so that we can grab the physical 592 * EFI runtime services before set_virtual_address_map
589 * address of several of the EFI runtime functions, needed to 593 * is invoked.
590 * set the firmware into virtual mode. 594 */
595 efi_phys.get_time = (efi_get_time_t *)
596 (unsigned long)runtime->get_time;
597 efi_phys.set_virtual_address_map =
598 (efi_set_virtual_address_map_t *)
599 (unsigned long)runtime->set_virtual_address_map;
600 /*
601 * Make efi_get_time can be called before entering
602 * virtual mode.
591 */ 603 */
604 efi.get_time = phys_efi_get_time;
605 early_iounmap(runtime, sizeof(efi_runtime_services_32_t));
606
607 return 0;
608}
609
610static int __init efi_runtime_init64(void)
611{
612 efi_runtime_services_64_t *runtime;
613
592 runtime = early_ioremap((unsigned long)efi.systab->runtime, 614 runtime = early_ioremap((unsigned long)efi.systab->runtime,
593 sizeof(efi_runtime_services_t)); 615 sizeof(efi_runtime_services_64_t));
594 if (!runtime) { 616 if (!runtime) {
595 pr_err("Could not map the runtime service table!\n"); 617 pr_err("Could not map the runtime service table!\n");
596 return -ENOMEM; 618 return -ENOMEM;
597 } 619 }
620
598 /* 621 /*
599 * We will only need *early* access to the following 622 * We will only need *early* access to the following two
600 * two EFI runtime services before set_virtual_address_map 623 * EFI runtime services before set_virtual_address_map
601 * is invoked. 624 * is invoked.
602 */ 625 */
603 efi_phys.get_time = (efi_get_time_t *)runtime->get_time; 626 efi_phys.get_time = (efi_get_time_t *)
627 (unsigned long)runtime->get_time;
604 efi_phys.set_virtual_address_map = 628 efi_phys.set_virtual_address_map =
605 (efi_set_virtual_address_map_t *) 629 (efi_set_virtual_address_map_t *)
606 runtime->set_virtual_address_map; 630 (unsigned long)runtime->set_virtual_address_map;
607 /* 631 /*
608 * Make efi_get_time can be called before entering 632 * Make efi_get_time can be called before entering
609 * virtual mode. 633 * virtual mode.
610 */ 634 */
611 efi.get_time = phys_efi_get_time; 635 efi.get_time = phys_efi_get_time;
612 early_iounmap(runtime, sizeof(efi_runtime_services_t)); 636 early_iounmap(runtime, sizeof(efi_runtime_services_64_t));
637
638 return 0;
639}
640
641static int __init efi_runtime_init(void)
642{
643 int rv;
644
645 /*
646 * Check out the runtime services table. We need to map
647 * the runtime services table so that we can grab the physical
648 * address of several of the EFI runtime functions, needed to
649 * set the firmware into virtual mode.
650 */
651 if (efi_enabled(EFI_64BIT))
652 rv = efi_runtime_init64();
653 else
654 rv = efi_runtime_init32();
655
656 if (rv)
657 return rv;
613 658
614 set_bit(EFI_RUNTIME_SERVICES, &efi.flags); 659 set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
615 660
@@ -747,7 +792,7 @@ void __init efi_init(void)
747 * that doesn't match the kernel 32/64-bit mode. 792 * that doesn't match the kernel 32/64-bit mode.
748 */ 793 */
749 794
750 if (!efi_is_native()) 795 if (!efi_runtime_supported())
751 pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); 796 pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n");
752 else { 797 else {
753 if (disable_runtime || efi_runtime_init()) 798 if (disable_runtime || efi_runtime_init())
@@ -833,6 +878,22 @@ void __init old_map_region(efi_memory_desc_t *md)
833 (unsigned long long)md->phys_addr); 878 (unsigned long long)md->phys_addr);
834} 879}
835 880
881static void native_runtime_setup(void)
882{
883 efi.get_time = virt_efi_get_time;
884 efi.set_time = virt_efi_set_time;
885 efi.get_wakeup_time = virt_efi_get_wakeup_time;
886 efi.set_wakeup_time = virt_efi_set_wakeup_time;
887 efi.get_variable = virt_efi_get_variable;
888 efi.get_next_variable = virt_efi_get_next_variable;
889 efi.set_variable = virt_efi_set_variable;
890 efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
891 efi.reset_system = virt_efi_reset_system;
892 efi.query_variable_info = virt_efi_query_variable_info;
893 efi.update_capsule = virt_efi_update_capsule;
894 efi.query_capsule_caps = virt_efi_query_capsule_caps;
895}
896
836/* Merge contiguous regions of the same type and attribute */ 897/* Merge contiguous regions of the same type and attribute */
837static void __init efi_merge_regions(void) 898static void __init efi_merge_regions(void)
838{ 899{
@@ -1015,19 +1076,10 @@ static void __init kexec_enter_virtual_mode(void)
1015 * Call EFI services through wrapper functions. 1076 * Call EFI services through wrapper functions.
1016 */ 1077 */
1017 efi.runtime_version = efi_systab.hdr.revision; 1078 efi.runtime_version = efi_systab.hdr.revision;
1018 efi.get_time = virt_efi_get_time; 1079
1019 efi.set_time = virt_efi_set_time; 1080 native_runtime_setup();
1020 efi.get_wakeup_time = virt_efi_get_wakeup_time; 1081
1021 efi.set_wakeup_time = virt_efi_set_wakeup_time;
1022 efi.get_variable = virt_efi_get_variable;
1023 efi.get_next_variable = virt_efi_get_next_variable;
1024 efi.set_variable = virt_efi_set_variable;
1025 efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
1026 efi.reset_system = virt_efi_reset_system;
1027 efi.set_virtual_address_map = NULL; 1082 efi.set_virtual_address_map = NULL;
1028 efi.query_variable_info = virt_efi_query_variable_info;
1029 efi.update_capsule = virt_efi_update_capsule;
1030 efi.query_capsule_caps = virt_efi_query_capsule_caps;
1031 1083
1032 if (efi_enabled(EFI_OLD_MEMMAP) && (__supported_pte_mask & _PAGE_NX)) 1084 if (efi_enabled(EFI_OLD_MEMMAP) && (__supported_pte_mask & _PAGE_NX))
1033 runtime_code_page_mkexec(); 1085 runtime_code_page_mkexec();
@@ -1071,15 +1123,6 @@ static void __init __efi_enter_virtual_mode(void)
1071 1123
1072 efi.systab = NULL; 1124 efi.systab = NULL;
1073 1125
1074 /*
1075 * We don't do virtual mode, since we don't do runtime services, on
1076 * non-native EFI
1077 */
1078 if (!efi_is_native()) {
1079 efi_unmap_memmap();
1080 return;
1081 }
1082
1083 efi_merge_regions(); 1126 efi_merge_regions();
1084 new_memmap = efi_map_regions(&count, &pg_shift); 1127 new_memmap = efi_map_regions(&count, &pg_shift);
1085 if (!new_memmap) { 1128 if (!new_memmap) {
@@ -1097,11 +1140,20 @@ static void __init __efi_enter_virtual_mode(void)
1097 efi_sync_low_kernel_mappings(); 1140 efi_sync_low_kernel_mappings();
1098 efi_dump_pagetable(); 1141 efi_dump_pagetable();
1099 1142
1100 status = phys_efi_set_virtual_address_map( 1143 if (efi_is_native()) {
1101 memmap.desc_size * count, 1144 status = phys_efi_set_virtual_address_map(
1102 memmap.desc_size, 1145 memmap.desc_size * count,
1103 memmap.desc_version, 1146 memmap.desc_size,
1104 (efi_memory_desc_t *)__pa(new_memmap)); 1147 memmap.desc_version,
1148 (efi_memory_desc_t *)__pa(new_memmap));
1149 } else {
1150 status = efi_thunk_set_virtual_address_map(
1151 efi_phys.set_virtual_address_map,
1152 memmap.desc_size * count,
1153 memmap.desc_size,
1154 memmap.desc_version,
1155 (efi_memory_desc_t *)__pa(new_memmap));
1156 }
1105 1157
1106 if (status != EFI_SUCCESS) { 1158 if (status != EFI_SUCCESS) {
1107 pr_alert("Unable to switch EFI into virtual mode (status=%lx)!\n", 1159 pr_alert("Unable to switch EFI into virtual mode (status=%lx)!\n",
@@ -1116,19 +1168,13 @@ static void __init __efi_enter_virtual_mode(void)
1116 * Call EFI services through wrapper functions. 1168 * Call EFI services through wrapper functions.
1117 */ 1169 */
1118 efi.runtime_version = efi_systab.hdr.revision; 1170 efi.runtime_version = efi_systab.hdr.revision;
1119 efi.get_time = virt_efi_get_time; 1171
1120 efi.set_time = virt_efi_set_time; 1172 if (efi_is_native())
1121 efi.get_wakeup_time = virt_efi_get_wakeup_time; 1173 native_runtime_setup();
1122 efi.set_wakeup_time = virt_efi_set_wakeup_time; 1174 else
1123 efi.get_variable = virt_efi_get_variable; 1175 efi_thunk_runtime_setup();
1124 efi.get_next_variable = virt_efi_get_next_variable; 1176
1125 efi.set_variable = virt_efi_set_variable;
1126 efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
1127 efi.reset_system = virt_efi_reset_system;
1128 efi.set_virtual_address_map = NULL; 1177 efi.set_virtual_address_map = NULL;
1129 efi.query_variable_info = virt_efi_query_variable_info;
1130 efi.update_capsule = virt_efi_update_capsule;
1131 efi.query_capsule_caps = virt_efi_query_capsule_caps;
1132 1178
1133 efi_runtime_mkexec(); 1179 efi_runtime_mkexec();
1134 1180
@@ -1311,7 +1357,7 @@ void __init efi_apply_memmap_quirks(void)
1311 * firmware/kernel architectures since there is no support for runtime 1357 * firmware/kernel architectures since there is no support for runtime
1312 * services. 1358 * services.
1313 */ 1359 */
1314 if (!efi_is_native()) { 1360 if (!efi_runtime_supported()) {
1315 pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); 1361 pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n");
1316 efi_unmap_memmap(); 1362 efi_unmap_memmap();
1317 } 1363 }