summaryrefslogtreecommitdiff
path: root/lib/efi_selftest
diff options
context:
space:
mode:
authorHeinrich Schuchardt <xypron.glpk@gmx.de>2018-04-03 21:59:34 +0200
committerAlexander Graf <agraf@suse.de>2018-06-03 15:27:21 +0200
commit85b469215f8e6b5566eb06fe970276344a56c7f4 (patch)
tree8581199a80b2c6547154f59bcb60120e60a60677 /lib/efi_selftest
parent78f90aaeeccc9e5501299291e441db18038d9fc7 (diff)
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/efi_selftest')
-rw-r--r--lib/efi_selftest/Makefile4
-rw-r--r--lib/efi_selftest/efi_selftest_unaligned.c67
2 files changed, 71 insertions, 0 deletions
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index 2b943bc4d8..4fe404d88d 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 0000000000..f799c6dd0f
--- /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,
+};