SPM: Use dedicated instrutions to clear context

There are dedicated context clearing instructions since v8.1m, use
them could save quite a few instructions.

Also, apply extra FP context clearing actions for v8.0m NS jump.

Still doing the jump in assembly code, this could control the context
accurately. As the NSPE launch is not a standard NS call, it has less
significance to apply the CMSE NS call feature.

Signed-off-by: Ken Liu <Ken.Liu@arm.com>
Change-Id: I22d56ea93b8318585eee511f9a66ce632961de13
diff --git a/secure_fw/include/security_defs.h b/secure_fw/include/security_defs.h
index 99a88d2..a776d8d 100644
--- a/secure_fw/include/security_defs.h
+++ b/secure_fw/include/security_defs.h
@@ -16,6 +16,8 @@
  */
 #define STACK_SEAL_PATTERN    0xFEF5EDA5
 
+#if (defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
+
 /* Attributes for psa api secure gateway functions */
 #if defined(__GNUC__) && !defined(__ARMCC_VERSION)
 /*
@@ -26,11 +28,16 @@
         __attribute__((cmse_nonsecure_entry, noclone, section("SFN")))
 #define __tz_naked_veneer \
         __attribute__((cmse_nonsecure_entry, noclone, naked, section("SFN")))
+
 #else /* __GNUC__ && !__ARMCC_VERSION */
+
 #define __tz_c_veneer \
         __attribute__((cmse_nonsecure_entry, section("SFN")))
 #define __tz_naked_veneer \
         __attribute__((cmse_nonsecure_entry, naked, section("SFN")))
+
 #endif /* __GNUC__ && !__ARMCC_VERSION */
 
+#endif /* __ARM_FEATURE_CMSE */
+
 #endif /* __SECURITY_DEFS_H__ */
diff --git a/secure_fw/partitions/ns_agent_tz/CMakeLists.txt b/secure_fw/partitions/ns_agent_tz/CMakeLists.txt
index e79f3dc..31d0a18 100644
--- a/secure_fw/partitions/ns_agent_tz/CMakeLists.txt
+++ b/secure_fw/partitions/ns_agent_tz/CMakeLists.txt
@@ -18,20 +18,24 @@
     return()
 endif()
 
-target_sources(tfm_spm
-    PRIVATE
-        ${CMAKE_CURRENT_SOURCE_DIR}/ns_agent_tz.c
-)
-
 target_sources(tfm_partitions
     INTERFACE
         ${CMAKE_CURRENT_SOURCE_DIR}/load_info_ns_agent_tz.c
 )
 
+set(ARM_V80M_ARCH armv8-m.base armv8-m.main)
+
+# Trustzone NS Agent is tighly coupled with SPM
+target_sources(tfm_spm
+    PRIVATE
+        ${CMAKE_CURRENT_SOURCE_DIR}/ns_agent_tz_init.c
+        "$<$<IN_LIST:${TFM_SYSTEM_ARCHITECTURE},${ARM_V80M_ARCH}>:${CMAKE_CURRENT_SOURCE_DIR}/ns_agent_tz_v80m.c>"
+        "$<$<NOT:$<IN_LIST:${TFM_SYSTEM_ARCHITECTURE},${ARM_V80M_ARCH}>>:${CMAKE_CURRENT_SOURCE_DIR}/ns_agent_tz.c>"
+)
+
 # If this is added to the spm, it is discarded as it is not used. Since the
 # spm is a static library it can't generate veneers under all compilers so
-# instead this single file is added to the tfm_s target.
-set(ARM_V80M_ARCH armv8-m.base armv8-m.main)
+# instead this single file is added to the 'tfm_s' target.
 target_sources(tfm_s
     PRIVATE
         "$<$<IN_LIST:${TFM_SYSTEM_ARCHITECTURE},${ARM_V80M_ARCH}>:${CMAKE_CURRENT_SOURCE_DIR}/psa_api_veneers_v80m.c>"
diff --git a/secure_fw/partitions/ns_agent_tz/ns_agent_tz.c b/secure_fw/partitions/ns_agent_tz/ns_agent_tz.c
index d140831..4cccf61 100644
--- a/secure_fw/partitions/ns_agent_tz/ns_agent_tz.c
+++ b/secure_fw/partitions/ns_agent_tz/ns_agent_tz.c
@@ -6,33 +6,15 @@
  */
 
 #include "compiler_ext_defs.h"
+#include "ns_agent_tz.h"
 #include "security_defs.h"
 #include "tfm_arch.h"
 #include "tfm_hal_platform.h"
 
 #if defined(__ICCARM__)
-static uint32_t ns_agent_tz_init_c(void);
 #pragma required = ns_agent_tz_init_c
 #endif
 
-/*
- * Initialization before launching NSPE in C.
- */
-__used static uint32_t ns_agent_tz_init_c(void)
-{
-    /* SCB_NS.VTOR points to the Non-secure vector table base address */
-    SCB_NS->VTOR = tfm_hal_get_ns_VTOR();
-
-    /* Setups Main stack pointer of the non-secure code */
-    __TZ_set_MSP_NS(tfm_hal_get_ns_MSP());
-
-    return tfm_hal_get_ns_entry_point();
-}
-
-/*
- * 'r0' implicitly holds the address of non-secure entry,
- * given during non-secure partition initialization.
- */
 __naked void ns_agent_tz_main(void)
 {
     __ASM volatile(
@@ -44,22 +26,17 @@
         "   ldr      r3, ="M2S(STACK_SEAL_PATTERN)" \n" /* SEAL double-check */
         "   cmp      r2, r3                         \n"
         "   bne      ns_agent_nspe_jump_panic       \n"
-        "   mov      r4, r0                         \n"
-        "   movs     r2, #1                         \n" /* For NS execution */
-        "   bics     r4, r2                         \n"
-        "   mov      r0, r4                         \n"
-        "   mov      r1, r4                         \n"
-        "   mov      r2, r4                         \n"
-        "   mov      r3, r4                         \n"
-        "   mov      r5, r4                         \n"
-        "   mov      r6, r4                         \n"
-        "   mov      r7, r4                         \n"
-        "   mov      r8, r4                         \n"
-        "   mov      r9, r4                         \n"
-        "   mov      r10, r4                        \n"
-        "   mov      r11, r4                        \n"
-        "   mov      r12, r4                        \n"
-        "   mov      r14, r4                        \n"
+#if defined(CONFIG_TFM_ENABLE_FPU)
+        "   vscclrm  {s0-s31, vpr}                  \n"
+        "   mov      r1, #0                         \n"
+        "   vmsr     fpscr_nzcvqc, r1               \n"
+        "   mrs      r1, control                    \n"
+        "   bic      r1, r1, #4                     \n"
+        "   msr      control, r1                    \n"
+        "   isb                                     \n"
+#endif
+        "   clrm     {r1-r12, r14, apsr}            \n"
+        "   bic      r0, r0, #1                     \n"
         "   bxns     r0                             \n"
         "ns_agent_nspe_jump_panic:                  \n"
         "   b        .                              \n"
diff --git a/secure_fw/partitions/ns_agent_tz/ns_agent_tz.h b/secure_fw/partitions/ns_agent_tz/ns_agent_tz.h
new file mode 100644
index 0000000..344d76c
--- /dev/null
+++ b/secure_fw/partitions/ns_agent_tz/ns_agent_tz.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __NS_AGENT_TZ_H__
+#define __NS_AGENT_TZ_H__
+
+#include <stdint.h>
+
+uint32_t ns_agent_tz_init_c(void);
+
+#endif /* __NS_AGENT_TZ_H__ */
diff --git a/secure_fw/partitions/ns_agent_tz/ns_agent_tz_init.c b/secure_fw/partitions/ns_agent_tz/ns_agent_tz_init.c
new file mode 100644
index 0000000..3206eda
--- /dev/null
+++ b/secure_fw/partitions/ns_agent_tz/ns_agent_tz_init.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "compiler_ext_defs.h"
+#include "ns_agent_tz.h"
+#include "tfm_arch.h"
+#include "tfm_hal_platform.h"
+
+/*
+ * Initialization before launching NSPE (in C source).
+ */
+__used uint32_t ns_agent_tz_init_c(void)
+{
+    /* SCB_NS.VTOR points to the Non-secure vector table base address */
+    SCB_NS->VTOR = tfm_hal_get_ns_VTOR();
+
+    /* Setups Main stack pointer of the non-secure code */
+    __TZ_set_MSP_NS(tfm_hal_get_ns_MSP());
+
+    return tfm_hal_get_ns_entry_point();
+}
diff --git a/secure_fw/partitions/ns_agent_tz/ns_agent_tz_v80m.c b/secure_fw/partitions/ns_agent_tz/ns_agent_tz_v80m.c
new file mode 100644
index 0000000..f4aa594
--- /dev/null
+++ b/secure_fw/partitions/ns_agent_tz/ns_agent_tz_v80m.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "compiler_ext_defs.h"
+#include "ns_agent_tz.h"
+#include "security_defs.h"
+#include "tfm_arch.h"
+#include "tfm_hal_platform.h"
+
+#if defined(__ICCARM__)
+#pragma required = ns_agent_tz_init_c
+#endif
+
+__naked void ns_agent_tz_main(void)
+{
+    __ASM volatile(
+#ifndef __ICCARM__
+        ".syntax unified                            \n"
+#endif
+        "   bl       ns_agent_tz_init_c             \n"
+        "   ldr      r2, [sp]                       \n"
+        "   ldr      r3, ="M2S(STACK_SEAL_PATTERN)" \n" /* SEAL double-check */
+        "   cmp      r2, r3                         \n"
+        "   bne      ns_agent_nspe_jump_panic       \n"
+        "   movs     r2, #1                         \n" /* For NS execution */
+        "   bics     r0, r2                         \n"
+        "   mov      r1, r0                         \n"
+#if defined(CONFIG_TFM_ENABLE_FPU)
+        "   vmov     d0, r0, r1                     \n"
+        "   vmov     d1, r0, r1                     \n"
+        "   vmov     d2, r0, r1                     \n"
+        "   vmov     d3, r0, r1                     \n"
+        "   vmov     d4, r0, r1                     \n"
+        "   vmov     d5, r0, r1                     \n"
+        "   vmov     d6, r0, r1                     \n"
+        "   vmov     d7, r0, r1                     \n"
+        "   mrs      r2, control                    \n"
+        "   bic      r2, r2, #4                     \n"
+        "   msr      control, r2                    \n"
+        "   isb                                     \n"
+#endif
+        "   mov      r2, r0                         \n"
+        "   mov      r3, r0                         \n"
+        "   mov      r4, r0                         \n"
+        "   mov      r5, r0                         \n"
+        "   mov      r6, r0                         \n"
+        "   mov      r7, r0                         \n"
+        "   mov      r8, r0                         \n"
+        "   mov      r9, r0                         \n"
+        "   mov      r10, r0                        \n"
+        "   mov      r11, r0                        \n"
+        "   mov      r12, r0                        \n"
+        "   mov      r14, r0                        \n"
+        "   bxns     r0                             \n"
+        "ns_agent_nspe_jump_panic:                  \n"
+        "   b        .                              \n"
+    );
+}