Skip to content

Commit bf34cf9

Browse files
ioannisgnashif
authored andcommitted
arch: arm: mpu: Updates in ARM MPU-related convenience macros
This commit does the following: - it introduces additional convenience macros for representing MPU attributions for no-cacheability, in both ARMv7-M and ARMv8-M MPU architectures, - it adds documentation in K_MEM_PARTITION_IS_WRITABLE/CACHEABLE macros in all macro definitions in the different MPU variants - it moves the type definition of k_mem_partition_attr_t inside the architecture-specific MPU headers, so it can be defined per-architecture. It generalizes app_mem_domain.h, to be able to work with _any_ (struct) type of k_mem_partition_attr_t. - it refactors the type of k_mem_partition_attr_t for ARMv8-M to comply with the MPU register API. - for NXP MPU, the commit moves the macros for region access permissions' attributes inside nxp_mpu.h, to align with what we do for ARM MPU. Signed-off-by: Ioannis Glaropoulos <[email protected]>
1 parent 39bf24a commit bf34cf9

File tree

9 files changed

+311
-111
lines changed

9 files changed

+311
-111
lines changed

arch/arm/core/cortex_m/mpu/arm_mpu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ void arm_core_mpu_configure_mem_domain(struct k_mem_domain *mem_domain)
243243
region_index, pparts->start, pparts->size);
244244
region_conf.base = pparts->start;
245245
_get_ram_region_attr_by_conf(&region_conf.attr,
246-
pparts->attr, pparts->start, pparts->size);
246+
&pparts->attr, pparts->start, pparts->size);
247247
_region_init(region_index, &region_conf);
248248
num_partitions--;
249249
} else {
@@ -273,7 +273,7 @@ void arm_core_mpu_configure_mem_partition(u32_t part_index,
273273
LOG_DBG("set region 0x%x 0x%x 0x%x",
274274
region_index + part_index, part->start, part->size);
275275
_get_ram_region_attr_by_conf(&region_conf.attr,
276-
part->attr, part->start, part->size);
276+
&part->attr, part->start, part->size);
277277
region_conf.base = part->start;
278278
_region_init(region_index + part_index, &region_conf);
279279
} else {

arch/arm/core/cortex_m/mpu/arm_mpu_v7_internal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,14 @@ static inline void _get_mpu_ram_nocache_region_attr(arm_mpu_region_attr_t *p_att
132132
* parameter set.
133133
*/
134134
static inline void _get_ram_region_attr_by_conf(arm_mpu_region_attr_t *p_attr,
135-
u32_t attr, u32_t base, u32_t size)
135+
k_mem_partition_attr_t *attr, u32_t base, u32_t size)
136136
{
137137
/* in ARMv7-M MPU the base address is not required
138138
* to determine region attributes
139139
*/
140140
(void) base;
141141

142-
p_attr->rasr = attr | _size_to_mpu_rasr_size(size);
142+
p_attr->rasr = attr->rasr_attr | _size_to_mpu_rasr_size(size);
143143
}
144144

145145
/**

arch/arm/core/cortex_m/mpu/arm_mpu_v8_internal.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,17 @@ static void _mpu_init(void)
2121

2222
/* Flash region(s): Attribute-0
2323
* SRAM region(s): Attribute-1
24+
* SRAM no cache-able regions(s): Attribute-2
2425
*/
2526
MPU->MAIR0 =
2627
((MPU_MAIR_ATTR_FLASH << MPU_MAIR0_Attr0_Pos) &
2728
MPU_MAIR0_Attr0_Msk)
2829
|
2930
((MPU_MAIR_ATTR_SRAM << MPU_MAIR0_Attr1_Pos) &
30-
MPU_MAIR0_Attr1_Msk);
31+
MPU_MAIR0_Attr1_Msk)
32+
|
33+
((MPU_MAIR_ATTR_SRAM_NOCACHE << MPU_MAIR0_Attr2_Pos) &
34+
MPU_MAIR0_Attr2_Msk);
3135
}
3236

3337
/* This internal function performs MPU region initialization.
@@ -79,10 +83,10 @@ static inline void _get_mpu_ram_region_attr(arm_mpu_region_attr_t *p_attr,
7983
* the correct parameter set.
8084
*/
8185
static inline void _get_ram_region_attr_by_conf(arm_mpu_region_attr_t *p_attr,
82-
u32_t ap_attr, u32_t base, u32_t size)
86+
k_mem_partition_attr_t *attr, u32_t base, u32_t size)
8387
{
84-
p_attr->rbar = ap_attr & (MPU_RBAR_XN_Msk | MPU_RBAR_AP_Msk);
85-
p_attr->mair_idx = MPU_MAIR_INDEX_SRAM;
88+
p_attr->rbar = attr->rbar & (MPU_RBAR_XN_Msk | MPU_RBAR_AP_Msk);
89+
p_attr->mair_idx = attr->mair_idx;
8690
p_attr->r_limit = REGION_LIMIT_ADDR(base, size);
8791
}
8892

include/app_memory/app_memdomain.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ struct app_region {
6868

6969
/*
7070
* Declares a partition and provides a function to add the
71-
* partition to the linke dlist and initialize the partition.
71+
* partition to the linked list and initialize the partition.
7272
*/
7373
#ifdef CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT
7474
/* For power of 2 MPUs linker provides support to help us

include/arch/arm/arch.h

Lines changed: 1 addition & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -254,83 +254,13 @@ extern "C" {
254254

255255
#ifdef CONFIG_ARM_MPU
256256
#ifdef CONFIG_CPU_HAS_ARM_MPU
257-
#ifndef _ASMLANGUAGE
258257
#include <arch/arm/cortex_m/mpu/arm_mpu.h>
259-
#endif /* _ASMLANGUAGE */
260-
#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \
261-
BUILD_ASSERT_MSG(!(((size) & ((size) - 1))) && \
262-
(size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE && \
263-
!((u32_t)(start) & ((size) - 1)), \
264-
"the size of the partition must be power of 2" \
265-
" and greater than or equal to the minimum MPU region size." \
266-
"start address of the partition must align with size.")
267258
#endif /* CONFIG_CPU_HAS_ARM_MPU */
268259
#ifdef CONFIG_CPU_HAS_NXP_MPU
269-
#ifndef _ASMLANGUAGE
270260
#include <arch/arm/cortex_m/mpu/nxp_mpu.h>
271-
272-
#define K_MEM_PARTITION_P_NA_U_NA (MPU_REGION_SU)
273-
#define K_MEM_PARTITION_P_RW_U_RW (MPU_REGION_READ | MPU_REGION_WRITE | \
274-
MPU_REGION_SU)
275-
#define K_MEM_PARTITION_P_RW_U_RO (MPU_REGION_READ | MPU_REGION_SU_RW)
276-
#define K_MEM_PARTITION_P_RW_U_NA (MPU_REGION_SU_RW)
277-
#define K_MEM_PARTITION_P_RO_U_RO (MPU_REGION_READ | MPU_REGION_SU)
278-
#define K_MEM_PARTITION_P_RO_U_NA (MPU_REGION_SU_RX)
279-
280-
/* Execution-allowed attributes */
281-
#define K_MEM_PARTITION_P_RWX_U_RWX (MPU_REGION_READ | MPU_REGION_WRITE | \
282-
MPU_REGION_EXEC | MPU_REGION_SU)
283-
#define K_MEM_PARTITION_P_RWX_U_RX (MPU_REGION_READ | MPU_REGION_EXEC | \
284-
MPU_REGION_SU_RWX)
285-
#define K_MEM_PARTITION_P_RX_U_RX (MPU_REGION_READ | MPU_REGION_EXEC | \
286-
MPU_REGION_SU)
287-
288-
#define K_MEM_PARTITION_IS_WRITABLE(attr) \
289-
({ \
290-
int __is_writable__; \
291-
switch (attr) { \
292-
case MPU_REGION_WRITE: \
293-
case MPU_REGION_SU_RW: \
294-
__is_writable__ = 1; \
295-
break; \
296-
default: \
297-
__is_writable__ = 0; \
298-
} \
299-
__is_writable__; \
300-
})
301-
#define K_MEM_PARTITION_IS_EXECUTABLE(attr) \
302-
({ \
303-
int __is_executable__; \
304-
switch (attr) { \
305-
case MPU_REGION_SU_RX: \
306-
case MPU_REGION_EXEC: \
307-
__is_executable__ = 1; \
308-
break; \
309-
default: \
310-
__is_executable__ = 0; \
311-
} \
312-
__is_executable__; \
313-
})
314-
315-
#endif /* _ASMLANGUAGE */
316-
#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \
317-
BUILD_ASSERT_MSG((size) % \
318-
CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0 && \
319-
(size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE && \
320-
(u32_t)(start) % CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE == 0, \
321-
"the size of the partition must align with minimum MPU \
322-
region size" \
323-
" and greater than or equal to minimum MPU region size." \
324-
"start address of the partition must align with minimum MPU \
325-
region size.")
326-
#endif /* CONFIG_CPU_HAS_NXP_MPU */
261+
#endif /* CONFIG_CPU_HAS_NXP_MPU */
327262
#endif /* CONFIG_ARM_MPU */
328263

329-
#ifndef _ASMLANGUAGE
330-
/* Typedef for the k_mem_partition attribute*/
331-
typedef u32_t k_mem_partition_attr_t;
332-
#endif /* _ASMLANGUAGE */
333-
334264
#ifdef __cplusplus
335265
}
336266
#endif

include/arch/arm/cortex_m/mpu/arm_mpu.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MPU_ARM_MPU_H_
77
#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MPU_ARM_MPU_H_
88

9-
#include <arch/arm/cortex_m/mpu/arm_core_mpu_dev.h>
10-
#include <arch/arm/cortex_m/cmsis.h>
11-
129
#if defined(CONFIG_CPU_CORTEX_M0PLUS) || \
1310
defined(CONFIG_CPU_CORTEX_M3) || \
1411
defined(CONFIG_CPU_CORTEX_M4) || \
@@ -21,6 +18,10 @@
2118
#error "Unsupported ARM CPU"
2219
#endif
2320

21+
#ifndef _ASMLANGUAGE
22+
23+
#include <arch/arm/cortex_m/mpu/arm_core_mpu_dev.h>
24+
2425
/* Region definition data structure */
2526
struct arm_mpu_region {
2627
/* Region Base Address */
@@ -56,4 +57,6 @@ struct arm_mpu_config {
5657
*/
5758
extern const struct arm_mpu_config mpu_config;
5859

60+
#endif /* _ASMLANGUAGE */
61+
5962
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MPU_ARM_MPU_H_ */

include/arch/arm/cortex_m/mpu/arm_mpu_v7m.h

Lines changed: 100 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55
* SPDX-License-Identifier: Apache-2.0
66
*/
77

8+
#ifndef _ASMLANGUAGE
9+
10+
#include <arch/arm/cortex_m/cmsis.h>
11+
12+
/* Convenience macros to represent the ARMv7-M-specific
13+
* configuration for memory access permission and
14+
* cache-ability attribution.
15+
*/
16+
817
/* Privileged No Access, Unprivileged No Access */
918
#define NO_ACCESS 0x0
1019
#define NO_ACCESS_Msk ((NO_ACCESS << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk)
@@ -129,24 +138,54 @@ struct arm_mpu_region_attr {
129138

130139
typedef struct arm_mpu_region_attr arm_mpu_region_attr_t;
131140

132-
#ifndef _ASMLANGUAGE
141+
/* Typedef for the k_mem_partition attribute */
142+
typedef struct {
143+
u32_t rasr_attr;
144+
} k_mem_partition_attr_t;
145+
146+
/* Kernel macros for memory attribution
147+
* (access permissions and cache-ability).
148+
*
149+
* The macros are to be stored in k_mem_partition_attr_t
150+
* objects. The format of k_mem_partition_attr_t is an
151+
* "1-1" mapping of the ARMv7-M MPU RASR attribute register
152+
* fields (excluding the <size> and <enable> bit-fields).
153+
*/
154+
133155
/* Read-Write access permission attributes */
134-
#define K_MEM_PARTITION_P_NA_U_NA (NO_ACCESS_Msk | NOT_EXEC)
135-
#define K_MEM_PARTITION_P_RW_U_RW (P_RW_U_RW_Msk | NOT_EXEC)
136-
#define K_MEM_PARTITION_P_RW_U_RO (P_RW_U_RO_Msk | NOT_EXEC)
137-
#define K_MEM_PARTITION_P_RW_U_NA (P_RW_U_NA_Msk | NOT_EXEC)
138-
#define K_MEM_PARTITION_P_RO_U_RO (P_RO_U_RO_Msk | NOT_EXEC)
139-
#define K_MEM_PARTITION_P_RO_U_NA (P_RO_U_NA_Msk | NOT_EXEC)
156+
#define K_MEM_PARTITION_P_NA_U_NA ((k_mem_partition_attr_t) \
157+
{(NO_ACCESS_Msk | NOT_EXEC)})
158+
#define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \
159+
{(P_RW_U_RW_Msk | NOT_EXEC)})
160+
#define K_MEM_PARTITION_P_RW_U_RO ((k_mem_partition_attr_t) \
161+
{(P_RW_U_RO_Msk | NOT_EXEC)})
162+
#define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \
163+
{(P_RW_U_NA_Msk | NOT_EXEC)})
164+
#define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \
165+
{(P_RO_U_RO_Msk | NOT_EXEC)})
166+
#define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \
167+
{(P_RO_U_NA_Msk | NOT_EXEC)})
140168

141169
/* Execution-allowed attributes */
142-
#define K_MEM_PARTITION_P_RWX_U_RWX (P_RW_U_RW_Msk)
143-
#define K_MEM_PARTITION_P_RWX_U_RX (P_RW_U_RO_Msk)
144-
#define K_MEM_PARTITION_P_RX_U_RX (P_RO_U_RO_Msk)
170+
#define K_MEM_PARTITION_P_RWX_U_RWX ((k_mem_partition_attr_t) \
171+
{(P_RW_U_RW_Msk)})
172+
#define K_MEM_PARTITION_P_RWX_U_RX ((k_mem_partition_attr_t) \
173+
{(P_RW_U_RO_Msk)})
174+
#define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \
175+
{(P_RO_U_RO_Msk)})
145176

177+
/*
178+
* @brief Evaluate Write-ability
179+
*
180+
* Evaluate whether the access permissions include write-ability.
181+
*
182+
* @param attr The k_mem_partition_attr_t object holding the
183+
* MPU attributes to be checked against write-ability.
184+
*/
146185
#define K_MEM_PARTITION_IS_WRITABLE(attr) \
147186
({ \
148187
int __is_writable__; \
149-
switch (attr & MPU_RASR_AP_Msk) { \
188+
switch (attr.rasr_attr & MPU_RASR_AP_Msk) { \
150189
case P_RW_U_RW_Msk: \
151190
case P_RW_U_RO_Msk: \
152191
case P_RW_U_NA_Msk: \
@@ -158,6 +197,55 @@ typedef struct arm_mpu_region_attr arm_mpu_region_attr_t;
158197
__is_writable__; \
159198
})
160199

200+
/*
201+
* @brief Evaluate Execution allowance
202+
*
203+
* Evaluate whether the access permissions include execution.
204+
*
205+
* @param attr The k_mem_partition_attr_t object holding the
206+
* MPU attributes to be checked against execution
207+
* allowance.
208+
*/
161209
#define K_MEM_PARTITION_IS_EXECUTABLE(attr) \
162-
(!((attr) & (NOT_EXEC)))
210+
(!((attr.rasr_attr) & (NOT_EXEC)))
211+
212+
/* Attributes for no-cache enabling (share-ability is selected by default) */
213+
214+
#define K_MEM_PARTITION_P_NA_U_NA_NOCACHE ((k_mem_partition_attr_t) \
215+
{(K_MEM_PARTITION_P_NA_U_NA \
216+
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
217+
#define K_MEM_PARTITION_P_RW_U_RW_NOCACHE ((k_mem_partition_attr_t) \
218+
{(K_MEM_PARTITION_P_RW_U_RW \
219+
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
220+
#define K_MEM_PARTITION_P_RW_U_RO_NOCACHE ((k_mem_partition_attr_t) \
221+
{(K_MEM_PARTITION_P_RW_U_RO \
222+
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
223+
#define K_MEM_PARTITION_P_RW_U_NA_NOCACHE ((k_mem_partition_attr_t) \
224+
{(K_MEM_PARTITION_P_RW_U_NA \
225+
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
226+
#define K_MEM_PARTITION_P_RO_U_RO_NOCACHE ((k_mem_partition_attr_t) \
227+
{(K_MEM_PARTITION_P_RO_U_RO \
228+
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
229+
#define K_MEM_PARTITION_P_RO_U_NA_NOCACHE ((k_mem_partition_attr_t) \
230+
{(K_MEM_PARTITION_P_RO_U_NA \
231+
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
232+
233+
#define K_MEM_PARTITION_P_RWX_U_RWX_NOCACHE ((k_mem_partition_attr_t) \
234+
{(K_MEM_PARTITION_P_RWX_U_RWX \
235+
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
236+
#define K_MEM_PARTITION_P_RWX_U_RX_NOCACHE ((k_mem_partition_attr_t) \
237+
{(K_MEM_PARTITION_P_RWX_U_RX \
238+
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
239+
#define K_MEM_PARTITION_P_RX_U_RX_NOCACHE ((k_mem_partition_attr_t) \
240+
{(K_MEM_PARTITION_P_RX_U_RX \
241+
| NORMAL_OUTER_INNER_NON_CACHEABLE_SHAREABLE)})
242+
163243
#endif /* _ASMLANGUAGE */
244+
245+
#define _ARCH_MEM_PARTITION_ALIGN_CHECK(start, size) \
246+
BUILD_ASSERT_MSG(!(((size) & ((size) - 1))) && \
247+
(size) >= CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE && \
248+
!((u32_t)(start) & ((size) - 1)), \
249+
"the size of the partition must be power of 2" \
250+
" and greater than or equal to the minimum MPU region size." \
251+
"start address of the partition must align with size.")

0 commit comments

Comments
 (0)