Boot Linux faster!

Check our new training course

Boot Linux faster!

Check our new training course
and Creative Commons CC-BY-SA
lecture and lab materials

Bootlin logo

Elixir Cross Referencer

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief ARM Core CMSE API
 *
 * CMSE API for Cortex-M23/M33 CPUs.
 */

#ifndef ZEPHYR_ARCH_ARM_INCLUDE_CORTEX_M_CMSE_H_
#define ZEPHYR_ARCH_ARM_INCLUDE_CORTEX_M_CMSE_H_

#ifdef _ASMLANGUAGE

/* nothing */

#else

#include <arm_cmse.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Address information retrieval based on the TT instructions.
 *
 * The TT instructions are used to check the access permissions that different
 * security states and privilege levels have on memory at a specified address
 */

/**
 * @brief Get the MPU region number of an address
 *
 * Return the non-negative MPU region that the address maps to,
 * or -EINVAL to indicate that an invalid MPU region was retrieved.
 *
 * Note:
 * Obtained region is valid only if:
 * - the function is called from privileged mode
 * - the MPU is implemented and enabled
 * - the given address matches a single, enabled MPU region
 *
 * @param addr The address for which the MPU region is requested
 *
 * @return a valid MPU region number or -EINVAL
 */
int arm_cmse_mpu_region_get(u32_t addr);

/**
 * @brief Read accessibility of an address
 *
 * Evaluates whether a specified memory location can be read according to the
 * permissions of the current state MPU and the specified operation mode.
 *
 * This function shall always return zero:
 * - if executed from an unprivileged mode,
 * - if the address matches multiple MPU regions.
 *
 * @param addr The address for which the readability is requested
 * @param force_npriv Instruct to return the readability of the address
 *                    for unprivileged access, regardless of whether the current
 *                    mode is privileged or unprivileged.
 *
 * @return 1 if address is readable, 0 otherwise.
 */
int arm_cmse_addr_read_ok(u32_t addr, int force_npriv);

/**
 * @brief Read and Write accessibility of an address
 *
 * Evaluates whether a specified memory location can be read/written according
 * to the permissions of the current state MPU and the specified operation
 * mode.
 *
 * This function shall always return zero:
 * - if executed from an unprivileged mode,
 * - if the address matches multiple MPU regions.
 *
 * @param addr The address for which the RW ability is requested
 * @param force_npriv Instruct to return the RW ability of the address
 *                    for unprivileged access, regardless of whether the current
 *                    mode is privileged or unprivileged.
 *
 * @return 1 if address is Read and Writable, 0 otherwise.
 */
int arm_cmse_addr_readwrite_ok(u32_t addr, int force_npriv);

/**
 * @brief Read accessibility of an address range
 *
 * Evaluates whether a memory address range, specified by its base address
 * and size, can be read according to the permissions of the current state MPU
 * and the specified operation mode.
 *
 * This function shall always return zero:
 * - if executed from an unprivileged mode,
 * - if the address range overlaps with multiple MPU (and/or SAU/IDAU) regions.
 *
 * @param addr The base address of an address range,
 *             for which the readability is requested
 * @param size The size of the address range
 * @param force_npriv Instruct to return the readability of the address range
 *                    for unprivileged access, regardless of whether the current
 *                    mode is privileged or unprivileged.
 *
 * @return 1 if address range is readable, 0 otherwise.
 */
int arm_cmse_addr_range_read_ok(u32_t addr, u32_t size, int force_npriv);

/**
 * @brief Read and Write accessibility of an address range
 *
 * Evaluates whether a memory address range, specified by its base address
 * and size, can be read/written according to the permissions of the current
 * state MPU and the specified operation mode.
 *
 * This function shall always return zero:
 * - if executed from an unprivileged mode,
 * - if the address range overlaps with multiple MPU (and/or SAU/IDAU) regions.
 *
 * @param addr The base address of an address range,
 *             for which the RW ability is requested
 * @param size The size of the address range
 * @param force_npriv Instruct to return the RW ability of the address range
 *                    for unprivileged access, regardless of whether the current
 *                    mode is privileged or unprivileged.
 *
 * @return 1 if address range is Read and Writable, 0 otherwise.
 */
int arm_cmse_addr_range_readwrite_ok(u32_t addr, u32_t size, int force_npriv);

/* Required for C99 compilation (required for GCC-8.x version,
 * where typeof is used instead of __typeof__)
 */
#ifndef typeof
#define typeof  __typeof__
#endif

/**
 * @brief Read accessibility of an object
 *
 * Evaluates whether a given object can be read according to the
 * permissions of the current state MPU.
 *
 * The macro shall always evaluate to zero if called from an unprivileged mode.
 *
 * @param p_obj Pointer to the given object
 *              for which the readability is requested
 *
 * @pre Object is allocated in a single MPU (and/or SAU/IDAU) region.
 *
 * @return p_obj if object is readable, NULL otherwise.
 */
#define ARM_CMSE_OBJECT_READ_OK(p_obj) \
	cmse_check_pointed_object(p_obj, CMSE_MPU_READ)

/**
 * @brief Read accessibility of an object (nPRIV mode)
 *
 * Evaluates whether a given object can be read according to the
 * permissions of the current state MPU (unprivileged read).
 *
 * The macro shall always evaluate to zero if called from an unprivileged mode.
 *
 * @param p_obj Pointer to the given object
 *              for which the readability is requested
 *
 * @pre Object is allocated in a single MPU (and/or SAU/IDAU) region.
 *
 * @return p_obj if object is readable, NULL otherwise.
 */
#define ARM_CMSE_OBJECT_UNPRIV_READ_OK(p_obj) \
	cmse_check_pointed_object(p_obj, CMSE_MPU_UNPRIV | CMSE_MPU_READ)

/**
 * @brief Read and Write accessibility of an object
 *
 * Evaluates whether a given object can be read and written
 * according to the permissions of the current state MPU.
 *
 * The macro shall always evaluate to zero if called from an unprivileged mode.
 *
 * @param p_obj Pointer to the given object
 *              for which the read and write ability is requested
 *
 * @pre Object is allocated in a single MPU (and/or SAU/IDAU) region.
 *
 * @return p_obj if object is Read and Writable, NULL otherwise.
 */
#define ARM_CMSE_OBJECT_READWRITE_OK(p_obj) \
	cmse_check_pointed_object(p_obj, CMSE_MPU_READWRITE)

/**
 * @brief Read and Write accessibility of an object (nPRIV mode)
 *
 * Evaluates whether a given object can be read and written according
 * to the permissions of the current state MPU (unprivileged read/write).
 *
 * The macro shall always evaluate to zero if called from an unprivileged mode.
 *
 * @param p_obj Pointer to the given object
 *              for which the read and write ability is requested
 *
 * @pre Object is allocated in a single MPU (and/or SAU/IDAU) region.
 *
 * @return p_obj if object is Read and Writable, NULL otherwise.
 */
#define ARM_CMSE_OBJECT_UNPRIV_READWRITE_OK(p_obj) \
	cmse_check_pointed_object(p_obj, CMSE_MPU_UNPRIV | CMSE_MPU_READWRITE)

#if defined(CONFIG_ARM_SECURE_FIRMWARE)

/**
 * @brief Get the MPU (Non-Secure) region number of an address
 *
 * Return the non-negative MPU (Non-Secure) region that the address maps to,
 * or -EINVAL to indicate that an invalid MPU region was retrieved.
 *
 * Note:
 * Obtained region is valid only if:
 * - the function is called from Secure state
 * - the MPU is implemented and enabled
 * - the given address matches a single, enabled MPU region
 *
 * @param addr The address for which the MPU region is requested
 *
 * @return a valid MPU region number or -EINVAL
  */
int arm_cmse_mpu_nonsecure_region_get(u32_t addr);

/**
 * @brief Get the SAU region number of an address
 *
 * Return the non-negative SAU (Non-Secure) region that the address maps to,
 * or -EINVAL to indicate that an invalid SAU region was retrieved.
 *
 * Note:
 * Obtained region is valid only if:
 * - the function is called from Secure state
 * - the SAU is implemented and enabled
 * - the given address is not exempt from the secure memory attribution
 *
 * @param addr The address for which the SAU region is requested
 *
 * @return a valid SAU region number or -EINVAL
  */
int arm_cmse_sau_region_get(u32_t addr);

/**
 * @brief Get the IDAU region number of an address
 *
 * Return the non-negative IDAU (Non-Secure) region that the address maps to,
 * or -EINVAL to indicate that an invalid IDAU region was retrieved.
 *
 * Note:
 * Obtained region is valid only if:
 * - the function is called from Secure state
 * - the IDAU can provide a region number
 * - the given address is not exempt from the secure memory attribution
 *
 * @param addr The address for which the IDAU region is requested
 *
 * @return a valid IDAU region number or -EINVAL
  */
int arm_cmse_idau_region_get(u32_t addr);

/**
 * @brief Security attribution of an address
 *
 * Evaluates whether a specified memory location belongs to a Secure region.
 * This function shall always return zero if executed from Non-Secure state.
 *
 * @param addr The address for which the security attribution is requested
 *
 * @return 1 if address is Secure, 0 otherwise.
 */
int arm_cmse_addr_is_secure(u32_t addr);

/**
 * @brief Non-Secure Read accessibility of an address
 *
 * Evaluates whether a specified memory location can be read from Non-Secure
 * state according to the permissions of the Non-Secure state MPU and the
 * specified operation mode.
 *
 * This function shall always return zero:
 * - if executed from Non-Secure state
 * - if the address matches multiple MPU regions.
 *
 * @param addr The address for which the readability is requested
 * @param force_npriv Instruct to return the readability of the address
 *                    for unprivileged access, regardless of whether the current
 *                    mode is privileged or unprivileged.
 *
 * @return 1 if address is readable from Non-Secure state, 0 otherwise.
 */
int arm_cmse_addr_nonsecure_read_ok(u32_t addr, int force_npriv);

/**
 * @brief Non-Secure Read and Write accessibility of an address
 *
 * Evaluates whether a specified memory location can be read/written from
 * Non-Secure state according to the permissions of the Non-Secure state MPU
 * and the specified operation mode.
 *
 * This function shall always return zero:
 * - if executed from Non-Secure  mode,
 * - if the address matches multiple MPU regions.
 *
 * @param addr The address for which the RW ability is requested
 * @param force_npriv Instruct to return the RW ability of the address
 *                    for unprivileged access, regardless of whether the current
 *                    mode is privileged or unprivileged.
 *
 * @return 1 if address is Read and Writable from Non-Secure state, 0 otherwise
 */
int arm_cmse_addr_nonsecure_readwrite_ok(u32_t addr, int force_npriv);

/**
 * @brief Non-Secure Read accessibility of an address range
 *
 * Evaluates whether a memory address range, specified by its base address
 * and size, can be read according to the permissions of the Non-Secure state
 * MPU and the specified operation mode.
 *
 * This function shall always return zero:
 * - if executed from Non-Secure  mode,
 * - if the address matches multiple MPU (and/or SAU/IDAU) regions.
 *
 * @param addr The base address of an address range,
 *             for which the readability is requested
 * @param size The size of the address range
 * @param force_npriv Instruct to return the readability of the address range
 *                    for unprivileged access, regardless of whether the current
 *                    mode is privileged or unprivileged.
 *
 * @return 1 if address range is readable, 0 otherwise.
 */
int arm_cmse_addr_range_nonsecure_read_ok(u32_t addr, u32_t size,
	int force_npriv);

/**
 * @brief Non-Secure Read and Write accessibility of an address range
 *
 * Evaluates whether a memory address range, specified by its base address
 * and size, can be read and written according to the permissions of the
 * Non-Secure state MPU and the specified operation mode.
 *
 * This function shall always return zero:
 * - if executed from Non-Secure  mode,
 * - if the address matches multiple MPU (and/or SAU/IDAU) regions.
 *
 * @param addr The base address of an address range,
 *             for which Read and Write ability is requested
 * @param size The size of the address range
 * @param force_npriv Instruct to return the readability of the address range
 *                    for unprivileged access, regardless of whether the current
 *                    mode is privileged or unprivileged.
 *
 * @return 1 if address range is readable, 0 otherwise.
 */
int arm_cmse_addr_range_nonsecure_readwrite_ok(u32_t addr, u32_t size,
	int force_npriv);

/**
 * @brief Non-Secure Read accessibility of an object
 *
 * Evaluates whether a given object can be read according to the
 * permissions of the Non-Secure state MPU.
 *
 * The macro shall always evaluate to zero if called from Non-Secure state.
 *
 * @param p_obj Pointer to the given object
 *              for which the readability is requested
 *
 * @pre Object is allocated in a single MPU region.
 *
 * @return p_obj if object is readable from Non-Secure state, NULL otherwise.
 */
#define ARM_CMSE_OBJECT_NONSECURE_READ_OK(p_obj) \
	cmse_check_pointed_object(p_obj, CMSE_NONSECURE | CMSE_MPU_READ)

/**
 * @brief Non-Secure Read accessibility of an object (nPRIV mode)
 *
 * Evaluates whether a given object can be read according to the
 * permissions of the Non-Secure state MPU (unprivileged read).
 *
 * The macro shall always evaluate to zero if called from Non-Secure state.
 *
 * @param p_obj Pointer to the given object
 *              for which the readability is requested
 *
 * @pre Object is allocated in a single MPU region.
 *
 * @return p_obj if object is readable from Non-Secure state, NULL otherwise.
 */
#define ARM_CMSE_OBJECT_NONSECURE_UNPRIV_READ_OK(p_obj) \
	cmse_check_pointed_object(p_obj, \
		CMSE_NONSECURE | CMSE_MPU_UNPRIV | CMSE_MPU_READ)

/**
 * @brief Non-Secure Read and Write accessibility of an object
 *
 * Evaluates whether a given object can be read and written
 * according to the permissions of the Non-Secure state MPU.
 *
 * The macro shall always evaluate to zero if called from Non-Secure state.
 *
 * @param p_obj Pointer to the given object
 *              for which the read and write ability is requested
 *
 * @pre Object is allocated in a single MPU region.
 *
 * @return p_obj if object is Non-Secure Read and Writable, NULL otherwise.
 */
#define ARM_CMSE_OBJECT_NONSECURE_READWRITE_OK(p_obj) \
	cmse_check_pointed_object(p_obj, CMSE_NONSECURE | CMSE_MPU_READWRITE)

/**
 * @brief Non-Secure Read and Write accessibility of an object (nPRIV mode)
 *
 * Evaluates whether a given object can be read and written according
 * to the permissions of the Non-Secure state MPU (unprivileged read/write).
 *
 * The macro shall always evaluate to zero if called from Non-Secure state.
 *
 * @param p_obj Pointer to the given object
 *              for which the read and write ability is requested
 *
 * @pre Object is allocated in a single MPU region.
 *
 * @return p_obj if object is Non-Secure Read and Writable, NULL otherwise.
 */
#define ARM_CMSE_OBJECT_NON_SECURE_UNPRIV_READWRITE_OK(p_obj) \
	cmse_check_pointed_object(p_obj, \
			CMSE_NONSECURE | CMSE_MPU_UNPRIV | CMSE_MPU_READWRITE)

#endif /* CONFIG_ARM_SECURE_FIRMWARE */

#ifdef __cplusplus
}
#endif

#endif /* _ASMLANGUAGE */

#endif /* ZEPHYR_ARCH_ARM_INCLUDE_CORTEX_M_CMSE_H_ */