Line data Source code
1 0 : /*
2 : * Copyright (c) 2018 Linaro Limited.
3 : * Copyright (c) 2018 Nordic Semiconductor ASA.
4 : * Copyright (c) 2021-2023 Arm Limited (or its affiliates). All rights reserved.
5 : *
6 : * SPDX-License-Identifier: Apache-2.0
7 : */
8 : #ifndef ZEPHYR_INCLUDE_ARCH_ARM64_CORTEX_R_MPU_ARM_MPU_H_
9 : #define ZEPHYR_INCLUDE_ARCH_ARM64_CORTEX_R_MPU_ARM_MPU_H_
10 :
11 : /*
12 : * Convenience macros to represent the ARMv8-R64-specific configuration
13 : * for memory access permission and cache-ability attribution.
14 : */
15 : /* MPU MPUIR Register Definitions */
16 0 : #define MPU_IR_REGION_Msk (0xFFU)
17 : /* MPU RBAR Register attribute msk Definitions */
18 0 : #define MPU_RBAR_BASE_Pos 6U
19 0 : #define MPU_RBAR_BASE_Msk (0x3FFFFFFFFFFFFFFUL << MPU_RBAR_BASE_Pos)
20 0 : #define MPU_RBAR_SH_Pos 4U
21 0 : #define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos)
22 0 : #define MPU_RBAR_AP_Pos 2U
23 0 : #define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos)
24 : /* RBAR_EL1 XN */
25 0 : #define MPU_RBAR_XN_Pos 1U
26 0 : #define MPU_RBAR_XN_Msk (0x1UL << MPU_RBAR_XN_Pos)
27 :
28 : /* MPU PLBAR_ELx Register Definitions */
29 0 : #define MPU_RLAR_LIMIT_Pos 6U
30 0 : #define MPU_RLAR_LIMIT_Msk (0x3FFFFFFFFFFFFFFUL << MPU_RLAR_LIMIT_Pos)
31 0 : #define MPU_RLAR_AttrIndx_Pos 1U
32 0 : #define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos)
33 0 : #define MPU_RLAR_EN_Msk (0x1UL)
34 :
35 : /* PRBAR_ELx: Attribute flag for not-allowing execution (eXecute Never) */
36 0 : #define NOT_EXEC MPU_RBAR_XN_Msk /* PRBAR_EL1 */
37 :
38 : /* PRBAR_ELx: Attribute flag for access permissions */
39 : /* Privileged Read Write, Unprivileged No Access */
40 0 : #define P_RW_U_NA 0x0U
41 0 : #define P_RW_U_NA_Msk ((P_RW_U_NA << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
42 : /* Privileged Read Write, Unprivileged Read Write */
43 0 : #define P_RW_U_RW 0x1U
44 0 : #define P_RW_U_RW_Msk ((P_RW_U_RW << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
45 : /* Privileged Read Only, Unprivileged No Access */
46 0 : #define P_RO_U_NA 0x2U
47 0 : #define P_RO_U_NA_Msk ((P_RO_U_NA << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
48 : /* Privileged Read Only, Unprivileged Read Only */
49 0 : #define P_RO_U_RO 0x3U
50 0 : #define P_RO_U_RO_Msk ((P_RO_U_RO << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk)
51 :
52 : /* PRBAR_ELx: Attribute flags for share-ability */
53 0 : #define NON_SHAREABLE 0x0U
54 0 : #define NON_SHAREABLE_Msk \
55 : ((NON_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk)
56 0 : #define OUTER_SHAREABLE 0x2U
57 0 : #define OUTER_SHAREABLE_Msk \
58 : ((OUTER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk)
59 0 : #define INNER_SHAREABLE 0x3U
60 0 : #define INNER_SHAREABLE_Msk \
61 : ((INNER_SHAREABLE << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk)
62 :
63 : /* MPIR_ELx Attribute flags for cache-ability */
64 :
65 : /* Memory Attributes for Device Memory
66 : * 1.Gathering (G/nG)
67 : * Determines whether multiple accesses can be merged into a single
68 : * bus transaction.
69 : * nG: Number/size of accesses on the bus = number/size of accesses
70 : * in code.
71 : *
72 : * 2.Reordering (R/nR)
73 : * Determines whether accesses to the same device can be reordered.
74 : * nR: Accesses to the same IMPLEMENTATION DEFINED block size will
75 : * appear on the bus in program order.
76 : *
77 : * 3 Early Write Acknowledgment (E/nE)
78 : * Indicates to the memory system whether a buffer can send
79 : * acknowledgements.
80 : * nE: The response should come from the end slave, not buffering in
81 : * the interconnect.
82 : */
83 0 : #define DEVICE_nGnRnE 0x0U
84 0 : #define DEVICE_nGnRE 0x4U
85 0 : #define DEVICE_nGRE 0x8U
86 0 : #define DEVICE_GRE 0xCU
87 :
88 : /* Read/Write Allocation Configurations for Cacheable Memory */
89 0 : #define R_NON_W_NON 0x0U /* Do not allocate Read/Write */
90 0 : #define R_NON_W_ALLOC 0x1U /* Do not allocate Read, Allocate Write */
91 0 : #define R_ALLOC_W_NON 0x2U /* Allocate Read, Do not allocate Write */
92 0 : #define R_ALLOC_W_ALLOC 0x3U /* Allocate Read/Write */
93 :
94 : /* Memory Attributes for Normal Memory */
95 0 : #define NORMAL_O_WT_NT 0x80U /* Normal, Outer Write-through non-transient */
96 0 : #define NORMAL_O_WB_NT 0xC0U /* Normal, Outer Write-back non-transient */
97 0 : #define NORMAL_O_NON_C 0x40U /* Normal, Outer Non-Cacheable */
98 :
99 0 : #define NORMAL_I_WT_NT 0x08U /* Normal, Inner Write-through non-transient */
100 0 : #define NORMAL_I_WB_NT 0x0CU /* Normal, Inner Write-back non-transient */
101 0 : #define NORMAL_I_NON_C 0x04U /* Normal, Inner Non-Cacheable */
102 :
103 : /* Global MAIR configurations */
104 0 : #define MPU_MAIR_INDEX_DEVICE 0U
105 0 : #define MPU_MAIR_ATTR_DEVICE (DEVICE_nGnRnE)
106 :
107 0 : #define MPU_MAIR_INDEX_FLASH 1U
108 0 : #define MPU_MAIR_ATTR_FLASH \
109 : ((NORMAL_O_WT_NT | (R_ALLOC_W_NON << 4)) | \
110 : (NORMAL_I_WT_NT | R_ALLOC_W_NON))
111 :
112 0 : #define MPU_MAIR_INDEX_SRAM 2U
113 0 : #define MPU_MAIR_ATTR_SRAM \
114 : ((NORMAL_O_WB_NT | (R_ALLOC_W_ALLOC << 4)) | \
115 : (NORMAL_I_WB_NT | R_ALLOC_W_ALLOC))
116 :
117 0 : #define MPU_MAIR_INDEX_SRAM_NOCACHE 3U
118 0 : #define MPU_MAIR_ATTR_SRAM_NOCACHE \
119 : ((NORMAL_O_NON_C | (R_NON_W_NON << 4)) | \
120 : (NORMAL_I_NON_C | R_NON_W_NON))
121 :
122 0 : #define MPU_MAIR_ATTRS \
123 : ((MPU_MAIR_ATTR_DEVICE << (MPU_MAIR_INDEX_DEVICE * 8)) | \
124 : (MPU_MAIR_ATTR_FLASH << (MPU_MAIR_INDEX_FLASH * 8)) | \
125 : (MPU_MAIR_ATTR_SRAM << (MPU_MAIR_INDEX_SRAM * 8)) | \
126 : (MPU_MAIR_ATTR_SRAM_NOCACHE << (MPU_MAIR_INDEX_SRAM_NOCACHE * 8)))
127 :
128 : /* Some helper defines for common regions.
129 : *
130 : * Note that the ARMv8-R MPU architecture requires that the
131 : * enabled MPU regions are non-overlapping. Therefore, it is
132 : * recommended to use these helper defines only for configuring
133 : * fixed MPU regions at build-time.
134 : */
135 0 : #define REGION_IO_ATTR \
136 : { \
137 : /* AP, XN, SH */ \
138 : .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, \
139 : /* Cache-ability */ \
140 : .mair_idx = MPU_MAIR_INDEX_DEVICE, \
141 : }
142 :
143 0 : #define REGION_RAM_ATTR \
144 : { \
145 : /* AP, XN, SH */ \
146 : .rbar = NOT_EXEC | P_RW_U_NA_Msk | OUTER_SHAREABLE_Msk, \
147 : /* Cache-ability */ \
148 : .mair_idx = MPU_MAIR_INDEX_SRAM, \
149 : }
150 :
151 0 : #define REGION_RAM_NOCACHE_ATTR \
152 : { \
153 : /* AP, XN, SH */ \
154 : .rbar = NOT_EXEC | P_RW_U_NA_Msk | NON_SHAREABLE_Msk, \
155 : /* Cache-ability */ \
156 : .mair_idx = MPU_MAIR_INDEX_SRAM_NOCACHE, \
157 : }
158 :
159 0 : #define REGION_RAM_TEXT_ATTR \
160 : { \
161 : /* AP, XN, SH */ \
162 : .rbar = P_RO_U_RO_Msk | INNER_SHAREABLE_Msk, \
163 : /* Cache-ability */ \
164 : .mair_idx = MPU_MAIR_INDEX_SRAM, \
165 : }
166 :
167 0 : #define REGION_RAM_RO_ATTR \
168 : { \
169 : /* AP, XN, SH */ \
170 : .rbar = NOT_EXEC | P_RO_U_RO_Msk | INNER_SHAREABLE_Msk, \
171 : /* Cache-ability */ \
172 : .mair_idx = MPU_MAIR_INDEX_SRAM, \
173 : }
174 :
175 : #if defined(CONFIG_MPU_ALLOW_FLASH_WRITE)
176 : /* Note that the access permissions allow for un-privileged writes
177 : */
178 : #define REGION_FLASH_ATTR \
179 : { \
180 : .rbar = P_RW_U_RW_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
181 : /* Cache-ability */ \
182 : .mair_idx = MPU_MAIR_INDEX_FLASH, \
183 : }
184 : #else /* CONFIG_MPU_ALLOW_FLASH_WRITE */
185 0 : #define REGION_FLASH_ATTR \
186 : { \
187 : .rbar = P_RO_U_RO_Msk | NON_SHAREABLE_Msk, /* AP, XN, SH */ \
188 : /* Cache-ability */ \
189 : .mair_idx = MPU_MAIR_INDEX_FLASH, \
190 : }
191 : #endif /* CONFIG_MPU_ALLOW_FLASH_WRITE */
192 :
193 : #ifndef _ASMLANGUAGE
194 :
195 : struct arm_mpu_region_attr {
196 : /* Attributes belonging to PRBAR */
197 : uint8_t rbar : 6;
198 : /* MAIR index for attribute indirection */
199 : uint8_t mair_idx : 3;
200 : };
201 :
202 : /* Region definition data structure */
203 : struct arm_mpu_region {
204 : /* Region Base Address */
205 0 : uint64_t base;
206 : /* Region limit Address */
207 0 : uint64_t limit;
208 : /* Region Name */
209 : const char *name;
210 : /* Region Attributes */
211 0 : struct arm_mpu_region_attr attr;
212 : };
213 :
214 : /* MPU configuration data structure */
215 : struct arm_mpu_config {
216 : /* Number of regions */
217 : uint32_t num_regions;
218 : /* Regions */
219 : const struct arm_mpu_region *mpu_regions;
220 : };
221 :
222 0 : #define MPU_REGION_ENTRY(_name, _base, _limit, _attr) \
223 : { \
224 : .name = _name, \
225 : .base = _base, \
226 : .limit = _limit, \
227 : .attr = _attr, \
228 : }
229 :
230 0 : #define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \
231 : {(P_RW_U_RW_Msk), MPU_MAIR_INDEX_SRAM})
232 0 : #define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \
233 : {(P_RW_U_NA_Msk), MPU_MAIR_INDEX_SRAM})
234 0 : #define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \
235 : {(P_RO_U_RO_Msk), MPU_MAIR_INDEX_SRAM})
236 0 : #define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \
237 : {(P_RO_U_NA_Msk), MPU_MAIR_INDEX_SRAM})
238 :
239 0 : typedef struct arm_mpu_region_attr k_mem_partition_attr_t;
240 :
241 : /* Reference to the MPU configuration.
242 : *
243 : * This struct is defined and populated for each SoC (in the SoC definition),
244 : * and holds the build-time configuration information for the fixed MPU
245 : * regions enabled during kernel initialization. Dynamic MPU regions (e.g.
246 : * for Thread Stack, Stack Guards, etc.) are programmed during runtime, thus,
247 : * not kept here.
248 : */
249 0 : extern const struct arm_mpu_config mpu_config;
250 :
251 0 : struct dynamic_region_info {
252 0 : int index;
253 0 : struct arm_mpu_region region_conf;
254 : };
255 :
256 0 : #define ARM64_MPU_MAX_DYNAMIC_REGIONS \
257 : 1 + /* data section */ \
258 : (CONFIG_MAX_DOMAIN_PARTITIONS + 2) + \
259 : (IS_ENABLED(CONFIG_ARM64_STACK_PROTECTION) ? 2 : 0) + \
260 : (IS_ENABLED(CONFIG_USERSPACE) ? 2 : 0)
261 :
262 : #endif /* _ASMLANGUAGE */
263 :
264 : #endif /* ZEPHYR_INCLUDE_ARCH_ARM64_CORTEX_R_MPU_ARM_MPU_H_ */
|