diff options
author | Heinrich Schuchardt <xypron.glpk@gmx.de> | 2018-04-03 21:59:34 +0200 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2018-06-03 15:27:21 +0200 |
commit | 85b469215f8e6b5566eb06fe970276344a56c7f4 (patch) | |
tree | 8581199a80b2c6547154f59bcb60120e60a60677 /lib | |
parent | 78f90aaeeccc9e5501299291e441db18038d9fc7 (diff) | |
download | u-boot-85b469215f8e6b5566eb06fe970276344a56c7f4.zip u-boot-85b469215f8e6b5566eb06fe970276344a56c7f4.tar.gz u-boot-85b469215f8e6b5566eb06fe970276344a56c7f4.tar.bz2 |
efi_selftest: test unaligned memory access
According to the UEFI spec unaligned memory access should be enabled on
CPUs supporting it.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/efi_selftest/Makefile | 4 | ||||
-rw-r--r-- | lib/efi_selftest/efi_selftest_unaligned.c | 67 |
2 files changed, 71 insertions, 0 deletions
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index 2b943bc..4fe404d 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -31,6 +31,10 @@ efi_selftest_util.o \ efi_selftest_variables.o \ efi_selftest_watchdog.o +ifeq ($(CONFIG_CMD_BOOTEFI_SELFTEST),y) +obj-$(CONFIG_CPU_V7) += efi_selftest_unaligned.o +endif + ifeq ($(CONFIG_BLK)$(CONFIG_PARTITIONS),yy) obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += efi_selftest_block_device.o endif diff --git a/lib/efi_selftest/efi_selftest_unaligned.c b/lib/efi_selftest/efi_selftest_unaligned.c new file mode 100644 index 0000000..f799c6d --- /dev/null +++ b/lib/efi_selftest/efi_selftest_unaligned.c @@ -0,0 +1,67 @@ +/* + * efi_selftest_unaligned + * + * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Test unaligned memory access on ARMv7. + */ + +#include <efi_selftest.h> + +struct aligned_buffer { + char a[8] __aligned(8); +}; + +/* + * Return an u32 at a give address. + * If the address is not four byte aligned, an unaligned memory access + * occurs. + * + * @addr: address to read + * @return: value at the address + */ +static inline u32 deref(u32 *addr) +{ + int ret; + + asm( + "ldr %[out], [%[in]]\n\t" + : [out] "=r" (ret) + : [in] "r" (addr) + ); + return ret; +} + +/* + * Execute unit test. + * An unaligned memory access is executed. The result is checked. + * + * @return: EFI_ST_SUCCESS for success + */ +static int execute(void) +{ + struct aligned_buffer buf = { + {0, 1, 2, 3, 4, 5, 6, 7}, + }; + void *v = &buf; + u32 r = 0; + + /* Read an unaligned address */ + r = deref(v + 1); + + /* UEFI only supports low endian systems */ + if (r != 0x04030201) { + efi_st_error("Unaligned access failed"); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; +} + +EFI_UNIT_TEST(unaligned) = { + .name = "unaligned memory access", + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, + .execute = execute, +}; |