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