1 /*
2  * Copyright (c) 2018 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief ARM Core CMSE API
10  *
11  * CMSE API for Cortex-M23/M33 CPUs.
12  */
13 
14 #ifndef ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_CORTEX_M_CMSE_H_
15 #define ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_CORTEX_M_CMSE_H_
16 
17 #ifdef _ASMLANGUAGE
18 
19 /* nothing */
20 
21 #else
22 
23 #include <arm_cmse.h>
24 #include <stdint.h>
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 /*
31  * Address information retrieval based on the TT instructions.
32  *
33  * The TT instructions are used to check the access permissions that different
34  * security states and privilege levels have on memory at a specified address
35  */
36 
37 /**
38  * @brief Get the MPU region number of an address
39  *
40  * Return the non-negative MPU region that the address maps to,
41  * or -EINVAL to indicate that an invalid MPU region was retrieved.
42  *
43  * Note:
44  * Obtained region is valid only if:
45  * - the function is called from privileged mode
46  * - the MPU is implemented and enabled
47  * - the given address matches a single, enabled MPU region
48  *
49  * @param addr The address for which the MPU region is requested
50  *
51  * @return a valid MPU region number or -EINVAL
52  */
53 int arm_cmse_mpu_region_get(uint32_t addr);
54 
55 /**
56  * @brief Read accessibility of an address
57  *
58  * Evaluates whether a specified memory location can be read according to the
59  * permissions of the current state MPU and the specified operation mode.
60  *
61  * This function shall always return zero:
62  * - if executed from an unprivileged mode,
63  * - if the address matches multiple MPU regions.
64  *
65  * @param addr The address for which the readability is requested
66  * @param force_npriv Instruct to return the readability of the address
67  *                    for unprivileged access, regardless of whether the current
68  *                    mode is privileged or unprivileged.
69  *
70  * @return 1 if address is readable, 0 otherwise.
71  */
72 int arm_cmse_addr_read_ok(uint32_t addr, int force_npriv);
73 
74 /**
75  * @brief Read and Write accessibility of an address
76  *
77  * Evaluates whether a specified memory location can be read/written according
78  * to the permissions of the current state MPU and the specified operation
79  * mode.
80  *
81  * This function shall always return zero:
82  * - if executed from an unprivileged mode,
83  * - if the address matches multiple MPU regions.
84  *
85  * @param addr The address for which the RW ability is requested
86  * @param force_npriv Instruct to return the RW ability of the address
87  *                    for unprivileged access, regardless of whether the current
88  *                    mode is privileged or unprivileged.
89  *
90  * @return 1 if address is Read and Writable, 0 otherwise.
91  */
92 int arm_cmse_addr_readwrite_ok(uint32_t addr, int force_npriv);
93 
94 /**
95  * @brief Read accessibility of an address range
96  *
97  * Evaluates whether a memory address range, specified by its base address
98  * and size, can be read according to the permissions of the current state MPU
99  * and the specified operation mode.
100  *
101  * This function shall always return zero:
102  * - if executed from an unprivileged mode,
103  * - if the address range overlaps with multiple MPU (and/or SAU/IDAU) regions.
104  *
105  * @param addr The base address of an address range,
106  *             for which the readability is requested
107  * @param size The size of the address range
108  * @param force_npriv Instruct to return the readability of the address range
109  *                    for unprivileged access, regardless of whether the current
110  *                    mode is privileged or unprivileged.
111  *
112  * @return 1 if address range is readable, 0 otherwise.
113  */
114 int arm_cmse_addr_range_read_ok(uint32_t addr, uint32_t size, int force_npriv);
115 
116 /**
117  * @brief Read and Write accessibility of an address range
118  *
119  * Evaluates whether a memory address range, specified by its base address
120  * and size, can be read/written according to the permissions of the current
121  * state MPU and the specified operation mode.
122  *
123  * This function shall always return zero:
124  * - if executed from an unprivileged mode,
125  * - if the address range overlaps with multiple MPU (and/or SAU/IDAU) regions.
126  *
127  * @param addr The base address of an address range,
128  *             for which the RW ability is requested
129  * @param size The size of the address range
130  * @param force_npriv Instruct to return the RW ability of the address range
131  *                    for unprivileged access, regardless of whether the current
132  *                    mode is privileged or unprivileged.
133  *
134  * @return 1 if address range is Read and Writable, 0 otherwise.
135  */
136 int arm_cmse_addr_range_readwrite_ok(uint32_t addr, uint32_t size, int force_npriv);
137 
138 /* Required for C99 compilation (required for GCC-8.x version,
139  * where typeof is used instead of __typeof__)
140  */
141 #ifndef typeof
142 #define typeof  __typeof__
143 #endif
144 
145 /**
146  * @brief Read accessibility of an object
147  *
148  * Evaluates whether a given object can be read according to the
149  * permissions of the current state MPU.
150  *
151  * The macro shall always evaluate to zero if called from an unprivileged mode.
152  *
153  * @param p_obj Pointer to the given object
154  *              for which the readability is requested
155  *
156  * @pre Object is allocated in a single MPU (and/or SAU/IDAU) region.
157  *
158  * @return p_obj if object is readable, NULL otherwise.
159  */
160 #define ARM_CMSE_OBJECT_READ_OK(p_obj) \
161 	cmse_check_pointed_object(p_obj, CMSE_MPU_READ)
162 
163 /**
164  * @brief Read accessibility of an object (nPRIV mode)
165  *
166  * Evaluates whether a given object can be read according to the
167  * permissions of the current state MPU (unprivileged read).
168  *
169  * The macro shall always evaluate to zero if called from an unprivileged mode.
170  *
171  * @param p_obj Pointer to the given object
172  *              for which the readability is requested
173  *
174  * @pre Object is allocated in a single MPU (and/or SAU/IDAU) region.
175  *
176  * @return p_obj if object is readable, NULL otherwise.
177  */
178 #define ARM_CMSE_OBJECT_UNPRIV_READ_OK(p_obj) \
179 	cmse_check_pointed_object(p_obj, CMSE_MPU_UNPRIV | CMSE_MPU_READ)
180 
181 /**
182  * @brief Read and Write accessibility of an object
183  *
184  * Evaluates whether a given object can be read and written
185  * according to the permissions of the current state MPU.
186  *
187  * The macro shall always evaluate to zero if called from an unprivileged mode.
188  *
189  * @param p_obj Pointer to the given object
190  *              for which the read and write ability is requested
191  *
192  * @pre Object is allocated in a single MPU (and/or SAU/IDAU) region.
193  *
194  * @return p_obj if object is Read and Writable, NULL otherwise.
195  */
196 #define ARM_CMSE_OBJECT_READWRITE_OK(p_obj) \
197 	cmse_check_pointed_object(p_obj, CMSE_MPU_READWRITE)
198 
199 /**
200  * @brief Read and Write accessibility of an object (nPRIV mode)
201  *
202  * Evaluates whether a given object can be read and written according
203  * to the permissions of the current state MPU (unprivileged read/write).
204  *
205  * The macro shall always evaluate to zero if called from an unprivileged mode.
206  *
207  * @param p_obj Pointer to the given object
208  *              for which the read and write ability is requested
209  *
210  * @pre Object is allocated in a single MPU (and/or SAU/IDAU) region.
211  *
212  * @return p_obj if object is Read and Writable, NULL otherwise.
213  */
214 #define ARM_CMSE_OBJECT_UNPRIV_READWRITE_OK(p_obj) \
215 	cmse_check_pointed_object(p_obj, CMSE_MPU_UNPRIV | CMSE_MPU_READWRITE)
216 
217 #if defined(CONFIG_ARM_SECURE_FIRMWARE)
218 
219 /**
220  * @brief Get the MPU (Non-Secure) region number of an address
221  *
222  * Return the non-negative MPU (Non-Secure) region that the address maps to,
223  * or -EINVAL to indicate that an invalid MPU region was retrieved.
224  *
225  * Note:
226  * Obtained region is valid only if:
227  * - the function is called from Secure state
228  * - the MPU is implemented and enabled
229  * - the given address matches a single, enabled MPU region
230  *
231  * @param addr The address for which the MPU region is requested
232  *
233  * @return a valid MPU region number or -EINVAL
234   */
235 int arm_cmse_mpu_nonsecure_region_get(uint32_t addr);
236 
237 /**
238  * @brief Get the SAU region number of an address
239  *
240  * Return the non-negative SAU (Non-Secure) region that the address maps to,
241  * or -EINVAL to indicate that an invalid SAU region was retrieved.
242  *
243  * Note:
244  * Obtained region is valid only if:
245  * - the function is called from Secure state
246  * - the SAU is implemented and enabled
247  * - the given address is not exempt from the secure memory attribution
248  *
249  * @param addr The address for which the SAU region is requested
250  *
251  * @return a valid SAU region number or -EINVAL
252   */
253 int arm_cmse_sau_region_get(uint32_t addr);
254 
255 /**
256  * @brief Get the IDAU region number of an address
257  *
258  * Return the non-negative IDAU (Non-Secure) region that the address maps to,
259  * or -EINVAL to indicate that an invalid IDAU region was retrieved.
260  *
261  * Note:
262  * Obtained region is valid only if:
263  * - the function is called from Secure state
264  * - the IDAU can provide a region number
265  * - the given address is not exempt from the secure memory attribution
266  *
267  * @param addr The address for which the IDAU region is requested
268  *
269  * @return a valid IDAU region number or -EINVAL
270   */
271 int arm_cmse_idau_region_get(uint32_t addr);
272 
273 /**
274  * @brief Security attribution of an address
275  *
276  * Evaluates whether a specified memory location belongs to a Secure region.
277  * This function shall always return zero if executed from Non-Secure state.
278  *
279  * @param addr The address for which the security attribution is requested
280  *
281  * @return 1 if address is Secure, 0 otherwise.
282  */
283 int arm_cmse_addr_is_secure(uint32_t addr);
284 
285 /**
286  * @brief Non-Secure Read accessibility of an address
287  *
288  * Evaluates whether a specified memory location can be read from Non-Secure
289  * state according to the permissions of the Non-Secure state MPU and the
290  * specified operation mode.
291  *
292  * This function shall always return zero:
293  * - if executed from Non-Secure state
294  * - if the address matches multiple MPU regions.
295  *
296  * @param addr The address for which the readability is requested
297  * @param force_npriv Instruct to return the readability of the address
298  *                    for unprivileged access, regardless of whether the current
299  *                    mode is privileged or unprivileged.
300  *
301  * @return 1 if address is readable from Non-Secure state, 0 otherwise.
302  */
303 int arm_cmse_addr_nonsecure_read_ok(uint32_t addr, int force_npriv);
304 
305 /**
306  * @brief Non-Secure Read and Write accessibility of an address
307  *
308  * Evaluates whether a specified memory location can be read/written from
309  * Non-Secure state according to the permissions of the Non-Secure state MPU
310  * and the specified operation mode.
311  *
312  * This function shall always return zero:
313  * - if executed from Non-Secure  mode,
314  * - if the address matches multiple MPU regions.
315  *
316  * @param addr The address for which the RW ability is requested
317  * @param force_npriv Instruct to return the RW ability of the address
318  *                    for unprivileged access, regardless of whether the current
319  *                    mode is privileged or unprivileged.
320  *
321  * @return 1 if address is Read and Writable from Non-Secure state, 0 otherwise
322  */
323 int arm_cmse_addr_nonsecure_readwrite_ok(uint32_t addr, int force_npriv);
324 
325 /**
326  * @brief Non-Secure Read accessibility of an address range
327  *
328  * Evaluates whether a memory address range, specified by its base address
329  * and size, can be read according to the permissions of the Non-Secure state
330  * MPU and the specified operation mode.
331  *
332  * This function shall always return zero:
333  * - if executed from Non-Secure  mode,
334  * - if the address matches multiple MPU (and/or SAU/IDAU) regions.
335  *
336  * @param addr The base address of an address range,
337  *             for which the readability is requested
338  * @param size The size of the address range
339  * @param force_npriv Instruct to return the readability of the address range
340  *                    for unprivileged access, regardless of whether the current
341  *                    mode is privileged or unprivileged.
342  *
343  * @return 1 if address range is readable, 0 otherwise.
344  */
345 int arm_cmse_addr_range_nonsecure_read_ok(uint32_t addr, uint32_t size,
346 	int force_npriv);
347 
348 /**
349  * @brief Non-Secure Read and Write accessibility of an address range
350  *
351  * Evaluates whether a memory address range, specified by its base address
352  * and size, can be read and written according to the permissions of the
353  * Non-Secure state MPU and the specified operation mode.
354  *
355  * This function shall always return zero:
356  * - if executed from Non-Secure  mode,
357  * - if the address matches multiple MPU (and/or SAU/IDAU) regions.
358  *
359  * @param addr The base address of an address range,
360  *             for which Read and Write ability is requested
361  * @param size The size of the address range
362  * @param force_npriv Instruct to return the readability of the address range
363  *                    for unprivileged access, regardless of whether the current
364  *                    mode is privileged or unprivileged.
365  *
366  * @return 1 if address range is readable, 0 otherwise.
367  */
368 int arm_cmse_addr_range_nonsecure_readwrite_ok(uint32_t addr, uint32_t size,
369 	int force_npriv);
370 
371 /**
372  * @brief Non-Secure Read accessibility of an object
373  *
374  * Evaluates whether a given object can be read according to the
375  * permissions of the Non-Secure state MPU.
376  *
377  * The macro shall always evaluate to zero if called from Non-Secure state.
378  *
379  * @param p_obj Pointer to the given object
380  *              for which the readability is requested
381  *
382  * @pre Object is allocated in a single MPU region.
383  *
384  * @return p_obj if object is readable from Non-Secure state, NULL otherwise.
385  */
386 #define ARM_CMSE_OBJECT_NONSECURE_READ_OK(p_obj) \
387 	cmse_check_pointed_object(p_obj, CMSE_NONSECURE | CMSE_MPU_READ)
388 
389 /**
390  * @brief Non-Secure Read accessibility of an object (nPRIV mode)
391  *
392  * Evaluates whether a given object can be read according to the
393  * permissions of the Non-Secure state MPU (unprivileged read).
394  *
395  * The macro shall always evaluate to zero if called from Non-Secure state.
396  *
397  * @param p_obj Pointer to the given object
398  *              for which the readability is requested
399  *
400  * @pre Object is allocated in a single MPU region.
401  *
402  * @return p_obj if object is readable from Non-Secure state, NULL otherwise.
403  */
404 #define ARM_CMSE_OBJECT_NONSECURE_UNPRIV_READ_OK(p_obj) \
405 	cmse_check_pointed_object(p_obj, \
406 		CMSE_NONSECURE | CMSE_MPU_UNPRIV | CMSE_MPU_READ)
407 
408 /**
409  * @brief Non-Secure Read and Write accessibility of an object
410  *
411  * Evaluates whether a given object can be read and written
412  * according to the permissions of the Non-Secure state MPU.
413  *
414  * The macro shall always evaluate to zero if called from Non-Secure state.
415  *
416  * @param p_obj Pointer to the given object
417  *              for which the read and write ability is requested
418  *
419  * @pre Object is allocated in a single MPU region.
420  *
421  * @return p_obj if object is Non-Secure Read and Writable, NULL otherwise.
422  */
423 #define ARM_CMSE_OBJECT_NONSECURE_READWRITE_OK(p_obj) \
424 	cmse_check_pointed_object(p_obj, CMSE_NONSECURE | CMSE_MPU_READWRITE)
425 
426 /**
427  * @brief Non-Secure Read and Write accessibility of an object (nPRIV mode)
428  *
429  * Evaluates whether a given object can be read and written according
430  * to the permissions of the Non-Secure state MPU (unprivileged read/write).
431  *
432  * The macro shall always evaluate to zero if called from Non-Secure state.
433  *
434  * @param p_obj Pointer to the given object
435  *              for which the read and write ability is requested
436  *
437  * @pre Object is allocated in a single MPU region.
438  *
439  * @return p_obj if object is Non-Secure Read and Writable, NULL otherwise.
440  */
441 #define ARM_CMSE_OBJECT_NON_SECURE_UNPRIV_READWRITE_OK(p_obj) \
442 	cmse_check_pointed_object(p_obj, \
443 			CMSE_NONSECURE | CMSE_MPU_UNPRIV | CMSE_MPU_READWRITE)
444 
445 #endif /* CONFIG_ARM_SECURE_FIRMWARE */
446 
447 #ifdef __cplusplus
448 }
449 #endif
450 
451 #endif /* _ASMLANGUAGE */
452 
453 #endif /* ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_CORTEX_M_CMSE_H_ */
454