/* * 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_AARCH32_CORTEX_M_CMSE_H_ #define ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_CORTEX_M_CMSE_H_ #ifdef _ASMLANGUAGE /* nothing */ #else #include #include #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(uint32_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(uint32_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(uint32_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(uint32_t addr, uint32_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(uint32_t addr, uint32_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(uint32_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(uint32_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(uint32_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(uint32_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(uint32_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(uint32_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(uint32_t addr, uint32_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(uint32_t addr, uint32_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_AARCH32_CORTEX_M_CMSE_H_ */