1 /*
2  * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
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 "cmsis_compiler.h"
13 #include "utilities.h"
14 
15 #if !TFM_MULTI_CORE_TOPOLOGY
16 #error "Armv6-M/Armv7-M can only support multi-core TF-M now."
17 #endif
18 
19 #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
20 #define EXC_RETURN_FPU_FRAME_BASIC              (1 << 4)
21 #endif
22 
23 #define EXC_RETURN_THREAD_S_PSP                 0xFFFFFFFD
24 #define EXC_RETURN_HANDLER_S_MSP                0xFFFFFFF1
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 #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
58 /**
59  * \brief Check whether the stack frame for this exception has space allocated
60  *        for Floating Point(FP) state information.
61  *
62  * \param[in] lr            LR register containing the EXC_RETURN value.
63  *
64  * \retval true             The stack allocates space for FP information
65  * \retval false            The stack doesn't allocate space for FP information
66  */
is_stack_alloc_fp_space(uint32_t lr)67 __STATIC_INLINE bool is_stack_alloc_fp_space(uint32_t lr)
68 {
69     return (lr & EXC_RETURN_FPU_FRAME_BASIC) ? false : true;
70 }
71 #elif defined(__ARM_ARCH_6M__)
72 /**
73  * \brief Check whether the stack frame for this exception has space allocated
74  *        for Floating Point(FP) state information.
75  *
76  * \param[in] lr            LR register containing the EXC_RETURN value.
77  *
78  * \retval false            The stack doesn't allocate space for FP information
79  */
is_stack_alloc_fp_space(uint32_t lr)80 __STATIC_INLINE bool is_stack_alloc_fp_space(uint32_t lr)
81 {
82     (void)lr;
83 
84     return false;
85 }
86 #endif
87 
88 /**
89  * \brief Set PSP limit value.
90  *
91  * \param[in] psplim        PSP limit value to be written.
92  */
tfm_arch_set_psplim(uint32_t psplim)93 __STATIC_INLINE void tfm_arch_set_psplim(uint32_t psplim)
94 {
95     /*
96      * Defined as an empty function now.
97      * The PSP limit value can be used in more strict memory check.
98      */
99     (void)psplim;
100 }
101 
102 /**
103  * \brief Set MSP limit value.
104  *
105  * \param[in] msplim        MSP limit value to be written.
106  */
tfm_arch_set_msplim(uint32_t msplim)107 __STATIC_INLINE void tfm_arch_set_msplim(uint32_t msplim)
108 {
109     /*
110      * Defined as an empty function now.
111      * The MSP limit value can be used in more strict memory check.
112      */
113     (void)msplim;
114 }
115 
116 /**
117  * \brief Seal the thread stack.
118  *
119  * \param[in] stk        Thread stack address.
120  *
121  * \retval stack         Updated thread stack address.
122  */
arch_seal_thread_stack(uintptr_t stk)123 __STATIC_INLINE uintptr_t arch_seal_thread_stack(uintptr_t stk)
124 {
125     SPM_ASSERT((stk & 0x7) == 0);
126     return stk;
127 }
128 
129 /**
130  * \brief Check MSP sealing.
131  */
tfm_arch_check_msp_sealing(void)132 __STATIC_INLINE void tfm_arch_check_msp_sealing(void)
133 {
134 }
135 #endif /* __TFM_ARCH_V6M_V7M_H__ */
136