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