Zephyr Project API 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
arm_mpu_v7m.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 Linaro Limited.
3 * Copyright (c) 2018 Nordic Semiconductor ASA.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef ZEPHYR_INCLUDE_ARCH_ARM_MPU_ARM_MPU_V7M_H_
9#define ZEPHYR_INCLUDE_ARCH_ARM_MPU_ARM_MPU_V7M_H_
10
11#ifndef _ASMLANGUAGE
12
13#include <cmsis_core.h>
14
15/* Convenience macros to represent the ARMv7-M-specific
16 * configuration for memory access permission and
17 * cache-ability attribution.
18 */
19
20/* Privileged No Access, Unprivileged No Access */
21#define NO_ACCESS 0x0
22#define NO_ACCESS_Msk ((NO_ACCESS << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
23/* Privileged No Access, Unprivileged No Access */
24#define P_NA_U_NA 0x0
25#define P_NA_U_NA_Msk ((P_NA_U_NA << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
26/* Privileged Read Write, Unprivileged No Access */
27#define P_RW_U_NA 0x1
28#define P_RW_U_NA_Msk ((P_RW_U_NA << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
29/* Privileged Read Write, Unprivileged Read Only */
30#define P_RW_U_RO 0x2
31#define P_RW_U_RO_Msk ((P_RW_U_RO << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
32/* Privileged Read Write, Unprivileged Read Write */
33#define P_RW_U_RW 0x3U
34#define P_RW_U_RW_Msk ((P_RW_U_RW << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
35/* Privileged Read Write, Unprivileged Read Write */
36#define FULL_ACCESS 0x3
37#define FULL_ACCESS_Msk ((FULL_ACCESS << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
38/* Privileged Read Only, Unprivileged No Access */
39#define P_RO_U_NA 0x5
40#define P_RO_U_NA_Msk ((P_RO_U_NA << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
41/* Privileged Read Only, Unprivileged Read Only */
42#define P_RO_U_RO 0x6
43#define P_RO_U_RO_Msk ((P_RO_U_RO << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
44/* Note: mode 0x7 is the same as 0x6 but supported only by Cortex-M, not Cortex-R */
45
46/* Attribute flag for not-allowing execution (eXecute Never) */
47#define NOT_EXEC MPU_RASR_XN_Msk
48
49/* The following definitions are for internal use in arm_mpu.h. */
50#define STRONGLY_ORDERED_SHAREABLE MPU_RASR_S_Msk
51#define DEVICE_SHAREABLE (MPU_RASR_B_Msk | MPU_RASR_S_Msk)
52#define NORMAL_OUTER_INNER_WRITE_THROUGH_SHAREABLE (MPU_RASR_C_Msk | MPU_RASR_S_Msk)
53#define NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE MPU_RASR_C_Msk
54/* clang-format off */
55#define NORMAL_OUTER_INNER_WRITE_BACK_SHAREABLE \
56 (MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk)
57/* clang-format on */
58#define NORMAL_OUTER_INNER_WRITE_BACK_NON_SHAREABLE (MPU_RASR_C_Msk | MPU_RASR_B_Msk)
59#define NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE ((1 << MPU_RASR_TEX_Pos) | MPU_RASR_S_Msk)
60#define NORMAL_OUTER_INNER_NON_CACHEABLE_NON_SHAREABLE (1 << MPU_RASR_TEX_Pos)
61#define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_SHAREABLE \
62 ((1 << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk)
63#define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE \
64 ((1 << MPU_RASR_TEX_Pos) | MPU_RASR_C_Msk | MPU_RASR_B_Msk)
65#define DEVICE_NON_SHAREABLE (2 << MPU_RASR_TEX_Pos)
66
67/* Bit-masks to disable sub-regions. */
68#define SUB_REGION_0_DISABLED ((0x01 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
69#define SUB_REGION_1_DISABLED ((0x02 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
70#define SUB_REGION_2_DISABLED ((0x04 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
71#define SUB_REGION_3_DISABLED ((0x08 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
72#define SUB_REGION_4_DISABLED ((0x10 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
73#define SUB_REGION_5_DISABLED ((0x20 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
74#define SUB_REGION_6_DISABLED ((0x40 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
75#define SUB_REGION_7_DISABLED ((0x80 << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk)
76
77#define REGION_SIZE(size) ((ARM_MPU_REGION_SIZE_##size << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk)
78
79#define REGION_32B REGION_SIZE(32B)
80#define REGION_64B REGION_SIZE(64B)
81#define REGION_128B REGION_SIZE(128B)
82#define REGION_256B REGION_SIZE(256B)
83#define REGION_512B REGION_SIZE(512B)
84#define REGION_1K REGION_SIZE(1KB)
85#define REGION_2K REGION_SIZE(2KB)
86#define REGION_4K REGION_SIZE(4KB)
87#define REGION_8K REGION_SIZE(8KB)
88#define REGION_16K REGION_SIZE(16KB)
89#define REGION_32K REGION_SIZE(32KB)
90#define REGION_64K REGION_SIZE(64KB)
91#define REGION_128K REGION_SIZE(128KB)
92#define REGION_256K REGION_SIZE(256KB)
93#define REGION_512K REGION_SIZE(512KB)
94#define REGION_1M REGION_SIZE(1MB)
95#define REGION_2M REGION_SIZE(2MB)
96#define REGION_4M REGION_SIZE(4MB)
97#define REGION_8M REGION_SIZE(8MB)
98#define REGION_16M REGION_SIZE(16MB)
99#define REGION_32M REGION_SIZE(32MB)
100#define REGION_64M REGION_SIZE(64MB)
101#define REGION_128M REGION_SIZE(128MB)
102#define REGION_256M REGION_SIZE(256MB)
103#define REGION_512M REGION_SIZE(512MB)
104#define REGION_1G REGION_SIZE(1GB)
105#define REGION_2G REGION_SIZE(2GB)
106#define REGION_4G REGION_SIZE(4GB)
107
108#if defined(CONFIG_CPU_AARCH32_CORTEX_R)
109#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \
110 { \
111 .name = p_name, \
112 .base = p_base, \
113 .size = size_to_mpu_rasr_size(p_size), \
114 .attr = p_attr(0U), \
115 }
116
117#else
118#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \
119 { \
120 .name = p_name, \
121 .base = p_base, \
122 .attr = p_attr(size_to_mpu_rasr_size(p_size)), \
123 }
124#endif
125
126/* Some helper defines for common regions */
127
128/* On Cortex-M, we can only set the XN bit when CONFIG_XIP=y. When
129 * CONFIG_XIP=n, the entire image will be linked to SRAM, so we need to keep
130 * the SRAM region XN bit clear or the application code will not be executable.
131 */
132#define REGION_RAM_ATTR(size) \
133 {(NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE | \
134 IF_ENABLED(CONFIG_XIP, (MPU_RASR_XN_Msk |)) size | P_RW_U_NA_Msk)}
135#define REGION_RAM_WT_ATTR(size) \
136 {(NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE | \
137 IF_ENABLED(CONFIG_XIP, (MPU_RASR_XN_Msk |)) size | P_RW_U_NA_Msk)}
138#define REGION_RAM_NOCACHE_ATTR(size) \
139 {(NORMAL_OUTER_INNER_NON_CACHEABLE_NON_SHAREABLE | MPU_RASR_XN_Msk | size | P_RW_U_NA_Msk)}
140#if defined(CONFIG_MPU_ALLOW_FLASH_WRITE)
141#define REGION_FLASH_ATTR(size) \
142 {(NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE | size | P_RW_U_RO_Msk)}
143#else
144#define REGION_FLASH_ATTR(size) \
145 {(NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE | size | P_RO_U_RO_Msk)}
146#endif
147/* Executing from Device or Strongly-ordered memory is architecturally
148 * UNPREDICTABLE on ARMv7-M, so device-type regions are always mapped
149 * Execute-Never. On Cortex-M7 the XN attribute is also what prevents the core
150 * from speculatively fetching instructions from these regions; the memory type
151 * alone does not. See the Arm Cortex-M7 TRM (DDI0489), "Memory system -
152 * Speculative accesses - Considerations for system design".
153 */
154#define REGION_PPB_ATTR(size) {(STRONGLY_ORDERED_SHAREABLE | NOT_EXEC | size | P_RW_U_NA_Msk)}
155#define REGION_IO_ATTR(size) {(DEVICE_NON_SHAREABLE | NOT_EXEC | size | P_RW_U_NA_Msk)}
156#define REGION_EXTMEM_ATTR(size) {(STRONGLY_ORDERED_SHAREABLE | NOT_EXEC | size | NO_ACCESS_Msk)}
157
159 /* Attributes belonging to RASR (including the encoded region size) */
161};
162
164
165/* Typedef for the k_mem_partition attribute */
169
170/* Read-Write access permission attributes */
171#define _K_MEM_PARTITION_P_NA_U_NA (NO_ACCESS_Msk | NOT_EXEC)
172#define _K_MEM_PARTITION_P_RW_U_RW (P_RW_U_RW_Msk | NOT_EXEC)
173#define _K_MEM_PARTITION_P_RW_U_RO (P_RW_U_RO_Msk | NOT_EXEC)
174#define _K_MEM_PARTITION_P_RW_U_NA (P_RW_U_NA_Msk | NOT_EXEC)
175#define _K_MEM_PARTITION_P_RO_U_RO (P_RO_U_RO_Msk | NOT_EXEC)
176#define _K_MEM_PARTITION_P_RO_U_NA (P_RO_U_NA_Msk | NOT_EXEC)
177
178/* Execution-allowed attributes */
179#define _K_MEM_PARTITION_P_RWX_U_RWX (P_RW_U_RW_Msk)
180#define _K_MEM_PARTITION_P_RWX_U_RX (P_RW_U_RO_Msk)
181#define _K_MEM_PARTITION_P_RX_U_RX (P_RO_U_RO_Msk)
182
183/* Kernel macros for memory attribution
184 * (access permissions and cache-ability).
185 *
186 * The macros are to be stored in k_mem_partition_attr_t
187 * objects. The format of k_mem_partition_attr_t is an
188 * "1-1" mapping of the ARMv7-M MPU RASR attribute register
189 * fields (excluding the <size> and <enable> bit-fields).
190 */
191
192/* Read-Write access permission attributes (default cache-ability) */
193#define K_MEM_PARTITION_P_NA_U_NA \
194 ((k_mem_partition_attr_t){ \
195 _K_MEM_PARTITION_P_NA_U_NA | \
196 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
197#define K_MEM_PARTITION_P_RW_U_RW \
198 ((k_mem_partition_attr_t){ \
199 _K_MEM_PARTITION_P_RW_U_RW | \
200 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
201#define K_MEM_PARTITION_P_RW_U_RO \
202 ((k_mem_partition_attr_t){ \
203 _K_MEM_PARTITION_P_RW_U_RO | \
204 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
205#define K_MEM_PARTITION_P_RW_U_NA \
206 ((k_mem_partition_attr_t){ \
207 _K_MEM_PARTITION_P_RW_U_NA | \
208 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
209#define K_MEM_PARTITION_P_RO_U_RO \
210 ((k_mem_partition_attr_t){ \
211 _K_MEM_PARTITION_P_RO_U_RO | \
212 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
213#define K_MEM_PARTITION_P_RO_U_NA \
214 ((k_mem_partition_attr_t){ \
215 _K_MEM_PARTITION_P_RO_U_NA | \
216 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
217
218/* Execution-allowed attributes (default-cacheability) */
219#define K_MEM_PARTITION_P_RWX_U_RWX \
220 ((k_mem_partition_attr_t){ \
221 _K_MEM_PARTITION_P_RWX_U_RWX | \
222 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
223#define K_MEM_PARTITION_P_RWX_U_RX \
224 ((k_mem_partition_attr_t){ \
225 _K_MEM_PARTITION_P_RWX_U_RX | \
226 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
227#define K_MEM_PARTITION_P_RX_U_RX \
228 ((k_mem_partition_attr_t){ \
229 _K_MEM_PARTITION_P_RX_U_RX | \
230 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE})
231
232/*
233 * @brief Evaluate Write-ability
234 *
235 * Evaluate whether the access permissions include write-ability.
236 *
237 * @param attr The k_mem_partition_attr_t object holding the
238 * MPU attributes to be checked against write-ability.
239 */
240#define K_MEM_PARTITION_IS_WRITABLE(attr) \
241 ({ \
242 int __is_writable__; \
243 switch (attr.rasr_attr & MPU_RASR_AP_Msk) { \
244 case P_RW_U_RW_Msk: \
245 case P_RW_U_RO_Msk: \
246 case P_RW_U_NA_Msk: \
247 __is_writable__ = 1; \
248 break; \
249 default: \
250 __is_writable__ = 0; \
251 break; \
252 } \
253 __is_writable__; \
254 })
255
256/*
257 * @brief Evaluate Execution allowance
258 *
259 * Evaluate whether the access permissions include execution.
260 *
261 * @param attr The k_mem_partition_attr_t object holding the
262 * MPU attributes to be checked against execution
263 * allowance.
264 */
265#define K_MEM_PARTITION_IS_EXECUTABLE(attr) (!((attr.rasr_attr) & (NOT_EXEC)))
266
267/* Attributes for no-cache enabling (share-ability is selected by default) */
268
269#define K_MEM_PARTITION_P_NA_U_NA_NOCACHE \
270 ((k_mem_partition_attr_t){ \
271 (_K_MEM_PARTITION_P_NA_U_NA | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
272#define K_MEM_PARTITION_P_RW_U_RW_NOCACHE \
273 ((k_mem_partition_attr_t){ \
274 (_K_MEM_PARTITION_P_RW_U_RW | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
275#define K_MEM_PARTITION_P_RW_U_RO_NOCACHE \
276 ((k_mem_partition_attr_t){ \
277 (_K_MEM_PARTITION_P_RW_U_RO | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
278#define K_MEM_PARTITION_P_RW_U_NA_NOCACHE \
279 ((k_mem_partition_attr_t){ \
280 (_K_MEM_PARTITION_P_RW_U_NA | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
281#define K_MEM_PARTITION_P_RO_U_RO_NOCACHE \
282 ((k_mem_partition_attr_t){ \
283 (_K_MEM_PARTITION_P_RO_U_RO | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
284#define K_MEM_PARTITION_P_RO_U_NA_NOCACHE \
285 ((k_mem_partition_attr_t){ \
286 (_K_MEM_PARTITION_P_RO_U_NA | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
287
288#define K_MEM_PARTITION_P_RWX_U_RWX_NOCACHE \
289 ((k_mem_partition_attr_t){ \
290 (_K_MEM_PARTITION_P_RWX_U_RWX | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
291#define K_MEM_PARTITION_P_RWX_U_RX_NOCACHE \
292 ((k_mem_partition_attr_t){ \
293 (_K_MEM_PARTITION_P_RWX_U_RX | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
294#define K_MEM_PARTITION_P_RX_U_RX_NOCACHE \
295 ((k_mem_partition_attr_t){ \
296 (_K_MEM_PARTITION_P_RX_U_RX | NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
297
298#endif /* _ASMLANGUAGE */
299
300#define _ARCH_MEM_PARTITION_ALIGN_CHECK_SIZE(size) \
301 BUILD_ASSERT(!(((size) & ((size) - 1))) && \
302 (size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE, \
303 "The size of the partition must be power of 2 and greater than or equal to " \
304 "the minimum MPU region size.\n")
305
306/* Some compilers do not handle BUILD_ASSERT on the values of pointers. */
307#if defined(__IAR_SYSTEMS_ICC__) || defined(__clang__)
308#define _ARCH_MEM_PARTITION_ALIGN_CHECK_START(start, size)
309#else
310#define _ARCH_MEM_PARTITION_ALIGN_CHECK_START(start, size) \
311 BUILD_ASSERT(!((uint32_t)(start) & ((size) - 1)), \
312 "The start address of the partition must align with size.")
313#endif
314
315#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \
316 _ARCH_MEM_PARTITION_ALIGN_CHECK_SIZE(size); \
317 _ARCH_MEM_PARTITION_ALIGN_CHECK_START(start, size)
318
319#endif /* ZEPHYR_INCLUDE_ARCH_ARM_MPU_ARM_MPU_V7M_H_ */
struct arm_mpu_region_attr arm_mpu_region_attr_t
Definition arm_mpu_v7m.h:163
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
Definition arm_mpu_v7m.h:158
uint32_t rasr
Definition arm_mpu_v7m.h:160
Definition arm_mpu_v7m.h:166
uint32_t rasr_attr
Definition arm_mpu_v7m.h:167