]> git.sur5r.net Git - u-boot/blob - lib/efi_selftest/efi_selftest_unaligned.c
Merge tag 'signed-efi-next' of git://github.com/agraf/u-boot
[u-boot] / lib / efi_selftest / efi_selftest_unaligned.c
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 };