summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/spd/tspd/tspd_common.c9
-rw-r--r--services/spd/tspd/tspd_main.c2
-rw-r--r--services/spd/tspd/tspd_pm.c16
-rw-r--r--services/spd/tspd/tspd_private.h37
4 files changed, 51 insertions, 13 deletions
diff --git a/services/spd/tspd/tspd_common.c b/services/spd/tspd/tspd_common.c
index d3fe5ddf..2d0b08b1 100644
--- a/services/spd/tspd/tspd_common.c
+++ b/services/spd/tspd/tspd_common.c
@@ -85,7 +85,14 @@ int32_t tspd_init_secure_context(uint64_t entrypoint,
write_ctx_reg(el1_state, CTX_SCTLR_EL1, sctlr);
/* Set this context as ready to be initialised i.e OFF */
- tsp_ctx->state = TSP_STATE_OFF;
+ set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_OFF);
+
+ /*
+ * This context has not been used yet. It will become valid
+ * when the TSP is interrupted and wants the TSPD to preserve
+ * the context.
+ */
+ clr_std_smc_active_flag(tsp_ctx->state);
/* Associate this context with the cpu specified */
tsp_ctx->mpidr = mpidr;
diff --git a/services/spd/tspd/tspd_main.c b/services/spd/tspd/tspd_main.c
index 21ff7ffe..f192d348 100644
--- a/services/spd/tspd/tspd_main.c
+++ b/services/spd/tspd/tspd_main.c
@@ -142,7 +142,7 @@ int32_t tspd_init(void)
rc = tspd_synchronous_sp_entry(tsp_ctx);
assert(rc != 0);
if (rc) {
- tsp_ctx->state = TSP_STATE_ON;
+ set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_ON);
/*
* TSP has been successfully initialized. Register power
diff --git a/services/spd/tspd/tspd_pm.c b/services/spd/tspd/tspd_pm.c
index 2447d9e8..75b4b300 100644
--- a/services/spd/tspd/tspd_pm.c
+++ b/services/spd/tspd/tspd_pm.c
@@ -56,7 +56,7 @@ static int32_t tspd_cpu_off_handler(uint64_t cookie)
tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
assert(tsp_entry_info);
- assert(tsp_ctx->state == TSP_STATE_ON);
+ assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_ON);
/* Program the entry point and enter the TSP */
cm_set_el3_elr(SECURE, (uint64_t) tsp_entry_info->cpu_off_entry);
@@ -73,7 +73,7 @@ static int32_t tspd_cpu_off_handler(uint64_t cookie)
* Reset TSP's context for a fresh start when this cpu is turned on
* subsequently.
*/
- tsp_ctx->state = TSP_STATE_OFF;
+ set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_OFF);
return 0;
}
@@ -90,7 +90,7 @@ static void tspd_cpu_suspend_handler(uint64_t power_state)
tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
assert(tsp_entry_info);
- assert(tsp_ctx->state == TSP_STATE_ON);
+ assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_ON);
/* Program the entry point, power_state parameter and enter the TSP */
write_ctx_reg(get_gpregs_ctx(&tsp_ctx->cpu_ctx),
@@ -107,7 +107,7 @@ static void tspd_cpu_suspend_handler(uint64_t power_state)
panic();
/* Update its context to reflect the state the TSP is in */
- tsp_ctx->state = TSP_STATE_SUSPEND;
+ set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_SUSPEND);
}
/*******************************************************************************
@@ -124,7 +124,7 @@ static void tspd_cpu_on_finish_handler(uint64_t cookie)
tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
assert(tsp_entry_info);
- assert(tsp_ctx->state == TSP_STATE_OFF);
+ assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_OFF);
/* Initialise this cpu's secure context */
tspd_init_secure_context((uint64_t) tsp_entry_info->cpu_on_entry,
@@ -143,7 +143,7 @@ static void tspd_cpu_on_finish_handler(uint64_t cookie)
panic();
/* Update its context to reflect the state the SP is in */
- tsp_ctx->state = TSP_STATE_ON;
+ set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_ON);
}
/*******************************************************************************
@@ -159,7 +159,7 @@ static void tspd_cpu_suspend_finish_handler(uint64_t suspend_level)
tsp_context_t *tsp_ctx = &tspd_sp_context[linear_id];
assert(tsp_entry_info);
- assert(tsp_ctx->state == TSP_STATE_SUSPEND);
+ assert(get_tsp_pstate(tsp_ctx->state) == TSP_PSTATE_SUSPEND);
/* Program the entry point, suspend_level and enter the SP */
write_ctx_reg(get_gpregs_ctx(&tsp_ctx->cpu_ctx),
@@ -176,7 +176,7 @@ static void tspd_cpu_suspend_finish_handler(uint64_t suspend_level)
panic();
/* Update its context to reflect the state the SP is in */
- tsp_ctx->state = TSP_STATE_ON;
+ set_tsp_pstate(tsp_ctx->state, TSP_PSTATE_ON);
}
/*******************************************************************************
diff --git a/services/spd/tspd/tspd_private.h b/services/spd/tspd/tspd_private.h
index 81484e1c..bb0afcd9 100644
--- a/services/spd/tspd/tspd_private.h
+++ b/services/spd/tspd/tspd_private.h
@@ -38,10 +38,41 @@
/*******************************************************************************
* Secure Payload PM state information e.g. SP is suspended, uninitialised etc
+ * and macros to access the state information in the per-cpu 'state' flags
******************************************************************************/
-#define TSP_STATE_OFF 0
-#define TSP_STATE_ON 1
-#define TSP_STATE_SUSPEND 2
+#define TSP_PSTATE_OFF 0
+#define TSP_PSTATE_ON 1
+#define TSP_PSTATE_SUSPEND 2
+#define TSP_PSTATE_SHIFT 0
+#define TSP_PSTATE_MASK 0x3
+#define get_tsp_pstate(state) ((state >> TSP_PSTATE_SHIFT) & TSP_PSTATE_MASK)
+#define clr_tsp_pstate(state) (state &= ~(TSP_PSTATE_MASK \
+ << TSP_PSTATE_SHIFT))
+#define set_tsp_pstate(st, pst) do { \
+ clr_tsp_pstate(st); \
+ st |= (pst & TSP_PSTATE_MASK) << \
+ TSP_PSTATE_SHIFT; \
+ } while (0);
+
+
+/*
+ * This flag is used by the TSPD to determine if the TSP is servicing a standard
+ * SMC request prior to programming the next entry into the TSP e.g. if TSP
+ * execution is preempted by a non-secure interrupt and handed control to the
+ * normal world. If another request which is distinct from what the TSP was
+ * previously doing arrives, then this flag will be help the TSPD to either
+ * reject the new request or service it while ensuring that the previous context
+ * is not corrupted.
+ */
+#define STD_SMC_ACTIVE_FLAG_SHIFT 2
+#define STD_SMC_ACTIVE_FLAG_MASK 1
+#define get_std_smc_active_flag(state) ((state >> STD_SMC_ACTIVE_FLAG_SHIFT) \
+ & STD_SMC_ACTIVE_FLAG_MASK)
+#define set_std_smc_active_flag(state) (state |= \
+ 1 << STD_SMC_ACTIVE_FLAG_SHIFT)
+#define clr_std_smc_active_flag(state) (state &= \
+ ~(STD_SMC_ACTIVE_FLAG_MASK \
+ << STD_SMC_ACTIVE_FLAG_SHIFT))
/*******************************************************************************
* Secure Payload execution state information i.e. aarch32 or aarch64