453 lines
15 KiB
C
453 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);
|
|
|
|
/* Required for C99 compilation */
|
|
#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 */
|
|
|
|
#endif /* _ASMLANGUAGE */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* ZEPHYR_ARCH_ARM_INCLUDE_CORTEX_M_CMSE_H_ */
|