SPM: Convert backend instances to direct function call

The two SPM backends (SFN and IPC) were expected to co-exist under
one implementation for processing respective partition model, to
allow IPC partitions and SFN partitions working togehter.

Now, the IPC model is expanded to support SFN partition work by
converting SFN partitions into IPC ones. The SFN model still
processes the SFN partitions only. This makes the co-existence of
two backends unnecessary, as each backend just needs to process
its dedicated partition model.

Convert the instance-based mechanism into direct function call one.
The backend function prototype is defined in the generic header
'backend.h' and function implementation is given by the chosen
backends.

Signed-off-by: Ken Liu <Ken.Liu@arm.com>
Change-Id: I4048213a7c715b0002b9d25007c412e334aab0f8
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c
index df2bfa8..2f0ada0 100755
--- a/secure_fw/spm/cmsis_psa/spm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.c
@@ -548,10 +548,10 @@
         }
 #endif /* TFM_FIH_PROFILE_ON */
 
-        backend_instance.comp_init_assuredly(partition, service_setting);
+        backend_init_comp_assuredly(partition, service_setting);
     }
 
-    return backend_instance.system_run();
+    return backend_system_run();
 }
 
 void update_caller_outvec_len(struct conn_handle_t *handle)
@@ -596,7 +596,7 @@
     partition->signals_asserted |= signal;
 
     if (partition->signals_waiting & signal) {
-        backend_instance.wake_up(partition);
+        backend_wake_up(partition);
     }
 
     CRITICAL_SECTION_LEAVE(cs_assert);
diff --git a/secure_fw/spm/ffm/backend_ipc.c b/secure_fw/spm/ffm/backend_ipc.c
index 515af61..873e4f7 100644
--- a/secure_fw/spm/ffm/backend_ipc.c
+++ b/secure_fw/spm/ffm/backend_ipc.c
@@ -95,8 +95,8 @@
  * Send message and wake up the SP who is waiting on message queue, block the
  * current thread and trigger scheduler.
  */
-static psa_status_t ipc_messaging(struct service_t *service,
-                                  struct conn_handle_t *handle)
+psa_status_t backend_messaging(struct service_t *service,
+                               struct conn_handle_t *handle)
 {
     struct partition_t *p_owner = NULL;
     psa_signal_t signal = 0;
@@ -137,7 +137,7 @@
     return PSA_SUCCESS;
 }
 
-static psa_status_t ipc_replying(struct conn_handle_t *handle, int32_t status)
+psa_status_t backend_replying(struct conn_handle_t *handle, int32_t status)
 {
     if (is_tfm_rpc_msg(handle)) {
         tfm_rpc_client_call_reply(handle, status);
@@ -156,8 +156,8 @@
 extern void sprt_main(void);
 
 /* Parameters are treated as assuredly */
-static void ipc_comp_init_assuredly(struct partition_t *p_pt,
-                                    uint32_t service_setting)
+void backend_init_comp_assuredly(struct partition_t *p_pt,
+                                 uint32_t service_setting)
 {
     const struct partition_load_info_t *p_pldi = p_pt->p_ldinf;
 
@@ -192,7 +192,7 @@
                THRD_GENERAL_EXIT);
 }
 
-static uint32_t ipc_system_run(void)
+uint32_t backend_system_run(void)
 {
     uint32_t control;
     struct partition_t *p_cur_pt;
@@ -215,13 +215,13 @@
     return control;
 }
 
-static psa_signal_t ipc_wait(struct partition_t *p_pt, psa_signal_t signal_mask)
+psa_signal_t backend_wait(struct partition_t *p_pt, psa_signal_t signal_mask)
 {
     struct critical_section_t cs_assert = CRITICAL_SECTION_STATIC_INIT;
     psa_signal_t ret_signal;
 
     /*
-     * 'ipc_wait()' sets the waiting signal mask for partition, and
+     * 'backend_wait()' sets the waiting signal mask for partition, and
      * blocks the partition thread state to wait for signals.
      * These changes should be inside the ciritical section to avoid
      * 'signal_waiting' or the thread state to be changed by interrupts
@@ -239,7 +239,7 @@
     return ret_signal;
 }
 
-static void ipc_wake_up(struct partition_t *p_pt)
+void backend_wake_up(struct partition_t *p_pt)
 {
     thrd_wake_up(&p_pt->waitobj,
                  p_pt->signals_asserted & p_pt->signals_waiting);
@@ -295,12 +295,3 @@
     }
     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,
-    .messaging           = ipc_messaging,
-    .replying            = ipc_replying,
-    .wait                = ipc_wait,
-    .wake_up             = ipc_wake_up,
-};
diff --git a/secure_fw/spm/ffm/backend_sfn.c b/secure_fw/spm/ffm/backend_sfn.c
index eae5d16..87d97ad 100644
--- a/secure_fw/spm/ffm/backend_sfn.c
+++ b/secure_fw/spm/ffm/backend_sfn.c
@@ -34,8 +34,8 @@
  * Send message and wake up the SP who is waiting on message queue, block the
  * current component state and activate the next component.
  */
-static psa_status_t sfn_messaging(struct service_t *service,
-                                  struct conn_handle_t *handle)
+psa_status_t backend_messaging(struct service_t *service,
+                               struct conn_handle_t *handle)
 {
     struct partition_t *p_target;
     psa_status_t status;
@@ -68,7 +68,7 @@
     return status;
 }
 
-static psa_status_t sfn_replying(struct conn_handle_t *handle, int32_t status)
+psa_status_t backend_replying(struct conn_handle_t *handle, int32_t status)
 {
     SET_CURRENT_COMPONENT(handle->p_client);
 
@@ -115,7 +115,8 @@
 }
 
 /* Parameters are treated as assuredly */
-void sfn_comp_init_assuredly(struct partition_t *p_pt, uint32_t service_set)
+void backend_init_comp_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;
@@ -139,12 +140,12 @@
     }
 }
 
-uint32_t sfn_system_run(void)
+uint32_t backend_system_run(void)
 {
     return EXC_RETURN_THREAD_S_PSP;
 }
 
-static psa_signal_t sfn_wait(struct partition_t *p_pt, psa_signal_t signal_mask)
+psa_signal_t backend_wait(struct partition_t *p_pt, psa_signal_t signal_mask)
 {
     while (!(p_pt->signals_asserted & signal_mask))
         ;
@@ -152,16 +153,7 @@
     return p_pt->signals_asserted & signal_mask;
 }
 
-static void sfn_wake_up(struct partition_t *p_pt)
+void backend_wake_up(struct partition_t *p_pt)
 {
     (void)p_pt;
 }
-
-const struct backend_ops_t backend_instance = {
-    .comp_init_assuredly = sfn_comp_init_assuredly,
-    .system_run          = sfn_system_run,
-    .messaging           = sfn_messaging,
-    .replying            = sfn_replying,
-    .wait                = sfn_wait,
-    .wake_up             = sfn_wake_up,
-};
diff --git a/secure_fw/spm/ffm/psa_api.c b/secure_fw/spm/ffm/psa_api.c
index 3f8c840..55cc169 100644
--- a/secure_fw/spm/ffm/psa_api.c
+++ b/secure_fw/spm/ffm/psa_api.c
@@ -311,7 +311,7 @@
     spm_fill_message(conn_handle, service, handle, type, client_id,
                      invecs, in_num, outvecs, out_num, outptr);
 
-    return backend_instance.messaging(service, conn_handle);
+    return backend_messaging(service, conn_handle);
 }
 
 /* Following PSA APIs are only needed by connection-based services */
@@ -374,7 +374,7 @@
     spm_fill_message(conn_handle, service, handle, PSA_IPC_CONNECT,
                      client_id, NULL, 0, NULL, 0, NULL);
 
-    return backend_instance.messaging(service, conn_handle);
+    return backend_messaging(service, conn_handle);
 }
 
 psa_status_t tfm_spm_client_psa_close(psa_handle_t handle)
@@ -423,7 +423,7 @@
     spm_fill_message(conn_handle, service, handle, PSA_IPC_DISCONNECT,
                      client_id, NULL, 0, NULL, 0, NULL);
 
-    return backend_instance.messaging(service, conn_handle);
+    return backend_messaging(service, conn_handle);
 }
 
 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
@@ -454,14 +454,14 @@
     }
 
     /*
-     * backend_instance.wait() blocks the caller thread if no signals are
+     * backend_wake_up() blocks the caller thread if no signals are
      * available. In this case, the return value of this function is temporary
      * set into runtime context. After new signal(s) are available, the return
      * value is updated with the available signal(s) and blocked thread gets
      * to run.
      */
     if (timeout == PSA_BLOCK) {
-        return backend_instance.wait(partition, signal_mask);
+        return backend_wait(partition, signal_mask);
     }
 
     return partition->signals_asserted & signal_mask;
@@ -838,7 +838,7 @@
      * involved.
      */
     CRITICAL_SECTION_ENTER(cs_assert);
-    ret = backend_instance.replying(handle, ret);
+    ret = backend_replying(handle, ret);
     CRITICAL_SECTION_LEAVE(cs_assert);
 
     if (handle->status == TFM_HANDLE_STATUS_TO_FREE) {
diff --git a/secure_fw/spm/include/ffm/backend.h b/secure_fw/spm/include/ffm/backend.h
index 3710aca..0132e86 100644
--- a/secure_fw/spm/include/ffm/backend.h
+++ b/secure_fw/spm/include/ffm/backend.h
@@ -14,50 +14,42 @@
 #include "load/spm_load_api.h"
 #include "psa/error.h"
 
-/* BASIC TYPE DEFINITIONS */
+/*
+ * Runtime model-specific component initialization routine. This
+ * is an `assuredly` function, would panic if any error occurred.
+ */
+void backend_init_comp_assuredly(struct partition_t *p_pt,
+                                 uint32_t service_setting);
 
-struct backend_ops_t {
-    /*
-     * Runtime model-specific component initialization routine. This
-     * is an `assuredly` function, would panic if any error occurred.
-     */
-    void (*comp_init_assuredly)(struct partition_t *p_pt,
-                                uint32_t service_setting);
+/*
+ * Runtime model-specific kick-off method for the whole system.
+ * Returns a hardware-specific control value, which is transparent
+ * to SPM common logic.
+ */
+uint32_t backend_system_run(void);
 
-    /*
-     * Runtime model-specific kick-off method for the whole system.
-     * Returns a hardware-specific control value, which is transparent
-     * to SPM common logic.
-     */
-    uint32_t (*system_run)(void);
+/* Runtime model-specific message handling mechanism. */
+psa_status_t backend_messaging(struct service_t *p_serv,
+                               struct conn_handle_t *handle);
 
-    /* Runtime model-specific message handling mechanism. */
-    psa_status_t (*messaging)(struct service_t *p_serv,
-                              struct conn_handle_t *handle);
+/*
+ * Runtime model-specific message replying.
+ * Return the connection handle or the acked status code.
+ */
+psa_status_t backend_replying(struct conn_handle_t *handle, int32_t status);
 
-    /*
-     * Runtime model-specific message replying.
-     * Return the connection handle or the acked status code.
-     */
-    psa_status_t (*replying)(struct conn_handle_t *handle, int32_t status);
+/*
+ * Runtime model-specific Partition wait operation.
+ * Put the Partition to a status that waits for signals.
+ */
+psa_signal_t backend_wait(struct partition_t *p_pt, psa_signal_t signal_mask);
 
-    /*
-     * Runtime model-specific Partition wait operation.
-     * Put the Partition to a status that waits for signals.
-     */
-    psa_signal_t (*wait)(struct partition_t *p_pt, psa_signal_t signal_mask);
+/*
+ * Runtime model-specific Partition wake up operation.
+ * Wakes up the Partition with the asserted signals in 'p_pt'.
+ */
+void backend_wake_up(struct partition_t *p_pt);
 
-    /*
-     * Runtime model-specific Partition wake up operation.
-     * Wakes up the Partition with the asserted signals in 'p_pt'.
-     */
-    void (*wake_up)(struct partition_t *p_pt);
-};
-
-/* RUNTIME MODEL BACKENDS DECLARATION */
-
-/* IPC backend */
-extern const struct backend_ops_t backend_instance;
 
 /* The component list, and a MACRO indicate this is not a common global. */
 extern struct partition_head_t partition_listhead;