FVP: Reclaim init code for the stack

Map the initialization code for BL31 to overlap with the memory
required for the secondary cores stack. Once BL31 has been
initialized the memory can be remapped to RW data so that it can
be used for secondary cores stacks. By moving code from .text to
.text.init the size of the BL31 image is decreased by a page.

Split arm_common.ld.S into two linker scripts, one for tzc_dram
(arm_tzc_dram.ld.S) and one for reclaiming initialization code
(arm_reclaim_init.ld.S) so that platforms can chose which memory
regions they wish to include.

Change-Id: I648e88f3eda1aa71765744cf34343ecda9320b32
Signed-off-by: Daniel Boulby <daniel.boulby@arm.com>
diff --git a/plat/arm/board/fvp/include/plat.ld.S b/plat/arm/board/fvp/include/plat.ld.S
index 24c3deb..f2a3ea6 100644
--- a/plat/arm/board/fvp/include/plat.ld.S
+++ b/plat/arm/board/fvp/include/plat.ld.S
@@ -6,6 +6,7 @@
 #ifndef __PLAT_LD_S__
 #define __PLAT_LD_S__
 
-#include <arm_common.ld.S>
+#include <arm_tzc_dram.ld.S>
+#include <arm_reclaim_init.ld.S>
 
 #endif /* __PLAT_LD_S__ */
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 4cd6a24..9bd3bde 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -201,6 +201,9 @@
 # Enable dynamic mitigation support by default
 DYNAMIC_WORKAROUND_CVE_2018_3639	:=	1
 
+# Enable reclaiming of BL31 initialisation code for secondary cores stacks for FVP
+RECLAIM_INIT_CODE	:=	1
+
 ifeq (${ENABLE_AMU},1)
 BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a75_pubsub.c	\
 				lib/cpus/aarch64/cortex_ares_pubsub.c	\
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index c545663..ed2c3fb 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -15,6 +15,8 @@
 #include <plat_arm.h>
 #include <platform.h>
 #include <ras.h>
+#include <utils.h>
+#include <arm_xlat_tables.h>
 
 /*
  * Placeholder variables for copying the arguments that have been passed to
@@ -35,10 +37,20 @@
 #pragma weak bl31_plat_arch_setup
 #pragma weak bl31_plat_get_next_image_ep_info
 
-#define MAP_BL31_TOTAL	MAP_REGION_FLAT(			\
+#define MAP_BL31_TOTAL		MAP_REGION_FLAT(			\
 					BL31_BASE,			\
 					BL31_END - BL31_BASE,		\
 					MT_MEMORY | MT_RW | MT_SECURE)
+#if RECLAIM_INIT_CODE
+IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE);
+IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END);
+
+#define MAP_BL_INIT_CODE	MAP_REGION_FLAT(			\
+					BL_INIT_CODE_BASE,		\
+					BL_INIT_CODE_END		\
+						- BL_INIT_CODE_BASE,	\
+					MT_CODE | MT_SECURE)
+#endif
 
 /*******************************************************************************
  * Return a pointer to the 'entry_point_info' structure of the next image for the
@@ -233,8 +245,29 @@
 
 	/* Initialize the runtime console */
 	arm_console_runtime_init();
+#if RECLAIM_INIT_CODE
+	arm_free_init_memory();
+#endif
 }
 
+#if RECLAIM_INIT_CODE
+/*
+ * Zero out and make RW memory used to store image boot time code so it can
+ * be reclaimed during runtime
+ */
+void arm_free_init_memory(void)
+{
+	int ret = xlat_change_mem_attributes(BL_INIT_CODE_BASE,
+				BL_INIT_CODE_END - BL_INIT_CODE_BASE,
+				MT_RW_DATA);
+
+	if (ret != 0) {
+		ERROR("Could not reclaim initialization code");
+		panic();
+	}
+}
+#endif
+
 void __init bl31_platform_setup(void)
 {
 	arm_bl31_platform_setup();
@@ -255,6 +288,9 @@
 {
 	const mmap_region_t bl_regions[] = {
 		MAP_BL31_TOTAL,
+#if RECLAIM_INIT_CODE
+		MAP_BL_INIT_CODE,
+#endif
 		ARM_MAP_BL_RO,
 #if USE_ROMLIB
 		ARM_MAP_ROMLIB_CODE,
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index ae06ef2..a21d189 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -38,6 +38,7 @@
  * as an array specifying the generic memory regions which can be;
  * - Code section;
  * - Read-only data section;
+ * - Init code section, if applicable
  * - Coherent memory region, if applicable.
  */
 
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index a8df5ba..276f780 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -273,3 +273,14 @@
     include ${IMG_PARSER_LIB_MK}
 
 endif
+
+# RECLAIM_INIT_CODE can only be set when LOAD_IMAGE_V2=2 and xlat tables v2
+# are used
+ifeq (${RECLAIM_INIT_CODE}, 1)
+    ifeq (${LOAD_IMAGE_V2}, 0)
+        $(error "LOAD_IMAGE_V2 must be enabled to use RECLAIM_INIT_CODE")
+    endif
+    ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
+        $(error "To reclaim init code xlat tables v2 must be used")
+    endif
+endif