blob: 0262376469e55df669f2f55f905de5fbb804b08f [file] [log] [blame]
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief TrustZone API
*
* TrustZone API for Cortex-M23/M33 CPUs implementing the Security Extension.
*/
#ifndef ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_CORTEX_M_TZ_H_
#define ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_CORTEX_M_TZ_H_
#ifdef _ASMLANGUAGE
/* nothing */
#else
#include <arm_cmse.h>
#include <zephyr/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
*
* @brief Initial Non-Secure state configuration
*
* A convenient struct to include all required Non-Secure
* state configuration.
*/
typedef struct tz_nonsecure_setup_conf {
uint32_t msp_ns;
uint32_t psp_ns;
uint32_t vtor_ns;
struct {
uint32_t npriv:1;
uint32_t spsel:1;
uint32_t reserved:30;
} control_ns;
} tz_nonsecure_setup_conf_t;
/**
*
* @brief Setup Non-Secure state core registers
*
* Configure the Non-Secure instances of the VTOR, MSP, PSP,
* and CONTROL register.
*
* @param p_ns_conf Pointer to a structure holding the desired configuration.
*
* Notes:
*
* This function shall only be called from Secure state, otherwise the
* Non-Secure instances of the core registers are RAZ/WI.
*
* This function shall be called before the Secure Firmware may transition
* to Non-Secure state.
*
*/
void tz_nonsecure_state_setup(const tz_nonsecure_setup_conf_t *p_ns_conf);
#if defined(CONFIG_ARMV8_M_MAINLINE)
/**
*
* @brief Setup Non-Secure Main Stack Pointer limit register
*
* Configure the Non-Secure instance of the MSPLIM register.
*
* @param val value to configure the MSPLIM_NS register with.
*
* Notes:
*
* This function shall only be called from Secure state.
* Only ARMv8-M Mainline implementations have Non-Secure MSPLIM instance.
*
*/
void tz_nonsecure_msplim_set(uint32_t val);
/**
*
* @brief Setup Non-Secure Process Stack Pointer limit register
*
* Configure the Non-Secure instance of the PSPLIM register.
*
* @param val value to configure the PSPLIM_NS register with.
*
* Notes:
*
* This function shall only be called from Secure state.
* Only ARMv8-M Mainline implementations have Non-Secure PSPLIM instance.
*
*/
void tz_nonsecure_psplim_set(uint32_t val);
#endif /* CONFIG_ARMV8_M_MAINLINE */
/**
* @brief Block or permit Non-Secure System Reset Requests
*
* Function allows the user to configure the system to block or
* permit the Non-Secure domain to issue System Reset Requests.
*
* @param block Flag indicating whether Non-Secure System Reset
* Requests shall be blocked (1), or permitted (0).
*
* Note:
*
* This function shall only be called from Secure state.
*/
void tz_nonsecure_system_reset_req_block(int block);
/**
* @brief Prioritize Secure exceptions
*
* Function allows the user to prioritize Secure exceptions over Non-Secure,
* enabling Secure exception priority boosting.
*
* @param secure_boost Flag indicating whether Secure priority boosting
* is desired; select 1 for priority boosting, otherwise 0.
*
* Note:
*
* This function shall only be called from Secure state.
*/
void tz_nonsecure_exception_prio_config(int secure_boost);
/**
* @brief Set target state for exceptions not banked between security states
*
* Function sets the security state (Secure or Non-Secure) target
* for ARMv8-M HardFault, NMI, and BusFault exception.
*
* @param secure_state 1 if target state is Secure, 0 if target state
* is Non-Secure.
*
* Secure state: BusFault, HardFault, and NMI are Secure.
* Non-Secure state: BusFault and NMI are Non-Secure and exceptions can
* target Non-Secure HardFault.
*
* Notes:
*
* - This function shall only be called from Secure state.
* - NMI and BusFault are not banked between security states; they
* shall either target Secure or Non-Secure state based on user selection.
* - HardFault exception generated through escalation will target the
* security state of the original fault before its escalation to HardFault.
* - If secure_state is set to 1 (Secure), all Non-Secure HardFaults are
* escalated to Secure HardFaults.
* - BusFault is present only if the Main Extension is implemented.
*/
void tz_nbanked_exception_target_state_set(int secure_state);
#if defined(CONFIG_ARMV7_M_ARMV8_M_FP)
/**
* @brief Allow Non-Secure firmware to access the FPU
*
* Function allows the Non-Secure firmware to access the Floating Point Unit.
*
* Relevant for ARMv8-M MCUs supporting the Floating Point Extension.
*
* Note:
*
* This function shall only be called from Secure state.
*/
void tz_nonsecure_fpu_access_enable(void);
#endif /* CONFIG_ARMV7_M_ARMV8_M_FP */
/**
*
* @brief Configure SAU
*
* Configure (enable or disable) the ARMv8-M Security Attribution Unit.
*
* @param enable SAU enable flag: 1 if SAU is to be enabled, 0 if SAU is
* to be disabled.
* @param allns SAU_CTRL.ALLNS flag: select 1 to set SAU_CTRL.ALLNS, 0
* to clear SAU_CTRL.ALLNS.
*
* Notes:
*
* SAU_CTRL.ALLNS bit: All Non-secure. When SAU_CTRL.ENABLE is 0
* this bit controls if the memory is marked as Non-secure or Secure.
* Values:
* Secure (not Non-Secure Callable): 0
* Non-Secure: 1
*
* This function shall only be called from Secure state, otherwise the
* Non-Secure instance of SAU_CTRL register is RAZ/WI.
*
* This function shall be called before the Secure Firmware may transition
* to Non-Secure state.
*
*/
void tz_sau_configure(int enable, int allns);
/**
*
* @brief Get number of SAU regions
*
* Get the number of regions implemented by the Security Attribution Unit,
* indicated by SAU_TYPE.SREGION (read-only) register field.
*
* Notes:
*
* The SREGION field reads as an IMPLEMENTATION DEFINED value.
*
* This function shall only be called from Secure state, otherwise the
* Non-Secure instance of SAU_TYPE register is RAZ.
*
* @return The number of configured SAU regions.
*/
uint32_t tz_sau_number_of_regions_get(void);
#if defined(CONFIG_CPU_HAS_ARM_SAU)
/**
*
* @brief SAU Region configuration
*
* A convenient struct to include all required elements
* for a SAU region configuration.
*/
typedef struct {
uint8_t region_num;
uint8_t enable:1;
uint8_t nsc:1;
uint32_t base_addr;
uint32_t limit_addr;
} tz_sau_conf_t;
/**
*
* @brief Configure SAU Region
*
* Configure an existing ARMv8-M SAU region.
*
* @param p_sau_conf pointer to a tz_sau_conf_t structure
*
* This function shall only be called from Secure state, otherwise the
* Non-Secure instances of SAU RNR, RLAR, RBAR registers are RAZ/WI.
*
* This function shall be called before the Secure Firmware may transition
* to Non-Secure state.
*
* @return 1 if configuration is successful, otherwise 0.
*/
int tz_sau_region_configure(tz_sau_conf_t *p_sau_conf);
#endif /* CONFIG_CPU_HAS_ARM_SAU */
/**
* @brief Non-Secure function type
*
* Defines a function pointer type to implement a non-secure function call,
* i.e. a function call that switches state from Secure to Non-secure.
*
* Note:
*
* A non-secure function call can only happen through function pointers.
* This is a consequence of separating secure and non-secure code into
* separate executable files.
*/
typedef void __attribute__((cmse_nonsecure_call)) (*tz_ns_func_ptr_t) (void);
/* Required for C99 compilation (required for GCC-8.x version,
* where typeof is used instead of __typeof__)
*/
#ifndef typeof
#define typeof __typeof__
#endif
#if defined(CONFIG_ARM_FIRMWARE_HAS_SECURE_ENTRY_FUNCS)
/**
* @brief Non-Secure entry function attribute.
*
* Declares a non-secure entry function that may be called from Non-Secure
* or from Secure state using the CMSE _cmse_nonsecure_entry intrinsic.
*
* Note:
*
* The function must reside in Non-Secure Callable memory region.
*/
#define __TZ_NONSECURE_ENTRY_FUNC \
__attribute__((cmse_nonsecure_entry, noinline))
#endif /* CONFIG_ARM_FIRMWARE_HAS_SECURE_ENTRY_FUNCS */
/**
* @brief Declare a pointer of non-secure function type
*
* Note:
*
* A non-secure function type must only be used as a base type of pointer.
*/
#define TZ_NONSECURE_FUNC_PTR_DECLARE(fptr) tz_ns_func_ptr_t fptr
/**
* @brief Define a non-secure function pointer
*
* A non-secure function pointer is a function pointer that has its LSB unset.
* The macro uses the CMSE intrinsic: cmse_nsfptr_create(p) to return the
* value of a pointer with its LSB cleared.
*/
#define TZ_NONSECURE_FUNC_PTR_CREATE(fptr) \
((tz_ns_func_ptr_t)(cmse_nsfptr_create(fptr)))
/**
* @brief Check if pointer can be of non-secure function type
*
* A non-secure function pointer is a function pointer that has its LSB unset.
* The macro uses the CMSE intrinsic: cmse_is_nsfptr(p) to evaluate whether
* the supplied pointer has its LSB cleared and, thus, can be of non-secure
* function type.
*
* @param fptr supplied pointer to be checked
*
* @return non-zero if pointer can be of non-secure function type
* (i.e. with LSB unset), zero otherwise.
*/
#define TZ_NONSECURE_FUNC_PTR_IS_NS(fptr) \
cmse_is_nsfptr(fptr)
#ifdef __cplusplus
}
#endif
#endif /* _ASMLANGUAGE */
#endif /* ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_CORTEX_M_TZ_H_ */