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
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index c935b7d..5b0a171 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -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 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(¶ms, sizeof(struct stm32_sdmmc2_params));
@@ -294,7 +294,7 @@
#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 @@
#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 @@
#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 @@
#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 @@
#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 @@
#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 @@
#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 @@
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 @@
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 @@
#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 @@
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 @@
{
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 @@
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 */
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index 1a59f0b..5514c09 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -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 @@
};
#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 @@
.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 @@
.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)
diff --git a/plat/st/stm32mp1/stm32mp1_fip_def.h b/plat/st/stm32mp1/stm32mp1_fip_def.h
index 4098386..fa2d20e 100644
--- a/plat/st/stm32mp1/stm32mp1_fip_def.h
+++ b/plat/st/stm32mp1/stm32mp1_fip_def.h
@@ -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 */