diff --git a/common/bl_common.c b/common/bl_common.c index d01ef9244..2a9f32fe2 100644 --- a/common/bl_common.c +++ b/common/bl_common.c @@ -211,7 +211,18 @@ int load_auth_image(unsigned int image_id, image_info_t *image_data) { int err; - err = load_auth_image_internal(image_id, image_data); + if ((plat_try_img_ops == NULL) || (plat_try_img_ops->next_instance == NULL)) { + err = load_auth_image_internal(image_id, image_data); + } 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) { /* diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst index f85294b5d..5643ea1fb 100644 --- a/docs/porting-guide.rst +++ b/docs/porting-guide.rst @@ -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 --------------------------------------------- diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 09fce8213..1015fca1b 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -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,6 +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); +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); diff --git a/plat/common/aarch32/plat_common.c b/plat/common/aarch32/plat_common.c index 2c1a8fa09..89791712f 100644 --- a/plat/common/aarch32/plat_common.c +++ b/plat/common/aarch32/plat_common.c @@ -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 #include +/* 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); diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c index 54f2a034d..7a228b976 100644 --- a/plat/common/aarch64/plat_common.c +++ b/plat/common/aarch64/plat_common.c @@ -17,6 +17,14 @@ #include #include +/* 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