cactus: secondary core cold boot

Provision a cold boot path for secondary cores (or secondary pinned
execution contexts). The primary cold boot path is traversed by the
first execution context for each SP at boot time. The secondary cold
boot path is run upon invocation of PSCI_CPU_ON from the normal world
for the first SP. Or through a first ffa_run invocation for other SPs.

Change-Id: I7accd8ffa8b9ca8c10ee3515a24edd1bb47ff121
Signed-off-by: Max Shvetsov <maksims.svecovs@arm.com>
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c
index 7e3f40b..e54f3b0 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -13,6 +13,7 @@
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
 #include <lib/aarch64/arch_helpers.h>
+#include <lib/tftf_lib.h>
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat_arm.h>
@@ -29,6 +30,8 @@
 extern const char build_message[];
 extern const char version_string[];
 
+extern void secondary_cold_entry(void);
+
 /*
  *
  * Message loop function
@@ -147,6 +150,16 @@
 	init_xlat_tables();
 }
 
+static void register_secondary_entrypoint(void)
+{
+	smc_args args;
+
+	args.fid = FFA_SECONDARY_EP_REGISTER_SMC64;
+	args.arg1 = (u_register_t)&secondary_cold_entry;
+
+	tftf_smc(&args);
+}
+
 int tftf_irq_handler_dispatcher(void)
 {
 	ERROR("%s\n", __func__);
@@ -154,31 +167,39 @@
 	return 0;
 }
 
-void __dead2 cactus_main(void)
+void __dead2 cactus_main(bool primary_cold_boot)
 {
 	assert(IS_IN_EL1() != 0);
 
 	struct mailbox_buffers mb;
 
-	/* Clear BSS */
-	memset((void *)CACTUS_BSS_START,
-	       0, CACTUS_BSS_END - CACTUS_BSS_START);
-
 	/* Get current FFA id */
 	smc_ret_values ffa_id_ret = ffa_id_get();
 	if (ffa_func_id(ffa_id_ret) != FFA_SUCCESS_SMC32) {
 		ERROR("FFA_ID_GET failed.\n");
 		panic();
 	}
-
 	ffa_vm_id_t ffa_id = ffa_id_ret.ret2 & 0xffff;
-	mb.send = (void *) get_sp_tx_start(ffa_id);
-	mb.recv = (void *) get_sp_rx_start(ffa_id);
 
-	/* Configure and enable Stage-1 MMU, enable D-Cache */
-	cactus_plat_configure_mmu(ffa_id);
+	if (primary_cold_boot == true) {
+		/* Clear BSS */
+		memset((void *)CACTUS_BSS_START,
+		       0, CACTUS_BSS_END - CACTUS_BSS_START);
+
+
+		mb.send = (void *) get_sp_tx_start(ffa_id);
+		mb.recv = (void *) get_sp_rx_start(ffa_id);
+
+		/* Configure and enable Stage-1 MMU, enable D-Cache */
+		cactus_plat_configure_mmu(ffa_id);
+	}
+
 	enable_mmu_el1(0);
 
+	if (primary_cold_boot == false) {
+		goto msg_loop;
+	}
+
 	if (ffa_id == SPM_VM_ID_FIRST) {
 		console_init(CACTUS_PL011_UART_BASE,
 			     CACTUS_PL011_UART_CLK_IN_HZ,
@@ -210,9 +231,12 @@
 	INFO("FF-A id: %x\n", ffa_id);
 	cactus_print_memory_layout(ffa_id);
 
+	register_secondary_entrypoint();
+
 	/* Invoking Tests */
 	ffa_tests(&mb);
 
+msg_loop:
 	/* End up to message loop */
 	message_loop(ffa_id, &mb);