From: Denis Mukhin <[email protected]> Add unit test coverage for GPT flags functions.
To run the test: truncate -s 16M mmc1.img ./test/py/test.py --bd sandbox --build -k test_gpt_flags -v Signed-off-by: Denis Mukhin <[email protected]> --- disk/part_efi.c | 12 ++-- test/dm/Makefile | 2 +- test/dm/gpt-flags.c | 148 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 6 deletions(-) create mode 100644 test/dm/gpt-flags.c diff --git a/disk/part_efi.c b/disk/part_efi.c index 6d5520e53912..9d94c1bd4efa 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -47,17 +47,19 @@ static inline u32 efi_crc32(const void *buf, u32 len) return crc32(0, buf, len); } +/* Public for unit tests. */ +int is_gpt_valid(struct blk_desc *desc, u64 lba, gpt_header *pgpt_head, + gpt_entry **pgpt_pte); +int is_pte_valid(gpt_entry * pte); + /* * Private function prototypes */ static int pmbr_part_valid(dos_partition_t *part); static int is_pmbr_valid(legacy_mbr * mbr); -static int is_gpt_valid(struct blk_desc *desc, u64 lba, gpt_header *pgpt_head, - gpt_entry **pgpt_pte); static gpt_entry *alloc_read_gpt_entries(struct blk_desc *desc, gpt_header *pgpt_head); -static int is_pte_valid(gpt_entry * pte); static int find_valid_gpt(struct blk_desc *desc, gpt_header *gpt_head, gpt_entry **pgpt_pte); @@ -1168,7 +1170,7 @@ static int is_pmbr_valid(legacy_mbr *mbr) * Description: returns 1 if valid, 0 on error, 2 if ignored header * If valid, returns pointers to PTEs. */ -static int is_gpt_valid(struct blk_desc *desc, u64 lba, gpt_header *pgpt_head, +int is_gpt_valid(struct blk_desc *desc, u64 lba, gpt_header *pgpt_head, gpt_entry **pgpt_pte) { /* Confirm valid arguments prior to allocation. */ @@ -1316,7 +1318,7 @@ static gpt_entry *alloc_read_gpt_entries(struct blk_desc *desc, * * Description: returns 1 if valid, 0 on error. */ -static int is_pte_valid(gpt_entry * pte) +int is_pte_valid(gpt_entry * pte) { efi_guid_t unused_guid; diff --git a/test/dm/Makefile b/test/dm/Makefile index d69b0e08d66a..df2bc28078d3 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -82,7 +82,7 @@ obj-y += ofread.o obj-y += of_extra.o obj-$(CONFIG_OSD) += osd.o obj-$(CONFIG_VIDEO) += panel.o -obj-$(CONFIG_EFI_PARTITION) += part.o +obj-$(CONFIG_EFI_PARTITION) += part.o gpt-flags.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_P2SB) += p2sb.o obj-$(CONFIG_PCI_ENDPOINT) += pci_ep.o diff --git a/test/dm/gpt-flags.c b/test/dm/gpt-flags.c new file mode 100644 index 000000000000..2792597da021 --- /dev/null +++ b/test/dm/gpt-flags.c @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Tests for ChromiumOS-style GPT PTE attributes. + * + * Copyright 2026 Ford Motor Company + * Written by Denis Mukhin <[email protected]> + */ + +#include <dm.h> +#include <memalign.h> +#include <mmc.h> +#include <part.h> +#include <part_efi.h> +#include <dm/test.h> +#include <test/ut.h> +#include <u-boot/crc.h> + +#define TEST_LBA_COUNT 48 +#define TEST_PARTNUM 1 + +int is_gpt_valid(struct blk_desc *desc, u64 lba, gpt_header *pgpt_head, + gpt_entry **pgpt_pte); +int is_pte_valid(gpt_entry * pte); + +static int mock_blk_desc(struct unit_test_state *uts, struct blk_desc **desc) +{ + struct udevice *dev; + char str_disk_guid[UUID_STR_LEN + 1]; + struct disk_partition parts[2] = { + { + .start = TEST_LBA_COUNT, + .size = 1, + .name = "test1", + }, + { + .start = 49, + .size = 1, + .name = "test2", + }, + }; + + ut_assertok(uclass_get_device_by_name(UCLASS_BLK, "mmc1.blk", &dev)); + *desc = (struct blk_desc *)dev_get_uclass_plat(dev); + + if (CONFIG_IS_ENABLED(RANDOM_UUID)) { + gen_rand_uuid_str(parts[0].uuid, UUID_STR_FORMAT_STD); + gen_rand_uuid_str(parts[1].uuid, UUID_STR_FORMAT_STD); + gen_rand_uuid_str(str_disk_guid, UUID_STR_FORMAT_STD); + } + ut_assertok(gpt_restore(*desc, str_disk_guid, parts, + ARRAY_SIZE(parts))); + + return 0; +} + +static int test_gpt_flags_default(struct unit_test_state *uts) +{ + struct blk_desc *desc; + u16 flags; + + ut_assertok(mock_blk_desc(uts, &desc)); + ut_assertok(read_disk_flags(desc, TEST_PARTNUM, &flags)); + ut_asserteq(0, flags); + + return 0; +} +DM_TEST(test_gpt_flags_default, UTF_SCAN_FDT); + +static int test_gpt_flags_some(struct unit_test_state *uts) +{ + struct blk_desc *desc; + u16 flags_in, flags_out; + + ut_assertok(mock_blk_desc(uts, &desc)); + + flags_in = 0x0111; /* priority=1, tries=1, successful=1 */ + ut_assertok(write_disk_flags(desc, TEST_PARTNUM, flags_in)); + ut_assertok(read_disk_flags(desc, TEST_PARTNUM, &flags_out)); + ut_asserteq(flags_in, flags_out); + + return 0; +} +DM_TEST(test_gpt_flags_some, UTF_SCAN_FDT); + +static int test_gpt_flags_update(struct unit_test_state *uts) +{ + struct blk_desc *desc; + u16 flags; + + ut_assertok(mock_blk_desc(uts, &desc)); + ut_assertok(write_disk_flags(desc, TEST_PARTNUM, 0x00FF)); + + /* other partitions must remain zero */ + ut_assertok(read_disk_flags(desc, TEST_PARTNUM + 1, &flags)); + ut_asserteq(0, flags); + + return 0; +} +DM_TEST(test_gpt_flags_update, UTF_SCAN_FDT); + +static int test_disk_flags_invalid_partnum(struct unit_test_state *uts) +{ + struct blk_desc *desc; + u16 flags; + + ut_assertok(mock_blk_desc(uts, &desc)); + ut_asserteq(-EINVAL, read_disk_flags(desc, 0, &flags)); + ut_asserteq(-EINVAL, write_disk_flags(desc, 0, 0)); + ut_asserteq(-EINVAL, write_disk_flags(desc, 255, 0)); + + return 0; +} +DM_TEST(test_disk_flags_invalid_partnum, UTF_SCAN_FDT); + +static int test_gpt_flags_headers(struct unit_test_state *uts) +{ + struct blk_desc *desc; + u16 flags_in = 0x0111; + + ut_assertok(mock_blk_desc(uts, &desc)); + ut_assertok(write_disk_flags(desc, TEST_PARTNUM, flags_in)); + + { + ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_h1, 1, desc->blksz); + ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_h2, 1, desc->blksz); + gpt_entry *gpt_primary = NULL, *gpt_backup = NULL; + u64 primary_attrs, backup_attrs; + + ut_asserteq(1, is_gpt_valid(desc, GPT_PRIMARY_PARTITION_TABLE_LBA, gpt_h1, + &gpt_primary)); + ut_asserteq(1, is_pte_valid(&gpt_primary[TEST_PARTNUM - 1])); + + ut_asserteq(1, is_gpt_valid(desc, desc->lba - 1, gpt_h2, &gpt_backup)); + ut_asserteq(1, is_pte_valid(&gpt_backup[TEST_PARTNUM - 1])); + + primary_attrs = le64_to_cpu(gpt_primary[TEST_PARTNUM - 1].attributes.raw); + ut_asserteq(flags_in, (primary_attrs >> 48) & 0xFFFFULL); + + backup_attrs = le64_to_cpu(gpt_backup[TEST_PARTNUM - 1].attributes.raw); + ut_asserteq(flags_in, (backup_attrs >> 48) & 0xFFFFULL); + + free(gpt_primary); + free(gpt_backup); + } + + return 0; +} +DM_TEST(test_gpt_flags_headers, UTF_SCAN_FDT); -- 2.54.0

