SPMD: [EXP] Use PSCI states to manage SPMC boot
This patch replaces private states used by the SPMD to determine whether SPMC
has booted on a CPU with PSCI affinity states. This enables the SPMC on the boot
CPU to use the PSCI_CPU_ON function to begin initialisation on secondary CPUs.
Signed-off-by: Achin Gupta <achin.gupta@arm.com>
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 52226cc..2e96803 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -97,10 +97,18 @@
static int32_t spmd_init(void)
{
uint64_t rc = 0;
+ uint32_t cnt = 0;
spmd_spm_core_context_t *ctx = &spm_core_context[plat_my_core_pos()];
INFO("SPM Core init start.\n");
- ctx->state = SPMC_STATE_RESET;
+ ctx->state = AFF_STATE_ON_PENDING;
+
+ /* Set the state of SPMC contexts on other cpus to OFF */
+ for (cnt = 0; cnt < PLATFORM_CORE_COUNT; cnt++) {
+ if (spm_core_context[cnt].state == AFF_STATE_ON_PENDING)
+ continue;
+ spm_core_context[cnt].state = AFF_STATE_OFF;
+ }
rc = spmd_spm_core_sync_entry(ctx);
if (rc) {
@@ -108,7 +116,8 @@
panic();
}
- ctx->state = SPMC_STATE_IDLE;
+ ctx->state = AFF_STATE_ON;
+
INFO("SPM Core init end.\n");
return 1;
@@ -262,6 +271,9 @@
cm_setup_context(&(spm_core_context[plat_my_core_pos()].cpu_ctx),
spmc_ep_info);
+ /* Reuse PSCI affinity states to mark this SPMC context as off */
+ spm_core_context[plat_my_core_pos()].state = AFF_STATE_OFF;
+
INFO("SPM core setup done.\n");
/* Register init function for deferred init. */
@@ -300,12 +312,6 @@
in_sstate = is_caller_non_secure(flags);
out_sstate = !in_sstate;
- INFO("SPM: 0x%x, 0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx \n",
- smc_fid, x1, x2, x3, x4, SMC_GET_GP(handle, CTX_GPREG_X5),
- SMC_GET_GP(handle, CTX_GPREG_X6),
- SMC_GET_GP(handle, CTX_GPREG_X7));
-
-
switch (smc_fid) {
case SPCI_ERROR:
/*
@@ -313,7 +319,8 @@
* this CPU. If so, then indicate that the SPM core initialised
* unsuccessfully.
*/
- if ((in_sstate == SECURE) && (ctx->state == SPMC_STATE_RESET))
+ if ((in_sstate == SECURE) &&
+ (ctx->state == AFF_STATE_ON_PENDING))
spmd_spm_core_sync_exit(x2);
/* Save incoming security state */
@@ -439,7 +446,8 @@
* this CPU from the Secure world. If so, then indicate that the
* SPM core initialised successfully.
*/
- if ((in_sstate == SECURE) && (ctx->state == SPMC_STATE_RESET))
+ if ((in_sstate == SECURE) &&
+ (ctx->state == AFF_STATE_ON_PENDING))
spmd_spm_core_sync_exit(0);
case SPCI_MSG_YIELD:
/* This interface must be invoked only by the Secure world */
diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h
index 519564c..4e4a779 100644
--- a/services/std_svc/spmd/spmd_private.h
+++ b/services/std_svc/spmd/spmd_private.h
@@ -30,6 +30,9 @@
#define SPMD_C_RT_CTX_ENTRIES (SPMD_C_RT_CTX_SIZE >> DWORD_SHIFT)
#ifndef __ASSEMBLY__
+#include <lib/psci/psci.h>
+#include <lib/spinlock.h>
+#include <lib/utils.h>
#include <services/spci_beta0.h>
#include <stdint.h>
@@ -39,11 +42,6 @@
*/
#define SPCI_FNO_TO_BIT_POS(_fid) (1 << ((_fid) & U(0x1f)))
-typedef enum spmc_state {
- SPMC_STATE_RESET = 0,
- SPMC_STATE_IDLE
-} spmc_state_t;
-
/*
* Data structure used by the SPM dispatcher (SPMD) in EL3 to track context of
* the SPM core (SPMC) at the next lower EL.
@@ -51,7 +49,8 @@
typedef struct spmd_spm_core_context {
uint64_t c_rt_ctx;
cpu_context_t cpu_ctx;
- spmc_state_t state;
+ aff_info_state_t state;
+ spinlock_t lock;
} spmd_spm_core_context_t;
/*