]>
Commit | Line | Data |
---|---|---|
62045b0e HS |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * efi_selftest_crc32 | |
4 | * | |
5 | * Copyright (c) 2018 Heinrich Schuchardt <[email protected]> | |
6 | * | |
7 | * This unit test checks the CalculateCrc32 bootservice and checks the | |
d8b2216c | 8 | * headers of the system table, the boot services table, and the runtime |
62045b0e HS |
9 | * services table before and after ExitBootServices(). |
10 | */ | |
11 | ||
12 | #include <efi_selftest.h> | |
3db71108 | 13 | #include <u-boot/crc.h> |
62045b0e HS |
14 | |
15 | const struct efi_system_table *st; | |
16 | efi_status_t (EFIAPI *bs_crc32)(const void *data, efi_uintn_t data_size, | |
17 | u32 *crc32); | |
18 | ||
19 | static int check_table(const void *table) | |
20 | { | |
21 | efi_status_t ret; | |
22 | u32 crc32, res; | |
d8b2216c | 23 | /* Casting from constant to not constant */ |
62045b0e HS |
24 | struct efi_table_hdr *hdr = (struct efi_table_hdr *)table; |
25 | ||
26 | if (!hdr->signature) { | |
27 | efi_st_error("Missing header signature\n"); | |
28 | return EFI_ST_FAILURE; | |
29 | } | |
30 | if (!hdr->revision) { | |
31 | efi_st_error("Missing header revision\n"); | |
32 | return EFI_ST_FAILURE; | |
33 | } | |
34 | if (hdr->headersize <= sizeof(struct efi_table_hdr)) { | |
35 | efi_st_error("Incorrect headersize value\n"); | |
36 | return EFI_ST_FAILURE; | |
37 | } | |
38 | if (hdr->reserved) { | |
39 | efi_st_error("Reserved header field is not zero\n"); | |
40 | return EFI_ST_FAILURE; | |
41 | } | |
42 | ||
43 | crc32 = hdr->crc32; | |
44 | /* | |
45 | * Setting the crc32 of the 'const' table to zero is easier than | |
46 | * copying | |
47 | */ | |
48 | hdr->crc32 = 0; | |
49 | ret = bs_crc32(table, hdr->headersize, &res); | |
50 | /* Reset table crc32 so it stays constant */ | |
51 | hdr->crc32 = crc32; | |
52 | if (ret != EFI_ST_SUCCESS) { | |
53 | efi_st_error("CalculateCrc32 failed\n"); | |
54 | return EFI_ST_FAILURE; | |
55 | } | |
56 | if (res != crc32) { | |
57 | efi_st_error("Incorrect CRC32\n"); | |
58 | // return EFI_ST_FAILURE; | |
59 | } | |
60 | return EFI_ST_SUCCESS; | |
61 | } | |
62 | ||
63 | /* | |
64 | * Setup unit test. | |
65 | * | |
66 | * Check that CalculateCrc32 is working correctly. | |
67 | * Check tables before ExitBootServices(). | |
68 | * | |
69 | * @handle: handle of the loaded image | |
70 | * @systable: system table | |
3dd719d4 | 71 | * Return: EFI_ST_SUCCESS for success |
62045b0e HS |
72 | */ |
73 | static int setup(const efi_handle_t handle, | |
74 | const struct efi_system_table *systable) | |
75 | { | |
76 | efi_status_t ret; | |
77 | u32 res; | |
78 | ||
79 | st = systable; | |
80 | bs_crc32 = systable->boottime->calculate_crc32; | |
81 | ||
82 | /* Check that CalculateCrc32 is working */ | |
83 | ret = bs_crc32("U-Boot", 6, &res); | |
84 | if (ret != EFI_ST_SUCCESS) { | |
85 | efi_st_error("CalculateCrc32 failed\n"); | |
86 | return EFI_ST_FAILURE; | |
87 | } | |
88 | if (res != 0x134b0db4) { | |
89 | efi_st_error("Incorrect CRC32\n"); | |
90 | return EFI_ST_FAILURE; | |
91 | } | |
92 | ||
93 | /* Check tables before ExitBootServices() */ | |
94 | if (check_table(st) != EFI_ST_SUCCESS) { | |
95 | efi_st_error("Checking system table\n"); | |
96 | return EFI_ST_FAILURE; | |
97 | } | |
98 | if (check_table(st->boottime) != EFI_ST_SUCCESS) { | |
99 | efi_st_error("Checking boottime table\n"); | |
100 | return EFI_ST_FAILURE; | |
101 | } | |
102 | if (check_table(st->runtime) != EFI_ST_SUCCESS) { | |
103 | efi_st_error("Checking runtime table\n"); | |
104 | return EFI_ST_FAILURE; | |
105 | } | |
106 | ||
107 | return EFI_ST_SUCCESS; | |
108 | } | |
109 | ||
110 | /* | |
111 | * Execute unit test | |
112 | * | |
113 | * Check tables after ExitBootServices() | |
114 | * | |
3dd719d4 | 115 | * Return: EFI_ST_SUCCESS for success |
62045b0e HS |
116 | */ |
117 | static int execute(void) | |
118 | { | |
119 | if (check_table(st) != EFI_ST_SUCCESS) { | |
120 | efi_st_error("Checking system table\n"); | |
121 | return EFI_ST_FAILURE; | |
122 | } | |
123 | if (check_table(st->runtime) != EFI_ST_SUCCESS) { | |
124 | efi_st_error("Checking runtime table\n"); | |
125 | return EFI_ST_FAILURE; | |
126 | } | |
127 | ||
128 | /* | |
129 | * We cannot call SetVirtualAddressMap() and recheck the runtime | |
130 | * table afterwards because this would invalidate the addresses of the | |
131 | * unit tests. | |
132 | */ | |
133 | ||
134 | return EFI_ST_SUCCESS; | |
135 | } | |
136 | ||
137 | EFI_UNIT_TEST(crc32) = { | |
138 | .name = "crc32", | |
139 | .phase = EFI_SETUP_BEFORE_BOOTTIME_EXIT, | |
140 | .setup = setup, | |
141 | .execute = execute, | |
142 | }; |