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/CMakeLists.txt b/secure_fw/spm/CMakeLists.txt
index aed3438..98e4d56 100755
--- a/secure_fw/spm/CMakeLists.txt
+++ b/secure_fw/spm/CMakeLists.txt
@@ -56,7 +56,7 @@
         $<$<BOOL:${CONFIG_TFM_STACK_WATERMARKS}>:ffm/stack_watermark.c>
         $<$<BOOL:${TFM_PSA_API}>:cmsis_psa/tfm_core_svcalls_ipc.c>
         $<$<BOOL:${TFM_PSA_API}>:cmsis_psa/tfm_pools.c>
-        $<$<BOOL:${TFM_PSA_API}>:cmsis_psa/thread.c>
+        $<$<BOOL:${CONFIG_TFM_SPM_BACKEND_IPC}>:cmsis_psa/thread.c>
         $<$<NOT:$<BOOL:${TFM_PSA_API}>>:cmsis_func/main.c>
         $<$<NOT:$<BOOL:${TFM_PSA_API}>>:cmsis_func/arch.c>
         $<$<NOT:$<BOOL:${TFM_PSA_API}>>:cmsis_func/spm_func.c>
diff --git a/secure_fw/spm/cmsis_psa/arch/tfm_arch.c b/secure_fw/spm/cmsis_psa/arch/tfm_arch.c
index e340181..d6688bd 100644
--- a/secure_fw/spm/cmsis_psa/arch/tfm_arch.c
+++ b/secure_fw/spm/cmsis_psa/arch/tfm_arch.c
@@ -9,6 +9,7 @@
 #include "security_defs.h"
 #include "tfm_arch.h"
 #include "utilities.h"
+#include "config_impl.h"
 
 __naked void tfm_arch_free_msp_and_exc_ret(uint32_t msp_base,
                                            uint32_t exc_return)
@@ -26,7 +27,7 @@
         "bx      r1                             \n"
     );
 }
-
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1
 void tfm_arch_set_context_ret_code(void *p_ctx_ctrl, uint32_t ret_code)
 {
     struct context_ctrl_t *ctx_ctrl = (struct context_ctrl_t *)p_ctx_ctrl;
@@ -59,6 +60,7 @@
         "bx      lr                                    \n"
     );
 }
+#endif
 
 void tfm_arch_init_context(void *p_ctx_ctrl,
                            uintptr_t pfn, void *param, uintptr_t pfnlr)
diff --git a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.c b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.c
index 2b844ab..2f04b30 100644
--- a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.c
+++ b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.c
@@ -24,7 +24,7 @@
 /* IAR Specific */
 #if defined(__ICCARM__)
 
-#pragma required = do_schedule
+#pragma required = ipc_schedule
 #pragma required = scheduler_lock
 #pragma required = tfm_core_svc_handler
 
@@ -77,6 +77,7 @@
 
 #endif /* CONFIG_TFM_PSA_API_CROSS_CALL == 1*/
 
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1
 __attribute__((naked)) void PendSV_Handler(void)
 {
     __ASM volatile(
@@ -84,7 +85,7 @@
         ".syntax unified                    \n"
 #endif
         "   push    {r0, lr}                \n"
-        "   bl      do_schedule             \n"
+        "   bl      ipc_schedule             \n"
         "   pop     {r2, r3}                \n"
         "   mov     lr, r3                  \n"
         "   cmp     r0, r1                  \n" /* ctx of curr and next thrd */
@@ -118,6 +119,7 @@
         "   bx      lr                      \n"
     );
 }
+#endif
 
 __attribute__((naked)) void SVC_Handler(void)
 {
diff --git a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_base.c b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_base.c
index 15fc098..dd61599 100644
--- a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_base.c
+++ b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_base.c
@@ -25,7 +25,7 @@
 /* IAR Specific */
 #if defined(__ICCARM__)
 
-#pragma required = do_schedule
+#pragma required = ipc_schedule
 #pragma required = scheduler_lock
 #pragma required = tfm_core_svc_handler
 
@@ -85,6 +85,7 @@
 
 #endif /* CONFIG_TFM_PSA_API_CROSS_CALL == 1 */
 
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1
 __attribute__((naked)) void PendSV_Handler(void)
 {
     __ASM volatile(
@@ -96,7 +97,7 @@
         "   tst     r0, r1                              \n" /* NS interrupted */
         "   beq     v8b_pendsv_exit                     \n" /* No schedule */
         "   push    {r0, lr}                            \n" /* Save R0, LR */
-        "   bl      do_schedule                         \n"
+        "   bl      ipc_schedule                         \n"
         "   pop     {r2, r3}                            \n"
         "   mov     lr, r3                              \n"
         "   cmp     r0, r1                              \n" /* curr, next ctx */
@@ -132,6 +133,7 @@
         "   bx      lr                                  \n"
     );
 }
+#endif
 
 __attribute__((naked)) void SVC_Handler(void)
 {
diff --git a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_main.c b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_main.c
index 2398a81..aefcbe4 100644
--- a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_main.c
+++ b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v8m_main.c
@@ -30,7 +30,7 @@
 /* IAR Specific */
 #if defined(__ICCARM__)
 
-#pragma required = do_schedule
+#pragma required = ipc_schedule
 #pragma required = scheduler_lock
 #pragma required = tfm_core_svc_handler
 
@@ -88,6 +88,7 @@
 
 #endif /* CONFIG_TFM_PSA_API_CROSS_CALL == 1*/
 
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1
 __attribute__((naked)) void PendSV_Handler(void)
 {
     __ASM volatile(
@@ -98,7 +99,7 @@
         "   ands    r0, lr                              \n" /* NS interrupted */
         "   beq     v8m_pendsv_exit                     \n" /* No schedule */
         "   push    {r0, lr}                            \n" /* Save R0, LR */
-        "   bl      do_schedule                         \n"
+        "   bl      ipc_schedule                         \n"
         "   pop     {r2, lr}                            \n"
         "   cmp     r0, r1                              \n" /* curr, next ctx */
         "   beq     v8m_pendsv_exit                     \n" /* No schedule */
@@ -116,6 +117,7 @@
         "   bx      lr                                  \n"
     );
 }
+#endif
 
 #if defined(__ICCARM__)
 uint32_t tfm_core_svc_handler(uint32_t *msp, uint32_t exc_return,
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c
index f3f20b9..f83ba23 100755
--- a/secure_fw/spm/cmsis_psa/spm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.c
@@ -9,7 +9,6 @@
 #include <inttypes.h>
 #include <stdbool.h>
 #include <stdint.h>
-#include "aapcs_local.h"
 #include "bitops.h"
 #include "config_impl.h"
 #include "critical_section.h"
@@ -42,9 +41,6 @@
 #include "load/asset_defs.h"
 #include "load/spm_load_api.h"
 #include "tfm_nspm.h"
-#if defined(CONFIG_TFM_PARTITION_META)
-#include "tfm_hal_memory_symbols.h"
-#endif
 
 #if !(defined CONFIG_TFM_CONN_HANDLE_MAX_NUM) || (CONFIG_TFM_CONN_HANDLE_MAX_NUM == 0)
 #error "CONFIG_TFM_CONN_HANDLE_MAX_NUM must be defined and not zero."
@@ -54,17 +50,10 @@
 static struct service_head_t services_listhead;
 struct service_t *stateless_services_ref_tbl[STATIC_HANDLE_NUM_LIMIT];
 
-#if defined(CONFIG_TFM_PARTITION_META)
-/* Indicator point to the partition meta */
-static uintptr_t *partition_meta_indicator_pos = NULL;
-#endif
-
 /* Pools */
 TFM_POOL_DECLARE(conn_handle_pool, sizeof(struct conn_handle_t),
                  CONFIG_TFM_CONN_HANDLE_MAX_NUM);
 
-extern uint32_t scheduler_lock;
-
 /*********************** Connection handle conversion APIs *******************/
 
 #define CONVERSION_FACTOR_BITOFFSET    3
@@ -563,66 +552,9 @@
         backend_instance.comp_init_assuredly(partition, service_setting);
     }
 
-#if defined(CONFIG_TFM_PARTITION_META)
-    partition_meta_indicator_pos = (uintptr_t *)hal_mem_sp_meta_start;
-#endif
-
     return backend_instance.system_run();
 }
 
-uint64_t do_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);
-    }
-
-#if defined(CONFIG_TFM_PARTITION_META)
-    /* Update meta indicator */
-    if (partition_meta_indicator_pos && (p_part_next->p_metadata)) {
-        *partition_meta_indicator_pos = (uintptr_t)(p_part_next->p_metadata);
-    }
-#endif
-
-    return AAPCS_DUAL_U32_AS_U64(ctx_ctrls);
-}
-
 void update_caller_outvec_len(struct conn_handle_t *handle)
 {
     uint32_t i;
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.h b/secure_fw/spm/cmsis_psa/spm_ipc.h
index 88ebc3e..d8b6d70 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.h
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.h
@@ -118,15 +118,16 @@
     void                               *p_boundaries;
     void                               *p_interrupts;
     void                               *p_metadata;
-    struct context_ctrl_t              ctx_ctrl;
     uint32_t                           signals_allowed;
     uint32_t                           signals_waiting;
     volatile uint32_t                  signals_asserted;
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1
+    struct context_ctrl_t              ctx_ctrl;
     struct sync_obj_t                  waitobj;
-    union {
-        struct thread_t                thrd;            /* IPC model */
-        uint32_t                       state;           /* SFN model */
-    };
+    struct thread_t                    thrd;            /* IPC model */
+#else
+    uint32_t                           state;           /* SFN model */
+#endif
     struct conn_handle_t               *p_handles;
     struct partition_t                 *next;
 };
@@ -357,7 +358,7 @@
  *  Each takes 32 bits. The context control is used by PendSV_Handler to do
  *  context switch.
  */
-uint64_t do_schedule(void);
+uint64_t ipc_schedule(void);
 
 /**
  * \brief                      SPM initialization implementation
diff --git a/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c b/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c
index cbcc65e..8ee8621 100644
--- a/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c
+++ b/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c
@@ -32,6 +32,7 @@
                                      uint32_t *ctx, uint32_t lr);
 #endif
 
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1
 static int32_t SVC_Handler_IPC(uint8_t svc_num, uint32_t *ctx,
                                uint32_t lr)
 {
@@ -129,6 +130,7 @@
     spm_handle_programmer_errors(status);
     return status;
 }
+#endif
 
 uint32_t tfm_core_svc_handler(uint32_t *msp, uint32_t exc_return,
                               uint32_t *psp)
@@ -187,17 +189,25 @@
         break;
 #endif
     default:
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1
         if (((uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Limit)
                                      - (uint32_t)msp) > TFM_STACK_SEALED_SIZE) {
             /* The Main Stack has contents, not calling from Partition thread */
             tfm_core_panic();
         }
         svc_args[0] = SVC_Handler_IPC(svc_number, svc_args, exc_return);
-
         if (THRD_EXPECTING_SCHEDULE()) {
             tfm_arch_trigger_pendsv();
         }
-
+#else
+#ifdef PLATFORM_SVC_HANDLERS
+        svc_args[0] = (platform_svc_handlers(svc_number, svc_args, exc_return));
+#else
+        SPMLOG_ERRMSG("Unknown SVC number requested!\r\n");
+        svc_args[0] = PSA_ERROR_GENERIC_ERROR;
+#endif
+        spm_handle_programmer_errors(svc_args[0]);
+#endif
         break;
     }
 
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
     }
 }
diff --git a/secure_fw/spm/include/current.h b/secure_fw/spm/include/current.h
index e69473d..63a25bd 100644
--- a/secure_fw/spm/include/current.h
+++ b/secure_fw/spm/include/current.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -10,9 +10,17 @@
 #include "thread.h"
 #include "spm_ipc.h"
 
+#if CONFIG_TFM_SPM_BACKEND_SFN != 1
 /* Get current component */
 #define GET_CURRENT_COMPONENT()  GET_CTX_OWNER(CURRENT_THREAD->p_context_ctrl)
 /* Set current component */
 #define SET_CURRENT_COMPONENT(p) THRD_UPDATE_CUR_CTXCTRL(&(p)->ctx_ctrl)
+#else
+extern struct partition_t *p_current_partition;
+/* Get current component */
+#define GET_CURRENT_COMPONENT()  p_current_partition
+/* Set current component */
+#define SET_CURRENT_COMPONENT(p) p_current_partition = p
+#endif
 
 #endif /* __CURRENT_H__ */