diff options
author | David Hu <david.hu@arm.com> | 2019-07-02 14:31:34 +0800 |
---|---|---|
committer | David Hu <david.hu@arm.com> | 2019-07-04 16:13:16 +0800 |
commit | 5ff8dbf63964925ff213310e91fe814348c5f43f (patch) | |
tree | 44951e9a0b6ad167c1145865f1d4bfb834333d8e | |
parent | cfbf2a2fe46809b8b27de01079b16f903ad2bd0a (diff) | |
download | trusted-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.cmake | 1 | ||||
-rw-r--r-- | platform/ext/psoc6_sc.cmake | 1 | ||||
-rw-r--r-- | secure_fw/core/arch/CMakeLists.inc | 7 | ||||
-rw-r--r-- | secure_fw/core/arch/include/tfm_arch.h | 3 | ||||
-rw-r--r-- | secure_fw/core/arch/include/tfm_arch_v6m_v7m.h | 113 | ||||
-rw-r--r-- | secure_fw/core/arch/tfm_arch_v6m_v7m.c | 139 |
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) +{ +} |