Skip to contentSkip to conversation

x86_64 EFI runtime service support: EFI runtime services

PATCH In review Huang, Ying 3 participants 4 messages Oct 30, 2007 – Oct 31, 2007 x86

lore
Share & tools
lore
#0 lore raw

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
Index: linux-2.6.24-rc1/arch/x86/kernel/reboot_64.c
===================================================================
@@ -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
Index: linux-2.6.24-rc1/include/asm-x86/emergency-restart.h
===================================================================
@@ -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
Index: linux-2.6.24-rc1/include/asm-x86/time_64.h
===================================================================
@@ -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

#1 lore raw

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

#3 lore raw
In reply to Denys Vlasenko
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* 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?

efi_get_time is no longer inline in this patch. See efi.c of this patch.

Best Regards,
Huang Ying