FVP: make usage of Trusted DRAM optional at build time

This patch groups the current contents of the Trusted DRAM region at
address 0x00_0600_0000 (entrypoint mailboxes and BL3-1 parameters) in
a single shared memory area that may be allocated to Trusted SRAM
(default) or Trusted DRAM at build time by setting the
FVP_SHARED_DATA_LOCATION make variable. The size of this shared
memory is 4096 bytes.

The combination 'Shared data in Trusted SRAM + TSP in Trusted DRAM'
is not currently supported due to restrictions in the maximum number
of mmu tables that can be created.

Documentation has been updated to reflect these changes.

Fixes ARM-software/tf-issues#100

Change-Id: I26ff04d33ce4cacf8d770d1a1e24132b4fc53ff0
diff --git a/plat/fvp/aarch64/fvp_common.c b/plat/fvp/aarch64/fvp_common.c
index b8f32a1..5041511 100644
--- a/plat/fvp/aarch64/fvp_common.c
+++ b/plat/fvp/aarch64/fvp_common.c
@@ -56,8 +56,8 @@
  * configure_mmu_elx() will give the available subset of that,
  */
 const mmap_region_t fvp_mmap[] = {
-	{ FVP_TRUSTED_ROM_BASE,	FVP_TRUSTED_ROM_BASE,	FVP_TRUSTED_ROM_SIZE,
-						MT_MEMORY | MT_RO | MT_SECURE },
+	{ FVP_SHARED_RAM_BASE,	FVP_SHARED_RAM_BASE,	FVP_SHARED_RAM_SIZE,
+						MT_MEMORY | MT_RW | MT_SECURE },
 	{ FVP_TRUSTED_DRAM_BASE, FVP_TRUSTED_DRAM_BASE,	FVP_TRUSTED_DRAM_SIZE,
 						MT_MEMORY | MT_RW | MT_SECURE },
 	{ FLASH0_BASE,	FLASH0_BASE,	FLASH0_SIZE,
diff --git a/plat/fvp/aarch64/fvp_helpers.S b/plat/fvp/aarch64/fvp_helpers.S
index 4eecd4c..922329c 100644
--- a/plat/fvp/aarch64/fvp_helpers.S
+++ b/plat/fvp/aarch64/fvp_helpers.S
@@ -140,7 +140,7 @@
 	 * its safe to read it here with SO attributes
 	 * ---------------------------------------------
 	 */
-	ldr	x10, =FVP_TRUSTED_DRAM_BASE + MBOX_OFF
+	ldr	x10, =MBOX_BASE
 	bl	platform_get_core_pos
 	lsl	x0, x0, #CACHE_WRITEBACK_SHIFT
 	ldr	x0, [x10, x0]
@@ -153,8 +153,8 @@
 	/* -----------------------------------------------------
 	 * void platform_mem_init (void);
 	 *
-	 * Zero out the mailbox registers in the TZDRAM. The
-	 * mmu is turned off right now and only the primary can
+	 * Zero out the mailbox registers in the shared memory.
+	 * The mmu is turned off right now and only the primary can
 	 * ever execute this code. Secondaries will read the
 	 * mailboxes using SO accesses. In short, BL31 will
 	 * update the mailboxes after mapping the tzdram as
@@ -163,7 +163,7 @@
 	 * -----------------------------------------------------
 	 */
 func platform_mem_init
-	ldr	x0, =FVP_TRUSTED_DRAM_BASE + MBOX_OFF
+	ldr	x0, =MBOX_BASE
 	mov	w1, #PLATFORM_CORE_COUNT
 loop:
 	str	xzr, [x0], #CACHE_WRITEBACK_GRANULE
diff --git a/plat/fvp/bl2_fvp_setup.c b/plat/fvp/bl2_fvp_setup.c
index b200b37..2c26d97 100644
--- a/plat/fvp/bl2_fvp_setup.c
+++ b/plat/fvp/bl2_fvp_setup.c
@@ -72,6 +72,11 @@
 __attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
 		section("tzfw_coherent_mem")));
 
+/* Assert that BL3-1 parameters fit in shared memory */
+CASSERT((PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t)) <
+	(FVP_SHARED_RAM_BASE + FVP_SHARED_RAM_SIZE),
+	assert_bl31_params_do_not_fit_in_shared_memory);
+
 /*******************************************************************************
  * Reference to structures which holds the arguments which need to be passed
  * to BL31
@@ -97,14 +102,6 @@
 {
 	bl2_to_bl31_params_mem_t *bl31_params_mem;
 
-#if FVP_TSP_RAM_LOCATION_ID == FVP_IN_TRUSTED_DRAM
-	/*
-	 * Ensure that the secure DRAM memory used for passing BL31 arguments
-	 * does not overlap with the BL32_BASE.
-	 */
-	assert(BL32_BASE > PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t));
-#endif
-
 	/*
 	 * Allocate the memory for all the arguments that needs to
 	 * be passed to BL31
diff --git a/plat/fvp/fvp_def.h b/plat/fvp/fvp_def.h
index c54537f..b371ea9 100644
--- a/plat/fvp/fvp_def.h
+++ b/plat/fvp/fvp_def.h
@@ -74,10 +74,27 @@
 #define NSRAM_BASE		0x2e000000
 #define NSRAM_SIZE		0x10000
 
-#define MBOX_OFF		0x1000
+/* 4KB shared memory */
+#define FVP_SHARED_RAM_SIZE	0x1000
 
-/* Base address where parameters to BL31 are stored */
-#define PARAMS_BASE		FVP_TRUSTED_DRAM_BASE
+/* Location of shared memory */
+#if (FVP_SHARED_DATA_LOCATION_ID == FVP_IN_TRUSTED_DRAM)
+/* Shared memory at the base of Trusted DRAM */
+# define FVP_SHARED_RAM_BASE		FVP_TRUSTED_DRAM_BASE
+# define FVP_TRUSTED_SRAM_LIMIT		(FVP_TRUSTED_SRAM_BASE \
+					+ FVP_TRUSTED_SRAM_SIZE)
+#elif (FVP_SHARED_DATA_LOCATION_ID == FVP_IN_TRUSTED_SRAM)
+# if (FVP_TSP_RAM_LOCATION_ID == FVP_IN_TRUSTED_DRAM)
+#  error "Shared data in Trusted SRAM and TSP in Trusted DRAM is not supported"
+# endif
+/* Shared memory at the top of the Trusted SRAM */
+# define FVP_SHARED_RAM_BASE		(FVP_TRUSTED_SRAM_BASE \
+					+ FVP_TRUSTED_SRAM_SIZE \
+					- FVP_SHARED_RAM_SIZE)
+# define FVP_TRUSTED_SRAM_LIMIT		FVP_SHARED_RAM_BASE
+#else
+# error "Unsupported FVP_SHARED_DATA_LOCATION_ID value"
+#endif
 
 #define DRAM1_BASE		0x80000000ull
 #define DRAM1_SIZE		0x80000000ull
@@ -239,4 +256,15 @@
 #define FVP_NSAID_HDLCD0		2
 #define FVP_NSAID_CLCD			7
 
+/*******************************************************************************
+ *  Shared Data
+ ******************************************************************************/
+
+/* Entrypoint mailboxes */
+#define MBOX_BASE		FVP_SHARED_RAM_BASE
+#define MBOX_SIZE		0x200
+
+/* Base address where parameters to BL31 are stored */
+#define PARAMS_BASE		(MBOX_BASE + MBOX_SIZE)
+
 #endif /* __FVP_DEF_H__ */
diff --git a/plat/fvp/fvp_pm.c b/plat/fvp/fvp_pm.c
index 775e558..82a663b 100644
--- a/plat/fvp/fvp_pm.c
+++ b/plat/fvp/fvp_pm.c
@@ -103,7 +103,7 @@
 	} while (psysr & PSYSR_AFF_L0);
 
 	linear_id = platform_get_core_pos(mpidr);
-	fvp_mboxes = (mailbox_t *) (FVP_TRUSTED_DRAM_BASE + MBOX_OFF);
+	fvp_mboxes = (mailbox_t *)MBOX_BASE;
 	fvp_mboxes[linear_id].value = sec_entrypoint;
 	flush_dcache_range((unsigned long) &fvp_mboxes[linear_id],
 			   sizeof(unsigned long));
@@ -240,8 +240,7 @@
 
 			/* Program the jump address for the target cpu */
 			linear_id = platform_get_core_pos(mpidr);
-			fvp_mboxes = (mailbox_t *) (FVP_TRUSTED_DRAM_BASE +
-					MBOX_OFF);
+			fvp_mboxes = (mailbox_t *)MBOX_BASE;
 			fvp_mboxes[linear_id].value = sec_entrypoint;
 			flush_dcache_range((unsigned long) &fvp_mboxes[linear_id],
 					   sizeof(unsigned long));
@@ -330,8 +329,7 @@
 		fvp_pwrc_clr_wen(mpidr);
 
 		/* Zero the jump address in the mailbox for this cpu */
-		fvp_mboxes = (mailbox_t *) (FVP_TRUSTED_DRAM_BASE +
-				MBOX_OFF);
+		fvp_mboxes = (mailbox_t *)MBOX_BASE;
 		linear_id = platform_get_core_pos(mpidr);
 		fvp_mboxes[linear_id].value = 0;
 		flush_dcache_range((unsigned long) &fvp_mboxes[linear_id],
diff --git a/plat/fvp/include/platform_def.h b/plat/fvp/include/platform_def.h
index 3b94c42..79d789d 100644
--- a/plat/fvp/include/platform_def.h
+++ b/plat/fvp/include/platform_def.h
@@ -83,14 +83,12 @@
 #define BL1_RO_LIMIT			(FVP_TRUSTED_ROM_BASE \
 					+ FVP_TRUSTED_ROM_SIZE)
 /*
- * Put BL1 RW at the top of the Trusted SRAM. BL1_RW_BASE is calculated using
- * the current BL1 RW debug size plus a little space for growth.
+ * Put BL1 RW at the top of the Trusted SRAM (just below the shared memory, if
+ * present). BL1_RW_BASE is calculated using the current BL1 RW debug size plus
+ * a little space for growth.
  */
-#define BL1_RW_BASE			(FVP_TRUSTED_SRAM_BASE + \
-					 FVP_TRUSTED_SRAM_SIZE - \
-					 0x6000)
-#define BL1_RW_LIMIT			(FVP_TRUSTED_SRAM_BASE + \
-					 FVP_TRUSTED_SRAM_SIZE)
+#define BL1_RW_BASE			(FVP_TRUSTED_SRAM_LIMIT - 0x6000)
+#define BL1_RW_LIMIT			FVP_TRUSTED_SRAM_LIMIT
 
 /*******************************************************************************
  * BL2 specific defines.
@@ -106,15 +104,13 @@
  * BL31 specific defines.
  ******************************************************************************/
 /*
- * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the
- * current BL3-1 debug size plus a little space for growth.
+ * Put BL3-1 at the top of the Trusted SRAM (just below the shared memory, if
+ * present). BL31_BASE is calculated using the current BL3-1 debug size plus a
+ * little space for growth.
  */
-#define BL31_BASE			(FVP_TRUSTED_SRAM_BASE + \
-					 FVP_TRUSTED_SRAM_SIZE - \
-					 0x1D000)
+#define BL31_BASE			(FVP_TRUSTED_SRAM_LIMIT - 0x1D000)
 #define BL31_PROGBITS_LIMIT		BL1_RW_BASE
-#define BL31_LIMIT			(FVP_TRUSTED_SRAM_BASE + \
-					 FVP_TRUSTED_SRAM_SIZE)
+#define BL31_LIMIT			FVP_TRUSTED_SRAM_LIMIT
 
 /*******************************************************************************
  * BL32 specific defines.
@@ -131,7 +127,8 @@
 #elif FVP_TSP_RAM_LOCATION_ID == FVP_IN_TRUSTED_DRAM
 # define TSP_SEC_MEM_BASE		FVP_TRUSTED_DRAM_BASE
 # define TSP_SEC_MEM_SIZE		FVP_TRUSTED_DRAM_SIZE
-# define BL32_BASE			(FVP_TRUSTED_DRAM_BASE + 0x2000)
+# define BL32_BASE			(FVP_TRUSTED_DRAM_BASE \
+					+ FVP_SHARED_RAM_SIZE)
 # define BL32_LIMIT			(FVP_TRUSTED_DRAM_BASE + (1 << 21))
 #else
 # error "Unsupported FVP_TSP_RAM_LOCATION_ID value"
diff --git a/plat/fvp/platform.mk b/plat/fvp/platform.mk
index 945a300..8a33a60 100644
--- a/plat/fvp/platform.mk
+++ b/plat/fvp/platform.mk
@@ -28,6 +28,17 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
+# Shared memory may be allocated at the top of Trusted SRAM (tsram) or at the
+# base of Trusted SRAM (tdram)
+FVP_SHARED_DATA_LOCATION	:=	tsram
+ifeq (${FVP_SHARED_DATA_LOCATION}, tsram)
+  FVP_SHARED_DATA_LOCATION_ID := FVP_IN_TRUSTED_SRAM
+else ifeq (${FVP_SHARED_DATA_LOCATION}, tdram)
+  FVP_SHARED_DATA_LOCATION_ID := FVP_IN_TRUSTED_DRAM
+else
+  $(error "Unsupported FVP_SHARED_DATA_LOCATION value")
+endif
+
 # On FVP, the TSP can execute either from Trusted SRAM or Trusted DRAM.
 # Trusted SRAM is the default.
 FVP_TSP_RAM_LOCATION	:=	tsram
@@ -39,7 +50,14 @@
   $(error "Unsupported FVP_TSP_RAM_LOCATION value")
 endif
 
+ifeq (${FVP_SHARED_DATA_LOCATION}, tsram)
+  ifeq (${FVP_TSP_RAM_LOCATION}, tdram)
+    $(error Shared data in Trusted SRAM and TSP in Trusted DRAM is not supported)
+  endif
+endif
+
 # Process flags
+$(eval $(call add_define,FVP_SHARED_DATA_LOCATION_ID))
 $(eval $(call add_define,FVP_TSP_RAM_LOCATION_ID))
 
 PLAT_INCLUDES		:=	-Iplat/fvp/include/