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