From 246e60184604a59312a4f8d66d83e155ace847c2 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 10 Nov 2019 02:16:33 +0100 Subject: [PATCH 1/4] efi_loader: remove unused function efi_dp_from_dev() Function efi_dp_from_dev() is not used anywhere. Remove it. Signed-off-by: Heinrich Schuchardt --- include/efi_loader.h | 1 - lib/efi_loader/efi_device_path.c | 18 ++---------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index 381da80cdc..16a1b258b1 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -543,7 +543,6 @@ struct efi_device_path *efi_dp_get_next_instance(struct efi_device_path **dp, /* Check if a device path contains muliple instances */ bool efi_dp_is_multi_instance(const struct efi_device_path *dp); -struct efi_device_path *efi_dp_from_dev(struct udevice *dev); struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part); /* Create a device node for a block device partition. */ struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part); diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index 17a0c5bb45..73f1fe75a8 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -422,7 +422,7 @@ bool efi_dp_is_multi_instance(const struct efi_device_path *dp) /* size of device-path not including END node for device and all parents * up to the root device. */ -static unsigned dp_size(struct udevice *dev) +__maybe_unused static unsigned int dp_size(struct udevice *dev) { if (!dev || !dev->driver) return sizeof(ROOT); @@ -494,7 +494,7 @@ static unsigned dp_size(struct udevice *dev) * @dev device * @return pointer to the end of the device path */ -static void *dp_fill(void *buf, struct udevice *dev) +__maybe_unused static void *dp_fill(void *buf, struct udevice *dev) { if (!dev || !dev->driver) return buf; @@ -654,20 +654,6 @@ static void *dp_fill(void *buf, struct udevice *dev) return dp_fill(buf, dev->parent); } } - -/* Construct a device-path from a device: */ -struct efi_device_path *efi_dp_from_dev(struct udevice *dev) -{ - void *buf, *start; - - start = buf = dp_alloc(dp_size(dev) + sizeof(END)); - if (!buf) - return NULL; - buf = dp_fill(buf, dev); - *((struct efi_device_path *)buf) = END; - - return start; -} #endif static unsigned dp_part_size(struct blk_desc *desc, int part) From b20bb09b2108c8368cce7d2801e5e746f4279e1f Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 17 Nov 2019 10:44:16 +0100 Subject: [PATCH 2/4] efi_loader: restrict EFI_LOADER to armv7 and armv8 on ARM fatload USB was reported to fail on the Sheevaplug. Debugging showed that this was caused by an incorrect unaligned write to memory in path_to_uefi(). UEFI on ARM requires that unaligned memory access is enabled. * ARMv5 does not support unaligned access at all. * ARMv6 supports unaligned access when we clear the A flag and set the U flag. * On ARMv7 unaligned access is possible when clearing the aligned flag, which we do in function allow_unaligned() (arch/arm/cpu/armv7/sctlr.S). For none of the other cpus in arch/arm/cpu/ we have implemented a similar function. * ARMv8 allows unaligned access. Let EFI_LOADER on ARM depend on SYS_CPU=armv7 or SYS_CPU=armv8. Once we have implemented allow_unaligned() for other ARM CPUs we can add these to Kconfig. Reported-by: Gray Remlin Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/Kconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index c7027a9676..2f40e485ef 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -1,6 +1,9 @@ config EFI_LOADER bool "Support running UEFI applications" - depends on (ARM || X86 || RISCV || SANDBOX) && OF_LIBFDT + depends on OF_LIBFDT && ( \ + ARM && (SYS_CPU = armv7 || \ + SYS_CPU = armv8) || \ + X86 || RISCV || SANDBOX) # We need EFI_STUB_64BIT to be set on x86_64 with EFI_STUB depends on !EFI_STUB || !X86_64 || EFI_STUB_64BIT # We need EFI_STUB_32BIT to be set on x86_32 with EFI_STUB From d47a774680d18ee5dea43d8b631048c3dc1a2b5f Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 19 Nov 2019 04:02:10 +0100 Subject: [PATCH 3/4] arm: arm11: allow unaligned memory access The UEFI spec mandates that unaligned memory access should be enabled if supported by the CPU architecture. This patch implements the function unaligned_access() to set the enable unaligned data support flag and to clear the aligned flag in the system control register (SCTLR). It is called when UEFI related commands like bootefi are invoked. Reported-by: Cristian Ciocaltea Tested-by: Cristian Ciocaltea Tested-by: Guillaume Gardet Signed-off-by: Heinrich Schuchardt --- arch/arm/cpu/arm11/Makefile | 4 ++++ arch/arm/cpu/arm11/sctlr.S | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 arch/arm/cpu/arm11/sctlr.S diff --git a/arch/arm/cpu/arm11/Makefile b/arch/arm/cpu/arm11/Makefile index 5d721fce12..5dfa01ae8d 100644 --- a/arch/arm/cpu/arm11/Makefile +++ b/arch/arm/cpu/arm11/Makefile @@ -4,3 +4,7 @@ # Wolfgang Denk, DENX Software Engineering, wd@denx.de. obj-y = cpu.o + +ifneq ($(CONFIG_SPL_BUILD),y) +obj-$(CONFIG_EFI_LOADER) += sctlr.o +endif diff --git a/arch/arm/cpu/arm11/sctlr.S b/arch/arm/cpu/arm11/sctlr.S new file mode 100644 index 0000000000..74a7fc4a25 --- /dev/null +++ b/arch/arm/cpu/arm11/sctlr.S @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Routines to access the system control register + * + * Copyright (c) 2019 Heinrich Schuchardt + */ + +#include + +/* + * void allow_unaligned(void) - allow unaligned access + * + * This routine sets the enable unaligned data support flag and clears the + * aligned flag in the system control register. + * After calling this routine unaligned access does no longer leads to a + * data abort or undefined behavior but is handled by the CPU. + * For details see the "ARM Architecture Reference Manual" for ARMv6. + */ +ENTRY(allow_unaligned) + mrc p15, 0, r0, c1, c0, 0 @ load system control register + orr r0, r0, #1 << 22 @ set unaligned data support flag + bic r0, r0, #2 @ clear aligned flag + mcr p15, 0, r0, c1, c0, 0 @ write system control register + bx lr @ return +ENDPROC(allow_unaligned) From 38064ee04c9b42a299f914c36a093144bd86ac50 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 19 Nov 2019 04:19:09 +0100 Subject: [PATCH 4/4] efi_loader: enable EFI_LOADER on arm1136 and arm1176 With an implementation for allow_unaligned() available for arm1136 and arm1176 UEFI can be supported on these architectures. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/Kconfig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 2f40e485ef..7984d6f42d 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -1,8 +1,10 @@ config EFI_LOADER bool "Support running UEFI applications" depends on OF_LIBFDT && ( \ - ARM && (SYS_CPU = armv7 || \ - SYS_CPU = armv8) || \ + ARM && (SYS_CPU = arm1136 || \ + SYS_CPU = arm1176 || \ + SYS_CPU = armv7 || \ + SYS_CPU = armv8) || \ X86 || RISCV || SANDBOX) # We need EFI_STUB_64BIT to be set on x86_64 with EFI_STUB depends on !EFI_STUB || !X86_64 || EFI_STUB_64BIT