SPM: Remove thread management in SFN backend
In SFN backend, there is only one thread, so thread switch
will never happen. This patch is to remove the thread
context in partition struct and thread management in SPM.
Signed-off-by: Sherry Zhang <sherry.zhang2@arm.com>
Change-Id: Ie31dc5271f5fb1b32bbfc5312b02c736a85b9103
diff --git a/secure_fw/spm/ffm/backend_ipc.c b/secure_fw/spm/ffm/backend_ipc.c
index 597016d..515af61 100644
--- a/secure_fw/spm/ffm/backend_ipc.c
+++ b/secure_fw/spm/ffm/backend_ipc.c
@@ -7,11 +7,13 @@
*/
#include <stdint.h>
+#include "aapcs_local.h"
#include "critical_section.h"
#include "compiler_ext_defs.h"
#include "runtime_defs.h"
#include "ffm/stack_watermark.h"
#include "spm_ipc.h"
+#include "tfm_hal_memory_symbols.h"
#include "tfm_hal_isolation.h"
#include "tfm_hal_platform.h"
#include "tfm_rpc.h"
@@ -43,6 +45,11 @@
#endif
+/* Indicator point to the partition meta */
+uintptr_t *partition_meta_indicator_pos;
+
+extern uint32_t scheduler_lock;
+
static void prv_process_metadata(struct partition_t *p_pt)
{
const struct partition_load_info_t *p_pt_ldi;
@@ -194,6 +201,7 @@
TFM_CORE_ASSERT(SPM_THREAD_CONTEXT);
#endif
+ partition_meta_indicator_pos = (uintptr_t *)hal_mem_sp_meta_start;
control = thrd_start_scheduler(&CURRENT_THREAD);
p_cur_pt = TO_CONTAINER(CURRENT_THREAD->p_context_ctrl,
@@ -238,6 +246,56 @@
p_pt->signals_waiting = 0;
}
+uint64_t ipc_schedule(void)
+{
+ AAPCS_DUAL_U32_T ctx_ctrls;
+ struct partition_t *p_part_curr, *p_part_next;
+ struct context_ctrl_t *p_curr_ctx;
+ struct thread_t *pth_next = thrd_next();
+ struct critical_section_t cs = CRITICAL_SECTION_STATIC_INIT;
+
+ p_curr_ctx = (struct context_ctrl_t *)(CURRENT_THREAD->p_context_ctrl);
+
+ AAPCS_DUAL_U32_SET(ctx_ctrls, (uint32_t)p_curr_ctx, (uint32_t)p_curr_ctx);
+
+ p_part_curr = GET_CURRENT_COMPONENT();
+ p_part_next = GET_THRD_OWNER(pth_next);
+
+ if (scheduler_lock != SCHEDULER_LOCKED && pth_next != NULL &&
+ p_part_curr != p_part_next) {
+ /* Check if there is enough room on stack to save more context */
+ if ((p_curr_ctx->sp_limit +
+ sizeof(struct tfm_additional_context_t)) > __get_PSP()) {
+ tfm_core_panic();
+ }
+
+ CRITICAL_SECTION_ENTER(cs);
+ /*
+ * If required, let the platform update boundary based on its
+ * implementation. Change privilege, MPU or other configurations.
+ */
+ if (p_part_curr->p_boundaries != p_part_next->p_boundaries) {
+ if (tfm_hal_update_boundaries(p_part_next->p_ldinf,
+ p_part_next->p_boundaries)
+ != TFM_HAL_SUCCESS) {
+ tfm_core_panic();
+ }
+ }
+ ARCH_FLUSH_FP_CONTEXT();
+
+ AAPCS_DUAL_U32_SET_A1(ctx_ctrls, (uint32_t)pth_next->p_context_ctrl);
+
+ CURRENT_THREAD = pth_next;
+ CRITICAL_SECTION_LEAVE(cs);
+ }
+
+ /* Update meta indicator */
+ if (partition_meta_indicator_pos && (p_part_next->p_metadata)) {
+ *partition_meta_indicator_pos = (uintptr_t)(p_part_next->p_metadata);
+ }
+ return AAPCS_DUAL_U32_AS_U64(ctx_ctrls);
+}
+
const struct backend_ops_t backend_instance = {
.comp_init_assuredly = ipc_comp_init_assuredly,
.system_run = ipc_system_run,
diff --git a/secure_fw/spm/ffm/backend_sfn.c b/secure_fw/spm/ffm/backend_sfn.c
index 9218afc..eae5d16 100644
--- a/secure_fw/spm/ffm/backend_sfn.c
+++ b/secure_fw/spm/ffm/backend_sfn.c
@@ -27,6 +27,9 @@
/* Declare the global component list */
struct partition_head_t partition_listhead;
+/* Current running partition. */
+struct partition_t *p_current_partition;
+
/*
* Send message and wake up the SP who is waiting on message queue, block the
* current component state and activate the next component.
@@ -115,16 +118,10 @@
void sfn_comp_init_assuredly(struct partition_t *p_pt, uint32_t service_set)
{
const struct partition_load_info_t *p_pldi = p_pt->p_ldinf;
-
+ struct context_ctrl_t ns_agent_ctrl;
p_pt->p_handles = NULL;
p_pt->state = SFN_PARTITION_STATE_NOT_INITED;
- THRD_SYNC_INIT(&p_pt->waitobj);
-
- ARCH_CTXCTRL_INIT(&p_pt->ctx_ctrl,
- LOAD_ALLOCED_STACK_ADDR(p_pldi),
- p_pldi->stack_size);
-
watermark_stack(p_pt);
/*
@@ -132,18 +129,19 @@
* IDLE partition, and NS Agent (TZ) needs to be specific cared here.
*/
if (p_pldi->pid == TFM_SP_NON_SECURE_ID) {
- THRD_INIT(&p_pt->thrd, &p_pt->ctx_ctrl,
- TO_THREAD_PRIORITY(PARTITION_PRIORITY(p_pldi->flags)));
-
- thrd_start(&p_pt->thrd,
- POSITION_TO_ENTRY(spm_thread_fn, thrd_fn_t),
- POSITION_TO_ENTRY(p_pldi->entry, thrd_fn_t));
+ ARCH_CTXCTRL_INIT(&ns_agent_ctrl,
+ LOAD_ALLOCED_STACK_ADDR(p_pldi),
+ p_pldi->stack_size);
+ tfm_arch_init_context(&ns_agent_ctrl, (uintptr_t)spm_thread_fn,
+ NULL, p_pldi->entry);
+ tfm_arch_refresh_hardware_context(&ns_agent_ctrl);
+ SET_CURRENT_COMPONENT(p_pt);
}
}
uint32_t sfn_system_run(void)
{
- return thrd_start_scheduler(&CURRENT_THREAD);
+ return EXC_RETURN_THREAD_S_PSP;
}
static psa_signal_t sfn_wait(struct partition_t *p_pt, psa_signal_t signal_mask)
diff --git a/secure_fw/spm/ffm/interrupt.c b/secure_fw/spm/ffm/interrupt.c
index 99d796e..1b34e04 100644
--- a/secure_fw/spm/ffm/interrupt.c
+++ b/secure_fw/spm/ffm/interrupt.c
@@ -165,9 +165,11 @@
if (flih_result == PSA_FLIH_SIGNAL) {
spm_assert_signal(p_pt, p_ildi->signal);
-
+ /* In SFN backend, there is only one thread, no thread switch. */
+#if CONFIG_TFM_SPM_BACKEND_SFN != 1
if (THRD_EXPECTING_SCHEDULE()) {
tfm_arch_trigger_pendsv();
}
+#endif
}
}