feat(stm32mp1): add FWU with boot from NOR-SPI

Refactor the SDCARD/EMMC FWU, to add the NOR-SPI use case.
SPI-NOR FWU won't use a real partition uuid to find the correct FIP,
but the UUID from metadata will correspond with a hardcoded offset in
the NOR.
While at it change some __unused keywords to __maybe_unused to ease
checkpatch.pl analysis.

Signed-off-by: Frank Bodammer <frank.bodammer@siemens.com>
Signed-off-by: Nicolas Toromanoff <nicolas.toromanoff@foss.st.com>
Signed-off-by: Yann Gautier <yann.gautier@st.com>
Change-Id: I2fe56ba8534a3c5dfaf8aeb16e7b286909883cc2
This commit is contained in:
Nicolas Toromanoff 2022-02-07 10:12:29 +01:00 committed by Yann Gautier
parent 83fde9fcdf
commit dfbadfd96b
3 changed files with 118 additions and 53 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -222,7 +222,7 @@ static void print_boot_device(boot_api_context_t *boot_context)
static void boot_mmc(enum mmc_device_type mmc_dev_type,
uint16_t boot_interface_instance)
{
int io_result __unused;
int io_result __maybe_unused;
struct stm32_sdmmc2_params params;
zeromem(&params, sizeof(struct stm32_sdmmc2_params));
@ -294,7 +294,7 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type,
#if STM32MP_SPI_NOR
static void boot_spi_nor(boot_api_context_t *boot_context)
{
int io_result __unused;
int io_result __maybe_unused;
io_result = stm32_qspi_init();
assert(io_result == 0);
@ -313,7 +313,7 @@ static void boot_spi_nor(boot_api_context_t *boot_context)
#if STM32MP_RAW_NAND
static void boot_fmc2_nand(boot_api_context_t *boot_context)
{
int io_result __unused;
int io_result __maybe_unused;
io_result = stm32_fmc2_init();
assert(io_result == 0);
@ -332,7 +332,7 @@ static void boot_fmc2_nand(boot_api_context_t *boot_context)
#if STM32MP_SPI_NAND
static void boot_spi_nand(boot_api_context_t *boot_context)
{
int io_result __unused;
int io_result __maybe_unused;
io_result = stm32_qspi_init();
assert(io_result == 0);
@ -351,7 +351,7 @@ static void boot_spi_nand(boot_api_context_t *boot_context)
#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
static void mmap_io_setup(void)
{
int io_result __unused;
int io_result __maybe_unused;
io_result = register_io_dev_memmap(&memmap_dev_con);
assert(io_result == 0);
@ -364,7 +364,7 @@ static void mmap_io_setup(void)
#if STM32MP_UART_PROGRAMMER
static void stm32cubeprogrammer_uart(void)
{
int ret __unused;
int ret __maybe_unused;
boot_api_context_t *boot_context =
(boot_api_context_t *)stm32mp_get_boot_ctx_address();
uintptr_t uart_base;
@ -378,7 +378,7 @@ static void stm32cubeprogrammer_uart(void)
#if STM32MP_USB_PROGRAMMER
static void stm32cubeprogrammer_usb(void)
{
int ret __unused;
int ret __maybe_unused;
struct usb_handle *pdev;
/* Init USB on platform */
@ -390,10 +390,9 @@ static void stm32cubeprogrammer_usb(void)
#endif
#endif /* STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER */
void stm32mp_io_setup(void)
{
int io_result __unused;
int io_result __maybe_unused;
boot_api_context_t *boot_context =
(boot_api_context_t *)stm32mp_get_boot_ctx_address();
@ -473,7 +472,7 @@ void stm32mp_io_setup(void)
int bl2_plat_handle_pre_image_load(unsigned int image_id)
{
static bool gpt_init_done __unused;
static bool gpt_init_done __maybe_unused;
uint16_t boot_itf = stm32mp_get_boot_itf_selected();
switch (boot_itf) {
@ -516,6 +515,7 @@ int bl2_plat_handle_pre_image_load(unsigned int image_id)
gpt_init_done = true;
} else {
bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
assert(bl_mem_params != NULL);
mmc_block_dev_spec.buffer.offset = bl_mem_params->image_info.image_base;
@ -538,7 +538,14 @@ int bl2_plat_handle_pre_image_load(unsigned int image_id)
#if STM32MP_SPI_NOR
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
/*
* 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
image_block_spec.offset = STM32MP_NOR_FIP_OFFSET;
#endif
break;
#endif
@ -591,7 +598,7 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
return rc;
}
#if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
/*
* In each boot in non-trial mode, we set the BKP register to
* FWU_MAX_TRIAL_REBOOT, and return the active_index from metadata.
@ -652,54 +659,108 @@ 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;
const partition_entry_t *entry __maybe_unused;
const uuid_t *img_type_uuid;
const uuid_t *img_uuid __maybe_unused;
io_block_spec_t *image_spec;
const uint16_t boot_itf = stm32mp_get_boot_itf_selected();
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;
img_uuid = &metadata->img_entry[i].img_props[boot_idx].img_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;
switch (boot_itf) {
#if (STM32MP_SDMMC || STM32MP_EMMC)
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
entry = get_partition_entry_by_uuid(img_uuid);
if (entry == NULL) {
ERROR("No partition with the uuid mentioned in metadata\n");
panic();
}
entry = get_partition_entry_by_uuid(img_uuid);
if (entry == NULL) {
ERROR("Unable to find the partition with the uuid mentioned in metadata\n");
image_spec->offset = entry->start;
image_spec->length = entry->length;
break;
#endif
#if STM32MP_SPI_NOR
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
if (guidcmp(img_uuid, &STM32MP_NOR_FIP_A_GUID) == 0) {
image_spec->offset = STM32MP_NOR_FIP_A_OFFSET;
} else if (guidcmp(img_uuid, &STM32MP_NOR_FIP_B_GUID) == 0) {
image_spec->offset = STM32MP_NOR_FIP_B_OFFSET;
} else {
ERROR("Invalid uuid mentioned in metadata\n");
panic();
}
break;
#endif
default:
panic();
break;
}
image_spec->offset = entry->start;
image_spec->length = entry->length;
}
}
static int plat_set_image_source(unsigned int image_id,
uintptr_t *handle,
uintptr_t *image_spec,
const char *part_name)
uintptr_t *image_spec)
{
struct plat_io_policy *policy;
io_block_spec_t *spec;
const partition_entry_t *entry = get_partition_entry(part_name);
if (entry == NULL) {
ERROR("Unable to find the %s partition\n", part_name);
return -ENOENT;
}
io_block_spec_t *spec __maybe_unused;
const partition_entry_t *entry __maybe_unused;
const uint16_t boot_itf = stm32mp_get_boot_itf_selected();
policy = &policies[image_id];
spec = (io_block_spec_t *)policy->image_spec;
spec->offset = entry->start;
spec->length = entry->length;
switch (boot_itf) {
#if (STM32MP_SDMMC || STM32MP_EMMC)
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
partition_init(GPT_IMAGE_ID);
if (image_id == FWU_METADATA_IMAGE_ID) {
entry = get_partition_entry(METADATA_PART_1);
} else {
entry = get_partition_entry(METADATA_PART_2);
}
if (entry == NULL) {
ERROR("Unable to find a metadata partition\n");
return -ENOENT;
}
spec->offset = entry->start;
spec->length = entry->length;
break;
#endif
#if STM32MP_SPI_NOR
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
if (image_id == FWU_METADATA_IMAGE_ID) {
spec->offset = STM32MP_NOR_METADATA1_OFFSET;
} else {
spec->offset = STM32MP_NOR_METADATA2_OFFSET;
}
spec->length = sizeof(struct fwu_metadata);
break;
#endif
default:
panic();
break;
}
*image_spec = policy->image_spec;
*handle = *policy->dev_handle;
@ -711,20 +772,9 @@ int plat_fwu_set_metadata_image_source(unsigned int image_id,
uintptr_t *handle,
uintptr_t *image_spec)
{
char *part_name;
assert((image_id == FWU_METADATA_IMAGE_ID) ||
(image_id == BKUP_FWU_METADATA_IMAGE_ID));
partition_init(GPT_IMAGE_ID);
if (image_id == FWU_METADATA_IMAGE_ID) {
part_name = METADATA_PART_1;
} else {
part_name = METADATA_PART_2;
}
return plat_set_image_source(image_id, handle, image_spec,
part_name);
return plat_set_image_source(image_id, handle, image_spec);
}
#endif /* (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT */
#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
* Copyright (c) 2021-2023, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -27,12 +27,12 @@ static io_block_spec_t gpt_block_spec = {
};
#endif
#if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
static io_block_spec_t metadata_block_spec = {
.offset = 0, /* To be filled at runtime */
.length = 0, /* To be filled at runtime */
};
#endif /* (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT */
#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
/* By default, STM32 platforms load images from the FIP */
struct plat_io_policy policies[MAX_NUMBER_IDS] = {
@ -58,7 +58,7 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = {
.check = open_storage
},
#endif
#if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
[FWU_METADATA_IMAGE_ID] = {
.dev_handle = &storage_dev_handle,
.image_spec = (uintptr_t)&metadata_block_spec,
@ -71,7 +71,7 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = {
.img_type_guid = NULL_GUID,
.check = open_storage
},
#endif /* (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT */
#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
};
#define DEFAULT_UUID_NUMBER U(7)

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2022, STMicroelectronics - All Rights Reserved
* Copyright (C) 2021-2023, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -128,11 +128,26 @@
* STM32MP1 RAW partition offset for devices without GPT
******************************************************************************/
#define STM32MP_EMMC_BOOT_FIP_OFFSET U(0x00040000)
#if PSA_FWU_SUPPORT
#define STM32MP_NOR_METADATA1_OFFSET U(0x00080000)
#define STM32MP_NOR_METADATA2_OFFSET U(0x000C0000)
#define STM32MP_NOR_FIP_A_OFFSET U(0x00100000)
#define STM32MP_NOR_FIP_A_GUID (const struct efi_guid)EFI_GUID(0x4fd84c93, \
0x54ef, 0x463f, 0xa7, 0xef, 0xae, 0x25, 0xff,\
0x88, 0x70, 0x87)
#define STM32MP_NOR_FIP_B_OFFSET U(0x00500000)
#define STM32MP_NOR_FIP_B_GUID (const struct efi_guid)EFI_GUID(0x09c54952, \
0xd5bf, 0x45af, 0xac, 0xee, 0x33, 0x53, 0x03,\
0x76, 0x6f, 0xb3)
#else /* PSA_FWU_SUPPORT */
#ifndef STM32MP_NOR_FIP_OFFSET
#define STM32MP_NOR_FIP_OFFSET U(0x00080000)
#endif
#ifndef STM32MP_NAND_FIP_OFFSET
#define STM32MP_NAND_FIP_OFFSET U(0x00200000)
#endif
#endif /* PSA_FWU_SUPPORT */
#endif /* STM32MP1_FIP_DEF_H */