SPM: Clear FP context when initialization ends

Hardware FP may be used during SPM initialization when it is enabled.
The existing FP context clearing is not late enough so that the SPM
execution still can bring FP context after the clearing.

Clear the FP context when SPM initialization ends when hardware FP
is enabled.

The FP status generated is cleared by the status bit in EXC_RETURN.
Hence the dedicated clear FP status function is not used anymore.

Signed-off-by: Ken Liu <Ken.Liu@arm.com>
Change-Id: Ief6855f18d27b26818e04206dadc406ffa07c753
diff --git a/secure_fw/spm/cmsis_psa/arch/tfm_arch.c b/secure_fw/spm/cmsis_psa/arch/tfm_arch.c
index d6688bd..7354ec1 100644
--- a/secure_fw/spm/cmsis_psa/arch/tfm_arch.c
+++ b/secure_fw/spm/cmsis_psa/arch/tfm_arch.c
@@ -11,6 +11,10 @@
 #include "utilities.h"
 #include "config_impl.h"
 
+#if defined(__ICCARM__)
+#pragma required = tfm_arch_clear_fp_data
+#endif
+
 __naked void tfm_arch_free_msp_and_exc_ret(uint32_t msp_base,
                                            uint32_t exc_return)
 {
@@ -18,13 +22,17 @@
 #if !defined(__ICCARM__)
         ".syntax unified                        \n"
 #endif
-        "mov     sp, r0                         \n"
-
+        "mov     r4, r0                         \n"
+        "mov     r5, r1                         \n"
+#if defined(CONFIG_TFM_ENABLE_FPU)
+        "bl      tfm_arch_clear_fp_data         \n"
+#endif
+        "mov     sp, r4                         \n"
         /* Seal Main Stack before using */
         "ldr     r2, ="M2S(STACK_SEAL_PATTERN)" \n"
         "ldr     r3, ="M2S(STACK_SEAL_PATTERN)" \n"
         "push    {r2, r3}                       \n"
-        "bx      r1                             \n"
+        "bx      r5                             \n"
     );
 }
 #if CONFIG_TFM_SPM_BACKEND_IPC == 1
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 d2e90a2..f804b7f 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
@@ -199,22 +199,3 @@
 #endif
 #endif
 }
-
-/* There is no FPCA in v6m */
-#ifndef __ARM_ARCH_6M__
-__attribute__((naked, noinline)) void tfm_arch_clear_fp_status(void)
-{
-    __ASM volatile(
-                   ".syntax unified          \n"
-                   "mrs  r0, control         \n"
-                   "bics r0, r0, #4          \n"
-                   "msr  control, r0         \n"
-                   "isb                      \n"
-                   "bx   lr                  \n"
-                  );
-}
-#else
-void tfm_arch_clear_fp_status(void)
-{
-}
-#endif
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 dd61599..e1ae6ee 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
@@ -229,8 +229,3 @@
 void tfm_arch_config_extensions(void)
 {
 }
-
-/* There is no FPCA in baseline. */
-void tfm_arch_clear_fp_status(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 242776a..9f25c56 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
@@ -264,19 +264,8 @@
 #endif
 }
 
-__attribute__((naked, noinline)) void tfm_arch_clear_fp_status(void)
-{
-    __ASM volatile(
-                   "mrs  r0, control         \n"
-                   "bics r0, r0, #4          \n"
-                   "msr  control, r0         \n"
-                   "isb                      \n"
-                   "bx   lr                  \n"
-                  );
-}
-
-#if (CONFIG_TFM_FP >= 1)
-__attribute__((naked, noinline)) void tfm_arch_clear_fp_data(void)
+#if defined(CONFIG_TFM_ENABLE_FPU)
+__attribute__((naked, noinline, used)) void tfm_arch_clear_fp_data(void)
 {
     __ASM volatile(
                     "eor  r0, r0, r0         \n"
diff --git a/secure_fw/spm/cmsis_psa/main.c b/secure_fw/spm/cmsis_psa/main.c
index a247f37..c42c0da 100644
--- a/secure_fw/spm/cmsis_psa/main.c
+++ b/secure_fw/spm/cmsis_psa/main.c
@@ -127,12 +127,6 @@
      */
     tfm_arch_set_secure_exception_priorities();
 
-#if (CONFIG_TFM_FP >= 1)
-    tfm_arch_clear_fp_data();
-#endif
-
-    tfm_arch_clear_fp_status();
-
     /* Move to handler mode for further SPM initialization. */
     tfm_core_handler_mode();
 
diff --git a/secure_fw/spm/include/tfm_arch.h b/secure_fw/spm/include/tfm_arch.h
index 9f2e1a2..72c44a9 100644
--- a/secure_fw/spm/include/tfm_arch.h
+++ b/secure_fw/spm/include/tfm_arch.h
@@ -193,13 +193,8 @@
 /* Configure various extensions. */
 void tfm_arch_config_extensions(void);
 
-/* Clear float point status. */
-void tfm_arch_clear_fp_status(void);
-
-#if (CONFIG_TFM_FP >= 1)
-/*
- * Clear float point data.
- */
+#if defined(CONFIG_TFM_ENABLE_FPU)
+/* Clear float point data. */
 void tfm_arch_clear_fp_data(void);
 #endif