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) cmse_check_pointed_object(p_obj, CMSE_MPU_READ)
161 
162 /**
163  * @brief Read accessibility of an object (nPRIV mode)
164  *
165  * Evaluates whether a given object can be read according to the
166  * permissions of the current state MPU (unprivileged read).
167  *
168  * The macro shall always evaluate to zero if called from an unprivileged mode.
169  *
170  * @param p_obj Pointer to the given object
171  *              for which the readability is requested
172  *
173  * @pre Object is allocated in a single MPU (and/or SAU/IDAU) region.
174  *
175  * @return p_obj if object is readable, NULL otherwise.
176  */
177 #define ARM_CMSE_OBJECT_UNPRIV_READ_OK(p_obj)                                                      \
178 	cmse_check_pointed_object(p_obj, CMSE_MPU_UNPRIV | CMSE_MPU_READ)
179 
180 /**
181  * @brief Read and Write accessibility of an object
182  *
183  * Evaluates whether a given object can be read and written
184  * according to the permissions of the current state MPU.
185  *
186  * The macro shall always evaluate to zero if called from an unprivileged mode.
187  *
188  * @param p_obj Pointer to the given object
189  *              for which the read and write ability is requested
190  *
191  * @pre Object is allocated in a single MPU (and/or SAU/IDAU) region.
192  *
193  * @return p_obj if object is Read and Writable, NULL otherwise.
194  */
195 #define ARM_CMSE_OBJECT_READWRITE_OK(p_obj) cmse_check_pointed_object(p_obj, CMSE_MPU_READWRITE)
196 
197 /**
198  * @brief Read and Write accessibility of an object (nPRIV mode)
199  *
200  * Evaluates whether a given object can be read and written according
201  * to the permissions of the current state MPU (unprivileged read/write).
202  *
203  * The macro shall always evaluate to zero if called from an unprivileged mode.
204  *
205  * @param p_obj Pointer to the given object
206  *              for which the read and write ability is requested
207  *
208  * @pre Object is allocated in a single MPU (and/or SAU/IDAU) region.
209  *
210  * @return p_obj if object is Read and Writable, NULL otherwise.
211  */
212 #define ARM_CMSE_OBJECT_UNPRIV_READWRITE_OK(p_obj)                                                 \
213 	cmse_check_pointed_object(p_obj, CMSE_MPU_UNPRIV | CMSE_MPU_READWRITE)
214 
215 #if defined(CONFIG_ARM_SECURE_FIRMWARE)
216 
217 /**
218  * @brief Get the MPU (Non-Secure) region number of an address
219  *
220  * Return the non-negative MPU (Non-Secure) region that the address maps to,
221  * or -EINVAL to indicate that an invalid MPU region was retrieved.
222  *
223  * Note:
224  * Obtained region is valid only if:
225  * - the function is called from Secure state
226  * - the MPU is implemented and enabled
227  * - the given address matches a single, enabled MPU region
228  *
229  * @param addr The address for which the MPU region is requested
230  *
231  * @return a valid MPU region number or -EINVAL
232  */
233 int arm_cmse_mpu_nonsecure_region_get(uint32_t addr);
234 
235 /**
236  * @brief Get the SAU region number of an address
237  *
238  * Return the non-negative SAU (Non-Secure) region that the address maps to,
239  * or -EINVAL to indicate that an invalid SAU region was retrieved.
240  *
241  * Note:
242  * Obtained region is valid only if:
243  * - the function is called from Secure state
244  * - the SAU is implemented and enabled
245  * - the given address is not exempt from the secure memory attribution
246  *
247  * @param addr The address for which the SAU region is requested
248  *
249  * @return a valid SAU region number or -EINVAL
250  */
251 int arm_cmse_sau_region_get(uint32_t addr);
252 
253 /**
254  * @brief Get the IDAU region number of an address
255  *
256  * Return the non-negative IDAU (Non-Secure) region that the address maps to,
257  * or -EINVAL to indicate that an invalid IDAU region was retrieved.
258  *
259  * Note:
260  * Obtained region is valid only if:
261  * - the function is called from Secure state
262  * - the IDAU can provide a region number
263  * - the given address is not exempt from the secure memory attribution
264  *
265  * @param addr The address for which the IDAU region is requested
266  *
267  * @return a valid IDAU region number or -EINVAL
268  */
269 int arm_cmse_idau_region_get(uint32_t addr);
270 
271 /**
272  * @brief Security attribution of an address
273  *
274  * Evaluates whether a specified memory location belongs to a Secure region.
275  * This function shall always return zero if executed from Non-Secure state.
276  *
277  * @param addr The address for which the security attribution is requested
278  *
279  * @return 1 if address is Secure, 0 otherwise.
280  */
281 int arm_cmse_addr_is_secure(uint32_t addr);
282 
283 /**
284  * @brief Non-Secure Read accessibility of an address
285  *
286  * Evaluates whether a specified memory location can be read from Non-Secure
287  * state according to the permissions of the Non-Secure state MPU and the
288  * specified operation mode.
289  *
290  * This function shall always return zero:
291  * - if executed from Non-Secure state
292  * - if the address matches multiple MPU regions.
293  *
294  * @param addr The address for which the readability is requested
295  * @param force_npriv Instruct to return the readability of the address
296  *                    for unprivileged access, regardless of whether the current
297  *                    mode is privileged or unprivileged.
298  *
299  * @return 1 if address is readable from Non-Secure state, 0 otherwise.
300  */
301 int arm_cmse_addr_nonsecure_read_ok(uint32_t addr, int force_npriv);
302 
303 /**
304  * @brief Non-Secure Read and Write accessibility of an address
305  *
306  * Evaluates whether a specified memory location can be read/written from
307  * Non-Secure state according to the permissions of the Non-Secure state MPU
308  * and the specified operation mode.
309  *
310  * This function shall always return zero:
311  * - if executed from Non-Secure  mode,
312  * - if the address matches multiple MPU regions.
313  *
314  * @param addr The address for which the RW ability is requested
315  * @param force_npriv Instruct to return the RW ability of the address
316  *                    for unprivileged access, regardless of whether the current
317  *                    mode is privileged or unprivileged.
318  *
319  * @return 1 if address is Read and Writable from Non-Secure state, 0 otherwise
320  */
321 int arm_cmse_addr_nonsecure_readwrite_ok(uint32_t addr, int force_npriv);
322 
323 /**
324  * @brief Non-Secure Read accessibility of an address range
325  *
326  * Evaluates whether a memory address range, specified by its base address
327  * and size, can be read according to the permissions of the Non-Secure state
328  * MPU and the specified operation mode.
329  *
330  * This function shall always return zero:
331  * - if executed from Non-Secure  mode,
332  * - if the address matches multiple MPU (and/or SAU/IDAU) regions.
333  *
334  * @param addr The base address of an address range,
335  *             for which the readability is requested
336  * @param size The size of the address range
337  * @param force_npriv Instruct to return the readability of the address range
338  *                    for unprivileged access, regardless of whether the current
339  *                    mode is privileged or unprivileged.
340  *
341  * @return 1 if address range is readable, 0 otherwise.
342  */
343 int arm_cmse_addr_range_nonsecure_read_ok(uint32_t addr, uint32_t size, int force_npriv);
344 
345 /**
346  * @brief Non-Secure Read and Write accessibility of an address range
347  *
348  * Evaluates whether a memory address range, specified by its base address
349  * and size, can be read and written according to the permissions of the
350  * Non-Secure state MPU and the specified operation mode.
351  *
352  * This function shall always return zero:
353  * - if executed from Non-Secure  mode,
354  * - if the address matches multiple MPU (and/or SAU/IDAU) regions.
355  *
356  * @param addr The base address of an address range,
357  *             for which Read and Write ability is requested
358  * @param size The size of the address range
359  * @param force_npriv Instruct to return the readability of the address range
360  *                    for unprivileged access, regardless of whether the current
361  *                    mode is privileged or unprivileged.
362  *
363  * @return 1 if address range is readable, 0 otherwise.
364  */
365 int arm_cmse_addr_range_nonsecure_readwrite_ok(uint32_t addr, uint32_t size, int force_npriv);
366 
367 /**
368  * @brief Non-Secure Read accessibility of an object
369  *
370  * Evaluates whether a given object can be read according to the
371  * permissions of the Non-Secure state MPU.
372  *
373  * The macro shall always evaluate to zero if called from Non-Secure state.
374  *
375  * @param p_obj Pointer to the given object
376  *              for which the readability is requested
377  *
378  * @pre Object is allocated in a single MPU region.
379  *
380  * @return p_obj if object is readable from Non-Secure state, NULL otherwise.
381  */
382 #define ARM_CMSE_OBJECT_NONSECURE_READ_OK(p_obj)                                                   \
383 	cmse_check_pointed_object(p_obj, CMSE_NONSECURE | CMSE_MPU_READ)
384 
385 /**
386  * @brief Non-Secure Read accessibility of an object (nPRIV mode)
387  *
388  * Evaluates whether a given object can be read according to the
389  * permissions of the Non-Secure state MPU (unprivileged read).
390  *
391  * The macro shall always evaluate to zero if called from Non-Secure state.
392  *
393  * @param p_obj Pointer to the given object
394  *              for which the readability is requested
395  *
396  * @pre Object is allocated in a single MPU region.
397  *
398  * @return p_obj if object is readable from Non-Secure state, NULL otherwise.
399  */
400 #define ARM_CMSE_OBJECT_NONSECURE_UNPRIV_READ_OK(p_obj)                                            \
401 	cmse_check_pointed_object(p_obj, CMSE_NONSECURE | CMSE_MPU_UNPRIV | CMSE_MPU_READ)
402 
403 /**
404  * @brief Non-Secure Read and Write accessibility of an object
405  *
406  * Evaluates whether a given object can be read and written
407  * according to the permissions of the Non-Secure state MPU.
408  *
409  * The macro shall always evaluate to zero if called from Non-Secure state.
410  *
411  * @param p_obj Pointer to the given object
412  *              for which the read and write ability is requested
413  *
414  * @pre Object is allocated in a single MPU region.
415  *
416  * @return p_obj if object is Non-Secure Read and Writable, NULL otherwise.
417  */
418 #define ARM_CMSE_OBJECT_NONSECURE_READWRITE_OK(p_obj)                                              \
419 	cmse_check_pointed_object(p_obj, CMSE_NONSECURE | CMSE_MPU_READWRITE)
420 
421 /**
422  * @brief Non-Secure Read and Write accessibility of an object (nPRIV mode)
423  *
424  * Evaluates whether a given object can be read and written according
425  * to the permissions of the Non-Secure state MPU (unprivileged read/write).
426  *
427  * The macro shall always evaluate to zero if called from Non-Secure state.
428  *
429  * @param p_obj Pointer to the given object
430  *              for which the read and write ability is requested
431  *
432  * @pre Object is allocated in a single MPU region.
433  *
434  * @return p_obj if object is Non-Secure Read and Writable, NULL otherwise.
435  */
436 #define ARM_CMSE_OBJECT_NON_SECURE_UNPRIV_READWRITE_OK(p_obj)                                      \
437 	cmse_check_pointed_object(p_obj, CMSE_NONSECURE | CMSE_MPU_UNPRIV | CMSE_MPU_READWRITE)
438 
439 #endif /* CONFIG_ARM_SECURE_FIRMWARE */
440 
441 #ifdef __cplusplus
442 }
443 #endif
444 
445 #endif /* _ASMLANGUAGE */
446 
447 #endif /* ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_CORTEX_M_CMSE_H_ */
448