Message ID | 20210208125246.32547-3-jose.marinho@arm.com |
---|---|
State | Superseded |
Delegated to: | Heinrich Schuchardt |
Headers | show |
Series | Add ESRT and test ESRT creation | expand |
On Mon, Feb 08, 2021 at 12:52:46PM +0000, Jose Marinho wrote: > This commit exercises the ESRT creation -- introduced in the previous > commit. > > A fake FMP, controlling TEST_ESRT_NUM_ENTRIES, is installed in the system > leading to the corresponding ESRT entries being populated. > The ESRT entries are checked against the FMP initialization input > datastructure. I hope that you will also provide a pytest to make sure that an entry in ESRT is correctly updated after capsule update. There are already some tests for capsule update. -Takahiro Akashi > Signed-off-by: Jose Marinho <jose.marinho@arm.com> > > CC: Heinrich Schuchardt <xypron.glpk@gmx.de> > CC: Sughosh Ganu <sughosh.ganu@linaro.org> > CC: AKASHI Takahiro <takahiro.akashi@linaro.org> > CC: Ilias Apalodimas <ilias.apalodimas@linaro.org> > CC: Andre Przywara <andre.przywara@arm.com> > CC: Alexander Graf <agraf@csgraf.de> > CC: nd@arm.com > > --- > test/lib/Makefile | 1 + > test/lib/efi_esrt.c | 188 ++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 189 insertions(+) > create mode 100644 test/lib/efi_esrt.c > > diff --git a/test/lib/Makefile b/test/lib/Makefile > index 97c11e35a8..687e791db0 100644 > --- a/test/lib/Makefile > +++ b/test/lib/Makefile > @@ -15,3 +15,4 @@ obj-$(CONFIG_UT_LIB_ASN1) += asn1.o > obj-$(CONFIG_UT_LIB_RSA) += rsa.o > obj-$(CONFIG_AES) += test_aes.o > obj-$(CONFIG_GETOPT) += getopt.o > +obj-y += efi_esrt.o > diff --git a/test/lib/efi_esrt.c b/test/lib/efi_esrt.c > new file mode 100644 > index 0000000000..3c9d1de731 > --- /dev/null > +++ b/test/lib/efi_esrt.c > @@ -0,0 +1,188 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Test ESRT tables support > + * > + * Copyright (C) 2021 Arm Ltd. > + */ > +#include <common.h> > +#include <efi_loader.h> > +#include <net.h> > +#include <test/lib.h> > +#include <test/test.h> > +#include <test/ut.h> > + > +#define TEST_ESRT_NUM_ENTRIES 255 > + > +#if 0x100 < TEST_ESRT_NUM_ENTRIES > +#error TEST_ESRT_NUM_ENTRIES must be lower or equal to 255. > +#endif > + > +static > +struct efi_firmware_image_descriptor static_img_info[TEST_ESRT_NUM_ENTRIES]; > +static const efi_guid_t esrt_guid = EFI_SYSTEM_RESOURCE_TABLE_GUID; > + > +static void efi_test_esrt_init_info(void) > +{ > + for (int idx = 0; idx < TEST_ESRT_NUM_ENTRIES; idx++) { > + static_img_info[idx].image_index = 1; > + > + // Note: the 16 byte value present in > + // static_img_info[idx].image_type_id is not strictly a GUID. > + // The value is used for the sake of code testing. > + static_img_info[idx].image_type_id.b[0] = idx; > + > + static_img_info[idx].image_id = 0; > + static_img_info[idx].image_id_name = NULL; > + static_img_info[idx].version = 0; > + static_img_info[idx].version_name = NULL; > + static_img_info[idx].size = 0; > + static_img_info[idx].lowest_supported_image_version = 1; > + static_img_info[idx].last_attempt_version = 2; > + static_img_info[idx].last_attempt_status = 3; > + static_img_info[idx].hardware_instance = 1; > + } > +} > + > +static efi_status_t > +EFIAPI efi_test_fmp_get_image_info(struct efi_firmware_management_protocol *this, > + efi_uintn_t *image_info_size, > + struct efi_firmware_image_descriptor *image_info, > + u32 *descriptor_version, > + u8 *descriptor_count, > + efi_uintn_t *descriptor_size, > + u32 *package_version, > + u16 **package_version_name) > +{ > + efi_status_t ret = EFI_SUCCESS; > + > + EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this, > + image_info_size, image_info, > + descriptor_version, descriptor_count, descriptor_size, > + package_version, package_version_name); > + > + if (!image_info_size) > + return EFI_EXIT(EFI_INVALID_PARAMETER); > + > + if (descriptor_version) > + *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; > + if (descriptor_count) > + *descriptor_count = TEST_ESRT_NUM_ENTRIES; > + if (descriptor_size) > + *descriptor_size = sizeof(*image_info); > + if (package_version) > + *package_version = 0xffffffff; > + if (package_version_name) > + *package_version_name = NULL; > + > + if (*image_info_size < sizeof(*image_info)) { > + *image_info_size = *descriptor_size * *descriptor_count; > + return EFI_EXIT(EFI_BUFFER_TOO_SMALL); > + } > + > + for (int idx = 0; idx < TEST_ESRT_NUM_ENTRIES; idx++) > + image_info[idx] = static_img_info[idx]; > + > + return EFI_EXIT(ret); > +} > + > +struct efi_firmware_management_protocol efi_test_fmp = { > + .get_image_info = efi_test_fmp_get_image_info, > + .get_image = NULL, > + .set_image = NULL, > + .check_image = NULL, > + .get_package_info = NULL, > + .set_package_info = NULL, > +}; > + > +static void *lib_test_get_esrt(void) > +{ > + for (int idx = 0; idx < systab.nr_tables; idx++) > + if (!guidcmp(&esrt_guid, &systab.tables[idx].guid)) > + return systab.tables[idx].table; > + > + return NULL; > +} > + > +static bool lib_test_check_uuid_entry(struct efi_system_resource_table *esrt, > + struct efi_firmware_image_descriptor > + *img_info) > +{ > + const u32 filled_entries = esrt->fw_resource_count; > + struct efi_system_resource_entry *entry = esrt->entries; > + > + for (u32 idx = 0; idx < filled_entries; idx++) { > + if (!guidcmp(&entry[idx].fw_class, &img_info->image_type_id)) { > + if (entry[idx].fw_version != img_info->version) > + return false; > + > + if (entry[idx].lowest_supported_fw_version != > + img_info->lowest_supported_image_version) > + return false; > + > + if (entry[idx].last_attempt_version != > + img_info->last_attempt_version) > + return false; > + > + if (entry[idx].last_attempt_status != > + img_info->last_attempt_status) > + return false; > + > + /* > + * The entry with fw_class = img_uuid matches with the > + * remainder fmp input. > + */ > + return true; > + } > + } > + > + /* There exists no entry with fw_class equal to img_uuid in the ESRT. */ > + return false; > +} > + > +int lib_test_efi_esrt(struct unit_test_state *uts) > +{ > + struct efi_system_resource_table *esrt; > + efi_status_t ret = EFI_SUCCESS; > + struct efi_boot_services *bt; > + > + efi_test_esrt_init_info(); > + > + ret = efi_init_obj_list(); > + > + bt = systab.boottime; > + ut_asserteq(ret, EFI_SUCCESS); > + > + assert(bt); > + > + ret = EFI_CALL(bt->install_multiple_protocol_interfaces > + (&efi_root, > + &efi_guid_firmware_management_protocol, > + &efi_test_fmp, > + NULL)); > + > + ut_asserteq(ret, EFI_SUCCESS); > + > + esrt = lib_test_get_esrt(); > + ut_assert(esrt); > + > + ut_asserteq(esrt->fw_resource_count, TEST_ESRT_NUM_ENTRIES); > + > + /* Add the same FMP. */ > + efi_esrt_add_from_fmp(&efi_test_fmp); > + > + /* Verify that the number of images remains the same. */ > + ut_asserteq(esrt->fw_resource_count, TEST_ESRT_NUM_ENTRIES); > + > + for (u32 idx = 0; idx < TEST_ESRT_NUM_ENTRIES; idx++) > + ut_assert(lib_test_check_uuid_entry(esrt, &static_img_info[idx])); > + > + ret = EFI_CALL(bt->uninstall_multiple_protocol_interfaces > + (efi_root, &efi_guid_firmware_management_protocol, > + &efi_test_fmp, NULL)); > + > + ut_asserteq(ret, EFI_SUCCESS); > + > + return ret; > +} > + > +LIB_TEST(lib_test_efi_esrt, 0); > -- > 2.17.1 >
diff --git a/test/lib/Makefile b/test/lib/Makefile index 97c11e35a8..687e791db0 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_UT_LIB_ASN1) += asn1.o obj-$(CONFIG_UT_LIB_RSA) += rsa.o obj-$(CONFIG_AES) += test_aes.o obj-$(CONFIG_GETOPT) += getopt.o +obj-y += efi_esrt.o diff --git a/test/lib/efi_esrt.c b/test/lib/efi_esrt.c new file mode 100644 index 0000000000..3c9d1de731 --- /dev/null +++ b/test/lib/efi_esrt.c @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Test ESRT tables support + * + * Copyright (C) 2021 Arm Ltd. + */ +#include <common.h> +#include <efi_loader.h> +#include <net.h> +#include <test/lib.h> +#include <test/test.h> +#include <test/ut.h> + +#define TEST_ESRT_NUM_ENTRIES 255 + +#if 0x100 < TEST_ESRT_NUM_ENTRIES +#error TEST_ESRT_NUM_ENTRIES must be lower or equal to 255. +#endif + +static +struct efi_firmware_image_descriptor static_img_info[TEST_ESRT_NUM_ENTRIES]; +static const efi_guid_t esrt_guid = EFI_SYSTEM_RESOURCE_TABLE_GUID; + +static void efi_test_esrt_init_info(void) +{ + for (int idx = 0; idx < TEST_ESRT_NUM_ENTRIES; idx++) { + static_img_info[idx].image_index = 1; + + // Note: the 16 byte value present in + // static_img_info[idx].image_type_id is not strictly a GUID. + // The value is used for the sake of code testing. + static_img_info[idx].image_type_id.b[0] = idx; + + static_img_info[idx].image_id = 0; + static_img_info[idx].image_id_name = NULL; + static_img_info[idx].version = 0; + static_img_info[idx].version_name = NULL; + static_img_info[idx].size = 0; + static_img_info[idx].lowest_supported_image_version = 1; + static_img_info[idx].last_attempt_version = 2; + static_img_info[idx].last_attempt_status = 3; + static_img_info[idx].hardware_instance = 1; + } +} + +static efi_status_t +EFIAPI efi_test_fmp_get_image_info(struct efi_firmware_management_protocol *this, + efi_uintn_t *image_info_size, + struct efi_firmware_image_descriptor *image_info, + u32 *descriptor_version, + u8 *descriptor_count, + efi_uintn_t *descriptor_size, + u32 *package_version, + u16 **package_version_name) +{ + efi_status_t ret = EFI_SUCCESS; + + EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this, + image_info_size, image_info, + descriptor_version, descriptor_count, descriptor_size, + package_version, package_version_name); + + if (!image_info_size) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + if (descriptor_version) + *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; + if (descriptor_count) + *descriptor_count = TEST_ESRT_NUM_ENTRIES; + if (descriptor_size) + *descriptor_size = sizeof(*image_info); + if (package_version) + *package_version = 0xffffffff; + if (package_version_name) + *package_version_name = NULL; + + if (*image_info_size < sizeof(*image_info)) { + *image_info_size = *descriptor_size * *descriptor_count; + return EFI_EXIT(EFI_BUFFER_TOO_SMALL); + } + + for (int idx = 0; idx < TEST_ESRT_NUM_ENTRIES; idx++) + image_info[idx] = static_img_info[idx]; + + return EFI_EXIT(ret); +} + +struct efi_firmware_management_protocol efi_test_fmp = { + .get_image_info = efi_test_fmp_get_image_info, + .get_image = NULL, + .set_image = NULL, + .check_image = NULL, + .get_package_info = NULL, + .set_package_info = NULL, +}; + +static void *lib_test_get_esrt(void) +{ + for (int idx = 0; idx < systab.nr_tables; idx++) + if (!guidcmp(&esrt_guid, &systab.tables[idx].guid)) + return systab.tables[idx].table; + + return NULL; +} + +static bool lib_test_check_uuid_entry(struct efi_system_resource_table *esrt, + struct efi_firmware_image_descriptor + *img_info) +{ + const u32 filled_entries = esrt->fw_resource_count; + struct efi_system_resource_entry *entry = esrt->entries; + + for (u32 idx = 0; idx < filled_entries; idx++) { + if (!guidcmp(&entry[idx].fw_class, &img_info->image_type_id)) { + if (entry[idx].fw_version != img_info->version) + return false; + + if (entry[idx].lowest_supported_fw_version != + img_info->lowest_supported_image_version) + return false; + + if (entry[idx].last_attempt_version != + img_info->last_attempt_version) + return false; + + if (entry[idx].last_attempt_status != + img_info->last_attempt_status) + return false; + + /* + * The entry with fw_class = img_uuid matches with the + * remainder fmp input. + */ + return true; + } + } + + /* There exists no entry with fw_class equal to img_uuid in the ESRT. */ + return false; +} + +int lib_test_efi_esrt(struct unit_test_state *uts) +{ + struct efi_system_resource_table *esrt; + efi_status_t ret = EFI_SUCCESS; + struct efi_boot_services *bt; + + efi_test_esrt_init_info(); + + ret = efi_init_obj_list(); + + bt = systab.boottime; + ut_asserteq(ret, EFI_SUCCESS); + + assert(bt); + + ret = EFI_CALL(bt->install_multiple_protocol_interfaces + (&efi_root, + &efi_guid_firmware_management_protocol, + &efi_test_fmp, + NULL)); + + ut_asserteq(ret, EFI_SUCCESS); + + esrt = lib_test_get_esrt(); + ut_assert(esrt); + + ut_asserteq(esrt->fw_resource_count, TEST_ESRT_NUM_ENTRIES); + + /* Add the same FMP. */ + efi_esrt_add_from_fmp(&efi_test_fmp); + + /* Verify that the number of images remains the same. */ + ut_asserteq(esrt->fw_resource_count, TEST_ESRT_NUM_ENTRIES); + + for (u32 idx = 0; idx < TEST_ESRT_NUM_ENTRIES; idx++) + ut_assert(lib_test_check_uuid_entry(esrt, &static_img_info[idx])); + + ret = EFI_CALL(bt->uninstall_multiple_protocol_interfaces + (efi_root, &efi_guid_firmware_management_protocol, + &efi_test_fmp, NULL)); + + ut_asserteq(ret, EFI_SUCCESS); + + return ret; +} + +LIB_TEST(lib_test_efi_esrt, 0);
This commit exercises the ESRT creation -- introduced in the previous commit. A fake FMP, controlling TEST_ESRT_NUM_ENTRIES, is installed in the system leading to the corresponding ESRT entries being populated. The ESRT entries are checked against the FMP initialization input datastructure. Signed-off-by: Jose Marinho <jose.marinho@arm.com> CC: Heinrich Schuchardt <xypron.glpk@gmx.de> CC: Sughosh Ganu <sughosh.ganu@linaro.org> CC: AKASHI Takahiro <takahiro.akashi@linaro.org> CC: Ilias Apalodimas <ilias.apalodimas@linaro.org> CC: Andre Przywara <andre.przywara@arm.com> CC: Alexander Graf <agraf@csgraf.de> CC: nd@arm.com --- test/lib/Makefile | 1 + test/lib/efi_esrt.c | 188 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+) create mode 100644 test/lib/efi_esrt.c