feat(bl): add plat handler for image loading
In case of load error, platform may need to try another instance, either
from another storage, or from the same storage in case of PSA FWU. On
MTD devices such as NAND, it is required to define backup partitions.
A new function plat_setup_try_img_ops() should be called by platform
code to register handlers (plat_try_images_ops) to manage loading
other images.
Signed-off-by: Yann Gautier <yann.gautier@st.com>
Signed-off-by: Lionel Debieve <lionel.debieve@foss.st.com>
Change-Id: Ideaecaf296c0037a26fb4e6680f33e507111378a
diff --git a/common/bl_common.c b/common/bl_common.c
index d01ef92..2a9f32f 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -211,7 +211,18 @@
{
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 f85294b..5643ea1 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -1518,6 +1518,40 @@
- 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 09fce82..1015fca 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -41,6 +41,16 @@
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
******************************************************************************/
#define ROTPK_IS_HASH (1 << 0)
@@ -154,6 +164,7 @@
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 2c1a8fa..8979171 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 <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);
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index 54f2a03..7a228b9 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -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