ARM platforms: Add support for EL3 TZC memory region

Some recent enhancements to EL3 runtime firmware like support for
save and restoring GICv3 register context during system_suspend
necessitates additional data memory for the firmware. This patch
introduces support for creating a TZC secured DDR carveout for use
by ARM reference platforms. A new linker section `el3_tzc_dram` is
created using platform supplied linker script and data marked with
the attribute `arm_el3_tzc_dram` will be placed in this section.
The FVP makefile now defines the `PLAT_EXTRA_LD_SCRIPT` variable to
allow inclusion of the platform linker script by the top level BL31
linker script.

Change-Id: I0e7f4a75a6ac51419c667875ff2677043df1585d
Signed-off-by: Soby Mathew <soby.mathew@arm.com>
diff --git a/include/plat/arm/common/arm_common.ld.S b/include/plat/arm/common/arm_common.ld.S
new file mode 100644
index 0000000..478b08c
--- /dev/null
+++ b/include/plat/arm/common/arm_common.ld.S
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef __ARM_COMMON_LD_S__
+#define __ARM_COMMON_LD_S__
+
+MEMORY {
+    EL3_SEC_DRAM (rw): ORIGIN = ARM_EL3_TZC_DRAM1_BASE, LENGTH = ARM_EL3_TZC_DRAM1_SIZE
+}
+
+SECTIONS
+{
+	. = ARM_EL3_TZC_DRAM1_BASE;
+	ASSERT(. == ALIGN(4096),
+	"ARM_EL3_TZC_DRAM_BASE address is not aligned on a page boundary.")
+	el3_tzc_dram (NOLOAD) : ALIGN(4096) {
+	__EL3_SEC_DRAM_START__ = .;
+	*(arm_el3_tzc_dram)
+	__EL3_SEC_DRAM_UNALIGNED_END__ = .;
+
+	. = NEXT(4096);
+	__EL3_SEC_DRAM_END__ = .;
+	} >EL3_SEC_DRAM
+}
+
+#endif /* __ARM_COMMON_LD_S__ */
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index dbf102b..8ae820a 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -75,11 +75,23 @@
 #define ARM_SCP_TZC_DRAM1_END		(ARM_SCP_TZC_DRAM1_BASE +	\
 					 ARM_SCP_TZC_DRAM1_SIZE - 1)
 
+/*
+ * Define a 2MB region within the TZC secured DRAM for use by EL3 runtime
+ * firmware. This region is meant to be NOLOAD and will not be zero
+ * initialized. Data sections with the attribute `arm_el3_tzc_dram` will be
+ * placed here.
+ */
+#define ARM_EL3_TZC_DRAM1_BASE		(ARM_SCP_TZC_DRAM1_BASE - ARM_EL3_TZC_DRAM1_SIZE)
+#define ARM_EL3_TZC_DRAM1_SIZE		ULL(0x00200000) /* 2 MB */
+#define ARM_EL3_TZC_DRAM1_END		(ARM_EL3_TZC_DRAM1_BASE +	\
+					ARM_EL3_TZC_DRAM1_SIZE - 1)
+
 #define ARM_AP_TZC_DRAM1_BASE		(ARM_DRAM1_BASE +		\
 					 ARM_DRAM1_SIZE -		\
 					 ARM_TZC_DRAM1_SIZE)
 #define ARM_AP_TZC_DRAM1_SIZE		(ARM_TZC_DRAM1_SIZE -		\
-					 ARM_SCP_TZC_DRAM1_SIZE)
+					 (ARM_SCP_TZC_DRAM1_SIZE +	\
+					 ARM_EL3_TZC_DRAM1_SIZE))
 #define ARM_AP_TZC_DRAM1_END		(ARM_AP_TZC_DRAM1_BASE +	\
 					 ARM_AP_TZC_DRAM1_SIZE - 1)
 
@@ -196,6 +208,11 @@
 						MT_MEMORY | MT_RW | MT_SECURE)
 #endif
 
+#define ARM_MAP_EL3_TZC_DRAM		MAP_REGION_FLAT(			\
+						ARM_EL3_TZC_DRAM1_BASE,	\
+						ARM_EL3_TZC_DRAM1_SIZE,	\
+						MT_MEMORY | MT_RW | MT_SECURE)
+
 /*
  * The number of regions like RO(code), coherent and data required by
  * different BL stages which need to be mapped in the MMU.
diff --git a/plat/arm/board/fvp/include/plat.ld.S b/plat/arm/board/fvp/include/plat.ld.S
new file mode 100644
index 0000000..24c3deb
--- /dev/null
+++ b/plat/arm/board/fvp/include/plat.ld.S
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef __PLAT_LD_S__
+#define __PLAT_LD_S__
+
+#include <arm_common.ld.S>
+
+#endif /* __PLAT_LD_S__ */
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 29da12e..1b50296 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -155,5 +155,8 @@
     NEED_BL32 := yes
 endif
 
+# Add support for platform supplied linker script for BL31 build
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+
 include plat/arm/board/common/board_common.mk
 include plat/arm/common/arm_common.mk
diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c
index 1d61c57..e19ca67 100644
--- a/plat/arm/common/arm_tzc400.c
+++ b/plat/arm/common/arm_tzc400.c
@@ -40,7 +40,7 @@
 
 	/* Region 1 set to cover Secure part of DRAM */
 	tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 1,
-			ARM_AP_TZC_DRAM1_BASE, ARM_AP_TZC_DRAM1_END,
+			ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END,
 			TZC_REGION_S_RDWR,
 			0);
 
diff --git a/plat/arm/common/arm_tzc_dmc500.c b/plat/arm/common/arm_tzc_dmc500.c
index 21ca4e8..8e41391 100644
--- a/plat/arm/common/arm_tzc_dmc500.c
+++ b/plat/arm/common/arm_tzc_dmc500.c
@@ -33,7 +33,7 @@
 
 	/* Region 1 set to cover Secure part of DRAM */
 	tzc_dmc500_configure_region(1, ARM_AP_TZC_DRAM1_BASE,
-		ARM_AP_TZC_DRAM1_END,
+		ARM_EL3_TZC_DRAM1_END,
 		TZC_REGION_S_RDWR,
 		0);