aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/platform
diff options
context:
space:
mode:
authorJan Beulich <JBeulich@suse.com>2012-05-25 11:20:31 -0400
committerMatt Fleming <matt.fleming@intel.com>2012-10-30 06:39:20 -0400
commitbd52276fa1d420c3a504b76ffaaa1642cc79d4c4 (patch)
tree8efb267177d802dda32695c1ef4f6f2013cf61e5 /arch/x86/platform
parentda5a108d05b4f350be33e62d2db125673823e7ff (diff)
x86-64/efi: Use EFI to deal with platform wall clock (again)
Other than ix86, x86-64 on EFI so far didn't set the {g,s}et_wallclock accessors to the EFI routines, thus incorrectly using raw RTC accesses instead. Simply removing the #ifdef around the respective code isn't enough, however: While so far early get-time calls were done in physical mode, this doesn't work properly for x86-64, as virtual addresses would still need to be set up for all runtime regions (which wasn't the case on the system I have access to), so instead the patch moves the call to efi_enter_virtual_mode() ahead (which in turn allows to drop all code related to calling efi-get-time in physical mode). Additionally the earlier calling of efi_set_executable() requires the CPA code to cope, i.e. during early boot it must be avoided to call cpa_flush_array(), as the first thing this function does is a BUG_ON(irqs_disabled()). Also make the two EFI functions in question here static - they're not being referenced elsewhere. History: This commit was originally merged as bacef661acdb ("x86-64/efi: Use EFI to deal with platform wall clock") but it resulted in some ASUS machines no longer booting due to a firmware bug, and so was reverted in f026cfa82f62. A pre-emptive fix for the buggy ASUS firmware was merged in 03a1c254975e ("x86, efi: 1:1 pagetable mapping for virtual EFI calls") so now this patch can be reapplied. Signed-off-by: Jan Beulich <jbeulich@suse.com> Tested-by: Matt Fleming <matt.fleming@intel.com> Acked-by: Matthew Garrett <mjg@redhat.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: H. Peter Anvin <hpa@zytor.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com> [added commit history]
Diffstat (limited to 'arch/x86/platform')
-rw-r--r--arch/x86/platform/efi/efi.c30
1 files changed, 4 insertions, 26 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index aded2a91162a..757834434e59 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -235,22 +235,7 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
235 return status; 235 return status;
236} 236}
237 237
238static efi_status_t __init phys_efi_get_time(efi_time_t *tm, 238static int efi_set_rtc_mmss(unsigned long nowtime)
239 efi_time_cap_t *tc)
240{
241 unsigned long flags;
242 efi_status_t status;
243
244 spin_lock_irqsave(&rtc_lock, flags);
245 efi_call_phys_prelog();
246 status = efi_call_phys2(efi_phys.get_time, virt_to_phys(tm),
247 virt_to_phys(tc));
248 efi_call_phys_epilog();
249 spin_unlock_irqrestore(&rtc_lock, flags);
250 return status;
251}
252
253int efi_set_rtc_mmss(unsigned long nowtime)
254{ 239{
255 int real_seconds, real_minutes; 240 int real_seconds, real_minutes;
256 efi_status_t status; 241 efi_status_t status;
@@ -279,7 +264,7 @@ int efi_set_rtc_mmss(unsigned long nowtime)
279 return 0; 264 return 0;
280} 265}
281 266
282unsigned long efi_get_time(void) 267static unsigned long efi_get_time(void)
283{ 268{
284 efi_status_t status; 269 efi_status_t status;
285 efi_time_t eft; 270 efi_time_t eft;
@@ -635,18 +620,13 @@ static int __init efi_runtime_init(void)
635 } 620 }
636 /* 621 /*
637 * We will only need *early* access to the following 622 * We will only need *early* access to the following
638 * two EFI runtime services before set_virtual_address_map 623 * EFI runtime service before set_virtual_address_map
639 * is invoked. 624 * is invoked.
640 */ 625 */
641 efi_phys.get_time = (efi_get_time_t *)runtime->get_time;
642 efi_phys.set_virtual_address_map = 626 efi_phys.set_virtual_address_map =
643 (efi_set_virtual_address_map_t *) 627 (efi_set_virtual_address_map_t *)
644 runtime->set_virtual_address_map; 628 runtime->set_virtual_address_map;
645 /* 629
646 * Make efi_get_time can be called before entering
647 * virtual mode.
648 */
649 efi.get_time = phys_efi_get_time;
650 early_iounmap(runtime, sizeof(efi_runtime_services_t)); 630 early_iounmap(runtime, sizeof(efi_runtime_services_t));
651 631
652 return 0; 632 return 0;
@@ -734,12 +714,10 @@ void __init efi_init(void)
734 efi_enabled = 0; 714 efi_enabled = 0;
735 return; 715 return;
736 } 716 }
737#ifdef CONFIG_X86_32
738 if (efi_native) { 717 if (efi_native) {
739 x86_platform.get_wallclock = efi_get_time; 718 x86_platform.get_wallclock = efi_get_time;
740 x86_platform.set_wallclock = efi_set_rtc_mmss; 719 x86_platform.set_wallclock = efi_set_rtc_mmss;
741 } 720 }
742#endif
743 721
744#if EFI_DEBUG 722#if EFI_DEBUG
745 print_efi_memmap(); 723 print_efi_memmap();