SPM: Add fault injection protection support in IPC model

Create a reference implementation of fault injection protection in IPC
model SPM initialization.

Change-Id: I789ef2f621f3187e6c99d683763f3d1b1aa3c465
Signed-off-by: David Hu <david.hu@arm.com>
diff --git a/secure_fw/spm/cmsis_psa/main.c b/secure_fw/spm/cmsis_psa/main.c
index c820a46..41bd91a 100644
--- a/secure_fw/spm/cmsis_psa/main.c
+++ b/secure_fw/spm/cmsis_psa/main.c
@@ -5,6 +5,7 @@
  *
  */
 
+#include "fih.h"
 #include "ffm/tfm_boot_data.h"
 #include "region.h"
 #include "spm_ipc.h"
@@ -32,44 +33,68 @@
 
 REGION_DECLARE(Image$$, ARM_LIB_STACK_MSP,  $$ZI$$Base);
 
-static int32_t tfm_core_init(void)
+static fih_int tfm_core_init(void)
 {
     size_t i;
     enum tfm_hal_status_t hal_status = TFM_HAL_ERROR_GENERIC;
     enum tfm_plat_err_t plat_err = TFM_PLAT_ERR_SYSTEM_ERR;
     enum irq_target_state_t irq_target_state = TFM_IRQ_TARGET_STATE_SECURE;
+#ifdef TFM_FIH_PROFILE_ON
+    fih_int fih_rc = FIH_FAILURE;
+#endif
 
     /* Enables fault handlers */
     plat_err = tfm_spm_hal_enable_fault_handlers();
     if (plat_err != TFM_PLAT_ERR_SUCCESS) {
-        return TFM_ERROR_GENERIC;
+        FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
     }
 
     /* Configures the system reset request properties */
     plat_err = tfm_spm_hal_system_reset_cfg();
     if (plat_err != TFM_PLAT_ERR_SUCCESS) {
-        return TFM_ERROR_GENERIC;
+        FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
     }
 
     /* Configures debug authentication */
+#ifdef TFM_FIH_PROFILE_ON
+    FIH_CALL(tfm_spm_hal_init_debug, fih_rc);
+    if (fih_not_eq(fih_rc, fih_int_encode(TFM_PLAT_ERR_SUCCESS))) {
+        FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
+    }
+#else /* TFM_FIH_PROFILE_ON */
     plat_err = tfm_spm_hal_init_debug();
     if (plat_err != TFM_PLAT_ERR_SUCCESS) {
         return TFM_ERROR_GENERIC;
     }
+#endif /* TFM_FIH_PROFILE_ON */
 
     /*
      * Access to any peripheral should be performed after programming
      * the necessary security components such as PPC/SAU.
      */
+#ifdef TFM_FIH_PROFILE_ON
+    FIH_CALL(tfm_hal_set_up_static_boundaries, fih_rc);
+    if (fih_not_eq(fih_rc, fih_int_encode(TFM_HAL_SUCCESS))) {
+        FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
+    }
+#else /* TFM_FIH_PROFILE_ON */
     hal_status = tfm_hal_set_up_static_boundaries();
     if (hal_status != TFM_HAL_SUCCESS) {
         return TFM_ERROR_GENERIC;
     }
+#endif /* TFM_FIH_PROFILE_ON */
+
+#ifdef TFM_FIH_PROFILE_ON
+    FIH_CALL(tfm_spm_hal_verify_isolation_hw, fih_rc);
+    if (fih_not_eq(fih_rc, fih_int_encode(TFM_PLAT_ERR_SUCCESS))) {
+        tfm_core_panic();
+    }
+#endif
 
     /* Performs platform specific initialization */
     hal_status = tfm_hal_platform_init();
     if (hal_status != TFM_HAL_SUCCESS) {
-        return TFM_ERROR_GENERIC;
+        FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
     }
 
     /* Configures architecture */
@@ -88,7 +113,7 @@
      */
     plat_err = tfm_spm_hal_nvic_interrupt_target_state_cfg();
     if (plat_err != TFM_PLAT_ERR_SUCCESS) {
-        return TFM_ERROR_GENERIC;
+        FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
     }
 
     for (i = 0; i < tfm_core_irq_signals_count; ++i) {
@@ -96,34 +121,40 @@
                                           tfm_core_irq_signals[i].irq_line,
                                           tfm_core_irq_signals[i].irq_priority);
         if (plat_err != TFM_PLAT_ERR_SUCCESS) {
-            return TFM_ERROR_GENERIC;
+            FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
         }
         irq_target_state = tfm_spm_hal_set_irq_target_state(
                                           tfm_core_irq_signals[i].irq_line,
                                           TFM_IRQ_TARGET_STATE_SECURE);
         if (irq_target_state != TFM_IRQ_TARGET_STATE_SECURE) {
-            return TFM_ERROR_GENERIC;
+            FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
         }
     }
 
     /* Enable secure peripherals interrupts */
     plat_err = tfm_spm_hal_nvic_interrupt_enable();
     if (plat_err != TFM_PLAT_ERR_SUCCESS) {
-        return TFM_ERROR_GENERIC;
+        FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
     }
 
-    return TFM_SUCCESS;
+    FIH_RET(fih_int_encode(TFM_SUCCESS));
 }
 
 int main(void)
 {
+    fih_int fih_rc = FIH_FAILURE;
+
     /* set Main Stack Pointer limit */
     tfm_arch_init_secure_msp((uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK_MSP,
                                                $$ZI$$Base));
 
-    if (tfm_core_init() != TFM_SUCCESS) {
+    fih_delay_init();
+
+    FIH_CALL(tfm_core_init, fih_rc);
+    if (fih_not_eq(fih_rc, fih_int_encode(TFM_SUCCESS))) {
         tfm_core_panic();
     }
+
     /* Print the TF-M version */
     SPMLOG_INFMSG("\033[1;34mBooting TFM v"VERSION_FULLSTR"\033[0m\r\n");