From 74a614d70ab3c8fe6bea24ad913c8b6eff609680 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 23 Jan 2021 19:08:04 +0100 Subject: [PATCH 1/6] efi_selftest: test EFI_BLOCK_IO_PROTOCOL.Media->LastBlock The field Media->LastBlock of the EFI_BLOCK_IO_PROTOCOL must be filled with the index of the last logical block (LBA) for the block device that our test driver provides. After calling ConnectController() U-Boot exposes the block IO protocol for the partition check that the value of Media->LastBlock equals the partition size minus one. Signed-off-by: Heinrich Schuchardt --- lib/efi_selftest/efi_selftest_block_device.c | 21 +++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/efi_selftest/efi_selftest_block_device.c b/lib/efi_selftest/efi_selftest_block_device.c index 5eb297d285a..15f03751ac8 100644 --- a/lib/efi_selftest/efi_selftest_block_device.c +++ b/lib/efi_selftest/efi_selftest_block_device.c @@ -194,7 +194,7 @@ static int setup(const efi_handle_t handle, decompress(&image); block_io.media->block_size = 1 << LB_BLOCK_SIZE; - block_io.media->last_block = img.length >> LB_BLOCK_SIZE; + block_io.media->last_block = (img.length >> LB_BLOCK_SIZE) - 1; ret = boottime->install_protocol_interface( &disk_handle, &block_io_protocol_guid, @@ -301,6 +301,7 @@ static int execute(void) efi_handle_t *handles; efi_handle_t handle_partition = NULL; struct efi_device_path *dp_partition; + struct efi_block_io *block_io_protocol; struct efi_simple_file_system_protocol *file_system; struct efi_file_handle *root, *file; struct { @@ -309,6 +310,7 @@ static int execute(void) } system_info; efi_uintn_t buf_size; char buf[16] __aligned(ARCH_DMA_MINALIGN); + u32 part1_size; u64 pos; /* Connect controller to virtual disk */ @@ -353,6 +355,23 @@ static int execute(void) return EFI_ST_FAILURE; } + /* Open the block_io_protocol */ + ret = boottime->open_protocol(handle_partition, + &block_io_protocol_guid, + (void **)&block_io_protocol, NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to open block IO protocol\n"); + return EFI_ST_FAILURE; + } + /* Get size of first MBR partition */ + memcpy(&part1_size, image + 0x1ca, sizeof(u32)); + if (block_io_protocol->media->last_block != part1_size - 1) { + efi_st_error("Last LBA of partition %x, expected %x\n", + (unsigned int)block_io_protocol->media->last_block, + part1_size - 1); + return EFI_ST_FAILURE; + } /* Open the simple file system protocol */ ret = boottime->open_protocol(handle_partition, &guid_simple_file_system_protocol, From 688e88256f4137b23522b45727a8207983be90a1 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 23 Jan 2021 19:33:11 +0100 Subject: [PATCH 2/6] efi_loader: correct block IO alignment check If the field Media->IoAlign of the EFI block IO protocol is zero, no alignment is required. Our code required 4 GiB alignment in this case. Don't check buffer alignment if Media->IoAlign == 0. Fixes: f59f0825e8b9 ("efi_loader: parameter checks BLOCK_IO_PROTOCOL") Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_disk.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index c0804effdef..d0aad0252a5 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -142,8 +142,9 @@ static efi_status_t EFIAPI efi_disk_read_blocks(struct efi_block_io *this, return EFI_MEDIA_CHANGED; if (!this->media->media_present) return EFI_NO_MEDIA; - /* media->io_align is a power of 2 */ - if ((uintptr_t)buffer & (this->media->io_align - 1)) + /* media->io_align is a power of 2 or 0 */ + if (this->media->io_align && + (uintptr_t)buffer & (this->media->io_align - 1)) return EFI_INVALID_PARAMETER; if (lba * this->media->block_size + buffer_size > this->media->last_block * this->media->block_size) @@ -209,8 +210,9 @@ static efi_status_t EFIAPI efi_disk_write_blocks(struct efi_block_io *this, return EFI_MEDIA_CHANGED; if (!this->media->media_present) return EFI_NO_MEDIA; - /* media->io_align is a power of 2 */ - if ((uintptr_t)buffer & (this->media->io_align - 1)) + /* media->io_align is a power of 2 or 0 */ + if (this->media->io_align && + (uintptr_t)buffer & (this->media->io_align - 1)) return EFI_INVALID_PARAMETER; if (lba * this->media->block_size + buffer_size > this->media->last_block * this->media->block_size) From 82d01f04facef1276cede067efd02d2a731ffe83 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 24 Jan 2021 14:34:12 +0000 Subject: [PATCH 3/6] efi_loader: switch to non-secure mode later MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some ARMv7 boards using PSCI require to be in secure-mode when booted via 'bootz' or 'bootm'. During distro-boot 'bootefi bootmgr' is called to check if booting via UEFI is possible. With the change we change the switch from secure mode to non-secure mode is moved from the UEFI subsystem setup to just before calling StartImage(). Cc: Jernej Škrabec Reported by: Andre Przywara Signed-off-by: Heinrich Schuchardt --- cmd/bootefi.c | 4 ++++ lib/efi_loader/efi_setup.c | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/bootefi.c b/cmd/bootefi.c index c8eb5c32b07..81dd8e0284f 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -8,6 +8,7 @@ #define LOG_CATEGORY LOGC_EFI #include +#include #include #include #include @@ -338,6 +339,9 @@ static efi_status_t do_bootefi_exec(efi_handle_t handle, void *load_options) efi_uintn_t exit_data_size = 0; u16 *exit_data = NULL; + /* On ARM switch from EL3 or secure mode to EL2 or non-secure mode */ + switch_to_non_secure_mode(); + /* Call our payload! */ ret = EFI_CALL(efi_start_image(handle, &exit_data_size, &exit_data)); if (ret != EFI_SUCCESS) { diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 5800cbf6d46..b1c5125032b 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -6,7 +6,6 @@ */ #include -#include #include #include @@ -188,9 +187,6 @@ efi_status_t efi_init_obj_list(void) /* Allow unaligned memory access */ allow_unaligned(); - /* On ARM switch from EL3 or secure mode to EL2 or non-secure mode */ - switch_to_non_secure_mode(); - /* Initialize root node */ ret = efi_root_node_register(); if (ret != EFI_SUCCESS) From 4e9bd0623775768be4e1e80ee32a7e42b8c9d3c5 Mon Sep 17 00:00:00 2001 From: Gary Bisson Date: Tue, 26 Jan 2021 14:56:23 +0100 Subject: [PATCH 4/6] disk: part_efi: update partition table entries after write Fixes fastboot issues when switching from mbr to gpt partition tables. Signed-off-by: Gary Bisson Reviewed-by: Heinrich Schuchardt --- disk/part_efi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/disk/part_efi.c b/disk/part_efi.c index 2f922662e6e..7a24e33d189 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -867,6 +867,9 @@ int write_mbr_and_gpt_partitions(struct blk_desc *dev_desc, void *buf) return 1; } + /* Update the partition table entries*/ + part_init(dev_desc); + return 0; } #endif From 850d27b4b9d4cc3244ff4331b90b0376a7e9691e Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 28 Jan 2021 22:46:13 +0100 Subject: [PATCH 5/6] tools: add mkeficapsule to .gitignore mkeficapsule is a build product. Add it to .gitignore Signed-off-by: Heinrich Schuchardt --- tools/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/.gitignore b/tools/.gitignore index a021ea95cd6..a88453f64da 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -20,6 +20,7 @@ /kwboot /lib/ /mips-relocs +/mkeficapsule /mkenvimage /mkexynosspl /mkimage From 18dd984c56b339be74e390df80fd3dc21b7a9b58 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 29 Jan 2021 12:35:51 +0100 Subject: [PATCH 6/6] efi_loader: add Linux magic to aarch64 crt0 Add the Linux magic to the EFI file header to allow running our test programs with GRUB's linux command. Now we can dump the fixed-up device tree with our dtbdump.efi tool. Signed-off-by: Heinrich Schuchardt --- arch/arm/lib/crt0_aarch64_efi.S | 3 ++- include/asm-generic/pe.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/lib/crt0_aarch64_efi.S b/arch/arm/lib/crt0_aarch64_efi.S index 368933ecf2d..492195f7654 100644 --- a/arch/arm/lib/crt0_aarch64_efi.S +++ b/arch/arm/lib/crt0_aarch64_efi.S @@ -18,7 +18,8 @@ .globl ImageBase ImageBase: .short IMAGE_DOS_SIGNATURE /* 'MZ' */ - .skip 58 /* 'MZ' + pad + offset == 64 */ + .skip 54 /* 'MZ' + pad + offset == 64 */ + .long LINUX_ARM64_MAGIC /* For GRUB's linux command */ .long pe_header - ImageBase /* Offset to the PE header */ pe_header: .long IMAGE_NT_SIGNATURE /* 'PE' */ diff --git a/include/asm-generic/pe.h b/include/asm-generic/pe.h index b247519a3d5..a1df7471348 100644 --- a/include/asm-generic/pe.h +++ b/include/asm-generic/pe.h @@ -51,4 +51,6 @@ #define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 #define IMAGE_SUBSYSTEM_EFI_ROM 13 +#define LINUX_ARM64_MAGIC 0x644d5241 + #endif /* _ASM_PE_H */