efi_selftest: test unaligned memory access
authorHeinrich Schuchardt <xypron.glpk@gmx.de>
Tue, 3 Apr 2018 19:59:34 +0000 (21:59 +0200)
committerAlexander Graf <agraf@suse.de>
Sun, 3 Jun 2018 13:27:21 +0000 (15:27 +0200)
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>
lib/efi_selftest/Makefile
lib/efi_selftest/efi_selftest_unaligned.c [new file with mode: 0644]

index 2b943bc4d84a3554547ba180e4b01fe87041db69..4fe404d88d8e7ebe41239e08f972273543dd8bc8 100644 (file)
@@ -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 (file)
index 0000000..f799c6d
--- /dev/null
@@ -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,
+};