blob: f2be35314a5344ecb94d1405b9306f7bfedfe899 [file] [log] [blame]
Heinrich Schuchardt62045b02018-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
Heinrich Schuchardtd8b22162018-09-27 20:44:40 +02008 * headers of the system table, the boot services table, and the runtime
Heinrich Schuchardt62045b02018-07-07 15:36:07 +02009 * services table before and after ExitBootServices().
10 */
11
12#include <efi_selftest.h>
Simon Glass3db71102019-11-14 12:57:16 -070013#include <u-boot/crc.h>
Heinrich Schuchardt62045b02018-07-07 15:36:07 +020014
15const struct efi_system_table *st;
16efi_status_t (EFIAPI *bs_crc32)(const void *data, efi_uintn_t data_size,
17 u32 *crc32);
18
19static int check_table(const void *table)
20{
21 efi_status_t ret;
22 u32 crc32, res;
Heinrich Schuchardtd8b22162018-09-27 20:44:40 +020023 /* Casting from constant to not constant */
Heinrich Schuchardt62045b02018-07-07 15:36:07 +020024 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
Heinrich Schuchardt3dd719d2022-01-20 19:48:20 +010071 * Return: EFI_ST_SUCCESS for success
Heinrich Schuchardt62045b02018-07-07 15:36:07 +020072 */
73static 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 *
Heinrich Schuchardt3dd719d2022-01-20 19:48:20 +0100115 * Return: EFI_ST_SUCCESS for success
Heinrich Schuchardt62045b02018-07-07 15:36:07 +0200116 */
117static 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
137EFI_UNIT_TEST(crc32) = {
138 .name = "crc32",
139 .phase = EFI_SETUP_BEFORE_BOOTTIME_EXIT,
140 .setup = setup,
141 .execute = execute,
142};