Zephyr API Documentation  2.7.0-rc2
A Scalable Open Source RTOS
arch.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014 Wind River Systems, Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
16#ifndef ZEPHYR_INCLUDE_ARCH_ARC_ARCH_H_
17#define ZEPHYR_INCLUDE_ARCH_ARC_ARCH_H_
18
19#include <devicetree.h>
20#include <sw_isr_table.h>
21#include <arch/common/ffs.h>
22#include <arch/arc/thread.h>
24#include "sys-io-common.h"
25
26#include <arch/arc/v2/exc.h>
27#include <arch/arc/v2/irq.h>
28#include <arch/arc/v2/misc.h>
33#include <arch/arc/v2/error.h>
34
35#ifdef CONFIG_ARC_CONNECT
37#endif
38
39#ifdef CONFIG_ISA_ARCV2
40#include "v2/sys_io.h"
41#ifdef CONFIG_ARC_HAS_SECURE
43#endif
44#endif
45
46#ifndef _ASMLANGUAGE
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52#ifdef CONFIG_64BIT
53#define ARCH_STACK_PTR_ALIGN 8
54#else
55#define ARCH_STACK_PTR_ALIGN 4
56#endif /* CONFIG_64BIT */
57
58/* Indicate, for a minimally sized MPU region, how large it must be and what
59 * its base address must be aligned to.
60 *
61 * For regions that are NOT the minimum size, this define has no semantics
62 * on ARC MPUv2 as its regions must be power of two size and aligned to their
63 * own size. On ARC MPUv4, region sizes are arbitrary and this just indicates
64 * the required size granularity.
65 */
66#ifdef CONFIG_ARC_CORE_MPU
67#if CONFIG_ARC_MPU_VER == 2
68#define Z_ARC_MPU_ALIGN 2048
69#elif (CONFIG_ARC_MPU_VER == 3) || (CONFIG_ARC_MPU_VER == 4) || (CONFIG_ARC_MPU_VER == 6)
70#define Z_ARC_MPU_ALIGN 32
71#else
72#error "Unsupported MPU version"
73#endif
74#endif
75
76#ifdef CONFIG_MPU_STACK_GUARD
77#define Z_ARC_STACK_GUARD_SIZE Z_ARC_MPU_ALIGN
78#else
79#define Z_ARC_STACK_GUARD_SIZE 0
80#endif
81
82/* Kernel-only stacks have the following layout if a stack guard is enabled:
83 *
84 * +------------+ <- thread.stack_obj
85 * | Guard | } Z_ARC_STACK_GUARD_SIZE
86 * +------------+ <- thread.stack_info.start
87 * | Kernel |
88 * | stack |
89 * | |
90 * +............|
91 * | TLS | } thread.stack_info.delta
92 * +------------+ <- thread.stack_info.start + thread.stack_info.size
93 */
94#ifdef CONFIG_MPU_STACK_GUARD
95#define ARCH_KERNEL_STACK_RESERVED Z_ARC_STACK_GUARD_SIZE
96#define ARCH_KERNEL_STACK_OBJ_ALIGN Z_ARC_MPU_ALIGN
97#endif
98
99#ifdef CONFIG_USERSPACE
100/* Any thread running In user mode will have full access to the region denoted
101 * by thread.stack_info.
102 *
103 * Thread-local storage is at the very highest memory locations of this area.
104 * Memory for TLS and any initial random stack pointer offset is captured
105 * in thread.stack_info.delta.
106 */
107#ifdef CONFIG_MPU_STACK_GUARD
108/* MPU guards are only supported with V3 MPU and later. In this configuration
109 * the stack object will contain the MPU guard, the privilege stack, and then
110 * the stack buffer in that order:
111 *
112 * +------------+ <- thread.stack_obj
113 * | Guard | } Z_ARC_STACK_GUARD_SIZE
114 * +------------+ <- thread.arch.priv_stack_start
115 * | Priv Stack | } CONFIG_PRIVILEGED_STACK_SIZE
116 * +------------+ <- thread.stack_info.start
117 * | Thread |
118 * | stack |
119 * | |
120 * +............|
121 * | TLS | } thread.stack_info.delta
122 * +------------+ <- thread.stack_info.start + thread.stack_info.size
123 */
124#define ARCH_THREAD_STACK_RESERVED (Z_ARC_STACK_GUARD_SIZE + \
125 CONFIG_PRIVILEGED_STACK_SIZE)
126#define ARCH_THREAD_STACK_OBJ_ALIGN(size) Z_ARC_MPU_ALIGN
127/* We need to be able to exactly cover the stack buffer with an MPU region,
128 * so round its size up to the required granularity of the MPU
129 */
130#define ARCH_THREAD_STACK_SIZE_ADJUST(size) \
131 (ROUND_UP((size), Z_ARC_MPU_ALIGN))
132BUILD_ASSERT(CONFIG_PRIVILEGED_STACK_SIZE % Z_ARC_MPU_ALIGN == 0,
133 "improper privilege stack size");
134#else /* !CONFIG_MPU_STACK_GUARD */
135/* Userspace enabled, but supervisor stack guards are not in use */
136#ifdef CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT
137/* Use defaults for everything. The privilege elevation stack is located
138 * in another area of memory generated at build time by gen_kobject_list.py
139 *
140 * +------------+ <- thread.arch.priv_stack_start
141 * | Priv Stack | } Z_KERNEL_STACK_LEN(CONFIG_PRIVILEGED_STACK_SIZE)
142 * +------------+
143 *
144 * +------------+ <- thread.stack_obj = thread.stack_info.start
145 * | Thread |
146 * | stack |
147 * | |
148 * +............|
149 * | TLS | } thread.stack_info.delta
150 * +------------+ <- thread.stack_info.start + thread.stack_info.size
151 */
152#define ARCH_THREAD_STACK_SIZE_ADJUST(size) \
153 Z_POW2_CEIL(ROUND_UP((size), Z_ARC_MPU_ALIGN))
154#define ARCH_THREAD_STACK_OBJ_ALIGN(size) \
155 ARCH_THREAD_STACK_SIZE_ADJUST(size)
156#define ARCH_THREAD_STACK_RESERVED 0
157#else /* !CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT */
158/* Reserved area of the thread object just contains the privilege stack:
159 *
160 * +------------+ <- thread.stack_obj = thread.arch.priv_stack_start
161 * | Priv Stack | } CONFIG_PRIVILEGED_STACK_SIZE
162 * +------------+ <- thread.stack_info.start
163 * | Thread |
164 * | stack |
165 * | |
166 * +............|
167 * | TLS | } thread.stack_info.delta
168 * +------------+ <- thread.stack_info.start + thread.stack_info.size
169 */
170#define ARCH_THREAD_STACK_RESERVED CONFIG_PRIVILEGED_STACK_SIZE
171#define ARCH_THREAD_STACK_SIZE_ADJUST(size) \
172 (ROUND_UP((size), Z_ARC_MPU_ALIGN))
173#define ARCH_THREAD_STACK_OBJ_ALIGN(size) Z_ARC_MPU_ALIGN
174
175BUILD_ASSERT(CONFIG_PRIVILEGED_STACK_SIZE % Z_ARC_MPU_ALIGN == 0,
176 "improper privilege stack size");
177#endif /* CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT */
178#endif /* CONFIG_MPU_STACK_GUARD */
179
180#else /* !CONFIG_USERSPACE */
181
182#ifdef CONFIG_MPU_STACK_GUARD
183/* Only supported on ARC MPU V3 and higher. Reserve some memory for the stack
184 * guard. This is just a minimally-sized region at the beginning of the stack
185 * object, which is programmed to produce an exception if written to.
186 *
187 * +------------+ <- thread.stack_obj
188 * | Guard | } Z_ARC_STACK_GUARD_SIZE
189 * +------------+ <- thread.stack_info.start
190 * | Thread |
191 * | stack |
192 * | |
193 * +............|
194 * | TLS | } thread.stack_info.delta
195 * +------------+ <- thread.stack_info.start + thread.stack_info.size
196 */
197#define ARCH_THREAD_STACK_RESERVED Z_ARC_STACK_GUARD_SIZE
198#define ARCH_THREAD_STACK_OBJ_ALIGN(size) Z_ARC_MPU_ALIGN
199/* Default for ARCH_THREAD_STACK_SIZE_ADJUST */
200#else /* !CONFIG_MPU_STACK_GUARD */
201/* No stack guard, no userspace, Use defaults for everything. */
202#endif /* CONFIG_MPU_STACK_GUARD */
203#endif /* CONFIG_USERSPACE */
204
205#ifdef CONFIG_ARC_MPU
206
207/* Legacy case: retain containing extern "C" with C++ */
209
210#define K_MEM_PARTITION_P_NA_U_NA AUX_MPU_ATTR_N
211#define K_MEM_PARTITION_P_RW_U_RW (AUX_MPU_ATTR_UW | AUX_MPU_ATTR_UR | \
212 AUX_MPU_ATTR_KW | AUX_MPU_ATTR_KR)
213#define K_MEM_PARTITION_P_RW_U_RO (AUX_MPU_ATTR_UR | \
214 AUX_MPU_ATTR_KW | AUX_MPU_ATTR_KR)
215#define K_MEM_PARTITION_P_RW_U_NA (AUX_MPU_ATTR_KW | AUX_MPU_ATTR_KR)
216#define K_MEM_PARTITION_P_RO_U_RO (AUX_MPU_ATTR_UR | AUX_MPU_ATTR_KR)
217#define K_MEM_PARTITION_P_RO_U_NA (AUX_MPU_ATTR_KR)
218
219/* Execution-allowed attributes */
220#define K_MEM_PARTITION_P_RWX_U_RWX (AUX_MPU_ATTR_UW | AUX_MPU_ATTR_UR | \
221 AUX_MPU_ATTR_KW | AUX_MPU_ATTR_KR | \
222 AUX_MPU_ATTR_KE | AUX_MPU_ATTR_UE)
223#define K_MEM_PARTITION_P_RWX_U_RX (AUX_MPU_ATTR_UR | \
224 AUX_MPU_ATTR_KW | AUX_MPU_ATTR_KR | \
225 AUX_MPU_ATTR_KE | AUX_MPU_ATTR_UE)
226#define K_MEM_PARTITION_P_RX_U_RX (AUX_MPU_ATTR_UR | \
227 AUX_MPU_ATTR_KR | \
228 AUX_MPU_ATTR_KE | AUX_MPU_ATTR_UE)
229
230#define K_MEM_PARTITION_IS_WRITABLE(attr) \
231 ({ \
232 int __is_writable__; \
233 switch (attr & (AUX_MPU_ATTR_UW | AUX_MPU_ATTR_KW)) { \
234 case (AUX_MPU_ATTR_UW | AUX_MPU_ATTR_KW): \
235 case AUX_MPU_ATTR_UW: \
236 case AUX_MPU_ATTR_KW: \
237 __is_writable__ = 1; \
238 break; \
239 default: \
240 __is_writable__ = 0; \
241 break; \
242 } \
243 __is_writable__; \
244 })
245#define K_MEM_PARTITION_IS_EXECUTABLE(attr) \
246 ((attr) & (AUX_MPU_ATTR_KE | AUX_MPU_ATTR_UE))
247
248#if CONFIG_ARC_MPU_VER == 2
249#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \
250 BUILD_ASSERT(!(((size) & ((size) - 1))) && (size) >= Z_ARC_MPU_ALIGN \
251 && !((uint32_t)(start) & ((size) - 1)), \
252 "the size of the partition must be power of 2" \
253 " and greater than or equal to the mpu adddress alignment." \
254 "start address of the partition must align with size.")
255#elif CONFIG_ARC_MPU_VER == 4
256#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \
257 BUILD_ASSERT((size) % Z_ARC_MPU_ALIGN == 0 && \
258 (size) >= Z_ARC_MPU_ALIGN && \
259 (uint32_t)(start) % Z_ARC_MPU_ALIGN == 0, \
260 "the size of the partition must align with 32" \
261 " and greater than or equal to 32." \
262 "start address of the partition must align with 32.")
263#endif
264#endif /* CONFIG_ARC_MPU*/
265
266/* Typedef for the k_mem_partition attribute*/
268
269static ALWAYS_INLINE void arch_nop(void)
270{
271 __builtin_arc_nop();
272}
273
274#endif /* _ASMLANGUAGE */
275
276#ifdef __cplusplus
277}
278#endif
279#endif /* ZEPHYR_INCLUDE_ARCH_ARC_ARCH_H_ */
static ALWAYS_INLINE void arch_nop(void)
Definition: arch.h:269
uint32_t k_mem_partition_attr_t
Definition: arch.h:267
ARCv2 public error handling.
ARCv2 public exception handling.
ARCv2 public kernel miscellaneous.
ARCv2 ARC Connect driver.
Per-arch thread definition.
ARCv2 public interrupt handling.
ARCv2 auxiliary registers definitions.
#define ALWAYS_INLINE
Definition: common.h:116
Devicetree main header.
__UINT32_TYPE__ uint32_t
Definition: stdint.h:60
Software-managed ISR table.