HAL: Apply FIH to tfm_hal_platform_init

This patch applies Fault Inject Harden to the tfm_hal_platform_init
API.
And restore the FIH on init_debug() on AN521.

Change-Id: Ib6a640631d6e0ab592d83802158adf5bc4c93ec5
Signed-off-by: Kevin Peng <kevin.peng@arm.com>
diff --git a/docs/technical_references/design_docs/tfm_physical_attack_mitigation.rst b/docs/technical_references/design_docs/tfm_physical_attack_mitigation.rst
index ee0734e..4c8544a 100644
--- a/docs/technical_references/design_docs/tfm_physical_attack_mitigation.rst
+++ b/docs/technical_references/design_docs/tfm_physical_attack_mitigation.rst
@@ -372,17 +372,28 @@
 A malicious actor can perform physical attack against those platform specific
 implementations to bypass the countermeasures in TF-M common code.
 
-Debug access setting
-^^^^^^^^^^^^^^^^^^^^
-TF-M configures debug access according to device lifecycle and accessible debug
-certificates. In general, TF-M locks down the debug port if the device is in
-secure production state. TF-M exposed a HAL API for this purpose.
+Platform early initialization
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+TFM provides a HAL API for platforms to perform HW initialization before SPM
+initialization starts.
 The system integrator is responsible to implement this API on a particular SoC
 and harden it against physical attacks:
 
 .. code-block:: c
 
-  enum tfm_plat_err_t tfm_spm_hal_init_debug(void);
+  enum tfm_hal_status_t tfm_hal_platform_init(void);
+
+The API can have several initializations on different modules. The system
+integrator can choose to even harden some of these initializations functions
+within this platform init API. One of the examples is the debug access setting.
+
+Debug access setting
+********************
+TF-M configures debug access according to device lifecycle and accessible debug
+certificates. In general, TF-M locks down the debug port if the device is in
+secure production state.
+The system integrator can put the settings into an API and harden it against
+physical attacks.
 
 Platform specific isolation configuration
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -481,13 +492,13 @@
         |
         |--> tfm_core_init()
         |           |
-        |           |--> tfm_spm_hal_init_debug()
-        |           |                  |
-        |           |                  |--> platform specific debug init
-        |           |
         |           |--> tfm_hal_set_up_static_boundaries()
+        |           |                  |
+        |           |                  |--> platform specific isolation impl.
+        |           |
+        |           |--> tfm_hal_platform_init()
         |                              |
-        |                              |--> platform specific isolation impl.
+        |                              |--> platform specific init
         |
         |--> During each partition initialization
                     |
diff --git a/platform/ext/target/arm/mps2/an521/tfm_hal_platform.c b/platform/ext/target/arm/mps2/an521/tfm_hal_platform.c
index 4dd7691..e68200f 100644
--- a/platform/ext/target/arm/mps2/an521/tfm_hal_platform.c
+++ b/platform/ext/target/arm/mps2/an521/tfm_hal_platform.c
@@ -11,37 +11,51 @@
 #include "tfm_plat_defs.h"
 #include "uart_stdout.h"
 
+#ifdef TFM_FIH_PROFILE_ON
+fih_int tfm_hal_platform_init(void)
+#else
 enum tfm_hal_status_t tfm_hal_platform_init(void)
+#endif
 {
     enum tfm_plat_err_t plat_err = TFM_PLAT_ERR_SYSTEM_ERR;
+#ifdef TFM_FIH_PROFILE_ON
+    fih_int fih_rc = FIH_FAILURE;
+#endif
 
     plat_err = enable_fault_handlers();
     if (plat_err != TFM_PLAT_ERR_SUCCESS) {
-        return TFM_HAL_ERROR_GENERIC;
+        FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
     }
 
     plat_err = system_reset_cfg();
     if (plat_err != TFM_PLAT_ERR_SUCCESS) {
-        return TFM_HAL_ERROR_GENERIC;
+        FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
     }
 
+#ifdef TFM_FIH_PROFILE_ON
+    FIH_CALL(init_debug, fih_rc);
+    if (fih_not_eq(fih_rc, fih_int_encode(TFM_PLAT_ERR_SUCCESS))) {
+        FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
+    }
+#else
     plat_err = init_debug();
     if (plat_err != TFM_PLAT_ERR_SUCCESS) {
         return TFM_HAL_ERROR_GENERIC;
     }
+#endif
 
     __enable_irq();
     stdio_init();
 
     plat_err = nvic_interrupt_target_state_cfg();
     if (plat_err != TFM_PLAT_ERR_SUCCESS) {
-        return TFM_HAL_ERROR_GENERIC;
+        FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
     }
 
     plat_err = nvic_interrupt_enable();
     if (plat_err != TFM_PLAT_ERR_SUCCESS) {
-        return TFM_HAL_ERROR_GENERIC;
+        FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
     }
 
-    return TFM_HAL_SUCCESS;
+    FIH_RET(fih_int_encode(TFM_HAL_SUCCESS));
 }
diff --git a/platform/include/tfm_hal_platform.h b/platform/include/tfm_hal_platform.h
index bdab65f..4c1728d 100644
--- a/platform/include/tfm_hal_platform.h
+++ b/platform/include/tfm_hal_platform.h
@@ -11,8 +11,21 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include "fih.h"
 #include "tfm_hal_defs.h"
 
+#ifdef TFM_FIH_PROFILE_ON
+
+/**
+ * \brief This function performs the platform-specific initialization.
+ *
+ * This function is called after architecture and platform common initialization
+ * has finished during system early startup.
+ *
+ * \retval Returns values as specified by FIH specific platform error code.
+ */
+fih_int tfm_hal_platform_init(void);
+#else
 /**
  * \brief This function performs the platform-specific initialization.
  *
@@ -23,6 +36,7 @@
  * \retval TFM_HAL_ERROR_GENERIC    Generic errors.
  */
 enum tfm_hal_status_t tfm_hal_platform_init(void);
+#endif
 
 /**
  * \brief System reset
diff --git a/secure_fw/spm/cmsis_func/main.c b/secure_fw/spm/cmsis_func/main.c
index a50767f..0ea1911 100644
--- a/secure_fw/spm/cmsis_func/main.c
+++ b/secure_fw/spm/cmsis_func/main.c
@@ -65,10 +65,17 @@
     }
 #endif /* TFM_FIH_PROFILE_ON */
 
-    hal_status = tfm_hal_platform_init();
-    if (hal_status != TFM_HAL_SUCCESS) {
+#ifdef TFM_FIH_PROFILE_ON
+    FIH_CALL(tfm_hal_platform_init, 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_platform_init();
+    if (hal_status != TFM_HAL_SUCCESS) {
+        return TFM_ERROR_GENERIC;
+    }
+#endif /* TFM_FIH_PROFILE_ON */
 
     plat_err = tfm_plat_otp_init();
     if (plat_err != TFM_PLAT_ERR_SUCCESS) {
diff --git a/secure_fw/spm/cmsis_psa/main.c b/secure_fw/spm/cmsis_psa/main.c
index f2eb4d2..46fef6f 100644
--- a/secure_fw/spm/cmsis_psa/main.c
+++ b/secure_fw/spm/cmsis_psa/main.c
@@ -37,10 +37,11 @@
 
 static fih_int tfm_core_init(void)
 {
-    enum tfm_hal_status_t hal_status = TFM_HAL_ERROR_GENERIC;
     enum tfm_plat_err_t plat_err = TFM_PLAT_ERR_SYSTEM_ERR;
 #ifdef TFM_FIH_PROFILE_ON
     fih_int fih_rc = FIH_FAILURE;
+#else
+    enum tfm_hal_status_t hal_status = TFM_HAL_ERROR_GENERIC;
 #endif
 
     /*
@@ -66,10 +67,17 @@
     }
 #endif
 
-    hal_status = tfm_hal_platform_init();
-    if (hal_status != TFM_HAL_SUCCESS) {
+#ifdef TFM_FIH_PROFILE_ON
+    FIH_CALL(tfm_hal_platform_init, 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_platform_init();
+    if (hal_status != TFM_HAL_SUCCESS) {
+        return TFM_ERROR_GENERIC;
+    }
+#endif /* TFM_FIH_PROFILE_ON */
 
     plat_err = tfm_plat_otp_init();
     if (plat_err != TFM_PLAT_ERR_SUCCESS) {