SPMD: [EXP] Hook up support for PSCI usage from the secure world

This patch delegates invocation of PSCI calls from the secure world to the SMC
handler registered by the SPMD.

Signed-off-by: Achin Gupta <achin.gupta@arm.com>
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index 5c0e952..26f282f 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -381,8 +381,19 @@
 {
 	u_register_t ret;
 
-	if (is_caller_secure(flags))
-		return (u_register_t)SMC_UNK;
+	/*
+	 * Call PSCI secure SMC handler registered by the SPMD if one exists.
+	 */
+	if (is_caller_secure(flags)) {
+		if ((psci_spd_pm != NULL) &&
+		    (psci_spd_pm->psci_sec_smc_handler != NULL))
+			return psci_spd_pm->psci_sec_smc_handler(smc_fid,
+								 x1, x2, x3,
+								 x4, cookie,
+								 handle, flags);
+		else
+			return (u_register_t)SMC_UNK;
+	}
 
 	/* Check the fid against the capabilities */
 	if ((psci_caps & define_psci_cap(smc_fid)) == 0U)
diff --git a/services/std_svc/spmd/spmd.mk b/services/std_svc/spmd/spmd.mk
index e696555..86bfb2c 100644
--- a/services/std_svc/spmd/spmd.mk
+++ b/services/std_svc/spmd/spmd.mk
@@ -13,6 +13,7 @@
 
 SPMD_SOURCES	+=	$(addprefix services/std_svc/spmd/,	\
 			${ARCH}/spmd_helpers.S			\
+			spmd_pm.c				\
 			spmd_main.c)
 
 # Let the top-level Makefile know that we intend to include a BL32 image
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 2e96803..251c05d 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -274,6 +274,9 @@
 	/* Reuse PSCI affinity states to mark this SPMC context as off */
 	spm_core_context[plat_my_core_pos()].state = AFF_STATE_OFF;
 
+	/* Register power management hooks with PSCI */
+	psci_register_spd_pm_hook(&spmd_pm);
+
 	INFO("SPM core setup done.\n");
 
 	/* Register init function for deferred init.  */
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index 4e4a779..eb9a5c5 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -72,6 +72,11 @@
 uint64_t spmd_spm_core_enter(uint64_t *c_rt_ctx);
 void __dead2 spmd_spm_core_exit(uint64_t c_rt_ctx, uint64_t ret);
 
+/* Per-cpu SPMC context */
+extern spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT];
+
+/* SPMD PSCI power management handlers */
+extern const spd_pm_ops_t spmd_pm;
 
 /* SPMC entry point information */
 extern entry_point_info_t *spmc_ep_info;