From 945bde8da972c30b87027b43a42b21035707fea7 Mon Sep 17 00:00:00 2001 From: Ji Luo Date: Wed, 16 Dec 2020 21:07:13 +0800 Subject: [PATCH] MA-18422 Locate the misc partition by name Locating the misc partition by ID can help reduce the boot time but error may happen if the ID of the misc partition is changed. Moving the misc partition to the start of the GPT and locate the partition by name is another option but it will break the backward compatibility as the GPT is changed. part_get_info_by_name() will loop the PTE and return the matched partition info, but it will cost much time as it will reload the whole PTE from storage in each loop. This commit provides part_get_info_efi_by_name() to support return the partition info by name without reloading the whole PTE. Test: A/B slot switch in dual bootloader. Change-Id: I13cb2a7b3217f73aecc2aec6e06abc0d6e8abcdd Signed-off-by: Ji Luo (cherry picked from commit cd8f603f0d977ed73f0d0b44437c5c68fcebde25) (cherry picked from commit d9972736dc0272377f89ccf528e8a873199c7903) --- disk/part_efi.c | 56 ++++++++++++++++++++++++++++++++++++++ include/part.h | 5 ++++ lib/avb/fsl/fsl_bootctrl.c | 4 +-- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/disk/part_efi.c b/disk/part_efi.c index a319c4dc18..42cb38f44f 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -344,6 +344,62 @@ int part_get_info_efi(struct blk_desc *dev_desc, int part, return 0; } +#if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_SPL_BUILD) +int part_get_info_efi_by_name(struct blk_desc *dev_desc, const char *name, + struct disk_partition *info) +{ + ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz); + /* We don't free gpt_pte because the memory is allocated at + * CONFIG_SYS_SPL_PTE_RAM_BASE due to the limited memory at + * SPL stage. + */ + gpt_entry *gpt_pte = NULL; + int i = 0; + + if (name == NULL) { + printf("%s: Invalid Argument(s)\n", __func__); + return -1; + } + + /* This function validates AND fills in the GPT header and PTE */ + if (find_valid_gpt(dev_desc, gpt_head, &gpt_pte) != 1) + return -1; + + /* Search PTE to find matched partition. */ + for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) { + if (is_pte_valid(&gpt_pte[i]) && + strcmp(name, print_efiname(&gpt_pte[i])) == 0) { + /* Matched partition found, copy it. */ + /* The 'lbaint_t' casting may limit the maximum disk size to 2 TB */ + info->start = (lbaint_t)le64_to_cpu(gpt_pte[i].starting_lba); + /* The ending LBA is inclusive, to calculate size, add 1 to it */ + info->size = (lbaint_t)le64_to_cpu(gpt_pte[i].ending_lba) + 1 + - info->start; + info->blksz = dev_desc->blksz; + + snprintf((char *)info->name, sizeof(info->name), "%s", name); + strcpy((char *)info->type, "U-Boot"); + info->bootable = get_bootable(&gpt_pte[i]); +#if CONFIG_IS_ENABLED(PARTITION_UUIDS) + uuid_bin_to_str(gpt_pte[i].unique_partition_guid.b, info->uuid, + UUID_STR_FORMAT_GUID); +#endif +#ifdef CONFIG_PARTITION_TYPE_GUID + uuid_bin_to_str(gpt_pte[i].partition_type_guid.b, + info->type_guid, UUID_STR_FORMAT_GUID); +#endif + + debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s\n", __func__, + info->start, info->size, info->name); + + return i; + } + } + + return -1; +} +#endif /* CONFIG_DUAL_BOOTLOADER && CONFIG_SPL_BUILD */ + static int part_test_efi(struct blk_desc *dev_desc) { ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz); diff --git a/include/part.h b/include/part.h index ff05da9e3c..95170388f8 100644 --- a/include/part.h +++ b/include/part.h @@ -469,6 +469,11 @@ int gpt_verify_partitions(struct blk_desc *dev_desc, */ int get_disk_guid(struct blk_desc *dev_desc, char *guid); +#if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_SPL_BUILD) +int part_get_info_efi_by_name(struct blk_desc *dev_desc, const char *name, + struct disk_partition *info); +#endif + #endif #if CONFIG_IS_ENABLED(DOS_PARTITION) diff --git a/lib/avb/fsl/fsl_bootctrl.c b/lib/avb/fsl/fsl_bootctrl.c index b423c9a8a4..b10ccdaeb9 100755 --- a/lib/avb/fsl/fsl_bootctrl.c +++ b/lib/avb/fsl/fsl_bootctrl.c @@ -483,7 +483,7 @@ int fsl_save_metadata_if_changed_dual_uboot(struct blk_desc *dev_desc, /* Save metadata if changed. */ if (memcmp(ab_data, ab_data_orig, sizeof(struct bootloader_control)) != 0) { /* Get misc partition info */ - if (part_get_info_by_name(dev_desc, FASTBOOT_PARTITION_MISC, &info) == -1) { + if (part_get_info_efi_by_name(dev_desc, FASTBOOT_PARTITION_MISC, &info) == -1) { printf("Can't get partition info of partition: misc\n"); return -1; } @@ -511,7 +511,7 @@ int fsl_load_metadata_dual_uboot(struct blk_desc *dev_desc, struct bootloader_control serialized; size_t num_bytes; - if (part_get_info_by_name(dev_desc, FASTBOOT_PARTITION_MISC, &info) == -1) { + if (part_get_info_efi_by_name(dev_desc, FASTBOOT_PARTITION_MISC, &info) == -1) { printf("Can't get partition info of partition: misc\n"); return -1; } else { -- 2.17.1