CSS: Enable booting of EL3 payloads

This patch adds support for booting EL3 payloads on CSS platforms,
for example Juno. In this scenario, the Trusted Firmware follows
its normal boot flow up to the point where it would normally pass
control to the BL31 image. At this point, it jumps to the EL3
payload entry point address instead.

Before handing over to the EL3 payload, the data SCP writes for AP
at the beginning of the Trusted SRAM is restored, i.e. we zero the
first 128 bytes and restore the SCP Boot configuration. The latter
is saved before transferring the BL30 image to SCP and is restored
just after the transfer (in BL2). The goal is to make it appear that
the EL3 payload is the first piece of software to run on the target.

The BL31 entrypoint info structure is updated to make the primary
CPU jump to the EL3 payload instead of the BL31 image.

The mailbox is populated with the EL3 payload entrypoint address,
which releases the secondary CPUs out of their holding pen (if the
SCP has powered them on). The arm_program_trusted_mailbox() function
has been exported for this purpose.

The TZC-400 configuration in BL2 is simplified: it grants secure
access only to the whole DRAM. Other security initialization is
unchanged.

This alternative boot flow is disabled by default. A new build option
EL3_PAYLOAD_BASE has been introduced to enable it and provide the EL3
payload's entry point address. The build system has been modified
such that BL31 and BL33 are not compiled and/or not put in the FIP in
this case, as those images are not used in this boot flow.

Change-Id: Id2e26fa57988bbc32323a0effd022ab42f5b5077
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index ddf383f..887223c 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -145,6 +145,20 @@
 	arm_bl1_platform_setup();
 }
 
+void bl1_plat_prepare_exit(entry_point_info_t *ep_info)
+{
+#ifdef EL3_PAYLOAD_BASE
+	/*
+	 * Program the EL3 payload's entry point address into the CPUs mailbox
+	 * in order to release secondary CPUs from their holding pen and make
+	 * them jump there.
+	 */
+	arm_program_trusted_mailbox(ep_info->pc);
+	dsbsy();
+	sev();
+#endif
+}
+
 /*******************************************************************************
  * Before calling this function BL2 is loaded in memory and its entrypoint
  * is set by load_image. This is a placeholder for the platform to change
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index eb5ae11..7b23527 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -81,6 +81,11 @@
 				plat/arm/common/arm_bl1_setup.c			\
 				plat/arm/common/arm_io_storage.c		\
 				plat/common/aarch64/platform_up_stack.S
+ifdef EL3_PAYLOAD_BASE
+# Need the arm_program_trusted_mailbox() function to release secondary CPUs from
+# their holding pen
+BL1_SOURCES		+=	plat/arm/common/arm_pm.c
+endif
 
 BL2_SOURCES		+=	drivers/arm/tzc400/tzc400.c			\
 				drivers/io/io_fip.c				\
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index d13d268..cae6597 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -175,7 +175,7 @@
  * from reset. This function assumes that the Trusted mail box base is within
  * the ARM_SHARED_RAM region
  ******************************************************************************/
-static void arm_program_trusted_mailbox(uintptr_t address)
+void arm_program_trusted_mailbox(uintptr_t address)
 {
 	uintptr_t *mailbox = (void *) PLAT_ARM_TRUSTED_MAILBOX_BASE;
 
diff --git a/plat/arm/common/arm_security.c b/plat/arm/common/arm_security.c
index 990d8d4..8b46aae 100644
--- a/plat/arm/common/arm_security.c
+++ b/plat/arm/common/arm_security.c
@@ -40,8 +40,13 @@
 
 /*******************************************************************************
  * Initialize the TrustZone Controller for ARM standard platforms.
- * Configure Region 0 with no access, Region 1 with secure access only, and
- * the remaining DRAM regions access from the given Non-Secure masters.
+ * Configure:
+ *   - Region 0 with no access;
+ *   - Region 1 with secure access only;
+ *   - the remaining DRAM regions access from the given Non-Secure masters.
+ *
+ * When booting an EL3 payload, this is simplified: we configure region 0 with
+ * secure access only and do not enable any other region.
  ******************************************************************************/
 void arm_tzc_setup(void)
 {
@@ -52,6 +57,7 @@
 	/* Disable filters. */
 	tzc_disable_filters();
 
+#ifndef EL3_PAYLOAD_BASE
 	/* Region 0 set to no access by default */
 	tzc_configure_region0(TZC_REGION_S_NONE, 0);
 
@@ -73,6 +79,10 @@
 			ARM_DRAM2_BASE, ARM_DRAM2_END,
 			TZC_REGION_S_NONE,
 			PLAT_ARM_TZC_NS_DEV_ACCESS);
+#else
+	/* Allow secure access only to DRAM for EL3 payloads. */
+	tzc_configure_region0(TZC_REGION_S_RDWR, 0);
+#endif /* EL3_PAYLOAD_BASE */
 
 	/*
 	 * Raise an exception if a NS device tries to access secure memory