[PATCH v2 086/113] ARM64: add optional EFI stub

Ahmad Fatoum a.fatoum at pengutronix.de
Mon Mar 4 11:00:11 PST 2024


While very recent binutils releases have dedicated efi-*-aarch targets,
we may want to support older toolchains. For this reason, we import
the kernel's EFI stub PE fakery, so the same barebox-dt-2nd.img may be
loaded as if it were a "normal" or an EFI-stubbed kernel.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
v1 -> v2:
  - squash with commit introducing PECOFF_EDATA_PADDING
---
 Makefile                            |   6 +-
 arch/arm/Kconfig                    |   1 +
 arch/arm/cpu/Kconfig                |   1 +
 arch/arm/cpu/board-dt-2nd-aarch64.S |   8 +-
 arch/arm/cpu/cpu.c                  |   6 ++
 arch/arm/cpu/efi-header-aarch64.S   | 122 ++++++++++++++++++++++++++++
 arch/arm/cpu/entry.c                |   3 +
 arch/arm/cpu/interrupts_64.c        |   6 +-
 arch/arm/cpu/mmu-common.c           |   4 +
 arch/arm/cpu/start.c                |  16 ++--
 arch/arm/include/asm/memory.h       |  20 +++++
 arch/arm/include/asm/pci.h          |   4 +-
 arch/arm/lib/pbl.lds.S              |  31 +++++++
 arch/arm/lib64/armlinux.c           |   4 +
 arch/x86/Kconfig                    |   1 +
 efi/Kconfig                         |  13 ++-
 efi/payload/Makefile                |   2 +
 efi/payload/boarddata.c             |  45 ++++++++++
 efi/payload/entry-multi.c           |  45 ++++++++++
 include/pbl.h                       |   4 +
 test/self/mmu.c                     |   7 ++
 21 files changed, 337 insertions(+), 12 deletions(-)
 create mode 100644 arch/arm/cpu/efi-header-aarch64.S
 create mode 100644 efi/payload/boarddata.c
 create mode 100644 efi/payload/entry-multi.c

diff --git a/Makefile b/Makefile
index 358cd4140ce8..5a4300deadb2 100644
--- a/Makefile
+++ b/Makefile
@@ -734,7 +734,11 @@ images: barebox.bin FORCE
 images/%.s: barebox.bin FORCE
 	$(Q)$(MAKE) $(build)=images $@
 
-ifdef CONFIG_PBL_IMAGE
+ifdef CONFIG_EFI_STUB
+all: barebox.bin images barebox.efi
+barebox.efi: FORCE
+	$(Q)ln -fsn images/barebox-dt-2nd.img $@
+else ifdef CONFIG_PBL_IMAGE
 all: barebox.bin images
 else
 all: barebox-flash-image barebox-flash-images
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 86fc912ac49f..1377679ac90c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -9,6 +9,7 @@ config ARM
 	select HAVE_ARCH_KASAN
 	select ARCH_HAS_SJLJ
 	select ARM_OPTIMZED_STRING_FUNCTIONS if KASAN
+	select HAVE_EFI_STUB
 	default y
 
 config ARM_LINUX
diff --git a/arch/arm/cpu/Kconfig b/arch/arm/cpu/Kconfig
index 40dd35833a63..e69acaacdf2f 100644
--- a/arch/arm/cpu/Kconfig
+++ b/arch/arm/cpu/Kconfig
@@ -21,6 +21,7 @@ config CPU_64
 	select HAS_DMA
 	select ARCH_WANT_FRAME_POINTERS
 	select ARCH_HAS_ZERO_PAGE
+	select HAVE_EFI_PAYLOAD
 
 # Select CPU types depending on the architecture selected. This selects
 # which CPUs we support in the kernel image, and the compiler instruction
diff --git a/arch/arm/cpu/board-dt-2nd-aarch64.S b/arch/arm/cpu/board-dt-2nd-aarch64.S
index d2c9f132cef6..030366c1cbf5 100644
--- a/arch/arm/cpu/board-dt-2nd-aarch64.S
+++ b/arch/arm/cpu/board-dt-2nd-aarch64.S
@@ -2,6 +2,7 @@
 #include <linux/linkage.h>
 #include <asm/barebox-arm64.h>
 #include <asm/image.h>
+#include "efi-header-aarch64.S"
 
 #define IMAGE_FLAGS \
 	(ARM64_IMAGE_FLAG_PAGE_SIZE_4K << ARM64_IMAGE_FLAG_PAGE_SIZE_SHIFT) | \
@@ -9,7 +10,7 @@
 
 .section .text_head_entry_start_dt_2nd
 ENTRY("start_dt_2nd")
-	adr x1, 0	   	   /* code0 */
+	efi_signature_nop          /* code0 */
 	b 2f                       /* code1 */
 	.xword 0x80000             /* Image load offset */
 	.xword _barebox_image_size /* Effective Image size */
@@ -18,12 +19,15 @@ ENTRY("start_dt_2nd")
 	.xword 0                   /* reserved */
 	.xword 0                   /* reserved */
 	.ascii ARM64_IMAGE_MAGIC   /* magic number */
-	.int   0                   /* reserved (PE-COFF offset) */
+	.int   .Lpe_header_offset  /* reserved (PE-COFF offset) */
 	.asciz "barebox"	   /* unused for now */
 2:
+	adr x1, 0
 	mov sp, x1
 	/* Stack now grows into the 0x80000 image load offset specified
 	 * above. This is more than enough until FDT /memory is decoded.
 	 */
 	b dt_2nd_aarch64
+
+	__EFI_PE_HEADER
 ENTRY_PROC_END(start_dt_2nd)
diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c
index cacd442b28da..5f1ffe9a3c76 100644
--- a/arch/arm/cpu/cpu.c
+++ b/arch/arm/cpu/cpu.c
@@ -17,6 +17,7 @@
 #include <asm/cputype.h>
 #include <asm/cache.h>
 #include <asm/ptrace.h>
+#include <efi/efi-mode.h>
 
 /**
  * Enable processor's instruction cache
@@ -82,6 +83,8 @@ static void disable_interrupts(void)
  */
 static void arch_shutdown(void)
 {
+	if (efi_is_payload())
+		return;
 
 #ifdef CONFIG_MMU
 	mmu_disable();
@@ -96,6 +99,9 @@ extern unsigned long arm_stack_top;
 
 static int arm_request_stack(void)
 {
+	if (efi_is_payload())
+		return 0;
+
 	if (!request_sdram_region("stack", arm_stack_top - STACK_SIZE, STACK_SIZE))
 		pr_err("Error: Cannot request SDRAM region for stack\n");
 
diff --git a/arch/arm/cpu/efi-header-aarch64.S b/arch/arm/cpu/efi-header-aarch64.S
new file mode 100644
index 000000000000..941d0d8fdcaa
--- /dev/null
+++ b/arch/arm/cpu/efi-header-aarch64.S
@@ -0,0 +1,122 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013 - 2017 Linaro, Ltd.
+ * Copyright (C) 2013, 2014 Red Hat, Inc.
+ */
+
+#include <linux/pe.h>
+#include <linux/sizes.h>
+#include <asm/memory.h>
+
+	.macro	efi_signature_nop
+#ifdef CONFIG_EFI_STUB
+.L_head:
+	/*
+	 * This ccmp instruction has no meaningful effect except that
+	 * its opcode forms the magic "MZ" signature required by UEFI.
+	 */
+	ccmp	x18, #0, #0xd, pl
+#else
+	/*
+	 * Bootloaders may inspect the opcode at the start of the kernel
+	 * image to decide if the kernel is capable of booting via UEFI.
+	 * So put an ordinary NOP here, not the "MZ.." pseudo-nop above.
+	 */
+	nop
+#endif
+	.endm
+
+	.macro	__EFI_PE_HEADER
+#ifdef CONFIG_EFI_STUB
+	.set	.Lpe_header_offset, . - .L_head
+	.long	PE_MAGIC
+	.short	IMAGE_FILE_MACHINE_ARM64		// Machine
+	.short	.Lsection_count				// NumberOfSections
+	.long	0 					// TimeDateStamp
+	.long	0					// PointerToSymbolTable
+	.long	0					// NumberOfSymbols
+	.short	.Lsection_table - .Loptional_header	// SizeOfOptionalHeader
+	.short	IMAGE_FILE_DEBUG_STRIPPED | \
+		IMAGE_FILE_EXECUTABLE_IMAGE | \
+		IMAGE_FILE_LINE_NUMS_STRIPPED		// Characteristics
+
+.Loptional_header:
+	.short	PE_OPT_MAGIC_PE32PLUS			// PE32+ format
+	.byte	0x02					// MajorLinkerVersion
+	.byte	0x14					// MinorLinkerVersion
+	.long	_sdata - .Lefi_header_end		// SizeOfCode
+	.long	__pecoff_data_size			// SizeOfInitializedData
+	.long	0					// SizeOfUninitializedData
+	.long	__efistub_efi_pe_entry - .L_head	// AddressOfEntryPoint
+	.long	.Lefi_header_end - .L_head		// BaseOfCode
+
+	.quad	0					// ImageBase
+	.long	PBL_SEGMENT_ALIGN			// SectionAlignment
+	.long	PECOFF_FILE_ALIGNMENT			// FileAlignment
+	.short	0					// MajorOperatingSystemVersion
+	.short	0					// MinorOperatingSystemVersion
+	.short	LINUX_EFISTUB_MAJOR_VERSION		// MajorImageVersion
+	.short	LINUX_EFISTUB_MINOR_VERSION		// MinorImageVersion
+	.short	0					// MajorSubsystemVersion
+	.short	0					// MinorSubsystemVersion
+	.long	0					// Win32VersionValue
+
+	.long	__image_end - .L_head			// SizeOfImage
+
+	// Everything before the kernel image is considered part of the header
+	.long	.Lefi_header_end - .L_head		// SizeOfHeaders
+	.long	0					// CheckSum
+	.short	IMAGE_SUBSYSTEM_EFI_APPLICATION		// Subsystem
+	.short	0					// DllCharacteristics
+	.quad	0					// SizeOfStackReserve
+	.quad	0					// SizeOfStackCommit
+	.quad	0					// SizeOfHeapReserve
+	.quad	0					// SizeOfHeapCommit
+	.long	0					// LoaderFlags
+	.long	(.Lsection_table - .) / 8		// NumberOfRvaAndSizes
+
+	.quad	0					// ExportTable
+	.quad	0					// ImportTable
+	.quad	0					// ResourceTable
+	.quad	0					// ExceptionTable
+	.quad	0					// CertificationTable
+	.quad	0					// BaseRelocationTable
+
+	// Section table
+.Lsection_table:
+	.ascii	".text\0\0\0"
+	.long	_sdata - .Lefi_header_end		// VirtualSize
+	.long	.Lefi_header_end - .L_head		// VirtualAddress
+	.long	_sdata - .Lefi_header_end		// SizeOfRawData
+	.long	.Lefi_header_end - .L_head		// PointerToRawData
+
+	.long	0					// PointerToRelocations
+	.long	0					// PointerToLineNumbers
+	.short	0					// NumberOfRelocations
+	.short	0					// NumberOfLineNumbers
+	.long	IMAGE_SCN_CNT_CODE | \
+		IMAGE_SCN_MEM_READ | \
+		IMAGE_SCN_MEM_EXECUTE			// Characteristics
+
+	.ascii	".data\0\0\0"
+	.long	__pecoff_data_size			// VirtualSize
+	.long	_sdata - .L_head			// VirtualAddress
+	.long	__pecoff_data_rawsize			// SizeOfRawData
+	.long	_sdata - .L_head			// PointerToRawData
+
+	.long	0					// PointerToRelocations
+	.long	0					// PointerToLineNumbers
+	.short	0					// NumberOfRelocations
+	.short	0					// NumberOfLineNumbers
+	.long	IMAGE_SCN_CNT_INITIALIZED_DATA | \
+		IMAGE_SCN_MEM_READ | \
+		IMAGE_SCN_MEM_WRITE			// Characteristics
+
+	.set	.Lsection_count, (. - .Lsection_table) / 40
+
+	.balign	PBL_SEGMENT_ALIGN
+.Lefi_header_end:
+#else
+	.set	.Lpe_header_offset, 0x0
+#endif
+	.endm
diff --git a/arch/arm/cpu/entry.c b/arch/arm/cpu/entry.c
index dc264c877117..cc08d0ff7e42 100644
--- a/arch/arm/cpu/entry.c
+++ b/arch/arm/cpu/entry.c
@@ -42,3 +42,6 @@ void NAKED __noreturn barebox_arm_entry(unsigned long membase,
 	__barebox_arm_entry(membase, memsize, boarddata,
 			    arm_mem_stack_top(membase + memsize));
 }
+
+void __noreturn barebox_pbl_entry(ulong, ulong, void *)
+	__alias(barebox_arm_entry);
diff --git a/arch/arm/cpu/interrupts_64.c b/arch/arm/cpu/interrupts_64.c
index b3e7da179756..6262ba8872db 100644
--- a/arch/arm/cpu/interrupts_64.c
+++ b/arch/arm/cpu/interrupts_64.c
@@ -11,6 +11,7 @@
 #include <init.h>
 #include <asm/system.h>
 #include <asm/esr.h>
+#include <efi/efi-mode.h>
 
 /* Avoid missing prototype warning, called from assembly */
 void do_bad_sync (struct pt_regs *pt_regs);
@@ -204,6 +205,9 @@ static int aarch64_init_vectors(void)
 {
 	unsigned int el;
 
+	if (efi_is_payload())
+		return 0;
+
 	el = current_el();
 	switch (el) {
 	case 3:
@@ -221,4 +225,4 @@ static int aarch64_init_vectors(void)
 
 	return 0;
 }
-pure_initcall(aarch64_init_vectors);
+core_initcall(aarch64_init_vectors);
diff --git a/arch/arm/cpu/mmu-common.c b/arch/arm/cpu/mmu-common.c
index acd4a9d35413..aeaf6c269df6 100644
--- a/arch/arm/cpu/mmu-common.c
+++ b/arch/arm/cpu/mmu-common.c
@@ -13,6 +13,7 @@
 #include <memory.h>
 #include <zero_page.h>
 #include "mmu-common.h"
+#include <efi/efi-mode.h>
 
 void arch_sync_dma_for_cpu(void *vaddr, size_t size,
 			   enum dma_data_direction dir)
@@ -67,6 +68,9 @@ void zero_page_faulting(void)
 
 static int mmu_init(void)
 {
+	if (efi_is_payload())
+		return 0;
+
 	if (list_empty(&memory_banks)) {
 		resource_size_t start;
 		int ret;
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index 9f4cdfe67fbf..0351dcb9278d 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -43,14 +43,18 @@ static bool blob_is_arm_boarddata(const void *blob)
 	return bd->magic == BAREBOX_ARM_BOARDDATA_MAGIC;
 }
 
+const struct barebox_boarddata *barebox_get_boarddata(void)
+{
+	if (!barebox_boarddata || !blob_is_arm_boarddata(barebox_boarddata))
+		return NULL;
+
+	return barebox_boarddata;
+}
+
 u32 barebox_arm_machine(void)
 {
-	if (barebox_boarddata && blob_is_arm_boarddata(barebox_boarddata)) {
-		const struct barebox_arm_boarddata *bd = barebox_boarddata;
-		return bd->machine;
-	} else {
-		return 0;
-	}
+	const struct barebox_boarddata *bd = barebox_get_boarddata();
+	return bd ? bd->machine : 0;
 }
 
 void *barebox_arm_boot_dtb(void)
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 23fbbd8438a1..765b089beb59 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -3,6 +3,9 @@
 #ifndef __ASM_ARM_MEMORY_H
 #define __ASM_ARM_MEMORY_H
 
+#include <linux/sizes.h>
+
+#ifndef __ASSEMBLY__
 #include <memory.h>
 
 #include <linux/const.h>
@@ -13,4 +16,21 @@ static inline int arm_add_mem_device(const char* name, resource_size_t start,
 	return barebox_add_memory_bank(name, start, size);
 }
 
+#endif
+
+
+/*
+ * Alignment of barebox PBL segments (e.g. .text, .data).
+ *
+ *  4  B granule:  Same flat rwx mapping for everything
+ *  4 KB granule:  16 level 3 entries, with contiguous bit
+ * 16 KB granule:   4 level 3 entries, without contiguous bit
+ * 64 KB granule:   1 level 3 entry
+ */
+#ifdef CONFIG_EFI_PAYLOAD
+#define PBL_SEGMENT_ALIGN		SZ_64K
+#else
+#define PBL_SEGMENT_ALIGN		4
+#endif
+
 #endif	/* __ASM_ARM_MEMORY_H */
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index d7419cabe7ef..7c834f110111 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -2,6 +2,8 @@
 #ifndef __ASM_PCI_H
 #define __ASM_PCI_H
 
-#define pcibios_assign_all_busses()	1
+#include <efi/efi-mode.h>
+
+#define pcibios_assign_all_busses()	(!efi_is_payload())
 
 #endif
diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S
index cafb27b2d55e..ec7296f0fb34 100644
--- a/arch/arm/lib/pbl.lds.S
+++ b/arch/arm/lib/pbl.lds.S
@@ -3,8 +3,27 @@
 
 #include <linux/sizes.h>
 #include <asm/barebox.lds.h>
+#include <asm/memory.h>
 #include <asm-generic/memory_layout.h>
 #include <asm-generic/pointer.h>
+#include <asm/memory.h>
+
+/*
+ * The size of the PE/COFF section that covers the barebox image, which
+ * runs from _stext to _edata, must be a round multiple of the PE/COFF
+ * FileAlignment, which we set to its minimum value of 0x200. '_stext'
+ * itself must be 4 KB aligned, because that's what the adrp instructions
+ * expects, so padding out _edata to a 0x200 aligned boundary should be
+ * sufficient.
+ */
+PECOFF_FILE_ALIGNMENT = 0x200;
+
+#ifdef CONFIG_EFI_STUB
+#define PECOFF_EDATA_PADDING   \
+       .pecoff_edata_padding : { BYTE(0); . = ALIGN(PECOFF_FILE_ALIGNMENT); }
+#else
+#define PECOFF_EDATA_PADDING
+#endif
 
 #ifdef CONFIG_PBL_RELOCATABLE
 #define BASE	0x0
@@ -62,7 +81,9 @@ SECTIONS
 
 	.barebox_imd : { BAREBOX_IMD }
 
+	. = ALIGN(PBL_SEGMENT_ALIGN);
 	_etext = .;			/* End of text and rodata section */
+	_sdata = .;
 
 	. = ALIGN(4);
 	.data : { *(.data*) }
@@ -109,6 +130,16 @@ SECTIONS
 	}
 	__pblext_end = .;
 
+	PECOFF_EDATA_PADDING
+
+	__pecoff_data_rawsize = ABSOLUTE(. - _etext);
+
+	/* .bss is dwarfed by piggydata size, so we just handle .bss
+	 * as normal PE data
+	 */
+
+	__pecoff_data_size = ABSOLUTE(. - _etext);
+
 	.image_end : { KEEP(*(.__image_end)) }
 
 	pbl_image_size =  . - BASE;
diff --git a/arch/arm/lib64/armlinux.c b/arch/arm/lib64/armlinux.c
index 40fea37f53a7..4628c8ab5693 100644
--- a/arch/arm/lib64/armlinux.c
+++ b/arch/arm/lib64/armlinux.c
@@ -5,6 +5,7 @@
 #include <memory.h>
 #include <init.h>
 #include <bootm.h>
+#include <efi/efi-mode.h>
 
 static int do_bootm_linux(struct image_data *data)
 {
@@ -89,6 +90,9 @@ static struct image_handler aarch64_barebox_handler = {
 
 static int aarch64_register_image_handler(void)
 {
+	if (efi_is_payload())
+		return 0;
+
 	register_image_handler(&aarch64_linux_efi_handler);
 	register_image_handler(&aarch64_linux_handler);
 	register_image_handler(&aarch64_barebox_handler);
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 85f7e067d09a..aab0c3c63261 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -6,6 +6,7 @@ config X86
 	select HAS_DMA
 	select GENERIC_FIND_NEXT_BIT
 	select ARCH_DMA_DEFAULT_COHERENT
+	select HAVE_EFI_PAYLOAD
 	default y
 
 config ARCH_TEXT_BASE
diff --git a/efi/Kconfig b/efi/Kconfig
index 971d58a7a9c0..35a57a3a42de 100644
--- a/efi/Kconfig
+++ b/efi/Kconfig
@@ -2,8 +2,12 @@
 
 menu "EFI (Extensible Firmware Interface) Support"
 
-config EFI_PAYLOAD
+config HAVE_EFI_PAYLOAD
 	bool
+
+config EFI_PAYLOAD
+	bool "Build as EFI payload" if COMPILE_TEST
+	depends on HAVE_EFI_PAYLOAD
 	select EFI
 	select EFI_GUID
 	select EFI_DEVICEPATH
@@ -16,6 +20,13 @@ config EFI_PAYLOAD
 config EFI
 	bool
 
+config HAVE_EFI_STUB
+	bool
+
+config EFI_STUB
+	def_bool EFI_PAYLOAD
+	depends on HAVE_EFI_STUB
+
 config EFI_GUID
 	bool
 	help
diff --git a/efi/payload/Makefile b/efi/payload/Makefile
index 71305bee7006..a4a0332a8288 100644
--- a/efi/payload/Makefile
+++ b/efi/payload/Makefile
@@ -7,3 +7,5 @@ bbenv-y += env-efi
 obj-$(CONFIG_CMD_IOMEM) += iomem.o
 obj-pbl-$(CONFIG_EFI_PAYLOAD) += early-mem.o
 obj-$(CONFIG_EFI_PAYLOAD) += entry-single.o
+pbl-$(CONFIG_EFI_STUB) += entry-multi.o
+obj-$(CONFIG_EFI_STUB) += boarddata.o
diff --git a/efi/payload/boarddata.c b/efi/payload/boarddata.c
new file mode 100644
index 000000000000..3260e31c7bf7
--- /dev/null
+++ b/efi/payload/boarddata.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#define pr_fmt(fmt) "efi-boarddata: " fmt
+
+#ifdef CONFIG_DEBUG_INITCALLS
+#define DEBUG
+#endif
+
+#include <efi/efi-payload.h>
+#include <efi.h>
+#include <boarddata.h>
+#include <memory.h>
+#include <linux/kernel.h>
+#include <linux/printk.h>
+#include <debug_ll.h>
+#include <init.h>
+
+static int handle_efi_boarddata(void)
+{
+	const struct barebox_boarddata *bd = barebox_get_boarddata();
+	efi_status_t efiret;
+
+	if (!barebox_boarddata_is_machine(bd, BAREBOX_MACH_TYPE_EFI))
+		return 0;
+
+	barebox_add_memory_bank("ram0", mem_malloc_start(), mem_malloc_size());
+
+	efi_parent_image = bd->image;
+	efi_sys_table = bd->sys_table;
+	BS = efi_sys_table->boottime;
+	RT = efi_sys_table->runtime;
+
+	pr_debug("parent_image = %p, sys_table = %p\n",
+		 efi_parent_image, efi_sys_table);
+
+	efiret = BS->open_protocol(efi_parent_image, &efi_loaded_image_protocol_guid,
+			(void **)&efi_loaded_image,
+			efi_parent_image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+	if (!EFI_ERROR(efiret))
+		BS->handle_protocol(efi_loaded_image->device_handle,
+				&efi_device_path_protocol_guid, (void **)&efi_device_path);
+
+	return 0;
+}
+pure_initcall(handle_efi_boarddata);
diff --git a/efi/payload/entry-multi.c b/efi/payload/entry-multi.c
new file mode 100644
index 000000000000..f929ab01ec7b
--- /dev/null
+++ b/efi/payload/entry-multi.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/sizes.h>
+#include <boarddata.h>
+#include <stdio.h>
+#include <efi.h>
+#include <asm/common.h>
+#include <efi/efi-util.h>
+#include <efi/efi-payload.h>
+#include <pbl.h>
+
+static struct barebox_boarddata boarddata = {
+	.magic = BAREBOX_BOARDDATA_MAGIC,
+	.machine = BAREBOX_MACH_TYPE_EFI,
+};
+
+asmlinkage void __efistub_efi_pe_entry(void *image, struct efi_system_table *sys_table);
+
+static void efi_putc(void *ctx, int ch)
+{
+	struct efi_system_table *sys_table = ctx;
+	wchar_t ws[2] = { ch, L'\0' };
+
+	sys_table->con_out->output_string(sys_table->con_out, ws);
+}
+
+void __efistub_efi_pe_entry(void *image, struct efi_system_table *sys_table)
+{
+	size_t memsize;
+	efi_physical_addr_t mem;
+
+#ifdef DEBUG
+	sys_table->con_out->output_string(sys_table->con_out, L"\nbarebox\n");
+#endif
+	pbl_set_putc(efi_putc, sys_table);
+
+	boarddata.image = image;
+	boarddata.sys_table = sys_table;
+
+	mem = efi_earlymem_alloc(sys_table, &memsize);
+
+	barebox_pbl_entry(mem, memsize, &boarddata);
+}
diff --git a/include/pbl.h b/include/pbl.h
index 44957f59784e..0633e340bef3 100644
--- a/include/pbl.h
+++ b/include/pbl.h
@@ -15,6 +15,7 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/types.h>
+#include <linux/compiler.h>
 
 extern unsigned long free_mem_ptr;
 extern unsigned long free_mem_end_ptr;
@@ -36,4 +37,7 @@ int pbl_barebox_verify(const void *compressed_start, unsigned int len,
 		       const void *hash, unsigned int hash_len);
 #endif
 
+void __noreturn barebox_pbl_entry(ulong, ulong, void *);
+
+
 #endif /* __PBL_H__ */
diff --git a/test/self/mmu.c b/test/self/mmu.c
index dbe5004550a8..60bc9b38e84a 100644
--- a/test/self/mmu.c
+++ b/test/self/mmu.c
@@ -9,6 +9,7 @@
 #include <abort.h>
 #include <zero_page.h>
 #include <linux/sizes.h>
+#include <efi/efi-mode.h>
 #include <memory.h>
 
 #define TEST_BUFFER_SIZE		SZ_1M
@@ -258,6 +259,12 @@ static void test_zero_page(void)
 
 static void test_mmu(void)
 {
+	if (efi_is_payload()) {
+		pr_info("MMU was not initialized by us\n");
+		skipped_tests += 23;
+		return;
+	}
+
 	test_zero_page();
 	test_remap();
 }
-- 
2.39.2




More information about the barebox mailing list