Merge "Use constant stack size with RECLAIM_INIT_CODE" into integration
diff --git a/include/plat/arm/common/arm_reclaim_init.ld.S b/include/plat/arm/common/arm_reclaim_init.ld.S
index e4d4f12..717f65e 100644
--- a/include/plat/arm/common/arm_reclaim_init.ld.S
+++ b/include/plat/arm/common/arm_reclaim_init.ld.S
@@ -14,54 +14,30 @@
             __INIT_CODE_START__ = .;
 	    *(*text.init*);
             __INIT_CODE_END__ = .;
+            INIT_CODE_END_ALIGNED = ALIGN(PAGE_SIZE);
         } >RAM
 
 #ifdef BL31_PROGBITS_LIMIT
     ASSERT(__INIT_CODE_END__ <= BL31_PROGBITS_LIMIT,
             "BL31 init has exceeded progbits limit.")
 #endif
-
-    ASSERT(__INIT_CODE_END__ <= __STACKS_END__,
-        "Init code ends past the end of the stacks")
-
 }
 
-#undef	MIN
 #define	ABS		ABSOLUTE
-#define	COUNT		PLATFORM_CORE_COUNT
-#define	ALIGN_MASK	~(CACHE_WRITEBACK_GRANULE - 1)
-
-#define PRIMARY_STACK							\
-	__STACKS_START__ = .;						\
-	*(tzfw_normal_stacks)						\
-	OFFSET = ABS(SIZEOF(.init) - (. - __STACKS_START__));		\
-	/* Offset sign */						\
-	SIGN = ABS(OFFSET) & (1 << 63);					\
-	/* Offset mask */						\
-	MASK = ABS(SIGN >> 63) - 1;					\
-	. +=  ABS(OFFSET) & ABS(MASK);					\
-	.  = ALIGN(PAGE_SIZE);						\
-	__STACKS_END__ = .;						\
-	/* Total stack size */						\
-	SIZE = ABS(. - __STACKS_START__);				\
-	/* Maximum primary CPU stack */					\
-	STACK = ABS(__STACKS_START__ + SIZE / COUNT) & ALIGN_MASK;	\
-	/* Primary CPU stack */						\
-	__PRIMARY_STACK__ = MIN(STACK, ABS(__INIT_CODE_START__));
 
-#if (COUNT > 1)
-#define	SECONDARY_STACK					\
-	/* Size of the secondary CPUs' stack */		\
-	REST = ABS(__STACKS_END__ - __PRIMARY_STACK__);	\
-	/* Secondary per-CPU stack size */		\
-	__STACK_SIZE__ = ABS(REST / (COUNT - 1));
-#else
-#define	SECONDARY_STACK
-#endif
-
-#define STACK_SECTION		\
-	stacks (NOLOAD) : {	\
-		PRIMARY_STACK	\
-		SECONDARY_STACK	\
+#define STACK_SECTION							\
+	stacks (NOLOAD) : {						\
+		__STACKS_START__ = .;					\
+		*(tzfw_normal_stacks)					\
+		__STACKS_END__ = .;					\
+		/* Allow room for the init section where necessary. */	\
+		OFFSET = ABS(SIZEOF(.init) - (. - __STACKS_START__));	\
+		/* Offset sign */					\
+		SIGN = ABS(OFFSET) & (1 << 63);				\
+		/* Offset mask */					\
+		MASK = ABS(SIGN >> 63) - 1;				\
+		. +=  ABS(OFFSET) & ABS(MASK);				\
+		.  = ALIGN(PAGE_SIZE);					\
 	}
+
 #endif /* ARM_RECLAIM_INIT_LD_S */
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index fc238b1..81ef6e7 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -47,9 +47,12 @@
 #if RECLAIM_INIT_CODE
 IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE);
 IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_CODE_END_UNALIGNED);
+IMPORT_SYM(unsigned long, __STACKS_END__, BL_STACKS_END_UNALIGNED);
 
 #define	BL_INIT_CODE_END	((BL_CODE_END_UNALIGNED + PAGE_SIZE - 1) & \
 					~(PAGE_SIZE - 1))
+#define	BL_STACKS_END		((BL_STACKS_END_UNALIGNED + PAGE_SIZE - 1) & \
+					~(PAGE_SIZE - 1))
 
 #define MAP_BL_INIT_CODE	MAP_REGION_FLAT(			\
 					BL_INIT_CODE_BASE,		\
@@ -291,14 +294,39 @@
 
 #if RECLAIM_INIT_CODE
 /*
- * Zero out and make RW memory used to store image boot time code so it can
- * be reclaimed during runtime
+ * Make memory for image boot time code RW to reclaim it as stack for the
+ * secondary cores, or RO where it cannot be reclaimed:
+ *
+ *            |-------- INIT SECTION --------|
+ *  -----------------------------------------
+ * |  CORE 0  |  CORE 1  |  CORE 2  | EXTRA  |
+ * |  STACK   |  STACK   |  STACK   | SPACE  |
+ *  -----------------------------------------
+ *             <-------------------> <------>
+ *                MAKE RW AND XN       MAKE
+ *                  FOR STACKS       RO AND XN
  */
 void arm_free_init_memory(void)
 {
-	int ret = xlat_change_mem_attributes(BL_INIT_CODE_BASE,
+	int ret = 0;
+
+	if (BL_STACKS_END < BL_INIT_CODE_END) {
+		/* Reclaim some of the init section as stack if possible. */
+		if (BL_INIT_CODE_BASE < BL_STACKS_END) {
+			ret |= xlat_change_mem_attributes(BL_INIT_CODE_BASE,
+					BL_STACKS_END - BL_INIT_CODE_BASE,
+					MT_RW_DATA);
+		}
+		/* Make the rest of the init section read-only. */
+		ret |= xlat_change_mem_attributes(BL_STACKS_END,
+				BL_INIT_CODE_END - BL_STACKS_END,
+				MT_RO_DATA);
+	} else {
+		/* The stacks cover the init section, so reclaim it all. */
+		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");
diff --git a/plat/common/aarch64/platform_mp_stack.S b/plat/common/aarch64/platform_mp_stack.S
index ee0dbb4..c34a4cf 100644
--- a/plat/common/aarch64/platform_mp_stack.S
+++ b/plat/common/aarch64/platform_mp_stack.S
@@ -32,42 +32,9 @@
 	 * -----------------------------------------------------
 	 */
 func plat_get_my_stack
-#if (defined(IMAGE_BL31) && RECLAIM_INIT_CODE)
-#if (PLATFORM_CORE_COUNT == 1)
-	/* Single CPU */
-	adrp	x0, __PRIMARY_STACK__
-	add	x0, x0, :lo12:__PRIMARY_STACK__
-	ret
-#else
-	mov	x10, x30
-	bl	plat_my_core_pos
-	cbnz	x0, 2f
-
-	/* Primary CPU */
-	adrp	x0, __PRIMARY_STACK__
-	add	x0, x0, :lo12:__PRIMARY_STACK__
-	ret	x10
-
-	/* Secondary CPU */
-2:	sub	x0, x0, #(PLATFORM_CORE_COUNT - 1)
-	adrp	x1, __STACKS_END__
-	adrp	x2, __STACK_SIZE__
-	add	x1, x1, :lo12:__STACKS_END__
-	add	x2, x2, :lo12:__STACK_SIZE__
-
-	madd	x0, x0, x2, x1
-	bic	x0, x0, #(CACHE_WRITEBACK_GRANULE - 1)
-	ret	x10
-#endif
-	/* Prevent linker from removal of stack section */
-	.quad	platform_normal_stacks
-
-#else /* !(IMAGE_BL31 && RECLAIM_INIT_CODE) */
 	mov	x10, x30
 	get_my_mp_stack platform_normal_stacks, PLATFORM_STACK_SIZE
 	ret	x10
-
-#endif /* IMAGE_BL31 && RECLAIM_INIT_CODE */
 endfunc plat_get_my_stack
 
 	/* -----------------------------------------------------