
This test ensures the ECPT table is present and is consistent.
Invocation from the sandbox platform: add to sandbox_defconfig: +CONFIG_CMD_BOOTEFI_SELFTEST=y
make sandbox_capsule_defconfig all ./u-boot -d arch/sandbox/dts/test.dtb bootefi selftest
Signed-off-by: Jose Marinho jose.marinho@arm.com --- lib/efi_selftest/Makefile | 2 + lib/efi_selftest/efi_selftest_ecpt.c | 105 +++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 lib/efi_selftest/efi_selftest_ecpt.c
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index 9ff6e1760c..6cf548653f 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -112,3 +112,5 @@ $(obj)/efi_selftest_loadimage.o: $(obj)/efi_miniapp_file_image_exit.h $(obj)/efi_selftest_startimage_exit.o: $(obj)/efi_miniapp_file_image_exit.h
$(obj)/efi_selftest_startimage_return.o: $(obj)/efi_miniapp_file_image_return.h + +obj-$(CONFIG_EFI_ECPT) += efi_selftest_ecpt.o diff --git a/lib/efi_selftest/efi_selftest_ecpt.c b/lib/efi_selftest/efi_selftest_ecpt.c new file mode 100644 index 0000000000..555b59bc90 --- /dev/null +++ b/lib/efi_selftest/efi_selftest_ecpt.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Test ECPT tables support + * + * Copyright (C) 2022 Arm Ltd. + */ +#include <common.h> +#include <efi_loader.h> +#include <efi_selftest.h> + +static const struct efi_system_table *local_systable; + +/* + * Setup unit test. + * + * @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) +{ + local_systable = systable; + + return EFI_ST_SUCCESS; +} + +/* + * Traverse the ECPT table looking for a particular profile. + * + * @profile_guid: the guid of the conformance profile to find + * @ecpt: a pointer to the ECPT table + * @return: true if profile_guid is an entry in ECPT, false otherwise + */ +static bool find_profile(efi_guid_t *profile_guid, + struct efi_conformance_profiles_table *ecpt) +{ + for (int idx = 0; idx < local_systable->nr_tables; idx++) + if (!guidcmp(profile_guid, &ecpt->conformance_profiles[idx])) + return true; + return false; +} + +/* + * Perform the test + * + * The test consists of the following steps: + * + * 1) Obtain the ECPT + * 2) Quantify the number of expected profiles + * 3) Verify that each expected profile is in the ECPT + * 4) Ensure that the number of ECPT entries is the expected + * + * The failure of any of the above steps results in a test failure. + * + */ +static int execute(void) +{ + struct efi_conformance_profiles_table *ecpt; + efi_status_t ret = EFI_SUCCESS; + struct efi_boot_services *bt; + int expected_num_entries; + + bt = local_systable->boottime; + + if (!bt) { + efi_st_error("Cannot find boottime services structure\n"); + return EFI_ST_FAILURE; + } + + for (int idx = 0; idx < local_systable->nr_tables; idx++) + if (!guidcmp(&efi_ecpt_guid, &local_systable->tables[idx].guid)) + ecpt = (struct efi_conformance_profiles_table *) + local_systable->tables[idx].table; + + if (!ecpt) { + efi_st_error("ECPT table not present\n"); + return EFI_ST_FAILURE; + } + + /* + * Check for presence of each expected profile. + */ + if (IS_ENABLED(CONFIG_EFI_EBBR_2_0_CONFORMANCE)) { + expected_num_entries++; + if (!find_profile(&efi_ecpt_guid, ecpt)) { + efi_st_error("failed to find profile %pUL\n", &efi_ecpt_guid); + return EFI_ST_FAILURE; + } + } + + if (ecpt->number_of_profiles != expected_num_entries) { + efi_st_error("Mismatch in number of ECPT entries\n"); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; +} + +EFI_UNIT_TEST(ecpt) = { + .name = "ecpt", + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, + .setup = setup, + .execute = execute, +};