Add platform hooks for boot redundancy support

These hooks are intended to allow one platform to try load
images from alternative places. There is a hook to initialize
the sequence of boot locations and a hook to pass to the next
sequence.

Change-Id: Ia0f84c415208dc4fa4f9d060d58476db23efa5b2
Signed-off-by: Roberto Vargas <roberto.vargas@arm.com>
diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c
index 0fe82d9..018deb3 100644
--- a/bl2/bl2_main.c
+++ b/bl2/bl2_main.c
@@ -34,6 +34,9 @@
 	auth_mod_init();
 #endif /* TRUSTED_BOARD_BOOT */
 
+	/* initialize boot source */
+	bl2_plat_preload_setup();
+
 	/* Load the subsequent bootloader images. */
 	next_bl_ep_info = bl2_load_images();
 
diff --git a/common/bl_common.c b/common/bl_common.c
index cad4de9..e4473ed 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -354,7 +354,13 @@
  ******************************************************************************/
 int load_auth_image(unsigned int image_id, image_info_t *image_data)
 {
-	return load_auth_image_internal(image_id, image_data, 0);
+	int err;
+
+	do {
+		err = load_auth_image_internal(image_id, image_data, 0);
+	} while (err != 0 && plat_try_next_boot_source());
+
+	return err;
 }
 
 #else /* LOAD_IMAGE_V2 */
@@ -553,8 +559,14 @@
 		    image_info_t *image_data,
 		    entry_point_info_t *entry_point_info)
 {
-	return load_auth_image_internal(mem_layout, image_id, image_base,
-					image_data, entry_point_info, 0);
+	int err;
+
+	do {
+		err = load_auth_image_internal(mem_layout, image_id, image_base,
+					       image_data, entry_point_info, 0);
+	} while (err != 0 && plat_try_next_boot_source());
+
+	return err;
 }
 
 #endif /* LOAD_IMAGE_V2 */
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 6352bb9..f0a8aaf 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -1596,6 +1596,34 @@
 This function isn't needed if either ``PRELOADED_BL33_BASE`` or ``EL3_PAYLOAD_BASE``
 build options are used.
 
+Function : bl2\_plat\_preload\_setup [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+    Argument : void
+    Return   : void
+
+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.
+
 FWU Boot Loader Stage 2 (BL2U)
 ------------------------------
 
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index f03a399..e2bfa50 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -100,6 +100,8 @@
 void plat_error_handler(int err) __dead2;
 void plat_panic_handler(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);
 
 /*******************************************************************************
  * Mandatory BL1 functions
diff --git a/plat/common/aarch32/platform_helpers.S b/plat/common/aarch32/platform_helpers.S
index b5f41ff..61d21ab 100644
--- a/plat/common/aarch32/platform_helpers.S
+++ b/plat/common/aarch32/platform_helpers.S
@@ -14,6 +14,8 @@
 	.weak	plat_disable_acp
 	.weak	platform_mem_init
 	.weak	plat_panic_handler
+	.weak	bl2_plat_preload_setup
+	.weak	plat_try_next_boot_source
 
 	/* -----------------------------------------------------
 	 * Placeholder function which should be redefined by
@@ -79,3 +81,23 @@
 func plat_panic_handler
 	b	plat_panic_handler
 endfunc plat_panic_handler
+
+
+	/* -----------------------------------------------------
+	 * Placeholder function which should be redefined by
+	 * each platfrom.
+	 * -----------------------------------------------------
+	 */
+func bl2_plat_preload_setup
+	bx	lr
+endfunc bl2_plat_preload_setup
+
+	/* -----------------------------------------------------
+	 * Placeholder function which should be redefined by
+	 * each platfrom.
+	 * -----------------------------------------------------
+	 */
+func plat_try_next_boot_source
+	mov	r0, #0
+	bx	lr
+endfunc plat_try_next_boot_source
diff --git a/plat/common/aarch64/platform_helpers.S b/plat/common/aarch64/platform_helpers.S
index e60db20..797a936 100644
--- a/plat/common/aarch64/platform_helpers.S
+++ b/plat/common/aarch64/platform_helpers.S
@@ -17,6 +17,8 @@
 	.weak	bl1_plat_prepare_exit
 	.weak	plat_error_handler
 	.weak	plat_panic_handler
+	.weak	bl2_plat_preload_setup
+	.weak	plat_try_next_boot_source
 
 #if !ENABLE_PLAT_COMPAT
 	.globl	platform_get_core_pos
@@ -129,3 +131,22 @@
 	wfi
 	b	plat_panic_handler
 endfunc plat_panic_handler
+
+	/* -----------------------------------------------------
+	 * Placeholder function which should be redefined by
+	 * each platfrom.
+	 * -----------------------------------------------------
+	 */
+func bl2_plat_preload_setup
+	ret
+endfunc bl2_plat_preload_setup
+
+	/* -----------------------------------------------------
+	 * Placeholder function which should be redefined by
+	 * each platfrom.
+	 * -----------------------------------------------------
+	 */
+func plat_try_next_boot_source
+	mov	x0, #0
+	ret
+endfunc plat_try_next_boot_source