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