From dfbc2be47edcb5190d161390b50d2dcc5086710e Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 9 Jan 2022 18:16:11 +0100 Subject: riscv: revert Complete efi header for RV32/64 EDK II refuses to load the EFI binaries created by U-Boot. The reason is an incorrect PE-COFF header. The number of data directories does not match NumberOfRvaAndSizes. This leads to a failed consistency check in PeCoffLoaderGetPeHeader(): SizeOfOptionalHeader - HeaderWithoutDataDir) != NumberOfRvaAndSizes * sizeof(DATA_DIRECTORY)) Fixes: 9afaeec6ef8b ("riscv: Complete efi header for RV32/64") Signed-off-by: Heinrich Schuchardt --- arch/riscv/lib/crt0_riscv_efi.S | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'arch') diff --git a/arch/riscv/lib/crt0_riscv_efi.S b/arch/riscv/lib/crt0_riscv_efi.S index b0a7a39a722..3e62e8e67b0 100644 --- a/arch/riscv/lib/crt0_riscv_efi.S +++ b/arch/riscv/lib/crt0_riscv_efi.S @@ -110,16 +110,6 @@ extra_header_fields: .quad 0 /* ExceptionTable */ .quad 0 /* CertificationTable */ .quad 0 /* BaseRelocationTable */ - .quad 0 /* Debug */ - .quad 0 /* Architecture */ - .quad 0 /* Global Ptr */ - .quad 0 /* TLS Table */ - .quad 0 /* Load Config Table */ - .quad 0 /* Bound Import */ - .quad 0 /* IAT */ - .quad 0 /* Delay Import Descriptor */ - .quad 0 /* CLR Runtime Header */ - .quad 0 /* Reserved */ /* Section table */ section_table: -- cgit v1.2.3 From 9ef5ccaa712238f4ccd3c55f8a7ae6ca28a5a5bf Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 14 Jan 2022 21:40:15 +0100 Subject: efi_loader: fix SectionAlignment, FileAlignment The alignment of sections in the EFI binaries generated by U-Boot is incorrect. According to the PE-COFF specification [1] the minimum value for FileAlignment is 512. If the value of SectionAlignment is less then the page size, it must equal FileAlignment. Let's set both values to 512 for the ARM and RISC-V architectures. [1] https://docs.microsoft.com/en-us/windows/win32/debug/pe-format Signed-off-by: Heinrich Schuchardt --- arch/arm/lib/crt0_aarch64_efi.S | 5 +++-- arch/arm/lib/crt0_arm_efi.S | 5 +++-- arch/arm/lib/elf_aarch64_efi.lds | 4 ++-- arch/arm/lib/elf_arm_efi.lds | 4 ++-- arch/riscv/lib/crt0_riscv_efi.S | 5 +++-- arch/riscv/lib/elf_riscv32_efi.lds | 4 ++-- arch/riscv/lib/elf_riscv64_efi.lds | 4 ++-- 7 files changed, 17 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/arm/lib/crt0_aarch64_efi.S b/arch/arm/lib/crt0_aarch64_efi.S index 492195f7654..7f38465359c 100644 --- a/arch/arm/lib/crt0_aarch64_efi.S +++ b/arch/arm/lib/crt0_aarch64_efi.S @@ -47,8 +47,8 @@ optional_header: extra_header_fields: .quad 0 /* ImageBase */ - .long 0x20 /* SectionAlignment */ - .long 0x8 /* FileAlignment */ + .long 0x200 /* SectionAlignment */ + .long 0x200 /* FileAlignment */ .short 0 /* MajorOperatingSystemVersion */ .short 0 /* MinorOperatingSystemVersion */ .short 0 /* MajorImageVersion */ @@ -117,6 +117,7 @@ section_table: .short 0 /* NumberOfLineNumbers (0 for executables) */ .long 0xe0500020 /* Characteristics (section flags) */ + .align 9 _start: stp x29, x30, [sp, #-32]! mov x29, sp diff --git a/arch/arm/lib/crt0_arm_efi.S b/arch/arm/lib/crt0_arm_efi.S index cc8a115f319..75ee37b7d31 100644 --- a/arch/arm/lib/crt0_arm_efi.S +++ b/arch/arm/lib/crt0_arm_efi.S @@ -47,8 +47,8 @@ optional_header: extra_header_fields: .long 0 /* image_base */ - .long 0x20 /* SectionAlignment */ - .long 0x8 /* FileAlignment */ + .long 0x200 /* SectionAlignment */ + .long 0x200 /* FileAlignment */ .short 0 /* MajorOperatingSystemVersion */ .short 0 /* MinorOperatingSystemVersion */ .short 0 /* MajorImageVersion */ @@ -115,6 +115,7 @@ section_table: .short 0 /* NumberOfLineNumbers (0 for executables) */ .long 0xe0500020 /* Characteristics (section flags) */ + .align 9 _start: stmfd sp!, {r0-r2, lr} diff --git a/arch/arm/lib/elf_aarch64_efi.lds b/arch/arm/lib/elf_aarch64_efi.lds index 90af469f48b..c0604dad464 100644 --- a/arch/arm/lib/elf_aarch64_efi.lds +++ b/arch/arm/lib/elf_aarch64_efi.lds @@ -18,7 +18,7 @@ SECTIONS *(.gnu.linkonce.t.*) *(.srodata) *(.rodata*) - . = ALIGN(16); + . = ALIGN(512); } _etext = .; _text_size = . - _text; @@ -44,7 +44,7 @@ SECTIONS *(.bss) *(.bss.*) *(COMMON) - . = ALIGN(16); + . = ALIGN(512); _bss_end = .; _edata = .; } diff --git a/arch/arm/lib/elf_arm_efi.lds b/arch/arm/lib/elf_arm_efi.lds index d6d742e8687..767ebda6351 100644 --- a/arch/arm/lib/elf_arm_efi.lds +++ b/arch/arm/lib/elf_arm_efi.lds @@ -18,7 +18,7 @@ SECTIONS *(.gnu.linkonce.t.*) *(.srodata) *(.rodata*) - . = ALIGN(16); + . = ALIGN(512); } _etext = .; _text_size = . - _text; @@ -44,7 +44,7 @@ SECTIONS *(.bss) *(.bss.*) *(COMMON) - . = ALIGN(16); + . = ALIGN(512); _bss_end = .; _edata = .; } diff --git a/arch/riscv/lib/crt0_riscv_efi.S b/arch/riscv/lib/crt0_riscv_efi.S index 3e62e8e67b0..a01e08a3c6d 100644 --- a/arch/riscv/lib/crt0_riscv_efi.S +++ b/arch/riscv/lib/crt0_riscv_efi.S @@ -71,8 +71,8 @@ extra_header_fields: #else .quad 0 /* ImageBase */ #endif - .long 0x20 /* SectionAlignment */ - .long 0x8 /* FileAlignment */ + .long 0x200 /* SectionAlignment */ + .long 0x200 /* FileAlignment */ .short 0 /* MajorOperatingSystemVersion */ .short 0 /* MinorOperatingSystemVersion */ .short 1 /* MajorImageVersion */ @@ -148,6 +148,7 @@ section_table: .short 0 /* NumberOfLineNumbers (0 for executables) */ .long 0xe0500020 /* Characteristics (section flags) */ + .align 9 _start: addi sp, sp, -(SIZE_LONG * 3) SAVE_LONG(a0, 0) diff --git a/arch/riscv/lib/elf_riscv32_efi.lds b/arch/riscv/lib/elf_riscv32_efi.lds index 629705fc280..c3e0d20d577 100644 --- a/arch/riscv/lib/elf_riscv32_efi.lds +++ b/arch/riscv/lib/elf_riscv32_efi.lds @@ -20,7 +20,7 @@ SECTIONS *(.gnu.linkonce.t.*) *(.srodata) *(.rodata*) - . = ALIGN(16); + . = ALIGN(512); } _etext = .; _text_size = . - _text; @@ -46,7 +46,7 @@ SECTIONS *(.bss) *(.bss.*) *(COMMON) - . = ALIGN(16); + . = ALIGN(512); _bss_end = .; _edata = .; } diff --git a/arch/riscv/lib/elf_riscv64_efi.lds b/arch/riscv/lib/elf_riscv64_efi.lds index aece030c37b..ecb91395486 100644 --- a/arch/riscv/lib/elf_riscv64_efi.lds +++ b/arch/riscv/lib/elf_riscv64_efi.lds @@ -20,7 +20,7 @@ SECTIONS *(.gnu.linkonce.t.*) *(.srodata) *(.rodata*) - . = ALIGN(16); + . = ALIGN(512); } _etext = .; _text_size = . - _text; @@ -46,7 +46,7 @@ SECTIONS *(.bss) *(.bss.*) *(COMMON) - . = ALIGN(16); + . = ALIGN(512); _bss_end = .; _edata = .; } -- cgit v1.2.3 From ce1dc0cc17e94a0bf1c17bd1465cb0afd5bfb214 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Jan 2022 03:51:11 -0700 Subject: x86: efi: Update efi_get_next_mem_desc() to avoid needing a map At present this function requires a pointer to struct efi_entry_memmap but the only field used in there is the desc_size. We want to be able to use it from the app, so update it to use desc_size directly. Signed-off-by: Simon Glass --- arch/x86/cpu/efi/payload.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/cpu/efi/payload.c b/arch/x86/cpu/efi/payload.c index 04ce1880b4d..b7778565b19 100644 --- a/arch/x86/cpu/efi/payload.c +++ b/arch/x86/cpu/efi/payload.c @@ -51,7 +51,7 @@ ulong board_get_usable_ram_top(ulong total_size) end = (struct efi_mem_desc *)((ulong)map + size); desc = map->desc; - for (; desc < end; desc = efi_get_next_mem_desc(map, desc)) { + for (; desc < end; desc = efi_get_next_mem_desc(desc, map->desc_size)) { if (desc->type != EFI_CONVENTIONAL_MEMORY || desc->physical_start >= 1ULL << 32) continue; @@ -89,7 +89,7 @@ int dram_init(void) end = (struct efi_mem_desc *)((ulong)map + size); gd->ram_size = 0; desc = map->desc; - for (; desc < end; desc = efi_get_next_mem_desc(map, desc)) { + for (; desc < end; desc = efi_get_next_mem_desc(desc, map->desc_size)) { if (desc->type < EFI_MMAP_IO) gd->ram_size += desc->num_pages << EFI_PAGE_SHIFT; } @@ -114,7 +114,7 @@ int dram_init_banksize(void) desc = map->desc; for (num_banks = 0; desc < end && num_banks < CONFIG_NR_DRAM_BANKS; - desc = efi_get_next_mem_desc(map, desc)) { + desc = efi_get_next_mem_desc(desc, map->desc_size)) { /* * We only use conventional memory and ignore * anything less than 1MB. @@ -197,7 +197,7 @@ unsigned int install_e820_map(unsigned int max_entries, end = (struct efi_mem_desc *)((ulong)map + size); for (desc = map->desc; desc < end; - desc = efi_get_next_mem_desc(map, desc)) { + desc = efi_get_next_mem_desc(desc, map->desc_size)) { if (desc->num_pages == 0) continue; -- cgit v1.2.3 From 450ce56a118975364437cc466ec804d8ded75d29 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Jan 2022 03:51:13 -0700 Subject: x86: efi: Tweak the code used for the 64-bit EFI app Add an empty CPU init function to avoid fiddling with low-level CPU features in the app. Set up the C runtime correctly for 64-bit use and avoid clearing BSS, since this is done by EFI when U-Boot is loaded. Signed-off-by: Simon Glass --- arch/x86/cpu/x86_64/cpu.c | 5 +++++ arch/x86/lib/Makefile | 5 ++--- arch/x86/lib/relocate.c | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/cpu/x86_64/cpu.c b/arch/x86/cpu/x86_64/cpu.c index a3674e8e29a..6a387612916 100644 --- a/arch/x86/cpu/x86_64/cpu.c +++ b/arch/x86/cpu/x86_64/cpu.c @@ -45,3 +45,8 @@ int cpu_phys_address_size(void) { return CONFIG_CPU_ADDR_BITS; } + +int x86_cpu_init_f(void) +{ + return 0; +} diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 18757b29aa9..e5235b7c4f4 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -65,9 +65,8 @@ endif lib-$(CONFIG_USE_PRIVATE_LIBGCC) += div64.o -ifeq ($(CONFIG_$(SPL_)X86_64),) -obj-$(CONFIG_EFI_APP) += crt0_ia32_efi.o reloc_ia32_efi.o -endif +obj-$(CONFIG_EFI_APP_32BIT) += crt0_ia32_efi.o reloc_ia32_efi.o +obj-$(CONFIG_EFI_APP_64BIT) += crt0_x86_64_efi.o reloc_x86_64_efi.o ifneq ($(CONFIG_EFI_STUB),) diff --git a/arch/x86/lib/relocate.c b/arch/x86/lib/relocate.c index 6fe51516477..9060d19d46a 100644 --- a/arch/x86/lib/relocate.c +++ b/arch/x86/lib/relocate.c @@ -35,6 +35,7 @@ int copy_uboot_to_ram(void) return 0; } +#ifndef CONFIG_EFI_APP int clear_bss(void) { ulong dst_addr = (ulong)&__bss_start + gd->reloc_off; @@ -46,6 +47,7 @@ int clear_bss(void) return 0; } +#endif #if CONFIG_IS_ENABLED(X86_64) static void do_elf_reloc_fixups64(unsigned int text_base, uintptr_t size, -- cgit v1.2.3 From 3b4ae096b0ed21f3646378cb58d4c03ea2404bac Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Jan 2022 03:51:14 -0700 Subject: x86: efi: Round out the link script for 64-bit EFI Make sure the linker lists are in the right place and drop the eh_frame section, which is not needed. Signed-off-by: Simon Glass --- arch/x86/lib/elf_x86_64_efi.lds | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/lib/elf_x86_64_efi.lds b/arch/x86/lib/elf_x86_64_efi.lds index b436429b33e..75727400aa4 100644 --- a/arch/x86/lib/elf_x86_64_efi.lds +++ b/arch/x86/lib/elf_x86_64_efi.lds @@ -63,6 +63,7 @@ SECTIONS *(.rela.data*) *(.rela.got) *(.rela.stab) + *(.rela.u_boot_list*) } . = ALIGN(4096); @@ -70,9 +71,11 @@ SECTIONS . = ALIGN(4096); .dynstr : { *(.dynstr) } . = ALIGN(4096); + + /DISCARD/ : { *(.eh_frame) } + .ignored.reloc : { *(.rela.reloc) - *(.eh_frame) *(.note.GNU-stack) } -- cgit v1.2.3 From 59e8f36dd93e75f406410be97057b22e452741b1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Jan 2022 03:51:15 -0700 Subject: x86: efi: Don't use the 64-bit link script for the EFI app That script is not intended for use with EFI, so update the logic to avoid using it. Signed-off-by: Simon Glass Signed-off-by: Christian Melki --- arch/x86/cpu/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/cpu/config.mk b/arch/x86/cpu/config.mk index d3033b41603..87e242a2065 100644 --- a/arch/x86/cpu/config.mk +++ b/arch/x86/cpu/config.mk @@ -9,7 +9,7 @@ LDPPFLAGS += -DRESET_VEC_LOC=$(CONFIG_RESET_VEC_LOC) LDPPFLAGS += -DSTART_16=$(CONFIG_SYS_X86_START16) ifdef CONFIG_X86_64 -ifndef CONFIG_SPL_BUILD +ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_EFI_APP),) LDSCRIPT = $(srctree)/arch/x86/cpu/u-boot-64.lds endif endif -- cgit v1.2.3 From 081dfcf783c80a8abf717df984c94970d128b98a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Jan 2022 03:51:16 -0700 Subject: x86: efi: Set the correct link flags for the 64-bit EFI app At present some 32-bit settings are used with the 64-bit app. Fix this by separating out the two cases. Be careful not to break the 64-bit payload, which needs to build a 64-bit EFI stub with a 32-bit U-Boot. Signed-off-by: Christian Melki Signed-off-by: Simon Glass --- arch/x86/config.mk | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/config.mk b/arch/x86/config.mk index 589f2aed2bc..889497b6bd7 100644 --- a/arch/x86/config.mk +++ b/arch/x86/config.mk @@ -20,6 +20,11 @@ IS_32BIT := y endif endif +EFI_IS_32BIT := $(IS_32BIT) +ifdef CONFIG_EFI_STUB_64BIT +EFI_IS_32BIT := +endif + ifeq ($(IS_32BIT),y) PLATFORM_CPPFLAGS += -march=i386 -m32 else @@ -44,8 +49,14 @@ CFLAGS_EFI := -fpic -fshort-wchar # Compiler flags to be removed when building UEFI applications CFLAGS_NON_EFI := -mregparm=3 -fstack-protector-strong -ifeq ($(CONFIG_EFI_STUB_64BIT),) +ifeq ($(IS_32BIT),y) +EFIPAYLOAD_BFDARCH = i386 +else CFLAGS_EFI += $(call cc-option, -mno-red-zone) +EFIPAYLOAD_BFDARCH = x86_64 +endif + +ifeq ($(EFI_IS_32BIT),y) EFIARCH = ia32 EFIPAYLOAD_BFDTARGET = elf32-i386 else @@ -53,8 +64,6 @@ EFIARCH = x86_64 EFIPAYLOAD_BFDTARGET = elf64-x86-64 endif -EFIPAYLOAD_BFDARCH = i386 - LDSCRIPT_EFI := $(srctree)/arch/x86/lib/elf_$(EFIARCH)_efi.lds EFISTUB := crt0_$(EFIARCH)_efi.o reloc_$(EFIARCH)_efi.o OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH) -- cgit v1.2.3