Line data Source code
1 1 : /*
2 : * Copyright (c) 2013-2014 Wind River Systems, Inc.
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief ARM AArch32 specific kernel interface header
10 : *
11 : * This header contains the ARM AArch32 specific kernel interface. It is
12 : * included by the kernel interface architecture-abstraction header
13 : * (include/zephyr/arch/cpu.h).
14 : */
15 :
16 : #ifndef ZEPHYR_INCLUDE_ARCH_ARM_ARCH_H_
17 : #define ZEPHYR_INCLUDE_ARCH_ARM_ARCH_H_
18 :
19 : /* Add include for DTS generated information */
20 : #include <zephyr/devicetree.h>
21 :
22 : #include <zephyr/arch/arm/thread.h>
23 : #include <zephyr/arch/arm/exception.h>
24 : #include <zephyr/arch/arm/irq.h>
25 : #include <zephyr/arch/arm/error.h>
26 : #include <zephyr/arch/arm/misc.h>
27 : #include <zephyr/arch/common/addr_types.h>
28 : #include <zephyr/arch/common/ffs.h>
29 : #include <zephyr/arch/arm/nmi.h>
30 : #include <zephyr/arch/arm/asm_inline.h>
31 : #include <zephyr/arch/common/sys_bitops.h>
32 : #if defined(CONFIG_GDBSTUB)
33 : #include <zephyr/arch/arm/gdbstub.h>
34 : #endif
35 :
36 : #ifdef CONFIG_CPU_CORTEX_M
37 : #include <zephyr/arch/arm/cortex_m/cpu.h>
38 : #include <zephyr/arch/arm/cortex_m/memory_map.h>
39 : #include <zephyr/arch/common/sys_io.h>
40 : #elif defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A)
41 : #include <zephyr/arch/arm/cortex_a_r/cpu.h>
42 : #include <zephyr/arch/arm/cortex_a_r/sys_io.h>
43 : #if defined(CONFIG_AARCH32_ARMV8_R) || defined(CONFIG_CPU_CORTEX_A7)
44 : #include <zephyr/arch/arm/cortex_a_r/lib_helpers.h>
45 : #include <zephyr/arch/arm/cortex_a_r/armv7_v8_timer.h>
46 : #else
47 : #include <zephyr/arch/arm/cortex_a_r/timer.h>
48 : #endif
49 : #endif
50 :
51 : #ifdef __cplusplus
52 : extern "C" {
53 : #endif
54 :
55 : #ifndef _ASMLANGUAGE
56 :
57 : #include <zephyr/fatal_types.h>
58 :
59 0 : enum k_fatal_error_reason_arch {
60 : /* Cortex-M MEMFAULT exceptions */
61 : K_ERR_ARM_MEM_GENERIC = K_ERR_ARCH_START,
62 : K_ERR_ARM_MEM_STACKING,
63 : K_ERR_ARM_MEM_UNSTACKING,
64 : K_ERR_ARM_MEM_DATA_ACCESS,
65 : K_ERR_ARM_MEM_INSTRUCTION_ACCESS,
66 : K_ERR_ARM_MEM_FP_LAZY_STATE_PRESERVATION,
67 :
68 : /* Cortex-M BUSFAULT exceptions */
69 : K_ERR_ARM_BUS_GENERIC,
70 : K_ERR_ARM_BUS_STACKING,
71 : K_ERR_ARM_BUS_UNSTACKING,
72 : K_ERR_ARM_BUS_PRECISE_DATA_BUS,
73 : K_ERR_ARM_BUS_IMPRECISE_DATA_BUS,
74 : K_ERR_ARM_BUS_INSTRUCTION_BUS,
75 : K_ERR_ARM_BUS_FP_LAZY_STATE_PRESERVATION,
76 :
77 : /* Cortex-M USAGEFAULT exceptions */
78 : K_ERR_ARM_USAGE_GENERIC,
79 : K_ERR_ARM_USAGE_DIV_0,
80 : K_ERR_ARM_USAGE_UNALIGNED_ACCESS,
81 : K_ERR_ARM_USAGE_STACK_OVERFLOW,
82 : K_ERR_ARM_USAGE_NO_COPROCESSOR,
83 : K_ERR_ARM_USAGE_ILLEGAL_EXC_RETURN,
84 : K_ERR_ARM_USAGE_ILLEGAL_EPSR,
85 : K_ERR_ARM_USAGE_UNDEFINED_INSTRUCTION,
86 :
87 : /* Cortex-M SECURE exceptions */
88 : K_ERR_ARM_SECURE_GENERIC,
89 : K_ERR_ARM_SECURE_ENTRY_POINT,
90 : K_ERR_ARM_SECURE_INTEGRITY_SIGNATURE,
91 : K_ERR_ARM_SECURE_EXCEPTION_RETURN,
92 : K_ERR_ARM_SECURE_ATTRIBUTION_UNIT,
93 : K_ERR_ARM_SECURE_TRANSITION,
94 : K_ERR_ARM_SECURE_LAZY_STATE_PRESERVATION,
95 : K_ERR_ARM_SECURE_LAZY_STATE_ERROR,
96 :
97 : /* Cortex-A/R exceptions*/
98 : K_ERR_ARM_UNDEFINED_INSTRUCTION,
99 : K_ERR_ARM_ALIGNMENT_FAULT,
100 : K_ERR_ARM_BACKGROUND_FAULT,
101 : K_ERR_ARM_PERMISSION_FAULT,
102 : K_ERR_ARM_PERMISSION_FAULT_2ND_LEVEL,
103 : K_ERR_ARM_SYNC_EXTERNAL_ABORT,
104 : K_ERR_ARM_ASYNC_EXTERNAL_ABORT,
105 : K_ERR_ARM_SYNC_PARITY_ERROR,
106 : K_ERR_ARM_ASYNC_PARITY_ERROR,
107 : K_ERR_ARM_DEBUG_EVENT,
108 : K_ERR_ARM_TRANSLATION_FAULT,
109 : K_ERR_ARM_TRANSLATION_FAULT_2ND_LEVEL,
110 : K_ERR_ARM_UNSUPPORTED_EXCLUSIVE_ACCESS_FAULT,
111 : K_ERR_ARM_ACCESS_FLAG_FAULT_1ST_LEVEL,
112 : K_ERR_ARM_ACCESS_FLAG_FAULT_2ND_LEVEL,
113 : K_ERR_ARM_CACHE_MAINTENANCE_INSTRUCTION_FAULT,
114 : K_ERR_ARM_DOMAIN_FAULT_1ST_LEVEL,
115 : K_ERR_ARM_DOMAIN_FAULT_2ND_LEVEL,
116 : K_ERR_ARM_SYNC_EXTERNAL_ABORT_TRANSLATION_TABLE_1ST_LEVEL,
117 : K_ERR_ARM_SYNC_EXTERNAL_ABORT_TRANSLATION_TABLE_2ND_LEVEL,
118 : K_ERR_ARM_TLB_CONFLICT_ABORT,
119 : K_ERR_ARM_SYNC_PARITY_ERROR_TRANSLATION_TABLE_1ST_LEVEL,
120 : K_ERR_ARM_SYNC_PARITY_ERROR_TRANSLATION_TABLE_2ND_LEVEL,
121 : };
122 :
123 : #endif /* _ASMLANGUAGE */
124 :
125 : /**
126 : * @brief Declare the ARCH_STACK_PTR_ALIGN
127 : *
128 : * Denotes the required alignment of the stack pointer on public API
129 : * boundaries
130 : *
131 : */
132 : #ifdef CONFIG_STACK_ALIGN_DOUBLE_WORD
133 : #define ARCH_STACK_PTR_ALIGN 8
134 : #else
135 1 : #define ARCH_STACK_PTR_ALIGN 4
136 : #endif
137 :
138 : /**
139 : * @brief Declare the minimum alignment for a thread stack
140 : *
141 : * Denotes the minimum required alignment of a thread stack.
142 : *
143 : * Note:
144 : * User thread stacks must respect the minimum MPU region
145 : * alignment requirement.
146 : */
147 : #if defined(CONFIG_USERSPACE)
148 : #define Z_THREAD_MIN_STACK_ALIGN CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
149 : #elif defined(CONFIG_ARM_AARCH32_MMU)
150 : #define Z_THREAD_MIN_STACK_ALIGN CONFIG_ARM_MMU_REGION_MIN_ALIGN_AND_SIZE
151 : #else
152 : #define Z_THREAD_MIN_STACK_ALIGN ARCH_STACK_PTR_ALIGN
153 : #endif
154 :
155 : /**
156 : * @brief Declare a minimum MPU guard alignment and size
157 : *
158 : * This specifies the minimum MPU guard alignment/size for the MPU. This
159 : * will be used to denote the guard section of the stack, if it exists.
160 : *
161 : * One key note is that this guard results in extra bytes being added to
162 : * the stack. APIs which give the stack ptr and stack size will take this
163 : * guard size into account.
164 : *
165 : * Stack is allocated, but initial stack pointer is at the end
166 : * (highest address). Stack grows down to the actual allocation
167 : * address (lowest address). Stack guard, if present, will comprise
168 : * the lowest MPU_GUARD_ALIGN_AND_SIZE bytes of the stack.
169 : *
170 : * The guard region must include enough space for an exception frame
171 : * below the trapping region as a stack fault will end up storing
172 : * the exception data (0x20 bytes) onto the stack below wherever
173 : * the stack pointer refers, even if that is within the guard region,
174 : * so we make sure the region is strictly larger than this size by
175 : * setting it to 0x40 (to respect any power-of-two requirements).
176 : *
177 : * As the stack grows down, it will reach the end of the stack when it
178 : * encounters either the stack guard region, or the stack allocation
179 : * address.
180 : *
181 : * ----------------------- <---- Stack allocation address + stack size +
182 : * | | MPU_GUARD_ALIGN_AND_SIZE
183 : * | Some thread data | <---- Defined when thread is created
184 : * | ... |
185 : * |---------------------| <---- Actual initial stack ptr
186 : * | Initial Stack Ptr | aligned to ARCH_STACK_PTR_ALIGN
187 : * | ... |
188 : * | ... |
189 : * | ... |
190 : * | ... |
191 : * | ... |
192 : * | ... |
193 : * | ... |
194 : * | ... |
195 : * | Stack Ends |
196 : * |---------------------- <---- Stack Buffer Ptr from API
197 : * | MPU Guard, |
198 : * | if present |
199 : * ----------------------- <---- Stack Allocation address
200 : *
201 : */
202 : #if defined(CONFIG_MPU_STACK_GUARD)
203 : /* make sure there's more than enough space for an exception frame */
204 : #if CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE <= 0x20
205 : #define MPU_GUARD_ALIGN_AND_SIZE 0x40
206 : #else
207 : #define MPU_GUARD_ALIGN_AND_SIZE CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
208 : #endif
209 : #else
210 1 : #define MPU_GUARD_ALIGN_AND_SIZE 0
211 : #endif
212 :
213 : /**
214 : * @brief Declare the MPU guard alignment and size for a thread stack
215 : * that is using the Floating Point services.
216 : *
217 : * For threads that are using the Floating Point services under Shared
218 : * Registers (CONFIG_FPU_SHARING=y) mode, the exception stack frame may
219 : * contain both the basic stack frame and the FP caller-saved context,
220 : * upon exception entry. Therefore, a wide guard region is required to
221 : * guarantee that stack-overflow detection will always be successful.
222 : */
223 : #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) \
224 : && defined(CONFIG_MPU_STACK_GUARD)
225 : #if CONFIG_MPU_STACK_GUARD_MIN_SIZE_FLOAT <= 0x20
226 : #define MPU_GUARD_ALIGN_AND_SIZE_FLOAT 0x40
227 : #else
228 : #define MPU_GUARD_ALIGN_AND_SIZE_FLOAT CONFIG_MPU_STACK_GUARD_MIN_SIZE_FLOAT
229 : #endif
230 : #else
231 1 : #define MPU_GUARD_ALIGN_AND_SIZE_FLOAT 0
232 : #endif
233 :
234 : /**
235 : * @brief Define alignment of an MPU guard
236 : *
237 : * Minimum alignment of the start address of an MPU guard, depending on
238 : * whether the MPU architecture enforces a size (and power-of-two) alignment
239 : * requirement.
240 : */
241 : #if defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
242 : #define Z_MPU_GUARD_ALIGN (MAX(MPU_GUARD_ALIGN_AND_SIZE, \
243 : MPU_GUARD_ALIGN_AND_SIZE_FLOAT))
244 : #else
245 : #define Z_MPU_GUARD_ALIGN MPU_GUARD_ALIGN_AND_SIZE
246 : #endif
247 :
248 : #if defined(CONFIG_USERSPACE) && \
249 : defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
250 : /* This MPU requires regions to be sized to a power of two, and aligned to
251 : * their own size. Since an MPU region must be able to cover the entire
252 : * user-accessible stack buffer, we size/align to match. The privilege
253 : * mode stack is generated elsewhere in memory.
254 : */
255 : #define ARCH_THREAD_STACK_OBJ_ALIGN(size) Z_POW2_CEIL(size)
256 : #define ARCH_THREAD_STACK_SIZE_ADJUST(size) Z_POW2_CEIL(size)
257 : #else
258 0 : #define ARCH_THREAD_STACK_OBJ_ALIGN(size) MAX(Z_THREAD_MIN_STACK_ALIGN, \
259 : Z_MPU_GUARD_ALIGN)
260 : #ifdef CONFIG_USERSPACE
261 0 : #define ARCH_THREAD_STACK_SIZE_ADJUST(size) \
262 : ROUND_UP(size, CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE)
263 : #endif
264 : #endif
265 :
266 : #ifdef CONFIG_MPU_STACK_GUARD
267 : /* Kernel-only stacks need an MPU guard region programmed at the beginning of
268 : * the stack object, so align the object appropriately.
269 : */
270 : #define ARCH_KERNEL_STACK_RESERVED MPU_GUARD_ALIGN_AND_SIZE
271 : #define ARCH_KERNEL_STACK_OBJ_ALIGN Z_MPU_GUARD_ALIGN
272 : #endif
273 :
274 : /* On arm, all MPU guards are carve-outs. */
275 0 : #define ARCH_THREAD_STACK_RESERVED 0
276 :
277 : /* Legacy case: retain containing extern "C" with C++ */
278 : #ifdef CONFIG_ARM_MPU
279 : #ifdef CONFIG_CPU_HAS_ARM_MPU
280 : #include <zephyr/arch/arm/mpu/arm_mpu.h>
281 : #endif /* CONFIG_CPU_HAS_ARM_MPU */
282 : #ifdef CONFIG_CPU_HAS_NXP_SYSMPU
283 : #include <zephyr/arch/arm/mpu/nxp_mpu.h>
284 : #endif /* CONFIG_CPU_HAS_NXP_SYSMPU */
285 : #endif /* CONFIG_ARM_MPU */
286 : #ifdef CONFIG_ARM_AARCH32_MMU
287 : #include <zephyr/arch/arm/mmu/arm_mmu.h>
288 : #endif /* CONFIG_ARM_AARCH32_MMU */
289 :
290 : #ifdef __cplusplus
291 : }
292 : #endif
293 :
294 : #endif /* ZEPHYR_INCLUDE_ARCH_ARM_ARCH_H_ */
|