Add support for BL3-1 as a reset vector
This change adds optional reset vector support to BL3-1
which means BL3-1 entry point can detect cold/warm boot,
initialise primary cpu, set up cci and mail box.
When using BL3-1 as a reset vector it is assumed that
the BL3-1 platform code can determine the location of
the BL3-2 images, or load them as there are no parameters
that can be passed to BL3-1 at reset.
It also fixes the incorrect initialisation of mailbox
registers on the FVP platform
This feature can be enabled by building the code with
make variable RESET_TO_BL31 set as 1
Fixes ARM-software/TF-issues#133
Fixes ARM-software/TF-issues#20
Change-Id: I4e23939b1c518614b899f549f1e8d412538ee570
diff --git a/plat/fvp/bl31_plat_setup.c b/plat/fvp/bl31_plat_setup.c
index 949b156..033a8fa 100644
--- a/plat/fvp/bl31_plat_setup.c
+++ b/plat/fvp/bl31_plat_setup.c
@@ -29,6 +29,7 @@
*/
#include <arch.h>
+#include <arch_helpers.h>
#include <assert.h>
#include <bl_common.h>
#include <bl31.h>
@@ -67,11 +68,17 @@
#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+
+#if RESET_TO_BL31
+static entry_point_info_t bl32_entrypoint_info;
+static entry_point_info_t bl33_entrypoint_info;
+#else
/*******************************************************************************
* Reference to structure which holds the arguments that have been passed to
* BL31 from BL2.
******************************************************************************/
static bl31_params_t *bl2_to_bl31_params;
+#endif
/*******************************************************************************
* Return a pointer to the 'entry_point_info' structure of the next image for the
@@ -83,9 +90,22 @@
{
entry_point_info_t *next_image_info;
+#if RESET_TO_BL31
+
+ if (type == NON_SECURE)
+ plat_get_entry_point_info(NON_SECURE, &bl33_entrypoint_info);
+ else
+ plat_get_entry_point_info(SECURE, &bl32_entrypoint_info);
+
next_image_info = (type == NON_SECURE) ?
+ &bl33_entrypoint_info :
+ &bl32_entrypoint_info;
+#else
+ next_image_info = (type == NON_SECURE) ?
bl2_to_bl31_params->bl33_ep_info :
bl2_to_bl31_params->bl32_ep_info;
+#endif
+
/* None of the images on this platform can have 0x0 as the entrypoint */
if (next_image_info->pc)
@@ -108,16 +128,36 @@
void bl31_early_platform_setup(bl31_params_t *from_bl2,
void *plat_params_from_bl2)
{
- assert(from_bl2->h.type == PARAM_BL31);
- assert(from_bl2->h.version >= VERSION_1);
-
- bl2_to_bl31_params = from_bl2;
-
/* Initialize the console to provide early debug support */
console_init(PL011_UART0_BASE);
/* Initialize the platform config for future decision making */
platform_config_setup();
+
+#if RESET_TO_BL31
+ /* There are no parameters from BL2 if BL31 is a reset vector */
+ assert(from_bl2 == NULL);
+ assert(plat_params_from_bl2 == NULL);
+
+
+ /*
+ * Do initial security configuration to allow DRAM/device access. On
+ * Base FVP only DRAM security is programmable (via TrustZone), but
+ * other platforms might have more programmable security devices
+ * present.
+ */
+ plat_security_setup();
+#else
+ /* Check params passed from BL2 should not be NULL,
+ * We are not checking plat_params_from_bl2 as NULL as we are not
+ * using it on FVP
+ */
+ assert(from_bl2 != NULL);
+ assert(from_bl2->h.type == PARAM_BL31);
+ assert(from_bl2->h.version >= VERSION_1);
+
+ bl2_to_bl31_params = from_bl2;
+#endif
}
/*******************************************************************************
@@ -166,6 +206,10 @@
******************************************************************************/
void bl31_plat_arch_setup()
{
+#if RESET_TO_BL31
+ fvp_cci_setup();
+#endif
+
configure_mmu_el3(TZRAM_BASE,
TZRAM_SIZE,
BL31_RO_BASE,
@@ -173,3 +217,38 @@
BL31_COHERENT_RAM_BASE,
BL31_COHERENT_RAM_LIMIT);
}
+
+#if RESET_TO_BL31
+/*******************************************************************************
+ * Generate the entry point info for Non Secure and Secure images
+ * for transferring control from BL31
+ ******************************************************************************/
+void plat_get_entry_point_info(unsigned long target_security,
+ entry_point_info_t *target_entry_info)
+{
+ if (target_security == NON_SECURE) {
+ SET_PARAM_HEAD(target_entry_info,
+ PARAM_EP,
+ VERSION_1,
+ 0);
+ /*
+ * Tell BL31 where the non-trusted software image
+ * is located and the entry state information
+ */
+ target_entry_info->pc = plat_get_ns_image_entrypoint();
+
+ fvp_set_bl33_ep_info(target_entry_info);
+
+ } else {
+ SET_PARAM_HEAD(target_entry_info,
+ PARAM_EP,
+ VERSION_1,
+ 0);
+ if (BL32_BASE != 0) {
+ /* Hard coding entry point to the base of the BL32 */
+ target_entry_info->pc = BL32_BASE;
+ fvp_set_bl32_ep_info(target_entry_info);
+ }
+ }
+}
+#endif