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