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"
+ );
+}