mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 01:24:27 +00:00
Merge changes from topic "st-nand-backup-fwu" into integration
* changes: refactor(st): rename plat_set_image_source feat(st): add FWU with boot from NAND feat(st): manage backup partitions for NAND devices feat(bl): add plat handler for image loading refactor(bl)!: remove unused plat_try_next_boot_source
This commit is contained in:
commit
08fc380ab3
8 changed files with 171 additions and 55 deletions
|
@ -211,18 +211,18 @@ int load_auth_image(unsigned int image_id, image_info_t *image_data)
|
|||
{
|
||||
int err;
|
||||
|
||||
/*
|
||||
* All firmware banks should be part of the same non-volatile storage as per
|
||||
* PSA FWU specification, hence don't check for any alternate boot source
|
||||
* when PSA FWU is enabled.
|
||||
*/
|
||||
#if PSA_FWU_SUPPORT
|
||||
err = load_auth_image_internal(image_id, image_data);
|
||||
#else
|
||||
do {
|
||||
if ((plat_try_img_ops == NULL) || (plat_try_img_ops->next_instance == NULL)) {
|
||||
err = load_auth_image_internal(image_id, image_data);
|
||||
} while ((err != 0) && (plat_try_next_boot_source() != 0));
|
||||
#endif /* PSA_FWU_SUPPORT */
|
||||
} else {
|
||||
do {
|
||||
err = load_auth_image_internal(image_id, image_data);
|
||||
if (err != 0) {
|
||||
if (plat_try_img_ops->next_instance(image_id) != 0) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
} while (err != 0);
|
||||
}
|
||||
|
||||
if (err == 0) {
|
||||
/*
|
||||
|
|
|
@ -1518,6 +1518,40 @@ When CONDITIONAL_CMO flag is enabled:
|
|||
- The function must not clobber x1, x2 and x3. It's also not safe to rely on
|
||||
stack. Otherwise obey AAPCS.
|
||||
|
||||
Struct: plat_try_images_ops [optional]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This optional structure holds platform hooks for alternative images load.
|
||||
It has to be defined in platform code and registered by calling
|
||||
plat_setup_try_img_ops() function, passing it the address of the
|
||||
plat_try_images_ops struct.
|
||||
|
||||
Function : plat_setup_try_img_ops [optional]
|
||||
............................................
|
||||
|
||||
::
|
||||
|
||||
Argument : const struct plat_try_images_ops *
|
||||
Return : void
|
||||
|
||||
This optional function is called to register platform try images ops, given
|
||||
as argument.
|
||||
|
||||
Function : plat_try_images_ops.next_instance [optional]
|
||||
.......................................................
|
||||
|
||||
::
|
||||
|
||||
Argument : unsigned int image_id
|
||||
Return : int
|
||||
|
||||
This optional function tries to load images from alternative places.
|
||||
In case PSA FWU is not used, it can be any instance or media. If PSA FWU is
|
||||
used, it is mandatory that the backup image is on the same media.
|
||||
This is required for MTD devices like NAND.
|
||||
The argument is the ID of the image for which we are looking for an alternative
|
||||
place. It returns 0 in case of success and a negative errno value otherwise.
|
||||
|
||||
Modifications specific to a Boot Loader stage
|
||||
---------------------------------------------
|
||||
|
||||
|
@ -1607,9 +1641,6 @@ This function executes with the MMU and data caches enabled. It is responsible
|
|||
for performing any remaining platform-specific setup that can occur after the
|
||||
MMU and data cache have been enabled.
|
||||
|
||||
if support for multiple boot sources is required, it initializes the boot
|
||||
sequence used by plat_try_next_boot_source().
|
||||
|
||||
In Arm standard platforms, this function initializes the storage abstraction
|
||||
layer used to load the next bootloader image.
|
||||
|
||||
|
@ -1892,25 +1923,7 @@ Function : bl2_plat_preload_setup [optional]
|
|||
|
||||
This optional function performs any BL2 platform initialization
|
||||
required before image loading, that is not done later in
|
||||
bl2_platform_setup(). Specifically, if support for multiple
|
||||
boot sources is required, it initializes the boot sequence used by
|
||||
plat_try_next_boot_source().
|
||||
|
||||
Function : plat_try_next_boot_source() [optional]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
Argument : void
|
||||
Return : int
|
||||
|
||||
This optional function passes to the next boot source in the redundancy
|
||||
sequence.
|
||||
|
||||
This function moves the current boot redundancy source to the next
|
||||
element in the boot sequence. If there are no more boot sources then it
|
||||
must return 0, otherwise it must return 1. The default implementation
|
||||
of this always returns 0.
|
||||
bl2_platform_setup().
|
||||
|
||||
Boot Loader Stage 2 (BL2) at EL3
|
||||
--------------------------------
|
||||
|
|
|
@ -40,6 +40,16 @@ struct sp_res_desc;
|
|||
struct rmm_manifest;
|
||||
enum fw_enc_status_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* Structure populated by platform specific code to export routines which
|
||||
* perform load images functions, and associated pointer to platform ops
|
||||
******************************************************************************/
|
||||
struct plat_try_images_ops {
|
||||
int (*next_instance)(unsigned int image_id);
|
||||
};
|
||||
|
||||
extern const struct plat_try_images_ops *plat_try_img_ops;
|
||||
|
||||
/*******************************************************************************
|
||||
* plat_get_rotpk_info() flags
|
||||
******************************************************************************/
|
||||
|
@ -154,7 +164,7 @@ void plat_panic_handler(void) __dead2;
|
|||
void plat_system_reset(void) __dead2;
|
||||
const char *plat_log_get_prefix(unsigned int log_level);
|
||||
void bl2_plat_preload_setup(void);
|
||||
int plat_try_next_boot_source(void);
|
||||
void plat_setup_try_img_ops(const struct plat_try_images_ops *plat_try_ops);
|
||||
|
||||
#if MEASURED_BOOT
|
||||
int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -7,6 +7,14 @@
|
|||
#include <lib/xlat_tables/xlat_mmu_helpers.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
/* Pointer and function to register platform function to load alernate images */
|
||||
const struct plat_try_images_ops *plat_try_img_ops;
|
||||
|
||||
void plat_setup_try_img_ops(const struct plat_try_images_ops *plat_try_ops)
|
||||
{
|
||||
plat_try_img_ops = plat_try_ops;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following platform setup functions are weakly defined. They
|
||||
* provide typical implementations that may be re-used by multiple
|
||||
|
@ -14,7 +22,6 @@
|
|||
*/
|
||||
#pragma weak bl32_plat_enable_mmu
|
||||
|
||||
|
||||
void bl32_plat_enable_mmu(uint32_t flags)
|
||||
{
|
||||
enable_mmu_svc_mon(flags);
|
||||
|
|
|
@ -17,6 +17,14 @@
|
|||
#include <lib/xlat_tables/xlat_mmu_helpers.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
/* Pointer and function to register platform function to load alernate images */
|
||||
const struct plat_try_images_ops *plat_try_img_ops;
|
||||
|
||||
void plat_setup_try_img_ops(const struct plat_try_images_ops *plat_try_ops)
|
||||
{
|
||||
plat_try_img_ops = plat_try_ops;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following platform setup functions are weakly defined. They
|
||||
* provide typical implementations that may be re-used by multiple
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -24,7 +24,6 @@
|
|||
#pragma weak bl2_plat_preload_setup
|
||||
#pragma weak bl2_plat_handle_pre_image_load
|
||||
#pragma weak bl2_plat_handle_post_image_load
|
||||
#pragma weak plat_try_next_boot_source
|
||||
#pragma weak plat_get_enc_key_info
|
||||
#pragma weak plat_is_smccc_feature_available
|
||||
#pragma weak plat_get_soc_version
|
||||
|
@ -69,11 +68,6 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int plat_try_next_boot_source(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Weak implementation to provide dummy decryption key only for test purposes,
|
||||
* platforms must override this API for any real world firmware encryption
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -47,6 +47,7 @@ uintptr_t fip_dev_handle;
|
|||
uintptr_t storage_dev_handle;
|
||||
|
||||
static const io_dev_connector_t *fip_dev_con;
|
||||
static uint32_t nand_block_sz __maybe_unused;
|
||||
|
||||
#ifndef DECRYPTION_SUPPORT_none
|
||||
static const io_dev_connector_t *enc_dev_con;
|
||||
|
@ -310,11 +311,55 @@ static void boot_spi_nor(boot_api_context_t *boot_context)
|
|||
}
|
||||
#endif /* STM32MP_SPI_NOR */
|
||||
|
||||
#if STM32MP_RAW_NAND || STM32MP_SPI_NAND
|
||||
/*
|
||||
* This function returns 0 if it can find an alternate
|
||||
* image to be loaded or a negative errno otherwise.
|
||||
*/
|
||||
static int try_nand_backup_partitions(unsigned int image_id)
|
||||
{
|
||||
static unsigned int backup_id;
|
||||
static unsigned int backup_block_nb;
|
||||
|
||||
/* Check if NAND storage used */
|
||||
if (nand_block_sz == 0U) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (backup_id != image_id) {
|
||||
backup_block_nb = PLATFORM_MTD_MAX_PART_SIZE / nand_block_sz;
|
||||
backup_id = image_id;
|
||||
}
|
||||
|
||||
if (backup_block_nb-- == 0U) {
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
#if PSA_FWU_SUPPORT
|
||||
if (((image_block_spec.offset < STM32MP_NAND_FIP_B_OFFSET) &&
|
||||
((image_block_spec.offset + nand_block_sz) >= STM32MP_NAND_FIP_B_OFFSET)) ||
|
||||
(image_block_spec.offset + nand_block_sz >= STM32MP_NAND_FIP_B_MAX_OFFSET)) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
image_block_spec.offset += nand_block_sz;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct plat_try_images_ops try_img_ops = {
|
||||
.next_instance = try_nand_backup_partitions,
|
||||
};
|
||||
#endif /* STM32MP_RAW_NAND || STM32MP_SPI_NAND */
|
||||
|
||||
#if STM32MP_RAW_NAND
|
||||
static void boot_fmc2_nand(boot_api_context_t *boot_context)
|
||||
{
|
||||
int io_result __maybe_unused;
|
||||
|
||||
plat_setup_try_img_ops(&try_img_ops);
|
||||
|
||||
io_result = stm32_fmc2_init();
|
||||
assert(io_result == 0);
|
||||
|
||||
|
@ -326,6 +371,8 @@ static void boot_fmc2_nand(boot_api_context_t *boot_context)
|
|||
io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec,
|
||||
&storage_dev_handle);
|
||||
assert(io_result == 0);
|
||||
|
||||
nand_block_sz = nand_dev_spec.erase_size;
|
||||
}
|
||||
#endif /* STM32MP_RAW_NAND */
|
||||
|
||||
|
@ -334,6 +381,8 @@ static void boot_spi_nand(boot_api_context_t *boot_context)
|
|||
{
|
||||
int io_result __maybe_unused;
|
||||
|
||||
plat_setup_try_img_ops(&try_img_ops);
|
||||
|
||||
io_result = stm32_qspi_init();
|
||||
assert(io_result == 0);
|
||||
|
||||
|
@ -345,6 +394,8 @@ static void boot_spi_nand(boot_api_context_t *boot_context)
|
|||
(uintptr_t)&spi_nand_dev_spec,
|
||||
&storage_dev_handle);
|
||||
assert(io_result == 0);
|
||||
|
||||
nand_block_sz = spi_nand_dev_spec.erase_size;
|
||||
}
|
||||
#endif /* STM32MP_SPI_NAND */
|
||||
|
||||
|
@ -530,7 +581,14 @@ int bl2_plat_handle_pre_image_load(unsigned int image_id)
|
|||
#if STM32MP_SPI_NAND
|
||||
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI:
|
||||
#endif
|
||||
/*
|
||||
* 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_NAND_FIP_OFFSET;
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
@ -596,7 +654,7 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
|
|||
return rc;
|
||||
}
|
||||
|
||||
#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
|
||||
#if 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.
|
||||
|
@ -709,6 +767,19 @@ void plat_fwu_set_images_source(const struct fwu_metadata *metadata)
|
|||
panic();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if (STM32MP_RAW_NAND || STM32MP_SPI_NAND)
|
||||
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
|
||||
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI:
|
||||
if (guidcmp(img_guid, &STM32MP_NAND_FIP_A_GUID) == 0) {
|
||||
image_spec->offset = STM32MP_NAND_FIP_A_OFFSET;
|
||||
} else if (guidcmp(img_guid, &STM32MP_NAND_FIP_B_GUID) == 0) {
|
||||
image_spec->offset = STM32MP_NAND_FIP_B_OFFSET;
|
||||
} else {
|
||||
ERROR("Invalid uuid mentioned in metadata\n");
|
||||
panic();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
panic();
|
||||
|
@ -717,9 +788,9 @@ void plat_fwu_set_images_source(const struct fwu_metadata *metadata)
|
|||
}
|
||||
}
|
||||
|
||||
static int plat_set_image_source(unsigned int image_id,
|
||||
uintptr_t *handle,
|
||||
uintptr_t *image_spec)
|
||||
static int set_metadata_image_source(unsigned int image_id,
|
||||
uintptr_t *handle,
|
||||
uintptr_t *image_spec)
|
||||
{
|
||||
struct plat_io_policy *policy;
|
||||
io_block_spec_t *spec __maybe_unused;
|
||||
|
@ -762,6 +833,19 @@ static int plat_set_image_source(unsigned int image_id,
|
|||
spec->length = sizeof(struct fwu_metadata);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if (STM32MP_RAW_NAND || STM32MP_SPI_NAND)
|
||||
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
|
||||
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI:
|
||||
if (image_id == FWU_METADATA_IMAGE_ID) {
|
||||
spec->offset = STM32MP_NAND_METADATA1_OFFSET;
|
||||
} else {
|
||||
spec->offset = STM32MP_NAND_METADATA2_OFFSET;
|
||||
}
|
||||
|
||||
spec->length = sizeof(struct fwu_metadata);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
panic();
|
||||
break;
|
||||
|
@ -780,6 +864,6 @@ int plat_fwu_set_metadata_image_source(unsigned int image_id,
|
|||
assert((image_id == FWU_METADATA_IMAGE_ID) ||
|
||||
(image_id == BKUP_FWU_METADATA_IMAGE_ID));
|
||||
|
||||
return plat_set_image_source(image_id, handle, image_spec);
|
||||
return set_metadata_image_source(image_id, handle, image_spec);
|
||||
}
|
||||
#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
|
||||
#endif /* PSA_FWU_SUPPORT */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2023, STMicroelectronics - All Rights Reserved
|
||||
* Copyright (c) 2021-2024, 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 || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
|
||||
#if 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 || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
|
||||
#endif /* 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 || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
|
||||
#if 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 || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
|
||||
#endif /* PSA_FWU_SUPPORT */
|
||||
};
|
||||
|
||||
#define DEFAULT_UUID_NUMBER U(7)
|
||||
|
|
Loading…
Add table
Reference in a new issue