[U-Boot] [PATCH v2 3/3] efi_selftest: unit test for CalculateCrc32()

Heinrich Schuchardt xypron.glpk at gmx.de
Fri Jul 6 05:09:14 UTC 2018


This unit test checks the CalculateCrc32 bootservice and checks the
headers of the system table, the boot services tablle, and the runtime
services table before and after ExitBootServices().

Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
v2:
	no change
---
 lib/efi_selftest/Makefile             |   1 +
 lib/efi_selftest/efi_selftest_crc32.c | 141 ++++++++++++++++++++++++++
 2 files changed, 142 insertions(+)
 create mode 100644 lib/efi_selftest/efi_selftest_crc32.c

diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index d927208700..590f90b16d 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -16,6 +16,7 @@ efi_selftest_bitblt.o \
 efi_selftest_config_table.o \
 efi_selftest_controllers.o \
 efi_selftest_console.o \
+efi_selftest_crc32.o \
 efi_selftest_devicepath.o \
 efi_selftest_devicepath_util.o \
 efi_selftest_events.o \
diff --git a/lib/efi_selftest/efi_selftest_crc32.c b/lib/efi_selftest/efi_selftest_crc32.c
new file mode 100644
index 0000000000..8555b8f114
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_crc32.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * efi_selftest_crc32
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk at gmx.de>
+ *
+ * This unit test checks the CalculateCrc32 bootservice and checks the
+ * headers of the system table, the boot services tablle, and the runtime
+ * services table before and after ExitBootServices().
+ */
+
+#include <efi_selftest.h>
+
+const struct efi_system_table *st;
+efi_status_t (EFIAPI *bs_crc32)(const void *data, efi_uintn_t data_size,
+				u32 *crc32);
+
+static int check_table(const void *table)
+{
+	efi_status_t ret;
+	u32 crc32, res;
+	/* Casting from const to not const */
+	struct efi_table_hdr *hdr = (struct efi_table_hdr *)table;
+
+	if (!hdr->signature) {
+		efi_st_error("Missing header signature\n");
+		return EFI_ST_FAILURE;
+	}
+	if (!hdr->revision) {
+		efi_st_error("Missing header revision\n");
+		return EFI_ST_FAILURE;
+	}
+	if (hdr->headersize <= sizeof(struct efi_table_hdr)) {
+		efi_st_error("Incorrect headersize value\n");
+		return EFI_ST_FAILURE;
+	}
+	if (hdr->reserved) {
+		efi_st_error("Reserved header field is not zero\n");
+		return EFI_ST_FAILURE;
+	}
+
+	crc32 = hdr->crc32;
+	/*
+	 * Setting the crc32 of the 'const' table to zero is easier than
+	 * copying
+	 */
+	hdr->crc32 = 0;
+	ret = bs_crc32(table, hdr->headersize, &res);
+	/* Reset table crc32 so it stays constant */
+	hdr->crc32 = crc32;
+	if (ret != EFI_ST_SUCCESS) {
+		efi_st_error("CalculateCrc32 failed\n");
+		return EFI_ST_FAILURE;
+	}
+	if (res != crc32) {
+		efi_st_error("Incorrect CRC32\n");
+		// return EFI_ST_FAILURE;
+	}
+	return EFI_ST_SUCCESS;
+}
+
+/*
+ * Setup unit test.
+ *
+ * Check that CalculateCrc32 is working correctly.
+ * Check tables before ExitBootServices().
+ *
+ * @handle:	handle of the loaded image
+ * @systable:	system table
+ * @return:	EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+		 const struct efi_system_table *systable)
+{
+	efi_status_t ret;
+	u32 res;
+
+	st = systable;
+	bs_crc32 = systable->boottime->calculate_crc32;
+
+	/* Check that CalculateCrc32 is working */
+	ret = bs_crc32("U-Boot", 6, &res);
+	if (ret != EFI_ST_SUCCESS) {
+		efi_st_error("CalculateCrc32 failed\n");
+		return EFI_ST_FAILURE;
+	}
+	if (res != 0x134b0db4) {
+		efi_st_error("Incorrect CRC32\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* Check tables before ExitBootServices() */
+	if (check_table(st) != EFI_ST_SUCCESS) {
+		efi_st_error("Checking system table\n");
+		return EFI_ST_FAILURE;
+	}
+	if (check_table(st->boottime) != EFI_ST_SUCCESS) {
+		efi_st_error("Checking boottime table\n");
+		return EFI_ST_FAILURE;
+	}
+	if (check_table(st->runtime) != EFI_ST_SUCCESS) {
+		efi_st_error("Checking runtime table\n");
+		return EFI_ST_FAILURE;
+	}
+
+	return EFI_ST_SUCCESS;
+}
+
+/*
+ * Execute unit test
+ *
+ * Check tables after ExitBootServices()
+ *
+ * @return:	EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+	if (check_table(st) != EFI_ST_SUCCESS) {
+		efi_st_error("Checking system table\n");
+		return EFI_ST_FAILURE;
+	}
+	if (check_table(st->runtime) != EFI_ST_SUCCESS) {
+		efi_st_error("Checking runtime table\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/*
+	 * We cannot call SetVirtualAddressMap() and recheck the runtime
+	 * table afterwards because this would invalidate the addresses of the
+	 * unit tests.
+	 */
+
+	return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(crc32) = {
+	.name = "crc32",
+	.phase = EFI_SETUP_BEFORE_BOOTTIME_EXIT,
+	.setup = setup,
+	.execute = execute,
+};
-- 
2.18.0



More information about the U-Boot mailing list