Zephyr API Documentation 4.1.99
A Scalable Open Source RTOS
 4.1.99
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
arm_mpu_v8.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 _ASMLANGUAGE
9
10/* Convenience macros to represent the ARMv8-M-specific
11 * configuration for memory access permission and
12 * cache-ability attribution.
13 */
14#if defined(CONFIG_AARCH32_ARMV8_R)
15#define MPU_IR_REGION_Msk (0xFFU)
16#define MPU_IR_REGION_Pos 8U
17/* MPU RBAR Register attribute msk Definitions */
18#define MPU_RBAR_BASE_Pos 6U
19#define MPU_RBAR_BASE_Msk (0x3FFFFFFFFFFFFFFUL << MPU_RBAR_BASE_Pos)
20#define MPU_RBAR_SH_Pos 3U
21#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos)
22#define MPU_RBAR_AP_Pos 1U
23#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos)
24/* RBAR XN */
25#define MPU_RBAR_XN_Pos 0U
26#define MPU_RBAR_XN_Msk (0x1UL << MPU_RBAR_XN_Pos)
27
28/* MPU PLBAR Register Definitions */
29#define MPU_RLAR_LIMIT_Pos 6U
30#define MPU_RLAR_LIMIT_Msk (0x3FFFFFFFFFFFFFFUL << MPU_RLAR_LIMIT_Pos)
31#define MPU_RLAR_AttrIndx_Pos 1U
32#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos)
33#define MPU_RLAR_EN_Msk (0x1UL)
34#else
35#include <cmsis_core.h>
36#endif
37
38/* Privileged No Access, Unprivileged No Access */
39/*#define NO_ACCESS 0x0 */
40/*#define NO_ACCESS_Msk ((NO_ACCESS << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) */
41/* Privileged No Access, Unprivileged No Access */
42/*#define P_NA_U_NA 0x0 */
43/*#define P_NA_U_NA_Msk ((P_NA_U_NA << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) */
44/* Privileged Read Write, Unprivileged No Access */
45#define P_RW_U_NA 0x0
46#define P_RW_U_NA_Msk ((P_RW_U_NA << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
47/* Privileged Read Write, Unprivileged Read Only */
48/*#define P_RW_U_RO 0x2 */
49/*#define P_RW_U_RO_Msk ((P_RW_U_RO << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)*/
50/* Privileged Read Write, Unprivileged Read Write */
51#define P_RW_U_RW 0x1
52#define P_RW_U_RW_Msk ((P_RW_U_RW << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
53/* Privileged Read Write, Unprivileged Read Write */
54#define FULL_ACCESS 0x1
55#define FULL_ACCESS_Msk ((FULL_ACCESS << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
56/* Privileged Read Only, Unprivileged No Access */
57#define P_RO_U_NA 0x2
58#define P_RO_U_NA_Msk ((P_RO_U_NA << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
59/* Privileged Read Only, Unprivileged Read Only */
60#define P_RO_U_RO 0x3
61#define P_RO_U_RO_Msk ((P_RO_U_RO << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
62/* Privileged Read Only, Unprivileged Read Only */
63#define RO 0x3
64#define RO_Msk ((RO << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
65
66/* Attribute flag for not-allowing execution (eXecute Never) */
67#define NOT_EXEC MPU_RBAR_XN_Msk
68
69/* Attribute flags for share-ability */
70#define NON_SHAREABLE 0x0
71#define NON_SHAREABLE_Msk ((NON_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk)
72#define OUTER_SHAREABLE 0x2
73#define OUTER_SHAREABLE_Msk ((OUTER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk)
74#define INNER_SHAREABLE 0x3
75#define INNER_SHAREABLE_Msk ((INNER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk)
76
77/* Helper define to calculate the region limit address. */
78#define REGION_LIMIT_ADDR(base, size) (((base & MPU_RBAR_BASE_Msk) + size - 1) & MPU_RLAR_LIMIT_Msk)
79
80/* Attribute flags for cache-ability */
81
82/* Memory Attributes for Device Memory
83 * 1.Gathering (G/nG)
84 * Determines whether multiple accesses can be merged into a single
85 * bus transaction.
86 * nG: Number/size of accesses on the bus = number/size of accesses
87 * in code.
88 *
89 * 2.Reordering (R/nR)
90 * Determines whether accesses to the same device can be reordered.
91 * nR: Accesses to the same IMPLEMENTATION DEFINED block size will
92 * appear on the bus in program order.
93 *
94 * 3 Early Write Acknowledgment (E/nE)
95 * Indicates to the memory system whether a buffer can send
96 * acknowledgements.
97 * nE: The response should come from the end slave, not buffering in
98 * the interconnect.
99 */
100#define DEVICE_nGnRnE 0x0U
101#define DEVICE_nGnRE 0x4U
102#define DEVICE_nGRE 0x8U
103#define DEVICE_GRE 0xCU
104
105/* Read/Write Allocation Configurations for Cacheable Memory */
106#define R_NON_W_NON 0x0 /* Do not allocate Read/Write */
107#define R_NON_W_ALLOC 0x1 /* Do not allocate Read, Allocate Write */
108#define R_ALLOC_W_NON 0x2 /* Allocate Read, Do not allocate Write */
109#define R_ALLOC_W_ALLOC 0x3 /* Allocate Read/Write */
110
111/* Memory Attributes for Normal Memory */
112#define NORMAL_O_WT_NT 0x80 /* Normal, Outer Write-through non-transient */
113#define NORMAL_O_WB_NT 0xC0 /* Normal, Outer Write-back non-transient */
114#define NORMAL_O_NON_C 0x40 /* Normal, Outer Non-Cacheable */
115
116#define NORMAL_I_WT_NT 0x08 /* Normal, Inner Write-through non-transient */
117#define NORMAL_I_WB_NT 0x0C /* Normal, Inner Write-back non-transient */
118#define NORMAL_I_NON_C 0x04 /* Normal, Inner Non-Cacheable */
119
120#define NORMAL_OUTER_INNER_WRITE_THROUGH_READ_ALLOCATE_NON_TRANS \
121 ((NORMAL_O_WT_NT | (R_ALLOC_W_NON << 4)) | (NORMAL_I_WT_NT | R_ALLOC_W_NON))
122
123#define NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_TRANS \
124 ((NORMAL_O_WB_NT | (R_ALLOC_W_ALLOC << 4)) | (NORMAL_I_WB_NT | R_ALLOC_W_ALLOC))
125
126#define NORMAL_OUTER_INNER_NON_CACHEABLE \
127 ((NORMAL_O_NON_C | (R_NON_W_NON << 4)) | (NORMAL_I_NON_C | R_NON_W_NON))
128
129/* Common cache-ability configuration for Flash, SRAM regions */
130#define MPU_CACHE_ATTRIBUTES_FLASH NORMAL_OUTER_INNER_WRITE_THROUGH_READ_ALLOCATE_NON_TRANS
131/* clang-format off */
132#define MPU_CACHE_ATTRIBUTES_SRAM \
133 NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_TRANS
134/* clang-format on */
135#define MPU_CACHE_ATTRIBUTES_SRAM_NOCACHE NORMAL_OUTER_INNER_NON_CACHEABLE
136
137/* Global MAIR configurations */
138#define MPU_MAIR_ATTR_FLASH MPU_CACHE_ATTRIBUTES_FLASH
139#define MPU_MAIR_INDEX_FLASH 0
140#define MPU_MAIR_ATTR_SRAM MPU_CACHE_ATTRIBUTES_SRAM
141#define MPU_MAIR_INDEX_SRAM 1
142#define MPU_MAIR_ATTR_SRAM_NOCACHE MPU_CACHE_ATTRIBUTES_SRAM_NOCACHE
143#define MPU_MAIR_INDEX_SRAM_NOCACHE 2
144#define MPU_MAIR_ATTR_DEVICE DEVICE_nGnRnE
145#define MPU_MAIR_INDEX_DEVICE 3
146/* Flash region(s): Attribute-0
147 * SRAM region(s): Attribute-1
148 * SRAM no cache-able regions(s): Attribute-2
149 * DEVICE no cache-able regions(s): Attribute-3
150 */
151#define MPU_MAIR_ATTRS \
152 ((MPU_MAIR_ATTR_FLASH << (MPU_MAIR_INDEX_FLASH * 8)) | \
153 (MPU_MAIR_ATTR_SRAM << (MPU_MAIR_INDEX_SRAM * 8)) | \
154 (MPU_MAIR_ATTR_SRAM_NOCACHE << (MPU_MAIR_INDEX_SRAM_NOCACHE * 8)) | \
155 (MPU_MAIR_ATTR_DEVICE << (MPU_MAIR_INDEX_DEVICE * 8)))
156
157/* Some helper defines for common regions.
158 *
159 * Note that the ARMv8-M/R MPU architecture requires that the
160 * enabled MPU regions are non-overlapping. Therefore, it is
161 * recommended to use these helper defines only for configuring
162 * fixed MPU regions at build-time (i.e. regions that are not
163 * expected to be re-programmed or re-adjusted at run-time so
164 * that they do not overlap with other MPU regions).
165 */
166#if defined(CONFIG_AARCH32_ARMV8_R)
167
168#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \
169 { \
170 .name = p_name, \
171 .base = p_base, \
172 .attr = p_attr(p_base + p_size), \
173 }
174
175#define REGION_RAM_ATTR(limit) \
176 { \
177 .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
178 .mair_idx = MPU_MAIR_INDEX_SRAM, /* Cache-ability */ \
179 .r_limit = limit - 1, /* Region Limit */ \
180 }
181
182#define REGION_RAM_TEXT_ATTR(limit) \
183 { \
184 .rbar = P_RO_U_RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
185 .mair_idx = MPU_MAIR_INDEX_SRAM, /* Cache-ability */ \
186 .r_limit = limit - 1, /* Region Limit */ \
187 }
188
189#define REGION_RAM_RO_ATTR(limit) \
190 { \
191 .rbar = NOT_EXEC | P_RO_U_RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
192 .mair_idx = MPU_MAIR_INDEX_SRAM, /* Cache-ability */ \
193 .r_limit = limit - 1, /* Region Limit */ \
194 }
195#define REGION_RAM_NOCACHE_ATTR(limit) \
196 { \
197 .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
198 .mair_idx = MPU_MAIR_INDEX_SRAM_NOCACHE, /* Cache-ability */ \
199 .r_limit = limit - 1, /* Region Limit */ \
200 }
201#if defined(CONFIG_MPU_ALLOW_FLASH_WRITE)
202/* Note that the access permissions allow for un-privileged writes, contrary
203 * to ARMv7-M where un-privileged code has Read-Only permissions.
204 */
205#define REGION_FLASH_ATTR(limit) \
206 { \
207 .rbar = P_RW_U_RW_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
208 .mair_idx = MPU_MAIR_INDEX_FLASH, /* Cache-ability */ \
209 .r_limit = limit - 1, /* Region Limit */ \
210 }
211#else /* CONFIG_MPU_ALLOW_FLASH_WRITE */
212#define REGION_FLASH_ATTR(limit) \
213 { \
214 .rbar = RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
215 .mair_idx = MPU_MAIR_INDEX_FLASH, /* Cache-ability */ \
216 .r_limit = limit - 1, /* Region Limit */ \
217 }
218#endif /* CONFIG_MPU_ALLOW_FLASH_WRITE */
219
220#define REGION_DEVICE_ATTR(limit) \
221 { \
222 .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
223 .mair_idx = MPU_MAIR_INDEX_DEVICE, /* Cache-ability */ \
224 .r_limit = limit - 1, /* Region Limit */ \
225 }
226#else
227
228#define ARM_MPU_REGION_INIT(p_name, p_base, p_size, p_attr) \
229 { \
230 .name = p_name, \
231 .base = p_base, \
232 .attr = p_attr(p_base, p_size), \
233 }
234
235/* On Cortex-M, we can only set the XN bit when CONFIG_XIP=y. When
236 * CONFIG_XIP=n, the entire image will be linked to SRAM, so we need to keep
237 * the SRAM region XN bit clear or the application code will not be executable.
238 */
239/* clang-format off */
240#define REGION_RAM_ATTR(base, size) \
241 { \
242 .rbar = IF_ENABLED(CONFIG_XIP, (NOT_EXEC |)) P_RW_U_NA_Msk | \
243 NON_SHAREABLE_Msk, /* AP, XN, SH */ \
244 .mair_idx = MPU_MAIR_INDEX_SRAM, /* Cache-ability */ \
245 .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \
246 }
247/* clang-format on */
248
249#define REGION_RAM_NOCACHE_ATTR(base, size) \
250 { \
251 .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
252 .mair_idx = MPU_MAIR_INDEX_SRAM_NOCACHE, /* Cache-ability */ \
253 .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \
254 }
255
256#if defined(CONFIG_MPU_ALLOW_FLASH_WRITE)
257/* Note that the access permissions allow for un-privileged writes, contrary
258 * to ARMv7-M where un-privileged code has Read-Only permissions.
259 */
260#define REGION_FLASH_ATTR(base, size) \
261 { \
262 .rbar = P_RW_U_RW_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
263 .mair_idx = MPU_MAIR_INDEX_FLASH, /* Cache-ability */ \
264 .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \
265 }
266#else /* CONFIG_MPU_ALLOW_FLASH_WRITE */
267#define REGION_FLASH_ATTR(base, size) \
268 { \
269 .rbar = RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
270 .mair_idx = MPU_MAIR_INDEX_FLASH, /* Cache-ability */ \
271 .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \
272 }
273#endif /* CONFIG_MPU_ALLOW_FLASH_WRITE */
274
275#define REGION_DEVICE_ATTR(base, size) \
276 { \
277 .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
278 .mair_idx = MPU_MAIR_INDEX_DEVICE, /* Cache-ability */ \
279 .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \
280 }
281#endif
282
283struct arm_mpu_region_attr {
284 /* Attributes belonging to RBAR */
286 /* MAIR index for attribute indirection */
288 /* Region Limit Address value to be written to the RLAR register. */
290};
291
293
294/* Typedef for the k_mem_partition attribute */
295typedef struct {
299
300/* Kernel macros for memory attribution
301 * (access permissions and cache-ability).
302 *
303 * The macros are to be stored in k_mem_partition_attr_t
304 * objects. The format of a k_mem_partition_attr_t object
305 * is as follows: field <rbar> contains a direct mapping
306 * of the <XN> and <AP> bit-fields of the RBAR register;
307 * field <mair_idx> contains a direct mapping of AttrIdx
308 * bit-field, stored in RLAR register.
309 */
310
311/* Read-Write access permission attributes */
312#define K_MEM_PARTITION_P_RW_U_RW \
313 ((k_mem_partition_attr_t){(P_RW_U_RW_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM})
314#define K_MEM_PARTITION_P_RW_U_NA \
315 ((k_mem_partition_attr_t){(P_RW_U_NA_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM})
316#define K_MEM_PARTITION_P_RO_U_RO \
317 ((k_mem_partition_attr_t){(P_RO_U_RO_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM})
318#define K_MEM_PARTITION_P_RO_U_NA \
319 ((k_mem_partition_attr_t){(P_RO_U_NA_Msk | NOT_EXEC), MPU_MAIR_INDEX_SRAM})
320
321/* Execution-allowed attributes */
322#define K_MEM_PARTITION_P_RWX_U_RWX ((k_mem_partition_attr_t){(P_RW_U_RW_Msk), MPU_MAIR_INDEX_SRAM})
323#define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t){(P_RO_U_RO_Msk), MPU_MAIR_INDEX_SRAM})
324
325/*
326 * @brief Evaluate Write-ability
327 *
328 * Evaluate whether the access permissions include write-ability.
329 *
330 * @param attr The k_mem_partition_attr_t object holding the
331 * MPU attributes to be checked against write-ability.
332 */
333#define K_MEM_PARTITION_IS_WRITABLE(attr) \
334 ({ \
335 int __is_writable__; \
336 switch (attr.rbar & MPU_RBAR_AP_Msk) { \
337 case P_RW_U_RW_Msk: \
338 case P_RW_U_NA_Msk: \
339 __is_writable__ = 1; \
340 break; \
341 default: \
342 __is_writable__ = 0; \
343 } \
344 __is_writable__; \
345 })
346
347/*
348 * @brief Evaluate Execution allowance
349 *
350 * Evaluate whether the access permissions include execution.
351 *
352 * @param attr The k_mem_partition_attr_t object holding the
353 * MPU attributes to be checked against execution
354 * allowance.
355 */
356#define K_MEM_PARTITION_IS_EXECUTABLE(attr) (!((attr.rbar) & (NOT_EXEC)))
357
358/* Attributes for no-cache enabling (share-ability is selected by default) */
359
360/* Read-Write access permission attributes */
361#define K_MEM_PARTITION_P_RW_U_RW_NOCACHE \
362 ((k_mem_partition_attr_t){(P_RW_U_RW_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \
363 MPU_MAIR_INDEX_SRAM_NOCACHE})
364#define K_MEM_PARTITION_P_RW_U_NA_NOCACHE \
365 ((k_mem_partition_attr_t){(P_RW_U_NA_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \
366 MPU_MAIR_INDEX_SRAM_NOCACHE})
367#define K_MEM_PARTITION_P_RO_U_RO_NOCACHE \
368 ((k_mem_partition_attr_t){(P_RO_U_RO_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \
369 MPU_MAIR_INDEX_SRAM_NOCACHE})
370#define K_MEM_PARTITION_P_RO_U_NA_NOCACHE \
371 ((k_mem_partition_attr_t){(P_RO_U_NA_Msk | NOT_EXEC | OUTER_SHAREABLE_Msk), \
372 MPU_MAIR_INDEX_SRAM_NOCACHE})
373
374/* Execution-allowed attributes */
375#define K_MEM_PARTITION_P_RWX_U_RWX_NOCACHE \
376 ((k_mem_partition_attr_t){(P_RW_U_RW_Msk | OUTER_SHAREABLE_Msk), \
377 MPU_MAIR_INDEX_SRAM_NOCACHE})
378#define K_MEM_PARTITION_P_RX_U_RX_NOCACHE \
379 ((k_mem_partition_attr_t){(P_RO_U_RO_Msk | OUTER_SHAREABLE_Msk), \
380 MPU_MAIR_INDEX_SRAM_NOCACHE})
381
382#endif /* _ASMLANGUAGE */
383
384#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \
385 BUILD_ASSERT((size > 0) && \
386 ((uint32_t)start % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0U) && \
387 ((size) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0), \
388 "The start and size of the partition must align with the minimum MPU " \
389 "region size.")
uint32_t k_mem_partition_attr_t
Definition arch.h:346
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
__UINT8_TYPE__ uint8_t
Definition stdint.h:88
__UINT16_TYPE__ uint16_t
Definition stdint.h:89
Definition arm_mpu_v7m.h:135
uint8_t rbar
Definition arm_mpu_v8.h:285
uint32_t r_limit
Definition arm_mpu_v8.h:289
uint8_t mair_idx
Definition arm_mpu_v8.h:287
uint16_t rbar
Definition arm_mpu_v8.h:296
uint16_t mair_idx
Definition arm_mpu_v8.h:297