aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Hu <david.hu@arm.com>2019-07-02 14:31:34 +0800
committerDavid Hu <david.hu@arm.com>2019-07-04 16:13:16 +0800
commit5ff8dbf63964925ff213310e91fe814348c5f43f (patch)
tree44951e9a0b6ad167c1145865f1d4bfb834333d8e
parentcfbf2a2fe46809b8b27de01079b16f903ad2bd0a (diff)
downloadtrusted-firmware-m-5ff8dbf63964925ff213310e91fe814348c5f43f.tar.gz
Arch: Add Armv6-M and Armv7-M support for multi-core topology
Implement Armv6-M and Armv7-M support in arch folder for TF-M multi-core topology. Change-Id: Ib8f8803857aa79339ec8740ad9f69c8b13ec513b Signed-off-by: David Hu <david.hu@arm.com>
-rw-r--r--platform/ext/psoc6_host.cmake1
-rw-r--r--platform/ext/psoc6_sc.cmake1
-rw-r--r--secure_fw/core/arch/CMakeLists.inc7
-rw-r--r--secure_fw/core/arch/include/tfm_arch.h3
-rw-r--r--secure_fw/core/arch/include/tfm_arch_v6m_v7m.h113
-rw-r--r--secure_fw/core/arch/tfm_arch_v6m_v7m.c139
6 files changed, 264 insertions, 0 deletions
diff --git a/platform/ext/psoc6_host.cmake b/platform/ext/psoc6_host.cmake
index 3b273e8f0c..505651c6ea 100644
--- a/platform/ext/psoc6_host.cmake
+++ b/platform/ext/psoc6_host.cmake
@@ -60,6 +60,7 @@ embedded_include_directories(PATH "${PLATFORM_DIR}/target/psoc6/Native_Driver/ge
embedded_include_directories(PATH "${PLATFORM_DIR}/target/psoc6/mailbox" ABSOLUTE)
embedded_include_directories(PATH "${PLATFORM_DIR}/target/psoc6/partition" ABSOLUTE)
embedded_include_directories(PATH "${TFM_ROOT_DIR}/interface/include" ABSOLUTE)
+embedded_include_directories(PATH "${TFM_ROOT_DIR}/secure_fw/core/arch/include" ABSOLUTE)
embedded_include_directories(PATH "${TFM_ROOT_DIR}/secure_fw/core/ipc/include" ABSOLUTE)
#Gather all source files we need.
diff --git a/platform/ext/psoc6_sc.cmake b/platform/ext/psoc6_sc.cmake
index c1424ca6c9..2a55198ce7 100644
--- a/platform/ext/psoc6_sc.cmake
+++ b/platform/ext/psoc6_sc.cmake
@@ -61,6 +61,7 @@ embedded_include_directories(PATH "${PLATFORM_DIR}/target/psoc6/Native_Driver/ge
embedded_include_directories(PATH "${PLATFORM_DIR}/target/psoc6/mailbox" ABSOLUTE)
embedded_include_directories(PATH "${PLATFORM_DIR}/target/psoc6/partition" ABSOLUTE)
embedded_include_directories(PATH "${TFM_ROOT_DIR}/interface/include" ABSOLUTE)
+embedded_include_directories(PATH "${TFM_ROOT_DIR}/secure_fw/core/arch/include" ABSOLUTE)
embedded_include_directories(PATH "${TFM_ROOT_DIR}/secure_fw/core/ipc/include" ABSOLUTE)
diff --git a/secure_fw/core/arch/CMakeLists.inc b/secure_fw/core/arch/CMakeLists.inc
index 8d080a27fa..71c7d4885c 100644
--- a/secure_fw/core/arch/CMakeLists.inc
+++ b/secure_fw/core/arch/CMakeLists.inc
@@ -34,6 +34,13 @@ elseif (${ARM_CPU_ARCHITECTURE} STREQUAL "ARMv8-M.MAIN")
set(TFM_ARCH_C_SRC "${TFM_ARCH_DIR}/tfm_arch_v8m_main.c")
elseif (${ARM_CPU_ARCHITECTURE} STREQUAL "ARMv8-M.BASE")
set(TFM_ARCH_C_SRC "${TFM_ARCH_DIR}/tfm_arch_v8m_base.c")
+elseif (${ARM_CPU_ARCHITECTURE} STREQUAL "ARMv7-M" OR
+ ${ARM_CPU_ARCHITECTURE} STREQUAL "ARMv6-M")
+ if (NOT DEFINED TFM_MULTI_CORE_TOPOLOGY OR NOT TFM_MULTI_CORE_TOPOLOGY)
+ message(FATAL_ERROR "Armv6-M/Armv7-M can only support multi-core TF-M.")
+ endif()
+
+ set(TFM_ARCH_C_SRC "${TFM_ARCH_DIR}/tfm_arch_v6m_v7m.c")
else ()
message(FATAL_ERROR "Unsupported architecture.")
endif()
diff --git a/secure_fw/core/arch/include/tfm_arch.h b/secure_fw/core/arch/include/tfm_arch.h
index 79eedbe238..0e340d73a6 100644
--- a/secure_fw/core/arch/include/tfm_arch.h
+++ b/secure_fw/core/arch/include/tfm_arch.h
@@ -15,6 +15,9 @@
#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
#include "tfm_arch_v8m.h"
+#elif defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_7M__) || \
+ defined(__ARM_ARCH_7EM__)
+#include "tfm_arch_v6m_v7m.h"
#else
#error "Unsupported ARM Architecture."
#endif
diff --git a/secure_fw/core/arch/include/tfm_arch_v6m_v7m.h b/secure_fw/core/arch/include/tfm_arch_v6m_v7m.h
new file mode 100644
index 0000000000..fbb75a357a
--- /dev/null
+++ b/secure_fw/core/arch/include/tfm_arch_v6m_v7m.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#ifndef __TFM_ARCH_V6M_V7M_H__
+#define __TFM_ARCH_V6M_V7M_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "cmsis_compiler.h"
+
+#if !TFM_MULTI_CORE_TOPOLOGY
+#error "Armv6-M/Armv7-M can only support multi-core TF-M now."
+#endif
+
+#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
+#define EXC_RETURN_FPU_FRAME_BASIC (1 << 4)
+#endif
+
+/* Initial EXC_RETURN value in LR when a thread is loaded at the first time */
+#define INIT_LR_UNPRIVILEGED 0xFFFFFFFD
+
+struct tfm_state_context_ext {
+ uint32_t r8;
+ uint32_t r9;
+ uint32_t r10;
+ uint32_t r11;
+ uint32_t r4;
+ uint32_t r5;
+ uint32_t r6;
+ uint32_t r7;
+ uint32_t sp;
+ uint32_t lr;
+};
+
+/**
+ * \brief Check whether Secure or Non-secure stack is used to restore stack
+ * frame on exception return.
+ *
+ * \param[in] lr LR register containing the EXC_RETURN value.
+ *
+ * \retval true Always return to Secure stack on secure core in
+ * multi-core topology.
+ */
+__STATIC_INLINE bool is_return_secure_stack(uint32_t lr)
+{
+ (void)lr;
+
+ return true;
+}
+
+#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
+/**
+ * \brief Check whether the stack frame for this exception has space allocated
+ * for Floating Point(FP) state information.
+ *
+ * \param[in] lr LR register containing the EXC_RETURN value.
+ *
+ * \retval true The stack allocates space for FP information
+ * \retval false The stack doesn't allocate space for FP information
+ */
+__STATIC_INLINE bool is_stack_alloc_fp_space(uint32_t lr)
+{
+ return (lr & EXC_RETURN_FPU_FRAME_BASIC) ? false : true;
+}
+#elif defined(__ARM_ARCH_6M__)
+/**
+ * \brief Check whether the stack frame for this exception has space allocated
+ * for Floating Point(FP) state information.
+ *
+ * \param[in] lr LR register containing the EXC_RETURN value.
+ *
+ * \retval false The stack doesn't allocate space for FP information
+ */
+__STATIC_INLINE bool is_stack_alloc_fp_space(uint32_t lr)
+{
+ (void)lr;
+
+ return false;
+}
+#endif
+
+/**
+ * \brief Set PSP limit value.
+ *
+ * \param[in] psplim PSP limit value to be written.
+ */
+__STATIC_INLINE void tfm_arch_set_psplim(uint32_t psplim)
+{
+ /*
+ * Defined as an empty function now.
+ * The PSP limit value can be used in more strict memory check.
+ */
+ (void)psplim;
+}
+
+/**
+ * \brief Set MSP limit value.
+ *
+ * \param[in] msplim MSP limit value to be written.
+ */
+__STATIC_INLINE void tfm_arch_set_msplim(uint32_t msplim)
+{
+ /*
+ * Defined as an empty function now.
+ * The MSP limit value can be used in more strict memory check.
+ */
+ (void)msplim;
+}
+
+#endif
diff --git a/secure_fw/core/arch/tfm_arch_v6m_v7m.c b/secure_fw/core/arch/tfm_arch_v6m_v7m.c
new file mode 100644
index 0000000000..8d6e8e0495
--- /dev/null
+++ b/secure_fw/core/arch/tfm_arch_v6m_v7m.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <inttypes.h>
+#include "cmsis.h"
+#include "tfm_arch.h"
+
+#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && \
+ !defined(__ARM_ARCH_7EM__)
+#error "Unsupported ARM Architecture."
+#endif
+
+extern uint32_t SVCHandler_main(uint32_t *svc_args, uint32_t lr);
+
+/*
+ * Stack status at PendSV entry:
+ *
+ * [ R0 - R3 ]<- PSP
+ * [ R12 ]
+ * [ LR_of_RA ]
+ * MSP->[ ........ ] [ RA ]
+ * [ ........ ] [ XPSR ]
+ * [ ........ ]
+ * [ ........ ]
+ *
+ * Stack status before calling tfm_pendsv_do_schedule():
+ *
+ * MSP->[ R8 - R9 ]
+ * [ R4 - R7 ]
+ * [ PSP ]--->[ R0 - R3 ]
+ * [ LR ] [ R12 ]
+ * [ ........ ] [ LR_of_RA ]
+ * [ ........ ] [ RA ]
+ * [ XPSR ]
+ * [ ........ ]
+ * [ ........ ]
+ *
+ * tfm_pendsv_do_schedule() updates stacked context into current thread and
+ * replace stacked context with context of next thread.
+ *
+ * Scheduler does not support handler mode thread so take PSP as thread SP.
+ */
+__attribute__((naked)) void PendSV_Handler(void)
+{
+ __ASM volatile(
+ "MRS r0, psp \n"
+ "PUSH {r0, lr} \n"
+ "PUSH {r4-r7} \n"
+ "MOV r4, r8 \n"
+ "MOV r5, r9 \n"
+ "MOV r6, r10 \n"
+ "MOV r7, r11 \n"
+ "PUSH {r4-r7} \n"
+ "MOV r0, sp \n"
+ "BL tfm_pendsv_do_schedule \n"
+ "POP {r4-r7} \n"
+ "MOV r8, r4 \n"
+ "MOV r9, r5 \n"
+ "MOV r10, r6 \n"
+ "MOV r11, r7 \n"
+ "POP {r4-r7} \n"
+ "POP {r0, r1} \n"
+ "MOV lr, r1 \n"
+ "MSR psp, r0 \n"
+ "BX lr \n"
+ );
+}
+
+void tfm_arch_initialize_ctx_ext(struct tfm_state_context_ext *p_ctxb,
+ uint32_t sp, uint32_t sp_limit)
+{
+ (void)sp_limit;
+
+ p_ctxb->sp = sp;
+ p_ctxb->lr = INIT_LR_UNPRIVILEGED;
+}
+
+__attribute__((naked)) void SVC_Handler(void)
+{
+ __ASM volatile(
+ ".syntax unified \n"
+ "MOVS r0, #4 \n" /* Check store SP in thread mode to r0 */
+ "MOV r1, lr \n"
+ "TST r0, r1 \n"
+ "BEQ handler \n"
+ "MRS r0, PSP \n" /* Coming from thread mode */
+ "B sp_stored \n"
+ "handler: \n"
+ "BX lr \n" /* Coming from handler mode */
+ "sp_stored: \n"
+ "MOV r1, lr \n"
+ "BL SVCHandler_main \n"
+ "BX r0 \n"
+ );
+}
+
+/**
+ * \brief Overwrites default Hard fault handler.
+ */
+#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
+void HardFault_Handler(void)
+{
+ /* HFSR can be read to provide further information of cause of HardFault */
+ __ASM volatile("b .");
+}
+#elif defined(__ARM_ARCH_6M__)
+void HardFault_Handler(void)
+{
+ /* In a baseline implementation there is no way, to find out whether this is
+ * a hard fault triggered directly, or another fault that has been
+ * escalated.
+ */
+ __ASM volatile("b .");
+}
+#endif
+
+/* Reserved for future usage */
+__attribute__((naked)) void MemManage_Handler(void)
+{
+ __ASM volatile("b .");
+}
+
+__attribute__((naked)) void BusFault_Handler(void)
+{
+ __ASM volatile("b .");
+}
+
+__attribute__((naked)) void UsageFault_Handler(void)
+{
+ __ASM volatile("b .");
+}
+
+void tfm_arch_prioritize_secure_exception(void)
+{
+}