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