x86_64 EFI runtime service support: EFI runtime services
PATCH 2/4 x86_64 EFI runtime service support: EFI runtime services
This patch adds support for several EFI runtime services for EFI x86_64 system.
The EFI support for emergency_restart and RTC clock is added. The EFI based implementation and legacy BIOS or CMOS based implementation are put in separate functions and can be chosen with kernel boot options.
---
arch/x86/kernel/reboot_64.c | 19 +++++++++----- arch/x86/kernel/time_64.c | 47 +++++++++++++++++++++++------------- include/asm-x86/emergency-restart.h | 8 ++++++ include/asm-x86/time.h | 47 +++--------------------------------- include/asm-x86/time_32.h | 44 +++++++++++++++++++++++++++++++++ include/asm-x86/time_64.h | 7 +++++ 6 files changed, 107 insertions(+), 65 deletions(-)
arch/x86/kernel/reboot_64.c +13 -6
@@ -9,6 +9,7 @@#include <linux/pm.h> #include <linux/kdebug.h> #include <linux/sched.h> +#include <linux/efi.h> #include <asm/io.h> #include <asm/delay.h> #include <asm/desc.h>
@@ -26,18 +27,16 @@EXPORT_SYMBOL (pm_power_off);static long no_idt[3 ]; -static enum { -BOOT_TRIPLE ='t' , -BOOT_KBD ='k' -} reboot_type =BOOT_KBD ; +enum reboot_type reboot_type =BOOT_KBD ;static int reboot_mode =0 ;int reboot_force; -/* reboot=t[riple] | k[bd] [, [w]arm | [c]old] +/* reboot=t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] warm Don't set the cold reboot flag cold Set the cold reboot flag triple Force a triple fault (init) kbd Use the keyboard controller. cold reset (default) +efi Use efi reset_system runtime service force Avoid anything that could hang. */ static int __init reboot_setup (char *str)
@@ -55,6 +54,7 @@case 't' :case 'b' :case 'k' : +case 'e' : reboot_type = *str;break ;case 'f' :
@@ -142,7 +142,14 @@ reboot_type =BOOT_KBD ;break ; - } + +case BOOT_EFI : +if (efi_enabled) + efi.reset_system (reboot_mode ?EFI_RESET_WARM :EFI_RESET_COLD , +EFI_SUCCESS ,0 ,NULL ); + reboot_type =BOOT_KBD ; +break ; + } } }
arch/x86/kernel/time_64.c +31 -16
98 lines not on this page · raw message
include/asm-x86/emergency-restart.h +8 -0
@@ -1,6 +1,14 @@#ifndef _ASM_EMERGENCY_RESTART_H#define _ASM_EMERGENCY_RESTART_H +enum reboot_type { +BOOT_TRIPLE ='t' , +BOOT_KBD ='k' , +BOOT_EFI ='e' +}; + +extern enum reboot_type reboot_type; +extern void machine_emergency_restart (void );#endif /* _ASM_EMERGENCY_RESTART_H */
include/asm-x86/time_64.h new file +7 -0
@@ -0,0 +1,7 @@ +#ifndef __ASM_X86_TIME_64_H +#define __ASM_X86_TIME_64_H + +extern unsigned long (*get_wallclock)(void ); +extern int (*set_wallclock)(unsigned long nowtime); + +#endif
include/asm-x86/time.h +4 -43
48 lines not on this page · raw message
include/asm-x86/time_32.h new file +44 -0
44 lines not on this page · raw message
include/asm-x86/time_32.h line 17
Quoted 11 lines · Ying
include/asm-x86/time_32.h new file +11
-0+static inline unsigned long native_get_wallclock (void ) +{ +unsigned long retval; + +if (efi_enabled) + retval =efi_get_time (); +else + retval =mach_get_cmos_time (); + +return retval; +}
mach_get_cmos_time() is itself an inline, and a _large_ one (~20 LOC with macro and function calls).
efi_get_time() is an inline too, although strange one:
it is declared inline *only* in efi.c file:
inline unsigned long efi_get_time(void)
(yes, just inline, not static/extern),
while efi.h has normal extern for it:
extern unsigned long efi_get_time(void);
Is it supposed to be like that?
include/asm-x86/time_32.h line 29
Quoted 11 lines
include/asm-x86/time_32.h new file +11
-0+static inline int native_set_wallclock (unsigned long nowtime) +{ +int retval; + +if (efi_enabled) + retval =efi_set_rtc_mmss (nowtime); +else + retval =mach_set_rtc_mmss (nowtime); + +return retval; +}
Same here, only mach_set_rtc_mmss is 50 LOC, not 20. --
vda
Quoted 4 lines · Denys Vlasenko
mach_get_cmos_time()is itself an inline, and a _large_ one (~20 LOC with macro and function calls).Same here, only
mach_set_rtc_mmssis 50 LOC, not 20.
It was:)
tglx
Quoted 16 lines · Denys Vlasenko
include/asm-x86/time_32.h line 17
Quoted 11 lines · Ying
include/asm-x86/time_32.h new file +11
-0+static inline unsigned long native_get_wallclock (void ) +{ +unsigned long retval; + +if (efi_enabled) + retval =efi_get_time (); +else + retval =mach_get_cmos_time (); + +return retval; +}
mach_get_cmos_time()is itself an inline, and a _large_ one (~20 LOC with macro and function calls).
Quoted 8 lines
efi_get_time()is an inline too, although strange one:
it is declared inline *only* inefi.cfile:
inline unsigned longefi_get_time(void)
(yes, just inline, not static/extern),
whileefi.hhas normal extern for it:extern unsigned long efi_get_time(void);Is it supposed to be like that?
efi_get_time is no longer inline in this patch. See efi.c of this patch.
Best Regards,
Huang Ying