summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJi Luo <ji.luo@nxp.com>2019-06-21 15:53:50 +0800
committerJi Luo <ji.luo@nxp.com>2022-04-18 16:40:07 +0800
commitef056c59807fa3f3269bf17b75e3bc18ecfb898f (patch)
treeef5b3136b299aa873b7918396119197a322b4696
parent5fa8aeba48b7f7e677ead8f0854b9ce3d7e8d3af (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.c7
-rw-r--r--common/spl/spl_fit.c14
-rw-r--r--common/spl/spl_mmc.c33
-rw-r--r--disk/part_efi.c25
-rw-r--r--include/part.h3
-rw-r--r--include/spl.h3
-rw-r--r--lib/avb/fsl/fsl_avb_ab_flow.c167
-rw-r--r--scripts/config_whitelist.txt1
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