SPM: Add interrupt handling support for SFN backend

This patch adds the interrupt handling support for SFN backend:
- Add two new ops in backend
- Add IRQ APIs for SFN interface

Change-Id: If5c694800f6c882f5852c9092143f4db5f0f4bd1
Signed-off-by: Kevin Peng <kevin.peng@arm.com>
diff --git a/secure_fw/spm/cmsis_psa/psa_interface_sfn.c b/secure_fw/spm/cmsis_psa/psa_interface_sfn.c
index a36e0b9..bbe3ef7 100644
--- a/secure_fw/spm/cmsis_psa/psa_interface_sfn.c
+++ b/secure_fw/spm/cmsis_psa/psa_interface_sfn.c
@@ -61,6 +61,11 @@
     tfm_spm_partition_psa_write(msg_handle, outvec_idx, buffer, num_bytes);
 }
 
+void psa_panic_sfn(void)
+{
+    tfm_spm_partition_psa_panic();
+}
+
 /* Following PSA APIs are only needed by connection-based services */
 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
 
@@ -103,6 +108,37 @@
 
 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
 
+#if CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1
+psa_signal_t psa_wait_sfn(psa_signal_t signal_mask, uint32_t timeout)
+{
+    return tfm_spm_partition_psa_wait(signal_mask, timeout);
+}
+
+void psa_irq_enable_sfn(psa_signal_t irq_signal)
+{
+    tfm_spm_partition_psa_irq_enable(irq_signal);
+}
+
+psa_irq_status_t psa_irq_disable_sfn(psa_signal_t irq_signal)
+{
+    return tfm_spm_partition_psa_irq_disable(irq_signal);
+}
+#endif
+
+#if CONFIG_TFM_SLIH_API == 1
+void psa_eoi_sfn(psa_signal_t irq_signal)
+{
+    tfm_spm_partition_psa_eoi(irq_signal);
+}
+#endif
+
+#if CONFIG_TFM_FLIH_API == 1
+void psa_reset_signal_sfn(psa_signal_t irq_signal)
+{
+    tfm_spm_partition_psa_reset_signal(irq_signal);
+}
+#endif
+
 #if PSA_FRAMEWORK_HAS_MM_IOVEC
 
 const void *psa_map_invec_sfn(psa_handle_t msg_handle, uint32_t invec_idx)
@@ -127,8 +163,3 @@
 }
 
 #endif /* PSA_FRAMEWORK_HAS_MM_IOVEC */
-
-void psa_panic_sfn(void)
-{
-    tfm_spm_partition_psa_panic();
-}
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c
index 249973f..01ff97e 100755
--- a/secure_fw/spm/cmsis_psa/spm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.c
@@ -679,9 +679,7 @@
     partition->signals_asserted |= signal;
 
     if (partition->signals_waiting & signal) {
-        thrd_wake_up(&partition->waitobj,
-                     partition->signals_asserted & partition->signals_waiting);
-        partition->signals_waiting &= ~signal;
+        backend_instance.wake_up(partition, signal);
     }
 
     CRITICAL_SECTION_LEAVE(cs_assert);
diff --git a/secure_fw/spm/ffm/backend_ipc.c b/secure_fw/spm/ffm/backend_ipc.c
index dba325a..fb9e4b3 100644
--- a/secure_fw/spm/ffm/backend_ipc.c
+++ b/secure_fw/spm/ffm/backend_ipc.c
@@ -202,9 +202,25 @@
     return control;
 }
 
+static void ipc_wait(struct partition_t *p_pt, psa_signal_t signals)
+{
+    (void)signals;
+
+    thrd_wait_on(&p_pt->waitobj, CURRENT_THREAD);
+}
+
+static void ipc_wake_up(struct partition_t *p_pt, psa_signal_t signals)
+{
+    thrd_wake_up(&p_pt->waitobj,
+                 p_pt->signals_asserted & p_pt->signals_waiting);
+    p_pt->signals_waiting &= ~signals;
+}
+
 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 f06cd9b..4c4ebbf 100644
--- a/secure_fw/spm/ffm/backend_sfn.c
+++ b/secure_fw/spm/ffm/backend_sfn.c
@@ -133,8 +133,6 @@
                    POSITION_TO_ENTRY(spm_thread_fn, thrd_fn_t),
                    POSITION_TO_ENTRY(p_pldi->entry, thrd_fn_t));
     }
-
-    (void)service_set;
 }
 
 uint32_t sfn_system_run(void)
@@ -142,9 +140,25 @@
     return thrd_start_scheduler(&CURRENT_THREAD);
 }
 
+static void sfn_wait(struct partition_t *p_pt, psa_signal_t signals)
+{
+    while (!(p_pt->signals_waiting & p_pt->signals_asserted))
+        ;
+
+    p_pt->signals_waiting &= ~signals;
+}
+
+static void sfn_wake_up(struct partition_t *p_pt, psa_signal_t signals)
+{
+    (void)p_pt;
+    (void)signals;
+}
+
 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
+    .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 32ece55..d787dd2 100644
--- a/secure_fw/spm/ffm/psa_api.c
+++ b/secure_fw/spm/ffm/psa_api.c
@@ -439,7 +439,8 @@
 
 /* PSA Partition API function body */
 
-#if CONFIG_TFM_SPM_BACKEND_IPC == 1
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1 \
+    || CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1
 psa_signal_t tfm_spm_partition_psa_wait(psa_signal_t signal_mask,
                                         uint32_t timeout)
 {
@@ -470,12 +471,14 @@
     if (timeout == PSA_BLOCK &&
         (partition->signals_asserted & signal_mask) == 0) {
         partition->signals_waiting = signal_mask;
-        thrd_wait_on(&partition->waitobj, CURRENT_THREAD);
+        backend_instance.wait(partition, signal_mask);
     }
 
     return partition->signals_asserted & signal_mask;
 }
+#endif
 
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1
 psa_status_t tfm_spm_partition_psa_get(psa_signal_t signal, psa_msg_t *msg)
 {
     struct conn_handle_t *handle = NULL;
diff --git a/secure_fw/spm/include/ffm/backend.h b/secure_fw/spm/include/ffm/backend.h
index d5e470c..d430da5 100644
--- a/secure_fw/spm/include/ffm/backend.h
+++ b/secure_fw/spm/include/ffm/backend.h
@@ -40,6 +40,18 @@
      * 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.
+     */
+    void (*wait)(struct partition_t *p_pt, psa_signal_t signals);
+
+    /*
+     * Runtime model-specific Partition wake up operation.
+     * Wakes up the Partition with the give signals.
+     */
+    void (*wake_up)(struct partition_t *p_pt, psa_signal_t signals);
 };
 
 /* RUNTIME MODEL BACKENDS DECLARATION */
diff --git a/secure_fw/spm/include/ffm/psa_api.h b/secure_fw/spm/include/ffm/psa_api.h
index 970ad2d..9f8354b 100644
--- a/secure_fw/spm/include/ffm/psa_api.h
+++ b/secure_fw/spm/include/ffm/psa_api.h
@@ -125,8 +125,8 @@
 
 /* PSA Partition API function body, for privileged use only. */
 
-/* This API is only used in IPC backend. */
-#if CONFIG_TFM_SPM_BACKEND_IPC == 1
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1 \
+    || CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1
 /**
  * \brief Function body of \ref psa_wait.
  *
@@ -141,7 +141,10 @@
  */
 psa_signal_t tfm_spm_partition_psa_wait(psa_signal_t signal_mask,
                                         uint32_t timeout);
+#endif
 
+/* This API is only used in IPC backend. */
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1
 /**
  * \brief Function body of \ref psa_get.
  *