Skip to contentSkip to conversation

x86_64 EFI runtime service support: EFI basic runtime service support

PATCH In review Huang, Ying 8 participants 32 messages Oct 25, 2007 – Oct 29, 2007 x86

lore
Share & tools
lore
#0 lore raw

PATCH 1/3 x86_64 EFI runtime service support: EFI basic runtime service support

This patch adds basic runtime services support for EFI x86_64 system. The main file of the patch is the addition of efi.c for x86_64. This file is modeled after the EFI IA32 avatar. EFI runtime services initialization are implemented in efi.c. Some x86_64 specifics are worth noting here. On x86_64, parameters passed to UEFI firmware services need to follow the UEFI calling convention. For this purpose, a set of functions named lin2win<x> (<x> is the number of parameters) are implemented. EFI function calls are wrapped before calling the firmware service.

---

 arch/x86/kernel/Makefile_64       |    1 
 arch/x86/kernel/efi_64.c          |  593 ++++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/efi_callwrap_64.S |   69 ++++
 arch/x86/kernel/setup_64.c        |   15 
 arch/x86_64/Kconfig               |   11 
 include/asm-x86/bootparam.h       |    5 
 include/asm-x86/efi_64.h          |    8 
 include/asm-x86/eficallwrap_64.h  |   33 ++
 include/asm-x86/fixmap_64.h       |    3 
 9 files changed, 735 insertions(+), 3 deletions(-)
include/asm-x86/eficallwrap_64.h new file +33 -0
Index: linux-2.6.24-rc1/include/asm-x86/eficallwrap_64.h
===================================================================
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (C) 2007 Intel Corp
+ *	Bibo Mao <[email protected]>
+ *	Huang Ying <[email protected]>
+ *
+ *  Function calling ABI conversion from SYSV to Windows for x86_64
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_X86_64_EFICALLWRAP_H
+#define __ASM_X86_64_EFICALLWRAP_H
+
+extern efi_status_t lin2win0(void *fp);
+extern efi_status_t lin2win1(void *fp, u64 arg1);
+extern efi_status_t lin2win2(void *fp, u64 arg1, u64 arg2);
+extern efi_status_t lin2win3(void *fp, u64 arg1, u64 arg2, u64 arg3);
+extern efi_status_t lin2win4(void *fp, u64 arg1, u64 arg2, u64 arg3, u64 arg4);
+extern efi_status_t lin2win5(void *fp, u64 arg1, u64 arg2, u64 arg3,
+			     u64 arg4, u64 arg5);
+extern efi_status_t lin2win6(void *fp, u64 arg1, u64 arg2, u64 arg3,
+			     u64 arg4, u64 arg5, u64 arg6);
+
+#endif
arch/x86/kernel/efi_64.c new file +593 -0

593 lines not on this page · raw message

arch/x86/kernel/efi_callwrap_64.S new file +69 -0

69 lines not on this page · raw message

arch/x86/kernel/setup_64.c +14 -1
Index: linux-2.6.24-rc1/arch/x86/kernel/setup_64.c
===================================================================
@@ -39,6 +39,7 @@
 #include <linux/dmi.h>
 #include <linux/dma-mapping.h>
 #include <linux/ctype.h>
+#include <linux/efi.h>
 
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
@@ -269,6 +270,11 @@
 	rd_prompt = ((boot_params.hdr.ram_size & RAMDISK_PROMPT_FLAG) != 0);
 	rd_doload = ((boot_params.hdr.ram_size & RAMDISK_LOAD_FLAG) != 0);
 #endif
+#ifdef CONFIG_EFI
+	if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
+		     "EFIL", 4))
+		efi_enabled = 1;
+#endif
 	setup_memory_region();
 	copy_edd();
 
@@ -308,6 +314,8 @@
 	discover_ebda();
 
 	init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
+	if (efi_enabled)
+		efi_init();
 
 	dmi_scan_machine();
 
@@ -379,6 +387,10 @@
         */
        acpi_reserve_bootmem();
 #endif
+
+	if (efi_enabled)
+		efi_reserve_bootmem();
+
 	/*
 	 * Find and reserve possible boot-time SMP configuration:
 	 */
@@ -448,7 +460,8 @@
 
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
-	conswitchp = &vga_con;
+	if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
+		conswitchp = &vga_con;
 #elif defined(CONFIG_DUMMY_CONSOLE)
 	conswitchp = &dummy_con;
 #endif
include/asm-x86/fixmap_64.h +3 -0
Index: linux-2.6.24-rc1/include/asm-x86/fixmap_64.h
===================================================================
@@ -15,6 +15,7 @@
 #include <asm/apicdef.h>
 #include <asm/page.h>
 #include <asm/vsyscall.h>
+#include <asm/efi_64.h>
 
 /*
  * Here we define all the compile-time 'special' virtual
@@ -41,6 +42,8 @@
 	FIX_APIC_BASE,	/* local (CPU) APIC) -- required for SMP or not */
 	FIX_IO_APIC_BASE_0,
 	FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,
+	FIX_EFI_IO_MAP_LAST_PAGE,
+	FIX_EFI_IO_MAP_FIRST_PAGE = FIX_EFI_IO_MAP_LAST_PAGE+MAX_EFI_IO_PAGES-1,
 	__end_of_fixed_addresses
 };
 
arch/x86_64/Kconfig +11 -0
Index: linux-2.6.24-rc1/arch/x86_64/Kconfig
===================================================================
@@ -269,6 +269,17 @@
 	depends on SMP && !MK8
 	default y
 
+config EFI
+	bool "EFI runtime service support (EXPERIMENTAL)"
+	---help---
+	  This enables the kernel to use any EFI runtime services that are
+	  available (such as the EFI variable services).
+	  This option is only useful on systems that have EFI firmware
+	  and will result in a kernel image that is ~8k larger. However,
+	  even with this option, the resultant kernel should continue to
+	  boot on existing non-EFI platforms. For more information on
+	  how to set up [U]EFI64 system, see Documentation/x86_64/uefi.txt.
+
 config MATH_EMULATION
 	bool
 
arch/x86/kernel/Makefile_64 +1 -0
Index: linux-2.6.24-rc1/arch/x86/kernel/Makefile_64
===================================================================
@@ -33,6 +33,7 @@
 obj-$(CONFIG_X86_VSMP)		+= vsmp_64.o
 obj-$(CONFIG_K8_NB)		+= k8.o
 obj-$(CONFIG_AUDIT)		+= audit_64.o
+obj-$(CONFIG_EFI)		+= efi_64.o efi_callwrap_64.o
 
 obj-$(CONFIG_MODULES)		+= module_64.o
 obj-$(CONFIG_PCI)		+= early-quirks.o
include/asm-x86/bootparam.h +3 -2
Index: linux-2.6.24-rc1/include/asm-x86/bootparam.h
===================================================================
@@ -54,13 +54,14 @@
 };
 
 struct efi_info {
-	__u32 _pad1;
+	__u32 efi_loader_signature;
 	__u32 efi_systab;
 	__u32 efi_memdesc_size;
 	__u32 efi_memdesc_version;
 	__u32 efi_memmap;
 	__u32 efi_memmap_size;
-	__u32 _pad2[2];
+	__u32 efi_systab_hi;
+	__u32 efi_memmap_hi;
 };
 
 /* The so-called "zeropage" */
include/asm-x86/efi_64.h new file +8 -0
Index: linux-2.6.24-rc1/include/asm-x86/efi_64.h
===================================================================
@@ -0,0 +1,8 @@
+#ifndef __ASM_X86_64_EFI_H
+#define __ASM_X86_64_EFI_H
+
+#define MAX_EFI_IO_PAGES	100
+
+extern void efi_reserve_bootmem(void);
+
+#endif
#1 lore raw
Quoted 3 lines · Ying

This patch adds basic runtime services support for EFI x86_64 system. The main file of the patch is the addition of efi.c for x86_64. This file is modeled after the EFI IA32 avatar.

modeled means copied and modified, right?

This is wrong. I compared efi_32.c and efi_64.c and a large amount of the code is simply the same. The small details can be sorted out by two sets of macros/inline functions easily.

Please fix this up.

Quoted 7 lines

EFI runtime
services initialization are implemented in efi.c. Some x86_64 specifics are worth noting here. On x86_64, parameters passed to UEFI firmware services need to follow the UEFI calling convention. For this purpose, a set of functions named lin2win<x> (<x> is the number of parameters) are implemented. EFI function calls are wrapped before calling the firmware service.

Why needs this to be called lin2win? We do not call Windows, we call EFI services, so please use a naming convention which is related to the functionality of the code.

Quoted 2 lines

+ *
+ * Function calling ABI conversion from SYSV to Windows for x86_64

Again, these are wrappers to access EFI and not Windows.

tglx

#2 lore raw
Quoted 9 lines · Thomas Gleixner
Quoted 8 lines

EFI runtime
services initialization are implemented in efi.c. Some x86_64 specifics are worth noting here. On x86_64, parameters passed to UEFI firmware services need to follow the UEFI calling convention. For this purpose, a set of functions named lin2win<x> (<x> is the number of parameters) are implemented. EFI function calls are wrapped before calling the firmware service.

Quoted 4 lines

Why needs this to be called lin2win? We do not call Windows, we call EFI services, so please use a naming convention which is related to the functionality of the code.

Well, presumably EFI inherited the calling convention (as well as another bunch of stupidity) from that corner.

-hpa

#3 lore raw
In reply to Thomas Gleixner
Quoted 6 lines · Thomas Gleixner
Quoted 3 lines · Ying

This patch adds basic runtime services support for EFI x86_64 system. The main file of the patch is the addition of efi.c for x86_64. This file is modeled after the EFI IA32 avatar.

Quoted 7 lines

modeled means copied and modified, right?

This is wrong. I compared efi_32.c and efi_64.c and a large amount of the code is simply the same. The small details can be sorted out by two sets of macros/inline functions easily.

Please fix this up.

I don't think there is a compelling case for us to use any efi services at this time so unification should be easy:
rm arch/x86/kernel/efi_32.c arch/x86/kernel/efi_stub_32.c

Especially for accessing the real time clock that has a well defined hardware interface going through efi an additional software emulation layer looks like asking for trouble.

Eric

#4 lore raw
Quoted 2 lines · On Thu, 25 Oct 2007 10:55:44 -0600 [email protected] (Eric W. Biederman)…

I don't think there is a compelling case for us to use any efi services at this time

I would almost agree with this if it wasn't for the 1 call that OS installers need to tell EFI about bootloader stuff; I've cc'd Peter Jones since he'll know better what OS installers need; if they don't need it after all...

Signature · 3 lines
If you want to reach me at my work email, use [email protected]
For development, discussion and tips for power savings, 
visit http://www.lesswatts.org
#5 lore raw
Quoted 10 lines · Arjan van de Ven
Quoted 2 lines · On Thu, 25 Oct 2007 10:55:44 -0600 [email protected] (Eric W. Biederman)…

I don't think there is a compelling case for us to use any efi services at this time

I would almost agree with this if it wasn't for the 1 call that OS installers need to tell EFI about bootloader stuff; I've cc'd Peter Jones since he'll know better what OS installers need; if they don't need it after all...

Yes. I think that is usage of the variable service. Although I don't know if that is actually needed.

Support for the variable service is not implemented in this patchset.

Eric

#6 lore raw
Quoted 13 lines · Eric W. Biederman
Quoted 10 lines · Arjan van de Ven
Quoted 2 lines · On Thu, 25 Oct 2007 10:55:44 -0600 [email protected] (Eric W. Biederman)…

I don't think there is a compelling case for us to use any efi services at this time

I would almost agree with this if it wasn't for the 1 call that OS installers need to tell EFI about bootloader stuff; I've cc'd Peter Jones since he'll know better what OS installers need; if they don't need it after all...

Quoted 5 lines

Yes. I think that is usage of the variable service. Although I don't know if that is actually needed.

Support for the variable service is not implemented in this patchset.

Support for the variable service has been implemented in this patchset. The interfaces are:

efi.get_variable
efi.get_next_variable
efi.set_variable

And a sysfs interface (/sys/firmware/efi/vars) is provided in drivers/firmware/efivars.c, which depends on this patchset to work.

Best Regards,
Huang Ying

#7 lore raw
In reply to Arjan van de Ven
Quoted 11 lines · Arjan van de Ven
Quoted 2 lines · On Thu, 25 Oct 2007 10:55:44 -0600 [email protected] (Eric W. Biederman)…

I don't think there is a compelling case for us to use any efi services at this time

I would almost agree with this if it wasn't for the 1 call that OS installers need to tell EFI about bootloader stuff; I've cc'd Peter Jones since he'll know better what OS installers need; if they don't need it after all...

Well, the original motivation for all of this was to enable implementation of a EFI framebuffer (UGA/GOP). Now, you can say what you want about EFI (and I definitely have my opinion on it), but that seems legitimate to me.

-hpa

#8 lore raw
Quoted 13 lines · H. Peter Anvin
Quoted 11 lines · Arjan van de Ven
Quoted 2 lines · On Thu, 25 Oct 2007 10:55:44 -0600 [email protected] (Eric W. Biederman)…

I don't think there is a compelling case for us to use any efi services at this time

I would almost agree with this if it wasn't for the 1 call that OS installers need to tell EFI about bootloader stuff; I've cc'd Peter Jones since he'll know better what OS installers need; if they don't need it after all...

Quoted 3 lines

Well, the original motivation for all of this was to enable implementation of a EFI framebuffer (UGA/GOP). Now, you can say what you want about EFI (and I definitely have my opinion on it), but that seems legitimate to me.

To be very clear. I think we need the EFI boot parameters but we certainly don't runtime services to implement an EFI framebuffer.

Eric

#9 lore raw
Quoted 8 lines · Eric W. Biederman
Quoted 4 lines
Quoted 1 line

Well, the original motivation for all of this was to enable implementation of a EFI framebuffer (UGA/GOP). Now, you can say what you want about EFI (and I definitely have my opinion on it), but that seems legitimate to me.

To be very clear. I think we need the EFI boot parameters but we certainly don't runtime services to implement an EFI framebuffer.

Ying claimed that GOP requires EFI runtime services. Is that not true?

-hpa

#10 lore raw
Quoted 4 lines · H. Peter Anvin
Quoted 2 lines · Eric W. Biederman
Quoted 2 lines
Quoted 1 line

Well, the original motivation for all of this was to enable implementation of

a

Quoted 8 lines
Quoted 6 lines
Quoted 2 lines

EFI framebuffer (UGA/GOP). Now, you can say what you want about EFI (and I definitely have my opinion on it), but that seems legitimate to me.

To be very clear. I think we need the EFI boot parameters but we certainly don't runtime services to implement an EFI framebuffer.

Ying claimed that GOP requires EFI runtime services. Is that not true?

None of the EFI framebuffer patches that I saw used EFI runtime services.

Eric

#11 lore raw
Quoted 5 lines · Eric W. Biederman
Quoted 2 lines
Quoted 1 line

Ying claimed that GOP requires EFI runtime services. Is that not true?

None of the EFI framebuffer patches that I saw used EFI runtime services.

Ying, could you please clarify this situation?

(Eric: do note that there are two EFI framebuffer standard, UGA and GOP.
Apparently UGA is obsolete and we have always been at war with GOP at
the moment.)

-hpa

#12 lore raw
Quoted 4 lines · H. Peter Anvin
Quoted 3 lines · Eric W. Biederman
Quoted 2 lines
Quoted 1 line

Ying claimed that GOP requires EFI runtime services. Is that not true?

Quoted 8 lines
Quoted 2 lines

None of the EFI framebuffer patches that I saw used EFI runtime services.

Ying, could you please clarify this situation?

(Eric: do note that there are two EFI framebuffer standard, UGA and GOP. Apparently UGA is obsolete and we have always been at war with GOP at the moment.)

Peter please look back in your email archives to yesterday and see Ying's patch:

[PATCH 1/2 -v2 resend] x86_64 EFI boot support: EFI frame buffer driver

All of the data the GOP needs is acquired through the a query made by the bootloader and passed through screen info.

Eric

#13 lore raw
Quoted 12 lines · Eric W. Biederman
Quoted 9 lines · H. Peter Anvin
Quoted 3 lines · Eric W. Biederman
Quoted 1 line

Ying claimed that GOP requires EFI runtime services. Is that not true?

None of the EFI framebuffer patches that I saw used EFI runtime services.

Ying, could you please clarify this situation?

(Eric: do note that there are two EFI framebuffer standard, UGA and GOP. Apparently UGA is obsolete and we have always been at war with GOP at the moment.)

Quoted 8 lines

Peter please look back in your email archives to yesterday and see Ying's patch:

[PATCH 1/2 -v2 resend] x86_64 EFI boot support: EFI frame buffer driver

All of the data the GOP needs is acquired through the a query made by the bootloader and passed through screen info.

Then I fully agree with your assessment.

-hpa

#14 lore raw
Quoted 16 lines · H. Peter Anvin
Quoted 15 lines · Eric W. Biederman
Quoted 9 lines · H. Peter Anvin
Quoted 3 lines · Eric W. Biederman
Quoted 1 line

Ying claimed that GOP requires EFI runtime services. Is that not true?

None of the EFI framebuffer patches that I saw used EFI runtime services.

Ying, could you please clarify this situation?

(Eric: do note that there are two EFI framebuffer standard, UGA and GOP. Apparently UGA is obsolete and we have always been at war with GOP at the moment.)

Peter please look back in your email archives to yesterday and see Ying's patch:

Quoted 7 lines
Quoted 5 lines

[PATCH 1/2 -v2 resend] x86_64 EFI boot support: EFI frame buffer driver

All of the data the GOP needs is acquired through the a query made by the bootloader and passed through screen info.

Then I fully agree with your assessment.

EFI framebuffer doesn't depend on EFI runtime service.

But EFI variable service depends on EFI runtime service, and most people think it is useful. It can be used to:

- Provide a standard method to communicate with BIOS, such as specifying the boot device or bootloader for the next boot.
- Provide a standard method to write the OOPS information to flash.

To improve the reliability of OOPS information writing, the virtual mode of EFI should be used. And through mapping all memory area used by EFI to the same virtual address across kexec, EFI can work with kexec under virtual mode just like that of IA-64.

So, I think the EFI runtime service is useful and it does not break anything. But the code duplication between efi_32.c and efi_64.c should be eliminated and I will work on this.

Best Regards,
Huang Ying

#15 lore raw
In reply to H. Peter Anvin
Quoted 4 lines · H. Peter Anvin
Quoted 3 lines · Eric W. Biederman
Quoted 2 lines
Quoted 1 line

Ying claimed that GOP requires EFI runtime services. Is that not true?

Quoted 8 lines
Quoted 2 lines

None of the EFI framebuffer patches that I saw used EFI runtime services.

Ying, could you please clarify this situation?

(Eric: do note that there are two EFI framebuffer standard, UGA and GOP.
Apparently UGA is obsolete and we have always been at war with GOP at
the moment.)

EFI framebuffer doesn't depend on EFI runtime service. It only depends on kernel boot parameters (screen_info).

Best Regards,
Huang Ying

#16 lore raw
In reply to Eric W. Biederman
Quoted 4 lines

Especially for accessing the real time clock that has a well defined hardware interface going through efi an additional software emulation layer looks like asking for trouble.

I agree it's pointless for the hardware clock, but EFI also offers services to write some data to the CMOS RAM which could be very useful to save oops data over reboot. I don't think this can be done safely otherwise without BIOS cooperation.

-Andi

#17 lore raw
Quoted 8 lines · Andi Kleen
Quoted 3 lines

Especially for accessing the real time clock that has a well defined hardware interface going through efi an additional software emulation layer looks like asking for trouble.

I agree it's pointless for the hardware clock, but EFI also offers services to write some data to the CMOS RAM which could be very useful to save oops data over reboot.
I don't think this can be done safely otherwise without BIOS cooperation.

The ability to scurry away even a small amount of data without relying on the disk system is highly desirable. Think next-boot type information.

-hpa

#18 lore raw
Quoted 5 lines · H. Peter Anvin
Quoted 4 lines · Andi Kleen
Quoted 3 lines

Especially for accessing the real time clock that has a well defined hardware interface going through efi an additional software emulation layer looks like asking for trouble.

Quoted 8 lines
Quoted 5 lines

I agree it's pointless for the hardware clock, but EFI also offers services to write some data to the CMOS RAM
which could be very useful to save oops data over reboot.
I don't think this can be done safely otherwise without BIOS cooperation.

The ability to scurry away even a small amount of data without relying on the disk system is highly desirable. Think next-boot type information.

Yes. If that were to be the justifying case and if that was what the code was implementing I could see the point.

However this point was made in an earlier review. This point was already been made, and still this patchset doesn't include that functionality and it still includes the code to disable direct hardware access for no seemingly sane reason.

Eric

#19 lore raw
Quoted 16 lines · Eric W. Biederman
Quoted 5 lines · H. Peter Anvin
Quoted 4 lines · Andi Kleen
Quoted 3 lines

Especially for accessing the real time clock that has a well defined hardware interface going through efi an additional software emulation layer looks like asking for trouble.

Quoted 8 lines
Quoted 5 lines

I agree it's pointless for the hardware clock, but EFI also offers services to write some data to the CMOS RAM
which could be very useful to save oops data over reboot.
I don't think this can be done safely otherwise without BIOS cooperation.

The ability to scurry away even a small amount of data without relying on the disk system is highly desirable. Think next-boot type information.

Quoted 8 lines

Yes. If that were to be the justifying case and if that was what the code was implementing I could see the point.

However this point was made in an earlier review. This point was already been made, and still this patchset doesn't include that functionality and it still includes the code to disable direct hardware access for no seemingly sane reason.

The EFI variable runtime service is included in this patchset.

The EFI time runtime service is selectable via kernel command line parameter now. If it is desired, it can be disabled by default, and only enabled if specified in kernel command line parameter. I think the time runtime service may be useful if the underlying hardware is changed silently by some vendor.

Best Regards,
Huang Ying

#20 lore raw
In reply to Thomas Gleixner
Quoted 8 lines · Thomas Gleixner
Quoted 7 lines

EFI runtime
services initialization are implemented in efi.c. Some x86_64 specifics are worth noting here. On x86_64, parameters passed to UEFI firmware services need to follow the UEFI calling convention. For this purpose, a set of functions named lin2win<x> (<x> is the number of parameters) are implemented. EFI function calls are wrapped before calling the firmware service.

Quoted 8 lines

Why needs this to be called lin2win? We do not call Windows, we call EFI services, so please use a naming convention which is related to the functionality of the code.

Quoted 2 lines

+ *
+ * Function calling ABI conversion from SYSV to Windows for x86_64

Again, these are wrappers to access EFI and not Windows.

EFI uses the Windows x86_64 calling convention. The lin2win may be a more general naming convention that can be used for some other code (the NDISwrapper?) in the future. Do you agree?

Best Regards,
Huang Ying

#21 lore raw
Quoted 13 lines · Ying
Quoted 12 lines · Thomas Gleixner
Quoted 7 lines

EFI runtime
services initialization are implemented in efi.c. Some x86_64 specifics are worth noting here. On x86_64, parameters passed to UEFI firmware services need to follow the UEFI calling convention. For this purpose, a set of functions named lin2win<x> (<x> is the number of parameters) are implemented. EFI function calls are wrapped before calling the firmware service.

Why needs this to be called lin2win? We do not call Windows, we call EFI services, so please use a naming convention which is related to the functionality of the code.

Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

+ *
+ * Function calling ABI conversion from SYSV to Windows for x86_64

Again, these are wrappers to access EFI and not Windows.

EFI uses the Windows x86_64 calling convention. The lin2win may be a more general naming convention that can be used for some other code (the NDISwrapper?) in the future. Do you agree?

I agree not at all. I do not care whether the EFI creators smoked the Windows-crackpipe or some other hallucinogen when they decided to use this calling convention. We definitely do not want to think about NDISwrapper or any other Windows related hackery in the kernel.

I still do not understand why we need all this EFI hackery at all aside of the possible usage for saving a crash dump on FLASH, which we could do directly from the kernel as well.

tglx

#22 lore raw
Quoted 8 lines · Thomas Gleixner
Quoted 3 lines

EFI uses the Windows x86_64 calling convention. The lin2win may be a more general naming convention that can be used for some other code (the NDISwrapper?) in the future. Do you agree?

I agree not at all. I do not care whether the EFI creators smoked the Windows-crackpipe or some other hallucinogen when they decided to use this calling convention. We definitely do not want to think about NDISwrapper or any other Windows related hackery in the kernel.

OK, I will change the name to something like lin2efi.

Quoted 3 lines

I still do not understand why we need all this EFI hackery at all aside of the possible usage for saving a crash dump on FLASH, which we could do directly from the kernel as well.

Ask every user to setup a crash dump environment is a bit difficult because some configuration like reserving memory, loading crash dump kernel must be done. But saving OOPS information in FLASH via EFI variable runtime service is quite simple, without configuration requirement. That is, there could be more bug report with OOPS information. I think this is useful.

Best Regards,
Huang Ying

#23 lore raw
Quoted 11 lines · Ying
Quoted 8 lines · Thomas Gleixner
Quoted 3 lines

EFI uses the Windows x86_64 calling convention. The lin2win may be a more general naming convention that can be used for some other code (the NDISwrapper?) in the future. Do you agree?

I agree not at all. I do not care whether the EFI creators smoked the Windows-crackpipe or some other hallucinogen when they decided to use this calling convention. We definitely do not want to think about NDISwrapper or any other Windows related hackery in the kernel.

OK, I will change the name to something like lin2efi.

Can we simply use call_efi_XXX(). lin2efi() sounds like a conversion routine, but it is not.

tglx

#24 lore raw
In reply to Thomas Gleixner
Quoted 4 lines

I still do not understand why we need all this EFI hackery at all aside of the possible usage for saving a crash dump on FLASH, which we could do directly from the kernel as well.

Battery backed up RAM not Flash. The layout of that RAM is BIOS dependent so we need some BIOS support for change it. Essentially it's a way to put something into the BIOS event log.

-Andi

#25 lore raw
In reply to Huang, Ying
Quoted 13 lines · Ying
Quoted 12 lines · Thomas Gleixner
Quoted 7 lines

EFI runtime
services initialization are implemented in efi.c. Some x86_64 specifics are worth noting here. On x86_64, parameters passed to UEFI firmware services need to follow the UEFI calling convention. For this purpose, a set of functions named lin2win<x> (<x> is the number of parameters) are implemented. EFI function calls are wrapped before calling the firmware service.

Why needs this to be called lin2win? We do not call Windows, we call EFI services, so please use a naming convention which is related to the functionality of the code.

Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

+ *
+ * Function calling ABI conversion from SYSV to Windows for x86_64

Again, these are wrappers to access EFI and not Windows.

EFI uses the Windows x86_64 calling convention. The lin2win may be a more general naming convention that can be used for some other code (the NDISwrapper?) in the future. Do you agree?

The SYSV description is wrong as well. SYSV has no calling convention. I think you mean iABI or iBCS2 ?

Whats wrong with following the pattern of other calls like syscall(...) and just having eficall() ?

Alan.

#26 lore raw
Quoted 10 lines · Alan Cox
Quoted 4 lines
Quoted 1 line

Again, these are wrappers to access EFI and not Windows.

EFI uses the Windows x86_64 calling convention. The lin2win may be a more general naming convention that can be used for some other code (the NDISwrapper?) in the future. Do you agree?

The SYSV description is wrong as well. SYSV has no calling convention. I think you mean iABI or iBCS2 ?

Whats wrong with following the pattern of other calls like syscall(...) and just having eficall() ?

Either that (which is basically his lin2win6), or use wrapper-generators like we used to do for system calls -- the latter will produce more efficient code. I don't think it matters.

-hpa

#27 lore raw
In reply to Alan Cox
Quoted 19 lines · Alan Cox
Quoted 16 lines · Ying
Quoted 15 lines · Thomas Gleixner
Quoted 7 lines

EFI runtime
services initialization are implemented in efi.c. Some x86_64 specifics are worth noting here. On x86_64, parameters passed to UEFI firmware services need to follow the UEFI calling convention. For this purpose, a set of functions named lin2win<x> (<x> is the number of parameters) are implemented. EFI function calls are wrapped before calling the firmware service.

Why needs this to be called lin2win? We do not call Windows, we call EFI services, so please use a naming convention which is related to the functionality of the code.

Quoted 2 lines

+ *
+ * Function calling ABI conversion from SYSV to Windows for x86_64

Quoted 8 lines
Quoted 5 lines
Quoted 1 line

Again, these are wrappers to access EFI and not Windows.

EFI uses the Windows x86_64 calling convention. The lin2win may be a more general naming convention that can be used for some other code (the NDISwrapper?) in the future. Do you agree?

The SYSV description is wrong as well. SYSV has no calling convention. I think you mean iABI or iBCS2 ?

The SYSV description comes from the following document:
http://www.x86-64.org/documentation/abi-0.98.pdf

Quoted 2 lines

Whats wrong with following the pattern of other calls like syscall(...) and just having eficall() ?

Yes. This is better.

Best Regards,
Huang Ying

#28 lore raw
In reply to Thomas Gleixner
Quoted 6 lines · Thomas Gleixner
Quoted 3 lines · Ying

This patch adds basic runtime services support for EFI x86_64 system. The main file of the patch is the addition of efi.c for x86_64. This file is modeled after the EFI IA32 avatar.

Quoted 7 lines

modeled means copied and modified, right?

This is wrong. I compared efi_32.c and efi_64.c and a large amount of the code is simply the same. The small details can be sorted out by two sets of macros/inline functions easily.

Please fix this up.

Yes. There are many duplicated code between efi_32.c and efi_64.c, and they should be merged. But there are some code that is different between efi_32.c and efi_64.c. For example, there is different implementations of efi_call_phys_prelog in both files, and there is an implementation of efi_memmap_walk only in efi_32.c not in efi_64.c.

3 possible schemes are as follow:

- One efi.c, with EFI 32/64 specific code inside corresponding #ifdef/#endif.

- 3 files: efi.c, efi_32.c, efi_64.c, common code goes in efi.c, EFI 32/64 specific code goes in efi_32/64.c. This will make some variable, function external instead of static.

- 3 files: efi.c, efi_32.c, efi_64.c, common code goes in efi.c, EFI 32/64 specific code goes in efi_32/64.c. efi.c include efi_32/64.c according to architecture.

Which one is preferred? Or I should take another scheme?

Best Regards,
Huang Ying

#29 lore raw
Quoted 5 lines · Ying

- 3 files: efi.c, efi_32.c, efi_64.c, common code goes in efi.c, EFI 32/64 specific code goes in efi_32/64.c. This will make some variable, function external instead of static.

This is preferred.

-hpa

#30 lore raw
In reply to Huang, Ying
Quoted 34 lines · Ying
arch/x86/kernel/efi_64.c new file +34 -0
+static void __init efi_call_phys_prelog(void) __acquires(efi_lock)
+{
+	unsigned long vaddress;
+
+	/*
+	 * Lock sequence is different from normal case because
+	 * efi_flags is global
+	 */
+	spin_lock(&efi_lock);
+	local_irq_save(efi_flags);
+	early_runtime_code_mapping_set_exec(1);
+	vaddress = (unsigned long)__va(0x0UL);
+	pgd_val(save_pgd) = pgd_val(*pgd_offset_k(0x0UL));
+	set_pgd(pgd_offset_k(0x0UL), *pgd_offset_k(vaddress));
+	global_flush_tlb();
+}
+
+static void __init efi_call_phys_epilog(void) __releases(efi_lock)
+{
+	/*
+	 * After the lock is released, the original page table is restored.
+	 */
+	set_pgd(pgd_offset_k(0x0UL), save_pgd);
+	early_runtime_code_mapping_set_exec(0);
+	global_flush_tlb();
+	local_irq_restore(efi_flags);
+	spin_unlock(&efi_lock);
+}
+
+static efi_status_t __init phys_efi_set_virtual_address_map(
+	unsigned long memory_map_size,
+	unsigned long descriptor_size,
+	u32 descriptor_version,
+	efi_memory_desc_t *virtual_map)

arch/x86/kernel/efi_64.c line 248

Quoted 10 lines
arch/x86/kernel/efi_64.c new file +10 -0
+{
+	efi_status_t status;
+
+	efi_call_phys_prelog();
+	status = lin2win4((void *)efi_phys.set_virtual_address_map,
+			  (u64)memory_map_size, (u64)descriptor_size,
+			  (u64)descriptor_version, (u64)virtual_map);
+	efi_call_phys_epilog();
+	return status;
+}

So you still have this piece of code which makes a kernel using efi not compatible with kexec. But you are still supporting a physical call mode for efi. If you are going to do this can we please just remove the hacks that make the EFI physical call mode early boot only and just always use that mode. Depending on weird call once functions like efi_set_virtual_address_map makes me very uncomfortable.

Eric

#31 lore raw
Quoted 14 lines · Eric W. Biederman
Quoted 14 lines
arch/x86/kernel/efi_64.c new file +14 -0
+static efi_status_t __init phys_efi_set_virtual_address_map(
+	unsigned long memory_map_size,
+	unsigned long descriptor_size,
+	u32 descriptor_version,
+	efi_memory_desc_t *virtual_map)
+{
+	efi_status_t status;
+
+	efi_call_phys_prelog();
+	status = lin2win4((void *)efi_phys.set_virtual_address_map,
+			  (u64)memory_map_size, (u64)descriptor_size,
+			  (u64)descriptor_version, (u64)virtual_map);
+	efi_call_phys_epilog();
+	return status;
Quoted 8 lines
Quoted 1 line

+}

So you still have this piece of code which makes a kernel using efi not compatible with kexec. But you are still supporting a physical call mode for efi. If you are going to do this can we please just remove the hacks that make the EFI physical call mode early boot only and just always use that mode. Depending on weird call once functions like efi_set_virtual_address_map makes me very uncomfortable.

The kexec issue is solved as that of IA-64. The EFI runtime code and data memory area is mapped with identity mapping, so they will have same virtual address across kexec. The memory mapped IO memory area used by EFI runtime services is mapped with fixmap, so they will have same virtual address across kexec too. And the efi_set_virtual_address_map runtime service function will be skipped in the kexeced kernel (set to "nop" in /sbin/kexec). So the kexeced kernel can use the virtual mode of EFI from kernel bootstrap on.

Best Regards,
Huang Ying