[U-Boot] [PATCH v3 22/28] x86: Handle running as EFI payload

Simon Glass sjg at chromium.org
Tue Aug 4 20:34:00 CEST 2015


When U-Boot runs as an EFI payload it needs to avoid setting up the CPU
again. Also U-Boot currently does not handle interrupts for many devices, so
run with interrupts disabled.

Signed-off-by: Simon Glass <sjg at chromium.org>
Reviewed-by: Bin Meng <bmeng.cn at gmail.com>
---

Changes in v3: None
Changes in v2:
- Add a note that bootm does not work when running as an EFI app
- Move EFI CAR settings to arch/x86/lib/efi/Kconfig
- Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP

 arch/x86/Kconfig          |  6 ++++++
 arch/x86/cpu/cpu.c        | 21 +++++++++++++--------
 arch/x86/cpu/interrupts.c | 10 ++++++++--
 arch/x86/lib/bootm.c      |  5 +++++
 arch/x86/lib/efi/Kconfig  | 11 +++++++++++
 5 files changed, 43 insertions(+), 10 deletions(-)
 create mode 100644 arch/x86/lib/efi/Kconfig

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index f124d58..01ed760 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -194,6 +194,7 @@ config X86_RAMTEST
 
 config HAVE_FSP
 	bool "Add an Firmware Support Package binary"
+	depends on !EFI
 	help
 	  Select this option to add an Firmware Support Package binary to
 	  the resulting U-Boot image. It is a binary blob which U-Boot uses
@@ -309,6 +310,7 @@ menu "System tables"
 
 config GENERATE_PIRQ_TABLE
 	bool "Generate a PIRQ table"
+	depends on !EFI
 	default n
 	help
 	  Generate a PIRQ routing table for this board. The PIRQ routing table
@@ -319,6 +321,7 @@ config GENERATE_PIRQ_TABLE
 
 config GENERATE_SFI_TABLE
 	bool "Generate a SFI (Simple Firmware Interface) table"
+	depends on !EFI
 	help
 	  The Simple Firmware Interface (SFI) provides a lightweight method
 	  for platform firmware to pass information to the operating system
@@ -333,6 +336,7 @@ config GENERATE_SFI_TABLE
 
 config GENERATE_MP_TABLE
 	bool "Generate an MP (Multi-Processor) table"
+	depends on !EFI
 	default n
 	help
 	  Generate an MP (Multi-Processor) table for this board. The MP table
@@ -383,4 +387,6 @@ config PCIE_ECAM_SIZE
 	  so a default 0x10000000 size covers all of the 256 buses which is the
 	  maximum number of PCI buses as defined by the PCI specification.
 
+source "arch/x86/lib/efi/Kconfig"
+
 endmenu
diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index d233a45..129777c 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -330,13 +330,15 @@ int x86_cpu_init_f(void)
 	const u32 em_rst = ~X86_CR0_EM;
 	const u32 mp_ne_set = X86_CR0_MP | X86_CR0_NE;
 
-	/* initialize FPU, reset EM, set MP and NE */
-	asm ("fninit\n" \
-	     "movl %%cr0, %%eax\n" \
-	     "andl %0, %%eax\n" \
-	     "orl  %1, %%eax\n" \
-	     "movl %%eax, %%cr0\n" \
-	     : : "i" (em_rst), "i" (mp_ne_set) : "eax");
+	if (ll_boot_init()) {
+		/* initialize FPU, reset EM, set MP and NE */
+		asm ("fninit\n" \
+		"movl %%cr0, %%eax\n" \
+		"andl %0, %%eax\n" \
+		"orl  %1, %%eax\n" \
+		"movl %%eax, %%cr0\n" \
+		: : "i" (em_rst), "i" (mp_ne_set) : "eax");
+	}
 
 	/* identify CPU via cpuid and store the decoded info into gd->arch */
 	if (has_cpuid()) {
@@ -712,5 +714,8 @@ __weak int x86_init_cpus(void)
 
 int cpu_init_r(void)
 {
-	return x86_init_cpus();
+	if (ll_boot_init())
+		return x86_init_cpus();
+
+	return 0;
 }
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
index a112938..9217307 100644
--- a/arch/x86/cpu/interrupts.c
+++ b/arch/x86/cpu/interrupts.c
@@ -258,8 +258,14 @@ int interrupt_init(void)
 	/* Initialize core interrupt and exception functionality of CPU */
 	cpu_init_interrupts();
 
-	/* It is now safe to enable interrupts */
-	enable_interrupts();
+	/*
+	 * It is now safe to enable interrupts.
+	 *
+	 * TODO(sjg at chromium.org): But we don't handle these correctly when
+	 * booted from EFI.
+	 */
+	if (ll_boot_init())
+		enable_interrupts();
 #endif
 
 	return 0;
diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c
index 445ee6e..f441c84 100644
--- a/arch/x86/lib/bootm.c
+++ b/arch/x86/lib/bootm.c
@@ -164,7 +164,11 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
 		* the data segments are 0x18, 4GB flat, and read/write.
 		* U-boot is setting them up that way for itself in
 		* arch/i386/cpu/cpu.c.
+		*
+		* Note that we cannot currently boot a kernel while running as
+		* an EFI application. Please use the payload option for that.
 		*/
+#ifndef CONFIG_EFI_APP
 		__asm__ __volatile__ (
 		"movl $0, %%ebp\n"
 		"cli\n"
@@ -173,6 +177,7 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
 		[boot_params] "S"(setup_base),
 		"b"(0), "D"(0)
 		);
+#endif
 	}
 
 	/* We can't get to here */
diff --git a/arch/x86/lib/efi/Kconfig b/arch/x86/lib/efi/Kconfig
new file mode 100644
index 0000000..e0975d3
--- /dev/null
+++ b/arch/x86/lib/efi/Kconfig
@@ -0,0 +1,11 @@
+if EFI
+
+config SYS_CAR_ADDR
+	hex
+	default 0x100000
+
+config SYS_CAR_SIZE
+	hex
+	default 0x20000
+
+endif
-- 
2.5.0.rc2.392.g76e840b



More information about the U-Boot mailing list