1 /* 2 * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 #ifndef __TFM_ARCH_V6M_V7M_H__ 8 #define __TFM_ARCH_V6M_V7M_H__ 9 10 #include <stdint.h> 11 #include <stdbool.h> 12 #include <assert.h> 13 #include "cmsis_compiler.h" 14 #include "utilities.h" 15 16 #if !TFM_MULTI_CORE_TOPOLOGY 17 #error "Armv6-M/Armv7-M can only support multi-core TF-M now." 18 #endif 19 20 extern uint32_t psp_limit; 21 22 #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) 23 #define EXC_RETURN_FTYPE (1 << 4) 24 #endif 25 26 /* Exception return behavior */ 27 28 /* stack pointer used to restore context: 0=MSP 1=PSP. */ 29 #define EXC_RETURN_SPSEL (1UL << 2) 30 /* processor mode for return: 0=Handler mode 1=Thread mod. */ 31 #define EXC_RETURN_MODE (1UL << 3) 32 33 /* Exception numbers */ 34 #define EXC_NUM_THREAD_MODE (0) 35 #define EXC_NUM_SVCALL (11) 36 #define EXC_NUM_PENDSV (14) 37 38 #define SCB_ICSR_ADDR (0xE000ED04) 39 #define SCB_ICSR_PENDSVSET_BIT (0x10000000) 40 41 /** 42 * \brief Check whether Secure or Non-secure stack is used to restore stack 43 * frame on exception return. 44 * 45 * \param[in] lr LR register containing the EXC_RETURN value. 46 * 47 * \retval true Always return to Secure stack on secure core in 48 * multi-core topology. 49 */ is_return_secure_stack(uint32_t lr)50__STATIC_INLINE bool is_return_secure_stack(uint32_t lr) 51 { 52 (void)lr; 53 54 return true; 55 } 56 57 /** 58 * \brief Check whether the default stacking rules apply, or whether the 59 * Additional state context, also known as callee registers, 60 * are already on the stack. 61 * 62 * \param[in] lr LR register containing the EXC_RETURN value. 63 * 64 * \retval true Always use default stacking rules on 65 * v6m/v7m architectures. 66 */ is_default_stacking_rules_apply(uint32_t lr)67__STATIC_INLINE bool is_default_stacking_rules_apply(uint32_t lr) 68 { 69 (void)lr; 70 71 return true; 72 } 73 74 #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) 75 /** 76 * \brief Check whether the stack frame for this exception has space allocated 77 * for Floating Point(FP) state information. 78 * 79 * \param[in] lr LR register containing the EXC_RETURN value. 80 * 81 * \retval true The stack allocates space for FP information 82 * \retval false The stack doesn't allocate space for FP information 83 */ is_stack_alloc_fp_space(uint32_t lr)84__STATIC_INLINE bool is_stack_alloc_fp_space(uint32_t lr) 85 { 86 return (lr & EXC_RETURN_FTYPE) ? false : true; 87 } 88 #elif defined(__ARM_ARCH_6M__) 89 /** 90 * \brief Check whether the stack frame for this exception has space allocated 91 * for Floating Point(FP) state information. 92 * 93 * \param[in] lr LR register containing the EXC_RETURN value. 94 * 95 * \retval false The stack doesn't allocate space for FP information 96 */ is_stack_alloc_fp_space(uint32_t lr)97__STATIC_INLINE bool is_stack_alloc_fp_space(uint32_t lr) 98 { 99 (void)lr; 100 101 return false; 102 } 103 #endif 104 105 /** 106 * \brief Get PSP Limit. 107 * 108 * \retval psp limit Limit of PSP stack. 109 */ tfm_arch_get_psplim(void)110__STATIC_INLINE uint32_t tfm_arch_get_psplim(void) 111 { 112 return psp_limit; 113 } 114 115 /** 116 * \brief Set PSP limit value. 117 * 118 * \param[in] psplim PSP limit value to be written. 119 */ tfm_arch_set_psplim(uint32_t psplim)120__STATIC_INLINE void tfm_arch_set_psplim(uint32_t psplim) 121 { 122 psp_limit = psplim; 123 } 124 125 /** 126 * \brief Set MSP limit value. 127 * 128 * \param[in] msplim MSP limit value to be written. 129 */ tfm_arch_set_msplim(uint32_t msplim)130__STATIC_INLINE void tfm_arch_set_msplim(uint32_t msplim) 131 { 132 /* 133 * Defined as an empty function now. 134 * The MSP limit value can be used in more strict memory check. 135 */ 136 (void)msplim; 137 } 138 139 /** 140 * \brief Seal the thread stack. 141 * 142 * \param[in] stk Thread stack address. 143 * 144 * \retval stack Updated thread stack address. 145 */ arch_seal_thread_stack(uintptr_t stk)146__STATIC_INLINE uintptr_t arch_seal_thread_stack(uintptr_t stk) 147 { 148 assert((stk & 0x7) == 0); 149 return stk; 150 } 151 152 /** 153 * \brief Check MSP sealing. 154 */ tfm_arch_check_msp_sealing(void)155__STATIC_INLINE void tfm_arch_check_msp_sealing(void) 156 { 157 } 158 159 /* 160 * Update thread stack to architecture registers. 161 * The stack 'bottom' is higher address in this architecture, 162 * and 'toplimit' is the limit of top which is lower address. 163 */ arch_update_process_sp(uint32_t bottom,uint32_t toplimit)164__STATIC_INLINE void arch_update_process_sp(uint32_t bottom, 165 uint32_t toplimit) 166 { 167 __set_PSP(bottom); 168 psp_limit = toplimit; 169 __ISB(); 170 } 171 172 /** 173 * \brief Empty implementation for branch protection. 174 * PACBTI applies for v8.1M Main Extension onwards. 175 */ tfm_arch_config_branch_protection(void)176__STATIC_INLINE void tfm_arch_config_branch_protection(void) 177 { 178 } 179 180 #endif /* __TFM_ARCH_V6M_V7M_H__ */ 181