feat(stm32mp1): add logic to select the images to be booted

With the FWU multi bank boot feature enabled, the platform can boot
from one of the multiple banks(partitions) containing the firmware
images. The bank whose firmware components are to be booted is read
from the FWU metadata structure -- the image to be booted is thus
derived by reading the metadata.

Read the metadata and set the image spec of the corresponding image
type to point to the partition from which the image is to be booted.

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
Change-Id: I3dfdc7e9202859e917ec4e1f7d1855aad42c6b70
This commit is contained in:
Sughosh Ganu 2021-12-01 16:45:11 +05:30
parent 41bd8b9e2a
commit 8dd755314f
1 changed files with 77 additions and 1 deletions

View File

@ -10,6 +10,8 @@
#include <arch_helpers.h>
#include <common/debug.h>
#include <common/desc_image_load.h>
#include <drivers/fwu/fwu.h>
#include <drivers/fwu/fwu_metadata.h>
#include <drivers/io/io_block.h>
#include <drivers/io/io_driver.h>
#include <drivers/io/io_fip.h>
@ -17,6 +19,7 @@
#include <drivers/io/io_mtd.h>
#include <drivers/io/io_storage.h>
#include <drivers/mmc.h>
#include <drivers/partition/efi.h>
#include <drivers/partition/partition.h>
#include <drivers/raw_nand.h>
#include <drivers/spi_nand.h>
@ -384,6 +387,12 @@ int bl2_plat_handle_pre_image_load(unsigned int image_id)
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
if (!gpt_init_done) {
/*
* With FWU Multi Bank feature enabled, the selection of
* the image to boot will be done by fwu_init calling the
* platform hook, plat_fwu_set_images_source.
*/
#if !PSA_FWU_SUPPORT
const partition_entry_t *entry;
partition_init(GPT_IMAGE_ID);
@ -396,7 +405,7 @@ int bl2_plat_handle_pre_image_load(unsigned int image_id)
image_block_spec.offset = entry->start;
image_block_spec.length = entry->length;
#endif
gpt_init_done = true;
} else {
bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
@ -473,3 +482,70 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
return rc;
}
#if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
/*
* Eventually, this function will return the
* boot index to be passed on to the Update
* Agent after performing certain checks like
* a watchdog timeout, or Auth failure while
* trying to load from a certain bank.
* For now, since we do not have that logic
* implemented, just pass the active_index
* read from the metadata.
*/
uint32_t plat_fwu_get_boot_idx(void)
{
const struct fwu_metadata *metadata;
metadata = fwu_get_metadata();
return metadata->active_index;
}
static void *stm32_get_image_spec(const uuid_t *img_type_uuid)
{
unsigned int i;
for (i = 0U; i < MAX_NUMBER_IDS; i++) {
if ((guidcmp(&policies[i].img_type_guid, img_type_uuid)) == 0) {
return (void *)policies[i].image_spec;
}
}
return NULL;
}
void plat_fwu_set_images_source(const struct fwu_metadata *metadata)
{
unsigned int i;
uint32_t boot_idx;
const partition_entry_t *entry;
const uuid_t *img_type_uuid, *img_uuid;
io_block_spec_t *image_spec;
boot_idx = plat_fwu_get_boot_idx();
assert(boot_idx < NR_OF_FW_BANKS);
for (i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
img_type_uuid = &metadata->img_entry[i].img_type_uuid;
image_spec = stm32_get_image_spec(img_type_uuid);
if (image_spec == NULL) {
ERROR("Unable to get image spec for the image in the metadata\n");
panic();
}
img_uuid =
&metadata->img_entry[i].img_props[boot_idx].img_uuid;
entry = get_partition_entry_by_uuid(img_uuid);
if (entry == NULL) {
ERROR("Unable to find the partition with the uuid mentioned in metadata\n");
panic();
}
image_spec->offset = entry->start;
image_spec->length = entry->length;
}
}
#endif /* (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT */