zephyr/arch/arm/include/cortex_m/cmse.h

448 lines
15 KiB
C

/*
* 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 __cplusplus
extern "C" {
#endif
#ifdef _ASMLANGUAGE
/* nothing */
#else
#include <arm_cmse.h>
#include <stdint.h>
/*
* 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);
/**
* @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 */
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_ARCH_ARM_INCLUDE_CORTEX_M_CMSE_H_ */