1 /* 2 * efi_selftest_unaligned 3 * 4 * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de> 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 * 8 * Test unaligned memory access on ARMv7. 9 */ 10 11 #include <efi_selftest.h> 12 13 struct aligned_buffer { 14 char a[8] __aligned(8); 15 }; 16 17 /* 18 * Return an u32 at a give address. 19 * If the address is not four byte aligned, an unaligned memory access 20 * occurs. 21 * 22 * @addr: address to read 23 * @return: value at the address 24 */ 25 static inline u32 deref(u32 *addr) 26 { 27 int ret; 28 29 asm( 30 "ldr %[out], [%[in]]\n\t" 31 : [out] "=r" (ret) 32 : [in] "r" (addr) 33 ); 34 return ret; 35 } 36 37 /* 38 * Execute unit test. 39 * An unaligned memory access is executed. The result is checked. 40 * 41 * @return: EFI_ST_SUCCESS for success 42 */ 43 static int execute(void) 44 { 45 struct aligned_buffer buf = { 46 {0, 1, 2, 3, 4, 5, 6, 7}, 47 }; 48 void *v = &buf; 49 u32 r = 0; 50 51 /* Read an unaligned address */ 52 r = deref(v + 1); 53 54 /* UEFI only supports low endian systems */ 55 if (r != 0x04030201) { 56 efi_st_error("Unaligned access failed"); 57 return EFI_ST_FAILURE; 58 } 59 60 return EFI_ST_SUCCESS; 61 } 62 63 EFI_UNIT_TEST(unaligned) = { 64 .name = "unaligned memory access", 65 .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, 66 .execute = execute, 67 }; 68