feat(el3-spmc): add support to handle power mgmt calls for s-el0 sp

Add support to setup S-EL0 SP context during power management power on
procedure. In case of power on, initialise the context data structure
for the secure world on the current CPU.
The S-EL0 SP does not support power message. Add the check to make
sure that it does not subscribe to any power messages.

Signed-off-by: Achin Gupta <achin.gupta@arm.com>
Signed-off-by: Nishant Sharma <nishant.sharma@arm.com>
Change-Id: Ic9cf98cd15b6ee5d86d071a52bc0973677049df3
diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
index 42747bf..7978f08 100644
--- a/services/std_svc/spm/el3_spmc/spmc_main.c
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -1902,6 +1902,11 @@
 	if (ret != 0) {
 		WARN("Missing Power Management Messages entry.\n");
 	} else {
+		if ((sp->runtime_el == S_EL0) && (config_32 != 0)) {
+			ERROR("Power messages not supported for S-EL0 SP\n");
+			return -EINVAL;
+		}
+
 		/*
 		 * Ensure only the currently supported power messages have
 		 * been requested.
diff --git a/services/std_svc/spm/el3_spmc/spmc_pm.c b/services/std_svc/spm/el3_spmc/spmc_pm.c
index c7e864f..517d6d5 100644
--- a/services/std_svc/spm/el3_spmc/spmc_pm.c
+++ b/services/std_svc/spm/el3_spmc/spmc_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,7 +36,7 @@
 }
 
 /*******************************************************************************
- * This CPU has been turned on. Enter the SP to initialise S-EL1.
+ * This CPU has been turned on. Enter the SP to initialise S-EL0 or S-EL1.
  ******************************************************************************/
 static void spmc_cpu_on_finish_handler(u_register_t unused)
 {
@@ -49,6 +49,19 @@
 	/* Sanity check for a NULL pointer dereference. */
 	assert(sp != NULL);
 
+	/* Obtain a reference to the SP execution context */
+	ec = &sp->ec[get_ec_index(sp)];
+
+	/*
+	 * In case of a S-EL0 SP, only initialise the context data structure for
+	 * the secure world on this cpu and return.
+	 */
+	if (sp->runtime_el == S_EL0) {
+		/* Assign the context of the SP to this CPU */
+		cm_set_context(&(ec->cpu_ctx), SECURE);
+		return;
+	}
+
 	/* Initialize entry point information for the SP. */
 	SET_PARAM_HEAD(&sec_ec_ep_info, PARAM_EP, VERSION_1,
 		       SECURE | EP_ST_ENABLE);