aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAchin Gupta <achin.gupta@arm.com>2014-05-04 18:23:26 +0100
committerAchin Gupta <achin.gupta@arm.com>2014-05-22 17:45:59 +0100
commit3ee8a16402522d6d2959e27520f75c79b1218a2b (patch)
tree76c3d460fb5284ef6632c0606f1ee2b23dd3662e
parentdbad1bacba0a7adfd3c7c559f0fd0805087aeddd (diff)
downloadarm-trusted-firmware-3ee8a16402522d6d2959e27520f75c79b1218a2b.tar.gz
Rework 'state' field usage in per-cpu TSP context
This patch lays the foundation for using the per-cpu 'state' field in the 'tsp_context' structure for other flags apart from the power state of the TSP. It allocates 2 bits for the power state, introduces the necessary macros to manipulate the power state in the 'state' field and accordingly reworks all use of the TSP_STATE_* states. It also allocates a flag bit to determine if the TSP is handling a standard SMC. If this flag is set then the TSP was interrupted due to non-secure or EL3 interupt depending upon the chosen routing model. Macros to get, set and clear this flag have been added as well. This flag will be used by subsequent patches. Change-Id: Ic6ee80bd5895812c83b35189cf2c3be70a9024a6
-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 d3fe5dd..2d0b08b 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 21ff7ff..f192d34 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 2447d9e..75b4b30 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 81484e1..bb0afcd 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