core: add plat_primary_init_early()

Adds plat_primary_init_early() which replaces plat_cpu_reset_late().
plat_cpu_reset_late() was called for each cpu, but
plat_primary_init_early() is only called on the primary cpu.

In practice that's not a problem (except for plat-stm, more on that
later) since all the platform specific plat_cpu_reset_late() only does
something if get_core_pos() returns 0, that is on the primary cpu.

On plat-stm SCR is now updated in plat_cpu_reset_early() instead.

This patch is needed because ASLR may relocate OP-TEE to a virtual base
address which differs from the physical base address. This means that
it's not possible to execute C code before MMU has been enabled.

Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
diff --git a/core/arch/arm/include/kernel/generic_boot.h b/core/arch/arm/include/kernel/generic_boot.h
index a83afe5..24e22e4 100644
--- a/core/arch/arm/include/kernel/generic_boot.h
+++ b/core/arch/arm/include/kernel/generic_boot.h
@@ -64,7 +64,7 @@
 
 /* weak routines eventually overridden by platform */
 void plat_cpu_reset_early(void);
-void plat_cpu_reset_late(void);
+void plat_primary_init_early(void);
 void arm_cl2_config(vaddr_t pl310);
 void arm_cl2_enable(vaddr_t pl310);
 
diff --git a/core/arch/arm/kernel/generic_boot.c b/core/arch/arm/kernel/generic_boot.c
index c6e758c..8fa784a 100644
--- a/core/arch/arm/kernel/generic_boot.c
+++ b/core/arch/arm/kernel/generic_boot.c
@@ -88,10 +88,10 @@
 #endif
 
 /* May be overridden in plat-$(PLATFORM)/main.c */
-__weak void plat_cpu_reset_late(void)
+__weak void plat_primary_init_early(void)
 {
 }
-KEEP_PAGER(plat_cpu_reset_late);
+KEEP_PAGER(plat_primary_init_early);
 
 /* May be overridden in plat-$(PLATFORM)/main.c */
 __weak void main_init_gic(void)
diff --git a/core/arch/arm/kernel/generic_entry_a32.S b/core/arch/arm/kernel/generic_entry_a32.S
index 8217232..4ebacef 100644
--- a/core/arch/arm/kernel/generic_entry_a32.S
+++ b/core/arch/arm/kernel/generic_entry_a32.S
@@ -324,7 +324,7 @@
 #define flush_cpu_semaphores
 #endif
 
-LOCAL_FUNC reset_primary , :
+LOCAL_FUNC reset_primary , :, .identity_map
 UNWIND(	.fnstart)
 UNWIND(	.cantunwind)
 
@@ -437,7 +437,7 @@
 	set_sp
 
 	/* complete ARM secure MP common configuration */
-	bl	plat_cpu_reset_late
+	bl	plat_primary_init_early
 
 	/* Enable Console */
 	bl	console_init
@@ -762,7 +762,7 @@
 
 #else /* defined(CFG_WITH_ARM_TRUSTED_FW) */
 
-LOCAL_FUNC reset_secondary , :
+LOCAL_FUNC reset_secondary , : , .identity_map
 UNWIND(	.fnstart)
 UNWIND(	.cantunwind)
 	ldr	r0, =reset_vect_table
@@ -772,8 +772,6 @@
 
 	set_sp
 
-	bl	plat_cpu_reset_late
-
 #if defined (CFG_BOOT_SECONDARY_REQUEST)
 	/* if L1 is not invalidated before, do it here */
 	mov	r0, #DCACHE_OP_INV
diff --git a/core/arch/arm/plat-imx/main.c b/core/arch/arm/plat-imx/main.c
index c632fa8..20a13fe 100644
--- a/core/arch/arm/plat-imx/main.c
+++ b/core/arch/arm/plat-imx/main.c
@@ -187,13 +187,11 @@
 }
 #endif
 
-void plat_cpu_reset_late(void)
+void plat_primary_init_early(void)
 {
-	if (!get_core_pos()) {
-		/* primary core */
+	/* primary core */
 #if defined(CFG_BOOT_SYNC_CPU)
-		psci_boot_allcpus()
+	psci_boot_allcpus()
 #endif
-		imx_configure_tzasc();
-	}
+	imx_configure_tzasc();
 }
diff --git a/core/arch/arm/plat-imx/pm/cpuidle-imx7d.c b/core/arch/arm/plat-imx/pm/cpuidle-imx7d.c
index 57b559c..2d730e9 100644
--- a/core/arch/arm/plat-imx/pm/cpuidle-imx7d.c
+++ b/core/arch/arm/plat-imx/pm/cpuidle-imx7d.c
@@ -208,7 +208,8 @@
 		 * TODO: Call the Wakeup Late function to restore some
 		 * HW configuration (e.g. TZASC)
 		 */
-		plat_cpu_reset_late();
+		if (!get_core_pos())
+			plat_primary_init_early();
 
 		main_init_gic();
 		gic_inited = 1;
diff --git a/core/arch/arm/plat-imx/pm/imx7_suspend.c b/core/arch/arm/plat-imx/pm/imx7_suspend.c
index 7436cdc..7ba528e 100644
--- a/core/arch/arm/plat-imx/pm/imx7_suspend.c
+++ b/core/arch/arm/plat-imx/pm/imx7_suspend.c
@@ -52,7 +52,8 @@
 		return 0;
 	}
 
-	plat_cpu_reset_late();
+	if (!get_core_pos())
+		plat_primary_init_early();
 
 	sm_restore_unbanked_regs(&nsec->ub_regs);
 
diff --git a/core/arch/arm/plat-ls/main.c b/core/arch/arm/plat-ls/main.c
index 6ad1664..7a99222 100644
--- a/core/arch/arm/plat-ls/main.c
+++ b/core/arch/arm/plat-ls/main.c
@@ -86,44 +86,42 @@
 }
 
 #ifdef CFG_ARM32_core
-void plat_cpu_reset_late(void)
+void plat_primary_init_early(void)
 {
 	vaddr_t addr;
 
-	if (!get_core_pos()) {
 #if defined(CFG_BOOT_SECONDARY_REQUEST)
-		/* set secondary entry address */
-		io_write32(DCFG_BASE + DCFG_SCRATCHRW1,
-			   __compiler_bswap32(TEE_LOAD_ADDR));
+	/* set secondary entry address */
+	io_write32(DCFG_BASE + DCFG_SCRATCHRW1,
+		   __compiler_bswap32(TEE_LOAD_ADDR));
 
-		/* release secondary cores */
-		io_write32(DCFG_BASE + DCFG_CCSR_BRR /* cpu1 */,
-			   __compiler_bswap32(0x1 << 1));
-		dsb();
-		sev();
+	/* release secondary cores */
+	io_write32(DCFG_BASE + DCFG_CCSR_BRR /* cpu1 */,
+		   __compiler_bswap32(0x1 << 1));
+	dsb();
+	sev();
 #endif
 
-		/* configure CSU */
+	/* configure CSU */
 
-		/* first grant all peripherals */
-		for (addr = CSU_BASE + CSU_CSL_START;
-			 addr != CSU_BASE + CSU_CSL_END;
-			 addr += 4)
-			io_write32(addr, __compiler_bswap32(CSU_ACCESS_ALL));
+	/* first grant all peripherals */
+	for (addr = CSU_BASE + CSU_CSL_START;
+		 addr != CSU_BASE + CSU_CSL_END;
+		 addr += 4)
+		io_write32(addr, __compiler_bswap32(CSU_ACCESS_ALL));
 
-		/* restrict key preipherals from NS */
-		io_write32(CSU_BASE + CSU_CSL30,
-			   __compiler_bswap32(CSU_ACCESS_SEC_ONLY));
-		io_write32(CSU_BASE + CSU_CSL37,
-			   __compiler_bswap32(CSU_ACCESS_SEC_ONLY));
+	/* restrict key preipherals from NS */
+	io_write32(CSU_BASE + CSU_CSL30,
+		   __compiler_bswap32(CSU_ACCESS_SEC_ONLY));
+	io_write32(CSU_BASE + CSU_CSL37,
+		   __compiler_bswap32(CSU_ACCESS_SEC_ONLY));
 
-		/* lock the settings */
-		for (addr = CSU_BASE + CSU_CSL_START;
-		     addr != CSU_BASE + CSU_CSL_END;
-		     addr += 4)
-			io_setbits32(addr,
-				     __compiler_bswap32(CSU_SETTING_LOCK));
-	}
+	/* lock the settings */
+	for (addr = CSU_BASE + CSU_CSL_START;
+	     addr != CSU_BASE + CSU_CSL_END;
+	     addr += 4)
+		io_setbits32(addr,
+			     __compiler_bswap32(CSU_SETTING_LOCK));
 }
 #endif
 
diff --git a/core/arch/arm/plat-sam/main.c b/core/arch/arm/plat-sam/main.c
index 7a806bb..070fd53 100644
--- a/core/arch/arm/plat-sam/main.c
+++ b/core/arch/arm/plat-sam/main.c
@@ -381,7 +381,7 @@
 					      ARRAY_SIZE(security_ps_peri_id));
 }
 
-void plat_cpu_reset_late(void)
+void plat_primary_init_early(void)
 {
 	matrix_init();
 }
diff --git a/core/arch/arm/plat-stm/main.c b/core/arch/arm/plat-stm/main.c
index 763c169..c91431b 100644
--- a/core/arch/arm/plat-stm/main.c
+++ b/core/arch/arm/plat-stm/main.c
@@ -127,18 +127,12 @@
 	arm_cl2_invbyway(pl310);
 }
 
-void plat_cpu_reset_late(void)
+void plat_primary_init_early(void)
 {
 	int i;
 
 	assert(!cpu_mmu_enabled());
 
-	/* Allow NSec to Imprecise abort */
-	write_scr(SCR_AW);
-
-	if (get_core_pos())
-		return;
-
 	io_write32(SCU_BASE + SCU_SAC, SCU_SAC_INIT);
 	io_write32(SCU_BASE + SCU_NSAC, SCU_NSAC_INIT);
 	io_write32(SCU_BASE + SCU_FILT_EA, CPU_PORT_FILT_END);
diff --git a/core/arch/arm/plat-stm/tz_a9init.S b/core/arch/arm/plat-stm/tz_a9init.S
index 580f762..ae74763 100644
--- a/core/arch/arm/plat-stm/tz_a9init.S
+++ b/core/arch/arm/plat-stm/tz_a9init.S
@@ -56,6 +56,10 @@
 FUNC plat_cpu_reset_early , :
 UNWIND(	.fnstart)
 
+	/* CPSR.A can be modified in any security state. */
+	mov_imm	r0, SCR_AW
+	write_scr r0
+
 	mov_imm r0, CPU_SCTLR_INIT
 	write_sctlr r0
 
diff --git a/core/arch/arm/plat-sunxi/main.c b/core/arch/arm/plat-sunxi/main.c
index 15b62b8..ee18fe2 100644
--- a/core/arch/arm/plat-sunxi/main.c
+++ b/core/arch/arm/plat-sunxi/main.c
@@ -175,13 +175,10 @@
 #endif
 
 #ifdef ARM32
-void plat_cpu_reset_late(void)
+void plat_primary_init_early(void)
 {
 	assert(!cpu_mmu_enabled());
 
-	if (get_core_pos())
-		return;
-
 	tzpc_init();
 }
 #endif
diff --git a/core/arch/arm/plat-zynq7k/main.c b/core/arch/arm/plat-zynq7k/main.c
index ae0753d..883ff16 100644
--- a/core/arch/arm/plat-zynq7k/main.c
+++ b/core/arch/arm/plat-zynq7k/main.c
@@ -69,43 +69,41 @@
 	return &handlers;
 }
 
-void plat_cpu_reset_late(void)
+void plat_primary_init_early(void)
 {
-	if (!get_core_pos()) {
-		/* primary core */
+	/* primary core */
 #if defined(CFG_BOOT_SECONDARY_REQUEST)
-		/* set secondary entry address and release core */
-		io_write32(SECONDARY_ENTRY_DROP, TEE_LOAD_ADDR);
-		dsb();
-		sev();
+	/* set secondary entry address and release core */
+	io_write32(SECONDARY_ENTRY_DROP, TEE_LOAD_ADDR);
+	dsb();
+	sev();
 #endif
 
-		/* SCU config */
-		io_write32(SCU_BASE + SCU_INV_SEC, SCU_INV_CTRL_INIT);
-		io_write32(SCU_BASE + SCU_SAC, SCU_SAC_CTRL_INIT);
-		io_write32(SCU_BASE + SCU_NSAC, SCU_NSAC_CTRL_INIT);
+	/* SCU config */
+	io_write32(SCU_BASE + SCU_INV_SEC, SCU_INV_CTRL_INIT);
+	io_write32(SCU_BASE + SCU_SAC, SCU_SAC_CTRL_INIT);
+	io_write32(SCU_BASE + SCU_NSAC, SCU_NSAC_CTRL_INIT);
 
-		/* SCU enable */
-		io_setbits32(SCU_BASE + SCU_CTRL, 0x1);
+	/* SCU enable */
+	io_setbits32(SCU_BASE + SCU_CTRL, 0x1);
 
-		/* NS Access control */
-		io_write32(SECURITY2_SDIO0, ACCESS_BITS_ALL);
-		io_write32(SECURITY3_SDIO1, ACCESS_BITS_ALL);
-		io_write32(SECURITY4_QSPI, ACCESS_BITS_ALL);
-		io_write32(SECURITY6_APB_SLAVES, ACCESS_BITS_ALL);
+	/* NS Access control */
+	io_write32(SECURITY2_SDIO0, ACCESS_BITS_ALL);
+	io_write32(SECURITY3_SDIO1, ACCESS_BITS_ALL);
+	io_write32(SECURITY4_QSPI, ACCESS_BITS_ALL);
+	io_write32(SECURITY6_APB_SLAVES, ACCESS_BITS_ALL);
 
-		io_write32(SLCR_UNLOCK_MAGIC, SLCR_UNLOCK);
+	io_write32(SLCR_UNLOCK_MAGIC, SLCR_UNLOCK);
 
-		io_write32(SLCR_TZ_DDR_RAM, ACCESS_BITS_ALL);
-		io_write32(SLCR_TZ_DMA_NS, ACCESS_BITS_ALL);
-		io_write32(SLCR_TZ_DMA_IRQ_NS, ACCESS_BITS_ALL);
-		io_write32(SLCR_TZ_DMA_PERIPH_NS, ACCESS_BITS_ALL);
-		io_write32(SLCR_TZ_GEM, ACCESS_BITS_ALL);
-		io_write32(SLCR_TZ_SDIO, ACCESS_BITS_ALL);
-		io_write32(SLCR_TZ_USB, ACCESS_BITS_ALL);
+	io_write32(SLCR_TZ_DDR_RAM, ACCESS_BITS_ALL);
+	io_write32(SLCR_TZ_DMA_NS, ACCESS_BITS_ALL);
+	io_write32(SLCR_TZ_DMA_IRQ_NS, ACCESS_BITS_ALL);
+	io_write32(SLCR_TZ_DMA_PERIPH_NS, ACCESS_BITS_ALL);
+	io_write32(SLCR_TZ_GEM, ACCESS_BITS_ALL);
+	io_write32(SLCR_TZ_SDIO, ACCESS_BITS_ALL);
+	io_write32(SLCR_TZ_USB, ACCESS_BITS_ALL);
 
-		io_write32(SLCR_LOCK, SLCR_LOCK_MAGIC);
-	}
+	io_write32(SLCR_LOCK, SLCR_LOCK_MAGIC);
 }
 
 void console_init(void)