diff options
author | Ji Luo <ji.luo@nxp.com> | 2019-06-21 15:53:50 +0800 |
---|---|---|
committer | Ji Luo <ji.luo@nxp.com> | 2022-04-18 16:40:07 +0800 |
commit | ef056c59807fa3f3269bf17b75e3bc18ecfb898f (patch) | |
tree | ef5b3136b299aa873b7918396119197a322b4696 | |
parent | 5fa8aeba48b7f7e677ead8f0854b9ce3d7e8d3af (diff) |
MA-14916-4 support dual bootloader for imx8m/imx8q
This commit enables dual bootloader feature for imx8m/imx8q, but
as commit 'a2018ab' already brings in some dual bootloader codes
when enabling fastboot support, so this commit won't be a complete
and standalone patch to introduce the dual bootloader feature.
This commit will do the following:
1. clean up dual bootloader flow and add missing implementation.
2. Merge the dual bootloader entry for fit and container to one
function 'mmc_load_image_raw_sector_dual_uboot'.
Change-Id: Ic9410a48092cc05de599dd897fc912177e2a1fe1
Signed-off-by: Ji Luo <ji.luo@nxp.com>
(cherry picked from commit d00da7c6e2d3b0ed5f3f93eb98d841d1b7a114ca)
-rw-r--r-- | arch/arm/mach-imx/parse-container.c | 7 | ||||
-rw-r--r-- | common/spl/spl_fit.c | 14 | ||||
-rw-r--r-- | common/spl/spl_mmc.c | 33 | ||||
-rw-r--r-- | disk/part_efi.c | 25 | ||||
-rw-r--r-- | include/part.h | 3 | ||||
-rw-r--r-- | include/spl.h | 3 | ||||
-rw-r--r-- | lib/avb/fsl/fsl_avb_ab_flow.c | 167 | ||||
-rw-r--r-- | scripts/config_whitelist.txt | 1 |
8 files changed, 93 insertions, 160 deletions
diff --git a/arch/arm/mach-imx/parse-container.c b/arch/arm/mach-imx/parse-container.c index e2a9e2b2732..503d2cf796c 100644 --- a/arch/arm/mach-imx/parse-container.c +++ b/arch/arm/mach-imx/parse-container.c @@ -139,6 +139,13 @@ static int read_auth_container(struct spl_image_info *spl_image, } } +#if defined(CONFIG_SPL_BUILD) && \ + defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_IMX_TRUSTY_OS) + /* Everything checks out, get the sw_version now. */ + spl_image->rbindex = (uint64_t)container->sw_version; +#endif + + end_auth: #ifdef CONFIG_AHAB_BOOT ahab_auth_release(); diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 26d3aff94a8..4e638c7561e 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -67,6 +67,10 @@ static int find_node_from_desc(const void *fit, int node, const char *str) return -ENOENT; } +#ifdef CONFIG_DUAL_BOOTLOADER +extern int spl_fit_get_rbindex(const void *fit); +#endif + /** * spl_fit_get_image_name(): By using the matching configuration subnode, * retrieve the name of an image, specified by a property name and an index @@ -737,6 +741,16 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, if (ret < 0) return ret; +#if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_IMX_TRUSTY_OS) + int rbindex; + rbindex = spl_fit_get_rbindex(ctx.fit); + if (rbindex < 0) { + printf("Error! Can't get rollback index!\n"); + return -1; + } else + spl_image->rbindex = rbindex; +#endif + if (IS_ENABLED(CONFIG_SPL_FPGA)) spl_fit_load_fpga(&ctx, info, sector); diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 1cda447fe4b..d3ca83e9ad9 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -59,7 +59,7 @@ static int mmc_load_legacy(struct spl_image_info *spl_image, return 0; } -static ulong h_spl_load_read(struct spl_load_info *load, ulong sector, +ulong h_spl_load_read(struct spl_load_info *load, ulong sector, ulong count, void *buf) { struct mmc *mmc = load->dev; @@ -80,6 +80,8 @@ static __maybe_unused unsigned long spl_mmc_raw_uboot_offset(int part) #if defined(CONFIG_IMX_TRUSTY_OS) /* Pre-declaration of check_rpmb_blob. */ int check_rpmb_blob(struct mmc *mmc); +int mmc_load_image_raw_sector_dual_uboot(struct spl_image_info *spl_image, + struct mmc *mmc); #endif static __maybe_unused @@ -135,21 +137,10 @@ end: return -1; } - /* Images loaded, now check the rpmb keyblob for Trusty OS. - * Skip this step when the dual bootloader feature is enabled - * since the blob should be checked earlier. - */ -#if defined(CONFIG_IMX_TRUSTY_OS) - if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) { -#if !defined(CONFIG_DUAL_BOOTLOADER) + /* Images loaded, now check the rpmb keyblob for Trusty OS. */ +#if defined(CONFIG_IMX_TRUSTY_OS) && !defined(CONFIG_AVB_ATX) ret = check_rpmb_blob(mmc); #endif - } else { -#if !defined(CONFIG_AVB_ATX) - ret = check_rpmb_blob(mmc); -#endif - } -#endif return ret; } @@ -383,10 +374,18 @@ int default_spl_mmc_emmc_boot_partition(struct mmc *mmc) * 1 and 2 match up to boot0 / boot1 and 7 is user data * which is the first physical partition (0). */ +#ifdef CONFIG_DUAL_BOOTLOADER + /* Bootloader is stored in eMMC user partition for + * dual bootloader. + */ + part = 0; +#else part = (mmc->part_config >> 3) & PART_ACCESS_MASK; if (part == 7) part = 0; #endif +#endif + return part; } @@ -449,7 +448,9 @@ int spl_mmc_load(struct spl_image_info *spl_image, return err; } +#ifndef CONFIG_DUAL_BOOTLOADER raw_sect = spl_mmc_get_uboot_raw_sector(mmc, raw_sect); +#endif #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION err = mmc_load_image_raw_partition(spl_image, bootdev, @@ -459,8 +460,12 @@ int spl_mmc_load(struct spl_image_info *spl_image, return err; #endif #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR +#ifdef CONFIG_DUAL_BOOTLOADER + err = mmc_load_image_raw_sector_dual_uboot(spl_image, mmc); +#else err = mmc_load_image_raw_sector(spl_image, bootdev, mmc, raw_sect + spl_mmc_raw_uboot_offset(part)); +#endif if (!err) return err; #endif diff --git a/disk/part_efi.c b/disk/part_efi.c index 87a7220e2c8..05b4ee63b83 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -272,8 +272,10 @@ void part_print_efi(struct blk_desc *dev_desc) printf("\tguid:\t%pUl\n", uuid); } +#if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD) /* Remember to free pte */ free(gpt_pte); +#endif return; } @@ -297,7 +299,9 @@ int part_get_info_efi(struct blk_desc *dev_desc, int part, !is_pte_valid(&gpt_pte[part - 1])) { debug("%s: *** ERROR: Invalid partition number %d ***\n", __func__, part); +#if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD) free(gpt_pte); +#endif return -1; } @@ -324,8 +328,14 @@ int part_get_info_efi(struct blk_desc *dev_desc, int part, debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s\n", __func__, info->start, info->size, info->name); - /* Remember to free pte */ +#if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD) + /* Heap memory is very limited in SPL, if the dual bootloader is + * enabled, just load pte to dram instead of oc-ram. In such case, + * this part of memory shouldn't be freed. But in common routine, + * don't forget to free the memory after use. + */ free(gpt_pte); +#endif return 0; } @@ -1123,10 +1133,19 @@ static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc, (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry), (ulong)count); - /* Allocate memory for PTE, remember to FREE */ + /* Allocate memory for PTE. + * Heap memory is very limited in SPL, if the dual bootloader is + * enabled, just load pte to dram instead of oc-ram. In such case, + * this part of memory shouldn't be freed. But in common routine, + * don't forget to free the memory after use. + */ if (count != 0) { +#if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_SPL_BUILD) + pte = (gpt_entry *)CONFIG_SYS_SPL_PTE_RAM_BASE; +#else pte = memalign(ARCH_DMA_MINALIGN, PAD_TO_BLOCKSIZE(count, dev_desc)); +#endif } if (count == 0 || pte == NULL) { @@ -1140,7 +1159,9 @@ static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc, blk_cnt = BLOCK_CNT(count, dev_desc); if (blk_dread(dev_desc, blk, (lbaint_t)blk_cnt, pte) != blk_cnt) { printf("*** ERROR: Can't read GPT Entries ***\n"); +#if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD) free(pte); +#endif return NULL; } return pte; diff --git a/include/part.h b/include/part.h index 047601dc50f..2427e7100f2 100644 --- a/include/part.h +++ b/include/part.h @@ -296,7 +296,8 @@ part_get_info_by_dev_and_name_or_num(const char *dev_iface, #ifdef CONFIG_SPL_BUILD # define part_print_ptr(x) NULL # if defined(CONFIG_SPL_FS_EXT4) || defined(CONFIG_SPL_FS_FAT) || \ - defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION) + defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION) || \ + defined(CONFIG_DUAL_BOOTLOADER) # define part_get_info_ptr(x) x # else # define part_get_info_ptr(x) NULL diff --git a/include/spl.h b/include/spl.h index ca60879eaea..89abf0d1eaa 100644 --- a/include/spl.h +++ b/include/spl.h @@ -229,6 +229,9 @@ struct spl_image_info { ulong dcrc_length; ulong dcrc; #endif +#ifdef CONFIG_DUAL_BOOTLOADER + uint64_t rbindex; +#endif }; /** diff --git a/lib/avb/fsl/fsl_avb_ab_flow.c b/lib/avb/fsl/fsl_avb_ab_flow.c index 76dd481f903..3bd25f8a03a 100644 --- a/lib/avb/fsl/fsl_avb_ab_flow.c +++ b/lib/avb/fsl/fsl_avb_ab_flow.c @@ -214,7 +214,7 @@ int fsl_load_metadata_dual_uboot(struct blk_desc *dev_desc, } } -#ifndef CONFIG_XEN +#if !defined(CONFIG_XEN) && defined(CONFIG_IMX_TRUSTY_OS) static int spl_verify_rbidx(struct mmc *mmc, AvbABSlotData *slot, struct spl_image_info *spl_image) { @@ -274,19 +274,21 @@ static int spl_verify_rbidx(struct mmc *mmc, AvbABSlotData *slot, } } -#endif /* CONFIG_XEN */ +#endif /* !CONFIG_XEN && CONFIG_IMX_TRUSTY_OS */ -#ifdef CONFIG_PARSE_CONTAINER -int mmc_load_image_parse_container_dual_uboot( - struct spl_image_info *spl_image, struct mmc *mmc) +int mmc_load_image_raw_sector_dual_uboot(struct spl_image_info *spl_image, + struct mmc *mmc) { struct disk_partition info; + unsigned long count; int ret = 0, n = 0; char partition_name[PARTITION_NAME_LEN]; struct blk_desc *dev_desc; + struct image_header *header; + struct spl_load_info load; AvbABData ab_data, ab_data_orig; size_t slot_index_to_boot, target_slot; -#ifndef CONFIG_XEN +#if !defined(CONFIG_XEN) && defined(CONFIG_IMX_TRUSTY_OS) struct keyslot_package kp; #endif @@ -302,8 +304,7 @@ int mmc_load_image_parse_container_dual_uboot( return -1; } -#ifndef CONFIG_XEN - /* Read RPMB keyslot package, xen won't check this. */ +#if !defined(CONFIG_XEN) && defined(CONFIG_IMX_TRUSTY_OS) read_keyslot_package(&kp); if (strcmp(kp.magic, KEYPACK_MAGIC)) { if (rpmbkey_is_set()) { @@ -347,126 +348,6 @@ int mmc_load_image_parse_container_dual_uboot( ret = -1; goto end; } else { - ret = mmc_load_image_parse_container(spl_image, mmc, info.start); - - /* Don't need to check rollback index for xen. */ -#ifndef CONFIG_XEN - /* Image loaded successfully, go to verify rollback index */ - if (!ret && rpmbkey_is_set()) - ret = spl_verify_rbidx(mmc, &ab_data.slots[target_slot], spl_image); - - /* Copy rpmb keyslot to secure memory. */ - if (!ret) - fill_secure_keyslot_package(&kp); -#endif - } - - /* Set current slot to unbootable if load/verify fail. */ - if (ret != 0) { - printf("Load or verify bootloader%s fail, setting unbootable..\n", - slot_suffixes[target_slot]); - fsl_slot_set_unbootable(&ab_data.slots[target_slot]); - /* Switch to another slot. */ - target_slot = (target_slot == 1 ? 0 : 1); - } else { - slot_index_to_boot = target_slot; - n = 2; - } - } - - if (slot_index_to_boot == 2) { - /* No bootable slots! */ - printf("No bootable slots found.\n"); - ret = -1; - goto end; - } else if (!ab_data.slots[slot_index_to_boot].successful_boot && - (ab_data.slots[slot_index_to_boot].tries_remaining > 0)) { - /* Set the bootloader_verified flag if current slot only has one chance. */ - if (ab_data.slots[slot_index_to_boot].tries_remaining == 1) - ab_data.slots[slot_index_to_boot].bootloader_verified = 1; - ab_data.slots[slot_index_to_boot].tries_remaining -= 1; - } - printf("Booting from bootloader%s...\n", slot_suffixes[slot_index_to_boot]); - -end: - /* Save metadata if changed. */ - if (fsl_save_metadata_if_changed_dual_uboot(dev_desc, &ab_data, &ab_data_orig)) { - ret = -1; - } - - if (ret) - return -1; - else - return 0; -} -#else /* CONFIG_PARSE_CONTAINER */ -int mmc_load_image_raw_sector_dual_uboot( - struct spl_image_info *spl_image, struct mmc *mmc) -{ - unsigned long count; - struct disk_partition info; - int ret = 0, n = 0; - char partition_name[PARTITION_NAME_LEN]; - struct blk_desc *dev_desc; - struct image_header *header; - AvbABData ab_data, ab_data_orig; - size_t slot_index_to_boot, target_slot; - struct keyslot_package kp; - - /* Check if gpt is valid */ - dev_desc = mmc_get_blk_desc(mmc); - if (dev_desc) { - if (part_get_info(dev_desc, 1, &info)) { - printf("GPT is invalid, please flash correct GPT!\n"); - return -1; - } - } else { - printf("Get block desc fail!\n"); - return -1; - } - - /* Init RPMB keyslot package if not initialized before. */ - read_keyslot_package(&kp); - if (strcmp(kp.magic, KEYPACK_MAGIC)) { - printf("keyslot package magic error. Will generate new one\n"); - if (gen_rpmb_key(&kp)) { - printf("Generate keyslot package fail!\n"); - return -1; - } - } - /* Set power-on write protection to boot1 partition. */ - if (mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, BOOT1_PWR_WP)) { - printf("Unable to set power-on write protection to boot1!\n"); - return -1; - } - - /* Load AB metadata from misc partition */ - if (fsl_load_metadata_dual_uboot(dev_desc, &ab_data, - &ab_data_orig)) { - return -1; - } - - slot_index_to_boot = 2; // Means not 0 or 1 - target_slot = - (ab_data.slots[1].priority > ab_data.slots[0].priority) ? 1 : 0; - - for (n = 0; n < 2; n++) { - if (!fsl_slot_is_bootable(&ab_data.slots[target_slot])) { - target_slot = (target_slot == 1 ? 0 : 1); - continue; - } - /* Choose slot to load. */ - snprintf(partition_name, PARTITION_NAME_LEN, - PARTITION_BOOTLOADER"%s", - slot_suffixes[target_slot]); - - /* Read part info from gpt */ - if (part_get_info_by_name(dev_desc, partition_name, &info) == -1) { - printf("Can't get partition info of partition bootloader%s\n", - slot_suffixes[target_slot]); - ret = -1; - goto end; - } else { header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); @@ -477,30 +358,32 @@ int mmc_load_image_raw_sector_dual_uboot( goto end; } - /* Load fit and check HAB */ + /* Load fit/container and check HAB */ + load.dev = mmc; + load.priv = NULL; + load.filename = NULL; + load.bl_len = mmc->read_bl_len; + load.read = h_spl_load_read; if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) { - struct spl_load_info load; - - debug("Found FIT\n"); - load.dev = mmc; - load.priv = NULL; - load.filename = NULL; - load.bl_len = mmc->read_bl_len; - load.read = h_spl_load_read; + /* Fit */ ret = spl_load_simple_fit(spl_image, &load, info.start, header); - } else { + } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) { + /* container */ + ret = spl_load_imx_container(spl_image, &load, info.start); + } else ret = -1; - } - /* Fit image loaded successfully, go to verify rollback index */ +#if !defined(CONFIG_XEN) && defined(CONFIG_IMX_TRUSTY_OS) + /* Image loaded successfully, go to verify rollback index */ if (!ret) ret = spl_verify_rbidx(mmc, &ab_data.slots[target_slot], spl_image); /* Copy rpmb keyslot to secure memory. */ if (!ret) fill_secure_keyslot_package(&kp); +#endif } /* Set current slot to unbootable if load/verify fail. */ @@ -545,12 +428,11 @@ end: /* * spl_fit_get_rbindex(): Get rollback index of the bootloader. * @fit: Pointer to the FDT blob. - * @images: Offset of the /images subnode. * * Return: the rollback index value of bootloader or a negative * error number. */ -int spl_fit_get_rbindex(const void *fit, int images) +int spl_fit_get_rbindex(const void *fit) { const char *str; uint64_t index; @@ -572,7 +454,6 @@ int spl_fit_get_rbindex(const void *fit, int images) return index; } -#endif /* CONFIG_PARSE_CONTAINER */ /* For normal build */ #elif !defined(CONFIG_SPL_BUILD) diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 93df1366e56..f8a44c6296f 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -1952,6 +1952,7 @@ CONFIG_SYS_SPL_ARGS_ADDR CONFIG_SYS_SPL_LEN CONFIG_SYS_SPL_MALLOC_SIZE CONFIG_SYS_SPL_MALLOC_START +CONFIG_SYS_SPL_PTE_RAM_BASE CONFIG_SYS_SPR CONFIG_SYS_SRIO CONFIG_SYS_SRIO1_MEM_PHYS |