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