/* * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include #include #include "soc/apm_defs.h" #include "soc/tee_reg.h" #include "soc/lp_tee_reg.h" #include "soc/hp_apm_reg.h" #include "soc/hp_apm_struct.h" #include "soc/lp_apm0_reg.h" #include "soc/lp_apm0_struct.h" #include "soc/lp_apm_reg.h" #include "soc/lp_apm_struct.h" #include "soc/cpu_apm_reg.h" #include "soc/cpu_apm_struct.h" #include "soc/pcr_reg.h" #include "soc/interrupts.h" #include "hal/apm_types.h" #ifdef __cplusplus extern "C" { #endif /* Helper macros for getting APM ctrl region pms attributes field mask */ #define APM_REGION_PMS_SHIFT(mode) (4U * ((mode) - 1)) #define APM_REGION_PMS_MASK(mode) (0x07U << APM_REGION_PMS_SHIFT(mode)) #define APM_REGION_PMS_FIELD(mode, pms) ((pms) << APM_REGION_PMS_SHIFT(mode)) /* Helper macros for getting TEE ctrl periph pms attributes field mask */ #define APM_PERI_PMS_MASK(mode) ((1U << (mode)) | (1U << ((mode) ^ 4U))) #define APM_PERI_PMS_R_FIELD(mode, pms) ((((pms) & APM_PERM_R) >> 2U) << (mode)) #define APM_PERI_PMS_W_FIELD(mode, pms) ((((pms) & APM_PERM_W) >> 1U) << ((mode) ^ 4U)) /** * @brief Set security mode for a specific master in HP-TEE * * @param id Master ID * @param mode Security mode to set */ static inline void apm_ll_hp_tee_set_master_sec_mode(apm_master_id_t id, apm_security_mode_t mode) { REG_WRITE(TEE_M0_MODE_CTRL_REG + APM_TEE_MODE_CTRL_OFFSET * id, mode); } /** * @brief Lock master security mode for HP-TEE * * @param id Master ID */ static inline void apm_ll_hp_tee_lock_master_sec_mode(apm_master_id_t id) { REG_SET_BIT(TEE_M0_MODE_CTRL_REG + APM_TEE_MODE_CTRL_OFFSET * id, APM_TEE_MODE_LOCK_BIT); } /** * @brief Set access permissions for a specific peripheral in HP-TEE * * @param periph Peripheral ID * @param mode Security mode * @param pms Access permissions */ static inline void apm_ll_hp_tee_set_peri_access(apm_tee_hp_periph_t periph, apm_security_mode_t mode, apm_perm_t pms) { uint32_t reg = TEE_UART0_CTRL_REG + APM_TEE_PERI_CTRL_OFFSET * periph; uint32_t val = REG_READ(reg); val &= ~APM_PERI_PMS_MASK(mode); val |= APM_PERI_PMS_R_FIELD(mode, pms); val |= APM_PERI_PMS_W_FIELD(mode, pms); REG_WRITE(reg, val); } /** * @brief Enable or disable error response from HP-TEE when access is blocked. * * @param enable true to enable error response, false to disable. */ static inline void apm_ll_hp_tee_enable_bus_err_resp(bool enable) { if (enable) { REG_SET_BIT(TEE_BUS_ERR_CONF_REG, TEE_BUS_ERR_RESP_EN); } else { REG_CLR_BIT(TEE_BUS_ERR_CONF_REG, TEE_BUS_ERR_RESP_EN); } } /** * @brief Enable/disable clock gating for HP-TEE * * @param enable True to enable, false to disable */ static inline void apm_ll_hp_tee_enable_clk_gating(bool enable) { if (enable) { REG_CLR_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); } else { REG_SET_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); } } /** * @brief Set security mode for a specific master in LP-TEE * * @param id Master ID (unused) * @param mode Security mode to set */ static inline void apm_ll_lp_tee_set_master_sec_mode(apm_master_id_t id, apm_security_mode_t mode) { (void)id; REG_WRITE(LP_TEE_M0_MODE_CTRL_REG, mode); } /** * @brief Lock master security mode for LP-TEE * * @param id Master ID (unused) */ static inline void apm_ll_lp_tee_lock_master_sec_mode(apm_master_id_t id) { (void)id; REG_SET_BIT(LP_TEE_M0_MODE_CTRL_REG, LP_TEE_M0_LOCK); } /** * @brief Set access permissions for a specific peripheral in LP-TEE * * @param periph Peripheral ID * @param mode Security mode * @param pms Access permissions */ static inline void apm_ll_lp_tee_set_peri_access(apm_tee_lp_periph_t periph, apm_security_mode_t mode, apm_perm_t pms) { uint32_t reg = LP_TEE_EFUSE_CTRL_REG + APM_TEE_PERI_CTRL_OFFSET * periph; uint32_t val = REG_READ(reg); val &= ~APM_PERI_PMS_MASK(mode); val |= APM_PERI_PMS_R_FIELD(mode, pms); val |= APM_PERI_PMS_W_FIELD(mode, pms); REG_WRITE(reg, val); } /** * @brief Enable or disable error response from LP-TEE when access is blocked. * * @param enable true to enable error response, false to disable. */ static inline void apm_ll_lp_tee_enable_bus_err_resp(bool enable) { if (enable) { REG_SET_BIT(LP_TEE_BUS_ERR_CONF_REG, LP_TEE_BUS_ERR_RESP_EN); } else { REG_CLR_BIT(LP_TEE_BUS_ERR_CONF_REG, LP_TEE_BUS_ERR_RESP_EN); } } /** * @brief Enable/disable clock gating for LP-TEE * * @param enable True to enable, false to disable */ static inline void apm_ll_lp_tee_enable_clk_gating(bool enable) { if (enable) { REG_CLR_BIT(LP_TEE_CLOCK_GATE_REG, LP_TEE_CLK_EN); } else { REG_SET_BIT(LP_TEE_CLOCK_GATE_REG, LP_TEE_CLK_EN); } } /** * @brief Enable/disable forced HP memory access for LP-TEE * * @param enable True to enable, false to disable */ static inline void apm_ll_lp_tee_enable_force_hp_mem_access(bool enable) { if (enable) { REG_SET_BIT(LP_TEE_FORCE_ACC_HP_REG, LP_TEE_FORCE_ACC_HPMEM_EN); } else { REG_CLR_BIT(LP_TEE_FORCE_ACC_HP_REG, LP_TEE_FORCE_ACC_HPMEM_EN); } } /** * @brief Enable/disable controller filter for specific path in HP-APM * * @param path Access path * @param enable True to enable, false to disable */ static inline void apm_ll_hp_apm_enable_ctrl_filter(apm_ctrl_access_path_t path, bool enable) { if (enable) { REG_SET_BIT(HP_APM_FUNC_CTRL_REG, BIT(path)); } else { REG_CLR_BIT(HP_APM_FUNC_CTRL_REG, BIT(path)); } } /** * @brief Enable/disable all controller filters in HP-APM * * @param enable True to enable, false to disable */ static inline void apm_ll_hp_apm_enable_ctrl_filter_all(bool enable) { REG_WRITE(HP_APM_FUNC_CTRL_REG, enable ? UINT32_MAX : 0); } /** * @brief Enable/disable region filter in HP-APM * * @param regn_num Region number * @param enable True to enable, false to disable */ static inline void apm_ll_hp_apm_enable_region_filter(uint32_t regn_num, bool enable) { if (enable) { REG_SET_BIT(HP_APM_REGION_FILTER_EN_REG, BIT(regn_num)); } else { REG_CLR_BIT(HP_APM_REGION_FILTER_EN_REG, BIT(regn_num)); } } /** * @brief Set region start address in HP-APM * * @param regn_num Region number * @param addr Start address */ static inline void apm_ll_hp_apm_set_region_start_addr(uint32_t regn_num, uint32_t addr) { REG_WRITE(HP_APM_REGION0_ADDR_START_REG + APM_REGION_ADDR_OFFSET * regn_num, addr); } /** * @brief Set region end address in HP-APM * * @param regn_num Region number * @param addr End address */ static inline void apm_ll_hp_apm_set_region_end_addr(uint32_t regn_num, uint32_t addr) { REG_WRITE(HP_APM_REGION0_ADDR_END_REG + APM_REGION_ADDR_OFFSET * regn_num, addr); } /** * @brief Set security mode region attributes in HP-APM * * @param regn_num Region number * @param mode Security mode * @param regn_pms Region PMS attributes */ static inline void apm_ll_hp_apm_set_sec_mode_region_attr(uint32_t regn_num, apm_security_mode_t mode, uint32_t regn_pms) { uint32_t reg = HP_APM_REGION0_ATTR_REG + APM_REGION_ATTR_OFFSET * regn_num; uint32_t val = REG_READ(reg); val &= ~APM_REGION_PMS_MASK(mode); val |= APM_REGION_PMS_FIELD(mode, regn_pms); REG_WRITE(reg, val); } /** * @brief Lock security mode region attributes in HP-APM * * @param regn_num Region number */ static inline void apm_ll_hp_apm_lock_sec_mode_region_attr(uint32_t regn_num) { REG_SET_BIT(HP_APM_REGION0_ATTR_REG + APM_REGION_ATTR_OFFSET * regn_num, APM_REGION_LOCK_BIT); } /** * @brief Get exception data (regn, master, security mode) from HP-APM * * @param path Access path * @return Exception data */ static inline uint32_t apm_ll_hp_apm_get_excp_data(apm_ctrl_access_path_t path) { return REG_READ(HP_APM_M0_EXCEPTION_INFO0_REG + APM_EXCP_INFO_OFFSET * path); } /** * @brief Get exception status from HP-APM * * @param path Access path * @return Exception type */ static inline uint32_t apm_ll_hp_apm_get_excp_type(apm_ctrl_access_path_t path) { return REG_READ(HP_APM_M0_STATUS_REG + APM_EXCP_INFO_OFFSET * path); } /** * @brief Get exception address from HP-APM * * @param path Access path * @return Exception address */ static inline uint32_t apm_ll_hp_apm_get_excp_addr(apm_ctrl_access_path_t path) { return REG_READ(HP_APM_M0_EXCEPTION_INFO1_REG + APM_EXCP_INFO_OFFSET * path); } /** * @brief Get exception information from HP-APM * * @param path Access path * @param info Pointer to store exception information */ static inline void apm_ll_hp_apm_get_excp_info(apm_ctrl_access_path_t path, apm_ctrl_exception_info_t *info) { hp_apm_m0_exception_info0_reg_t reg; reg.val = apm_ll_hp_apm_get_excp_data(path); info->regn = reg.m0_exception_region; info->mode = reg.m0_exception_mode; info->id = reg.m0_exception_id; info->type = apm_ll_hp_apm_get_excp_type(path); info->addr = apm_ll_hp_apm_get_excp_addr(path); } /** * @brief Clear controller exception status in HP-APM * * @param path Access path */ static inline void apm_ll_hp_apm_clear_ctrl_excp_status(apm_ctrl_access_path_t path) { REG_SET_BIT(HP_APM_M0_STATUS_CLR_REG + APM_EXCP_INFO_OFFSET * path, APM_EXCP_STATUS_CLR_BIT); } /** * @brief Enable/disable controller interrupt in HP-APM * * @param path Access path * @param enable True to enable, false to disable */ static inline void apm_ll_hp_apm_enable_ctrl_intr(apm_ctrl_access_path_t path, bool enable) { if (enable) { REG_SET_BIT(HP_APM_INT_EN_REG, BIT(path)); } else { REG_CLR_BIT(HP_APM_INT_EN_REG, BIT(path)); } } /** * @brief Get controller interrupt source number from HP-APM * * @param path Access path * @return Interrupt source number */ static inline int apm_ll_hp_apm_get_ctrl_intr_src(apm_ctrl_access_path_t path) { return ETS_HP_APM_M0_INTR_SOURCE + path; } /** * @brief Enable/disable controller clock gating in HP-APM * * @param enable True to enable, false to disable */ static inline void apm_ll_hp_apm_enable_ctrl_clk_gating(bool enable) { if (enable) { REG_CLR_BIT(HP_APM_CLOCK_GATE_REG, HP_APM_CLK_EN); } else { REG_SET_BIT(HP_APM_CLOCK_GATE_REG, HP_APM_CLK_EN); } } /** * @brief Enable/disable controller filter for specific path in LP-APM0 * * @param path Access path * @param enable True to enable, false to disable */ static inline void apm_ll_lp_apm0_enable_ctrl_filter(apm_ctrl_access_path_t path, bool enable) { if (enable) { REG_SET_BIT(LP_APM0_FUNC_CTRL_REG, BIT(path)); } else { REG_CLR_BIT(LP_APM0_FUNC_CTRL_REG, BIT(path)); } } /** * @brief Enable/disable all controller filters in LP-APM0 * * @param enable True to enable, false to disable */ static inline void apm_ll_lp_apm0_enable_ctrl_filter_all(bool enable) { REG_WRITE(LP_APM0_FUNC_CTRL_REG, enable ? UINT32_MAX : 0); } /** * @brief Enable/disable region filter in LP-APM0 * * @param regn_num Region number * @param enable True to enable, false to disable */ static inline void apm_ll_lp_apm0_enable_region_filter(uint32_t regn_num, bool enable) { if (enable) { REG_SET_BIT(LP_APM0_REGION_FILTER_EN_REG, BIT(regn_num)); } else { REG_CLR_BIT(LP_APM0_REGION_FILTER_EN_REG, BIT(regn_num)); } } /** * @brief Set region start address in LP-APM0 * * @param regn_num Region number * @param addr Start address */ static inline void apm_ll_lp_apm0_set_region_start_addr(uint32_t regn_num, uint32_t addr) { REG_WRITE(LP_APM0_REGION0_ADDR_START_REG + APM_REGION_ADDR_OFFSET * regn_num, addr); } /** * @brief Set region end address in LP-APM0 * * @param regn_num Region number * @param addr End address */ static inline void apm_ll_lp_apm0_set_region_end_addr(uint32_t regn_num, uint32_t addr) { REG_WRITE(LP_APM0_REGION0_ADDR_END_REG + APM_REGION_ADDR_OFFSET * regn_num, addr); } /** * @brief Set security mode region attributes in LP-APM0 * * @param regn_num Region number * @param mode Security mode * @param regn_pms Region PMS attributes */ static inline void apm_ll_lp_apm0_set_sec_mode_region_attr(uint32_t regn_num, apm_security_mode_t mode, uint32_t regn_pms) { uint32_t reg = LP_APM0_REGION0_ATTR_REG + APM_REGION_ATTR_OFFSET * regn_num; uint32_t val = REG_READ(reg); val &= ~APM_REGION_PMS_MASK(mode); val |= APM_REGION_PMS_FIELD(mode, regn_pms); REG_WRITE(reg, val); } /** * @brief Lock security mode region attributes in LP-APM0 * * @param regn_num Region number */ static inline void apm_ll_lp_apm0_lock_sec_mode_region_attr(uint32_t regn_num) { REG_SET_BIT(LP_APM0_REGION0_ATTR_REG + APM_REGION_ATTR_OFFSET * regn_num, APM_REGION_LOCK_BIT); } /** * @brief Get exception data (regn, master, security mode) from LP-APM0 * * @param path Access path * @return Exception data */ static inline uint32_t apm_ll_lp_apm0_get_excp_data(apm_ctrl_access_path_t path) { (void)path; return REG_READ(LP_APM0_M0_EXCEPTION_INFO0_REG); } /** * @brief Get exception status from LP-APM0 * * @param path Access path * @return Exception type */ static inline uint32_t apm_ll_lp_apm0_get_excp_type(apm_ctrl_access_path_t path) { (void)path; return REG_READ(LP_APM0_M0_STATUS_REG); } /** * @brief Get exception address from LP-APM0 * * @param path Access path * @return Exception address */ static inline uint32_t apm_ll_lp_apm0_get_excp_addr(apm_ctrl_access_path_t path) { (void)path; return REG_READ(LP_APM0_M0_EXCEPTION_INFO1_REG); } /** * @brief Get exception information from LP-APM0 * * @param path Access path * @param info Pointer to store exception information */ static inline void apm_ll_lp_apm0_get_excp_info(apm_ctrl_access_path_t path, apm_ctrl_exception_info_t *info) { lp_apm0_m0_exception_info0_reg_t reg; reg.val = apm_ll_lp_apm0_get_excp_data(path); info->regn = reg.m0_exception_region; info->mode = reg.m0_exception_mode; info->id = reg.m0_exception_id; info->type = apm_ll_lp_apm0_get_excp_type(path); info->addr = apm_ll_lp_apm0_get_excp_addr(path); } /** * @brief Clear controller exception status in LP-APM0 * * @param path Access path */ static inline void apm_ll_lp_apm0_clear_ctrl_excp_status(apm_ctrl_access_path_t path) { (void)path; REG_SET_BIT(LP_APM0_M0_STATUS_CLR_REG, APM_EXCP_STATUS_CLR_BIT); } /** * @brief Enable/disable controller interrupt in LP-APM0 * * @param path Access path * @param enable True to enable, false to disable */ static inline void apm_ll_lp_apm0_enable_ctrl_intr(apm_ctrl_access_path_t path, bool enable) { if (enable) { REG_SET_BIT(LP_APM0_INT_EN_REG, BIT(path)); } else { REG_CLR_BIT(LP_APM0_INT_EN_REG, BIT(path)); } } /** * @brief Get controller interrupt source number from LP-APM0 * * @param path Access path * @return Interrupt source number */ static inline int apm_ll_lp_apm0_get_ctrl_intr_src(apm_ctrl_access_path_t path) { (void)path; return ETS_LP_APM0_INTR_SOURCE; } /** * @brief Enable/disable controller clock gating in LP-APM0 * * @param enable True to enable, false to disable */ static inline void apm_ll_lp_apm0_enable_ctrl_clk_gating(bool enable) { if (enable) { REG_CLR_BIT(LP_APM0_CLOCK_GATE_REG, LP_APM0_CLK_EN); } else { REG_SET_BIT(LP_APM0_CLOCK_GATE_REG, LP_APM0_CLK_EN); } } /** * @brief Enable/disable controller filter for specific path in LP-APM * * @param path Access path * @param enable True to enable, false to disable */ static inline void apm_ll_lp_apm_enable_ctrl_filter(apm_ctrl_access_path_t path, bool enable) { if (enable) { REG_SET_BIT(LP_APM_FUNC_CTRL_REG, BIT(path)); } else { REG_CLR_BIT(LP_APM_FUNC_CTRL_REG, BIT(path)); } } /** * @brief Enable/disable all controller filters in LP-APM * * @param enable True to enable, false to disable */ static inline void apm_ll_lp_apm_enable_ctrl_filter_all(bool enable) { REG_WRITE(LP_APM_FUNC_CTRL_REG, enable ? UINT32_MAX : 0); } /** * @brief Enable/disable region filter in LP-APM * * @param regn_num Region number * @param enable True to enable, false to disable */ static inline void apm_ll_lp_apm_enable_region_filter(uint32_t regn_num, bool enable) { if (enable) { REG_SET_BIT(LP_APM_REGION_FILTER_EN_REG, BIT(regn_num)); } else { REG_CLR_BIT(LP_APM_REGION_FILTER_EN_REG, BIT(regn_num)); } } /** * @brief Set region start address in LP-APM * * @param regn_num Region number * @param addr Start address */ static inline void apm_ll_lp_apm_set_region_start_addr(uint32_t regn_num, uint32_t addr) { REG_WRITE(LP_APM_REGION0_ADDR_START_REG + APM_REGION_ADDR_OFFSET * regn_num, addr); } /** * @brief Set region end address in LP-APM * * @param regn_num Region number * @param addr End address */ static inline void apm_ll_lp_apm_set_region_end_addr(uint32_t regn_num, uint32_t addr) { REG_WRITE(LP_APM_REGION0_ADDR_END_REG + APM_REGION_ADDR_OFFSET * regn_num, addr); } /** * @brief Set security mode region attributes in LP-APM * * @param regn_num Region number * @param mode Security mode * @param regn_pms Region PMS attributes */ static inline void apm_ll_lp_apm_set_sec_mode_region_attr(uint32_t regn_num, apm_security_mode_t mode, uint32_t regn_pms) { uint32_t reg = LP_APM_REGION0_ATTR_REG + APM_REGION_ATTR_OFFSET * regn_num; uint32_t val = REG_READ(reg); val &= ~APM_REGION_PMS_MASK(mode); val |= APM_REGION_PMS_FIELD(mode, regn_pms); REG_WRITE(reg, val); } /** * @brief Lock security mode region attributes in LP-APM * * @param regn_num Region number */ static inline void apm_ll_lp_apm_lock_sec_mode_region_attr(uint32_t regn_num) { REG_SET_BIT(LP_APM_REGION0_ATTR_REG + APM_REGION_ATTR_OFFSET * regn_num, APM_REGION_LOCK_BIT); } /** * @brief Get exception data (regn, master, security mode) from LP-APM * * @param path Access path * @return Exception data */ static inline uint32_t apm_ll_lp_apm_get_excp_data(apm_ctrl_access_path_t path) { return REG_READ(LP_APM_M0_EXCEPTION_INFO0_REG + APM_EXCP_INFO_OFFSET * path); } /** * @brief Get exception status from LP-APM * * @param path Access path * @return Exception type */ static inline uint32_t apm_ll_lp_apm_get_excp_type(apm_ctrl_access_path_t path) { return REG_READ(LP_APM_M0_STATUS_REG + APM_EXCP_INFO_OFFSET * path); } /** * @brief Get exception address from LP-APM * * @param path Access path * @return Exception address */ static inline uint32_t apm_ll_lp_apm_get_excp_addr(apm_ctrl_access_path_t path) { return REG_READ(LP_APM_M0_EXCEPTION_INFO1_REG + APM_EXCP_INFO_OFFSET * path); } /** * @brief Get exception information from LP-APM * * @param path Access path * @param info Pointer to store exception information */ static inline void apm_ll_lp_apm_get_excp_info(apm_ctrl_access_path_t path, apm_ctrl_exception_info_t *info) { lp_apm_m0_exception_info0_reg_t reg; reg.val = apm_ll_lp_apm_get_excp_data(path); info->regn = reg.m0_exception_region; info->mode = reg.m0_exception_mode; info->id = reg.m0_exception_id; info->type = apm_ll_lp_apm_get_excp_type(path); info->addr = apm_ll_lp_apm_get_excp_addr(path); } /** * @brief Clear controller exception status in LP-APM * * @param path Access path */ static inline void apm_ll_lp_apm_clear_ctrl_excp_status(apm_ctrl_access_path_t path) { REG_SET_BIT(LP_APM_M0_STATUS_CLR_REG + APM_EXCP_INFO_OFFSET * path, APM_EXCP_STATUS_CLR_BIT); } /** * @brief Enable/disable controller interrupt in LP-APM * * @param path Access path * @param enable True to enable, false to disable */ static inline void apm_ll_lp_apm_enable_ctrl_intr(apm_ctrl_access_path_t path, bool enable) { if (enable) { REG_SET_BIT(LP_APM_INT_EN_REG, BIT(path)); } else { REG_CLR_BIT(LP_APM_INT_EN_REG, BIT(path)); } } /** * @brief Enable/disable controller clock gating in LP-APM * * @param enable True to enable, false to disable */ static inline void apm_ll_lp_apm_enable_ctrl_clk_gating(bool enable) { if (enable) { REG_CLR_BIT(LP_APM_CLOCK_GATE_REG, LP_APM_CLK_EN); } else { REG_SET_BIT(LP_APM_CLOCK_GATE_REG, LP_APM_CLK_EN); } } /** * @brief Get controller interrupt source number from LP-APM * * @param path Access path * @return Interrupt source number */ static inline int apm_ll_lp_apm_get_ctrl_intr_src(apm_ctrl_access_path_t path) { return ETS_LP_APM_M0_INTR_SOURCE + path; } /** * @brief Enable/disable controller filter for specific path in CPU-APM * * @param path Access path * @param enable True to enable, false to disable */ static inline void apm_ll_cpu_apm_enable_ctrl_filter(apm_ctrl_access_path_t path, bool enable) { if (enable) { REG_SET_BIT(CPU_APM_FUNC_CTRL_REG, BIT(path)); } else { REG_CLR_BIT(CPU_APM_FUNC_CTRL_REG, BIT(path)); } } /** * @brief Enable/disable all controller filters in CPU-APM * * @param enable True to enable, false to disable */ static inline void apm_ll_cpu_apm_enable_ctrl_filter_all(bool enable) { REG_WRITE(CPU_APM_FUNC_CTRL_REG, enable ? UINT32_MAX : 0); } /** * @brief Enable/disable region filter in CPU-APM * * @param regn_num Region number * @param enable True to enable, false to disable */ static inline void apm_ll_cpu_apm_enable_region_filter(uint32_t regn_num, bool enable) { if (enable) { REG_SET_BIT(CPU_APM_REGION_FILTER_EN_REG, BIT(regn_num)); } else { REG_CLR_BIT(CPU_APM_REGION_FILTER_EN_REG, BIT(regn_num)); } } /** * @brief Set region start address in CPU-APM * * @param regn_num Region number * @param addr Start address */ static inline void apm_ll_cpu_apm_set_region_start_addr(uint32_t regn_num, uint32_t addr) { REG_WRITE(CPU_APM_REGION0_ADDR_START_REG + APM_REGION_ADDR_OFFSET * regn_num, addr); } /** * @brief Set region end address in CPU-APM * * @param regn_num Region number * @param addr End address */ static inline void apm_ll_cpu_apm_set_region_end_addr(uint32_t regn_num, uint32_t addr) { REG_WRITE(CPU_APM_REGION0_ADDR_END_REG + APM_REGION_ADDR_OFFSET * regn_num, addr); } /** * @brief Set security mode region attributes in CPU-APM * * @param regn_num Region number * @param mode Security mode * @param regn_pms Region PMS attributes */ static inline void apm_ll_cpu_apm_set_sec_mode_region_attr(uint32_t regn_num, apm_security_mode_t mode, uint32_t regn_pms) { uint32_t reg = CPU_APM_REGION0_ATTR_REG + APM_REGION_ATTR_OFFSET * regn_num; uint32_t val = REG_READ(reg); val &= ~APM_REGION_PMS_MASK(mode); val |= APM_REGION_PMS_FIELD(mode, regn_pms); REG_WRITE(reg, val); } /** * @brief Lock security mode region attributes in CPU-APM * * @param regn_num Region number */ static inline void apm_ll_cpu_apm_lock_sec_mode_region_attr(uint32_t regn_num) { REG_SET_BIT(CPU_APM_REGION0_ATTR_REG + APM_REGION_ATTR_OFFSET * regn_num, APM_REGION_LOCK_BIT); } /** * @brief Get exception data (regn, master, security mode) from CPU-APM * * @param path Access path * @return Exception data */ static inline uint32_t apm_ll_cpu_apm_get_excp_data(apm_ctrl_access_path_t path) { return REG_READ(CPU_APM_M0_EXCEPTION_INFO0_REG + APM_EXCP_INFO_OFFSET * path); } /** * @brief Get exception status from CPU-APM * * @param path Access path * @return Exception type */ static inline uint32_t apm_ll_cpu_apm_get_excp_type(apm_ctrl_access_path_t path) { return REG_READ(CPU_APM_M0_STATUS_REG + APM_EXCP_INFO_OFFSET * path); } /** * @brief Get exception address from CPU-APM * * @param path Access path * @return Exception address */ static inline uint32_t apm_ll_cpu_apm_get_excp_addr(apm_ctrl_access_path_t path) { return REG_READ(CPU_APM_M0_EXCEPTION_INFO1_REG + APM_EXCP_INFO_OFFSET * path); } /** * @brief Get exception information from CPU-APM * * @param path Access path * @param info Pointer to store exception information */ static inline void apm_ll_cpu_apm_get_excp_info(apm_ctrl_access_path_t path, apm_ctrl_exception_info_t *info) { cpu_apm_m0_exception_info0_reg_t reg; reg.val = apm_ll_cpu_apm_get_excp_data(path); info->regn = reg.m0_exception_region; info->mode = reg.m0_exception_mode; info->id = reg.m0_exception_id; info->type = apm_ll_cpu_apm_get_excp_type(path); info->addr = apm_ll_cpu_apm_get_excp_addr(path); } /** * @brief Clear controller exception status in CPU-APM * * @param path Access path */ static inline void apm_ll_cpu_apm_clear_ctrl_excp_status(apm_ctrl_access_path_t path) { REG_SET_BIT(CPU_APM_M0_STATUS_CLR_REG + APM_EXCP_INFO_OFFSET * path, APM_EXCP_STATUS_CLR_BIT); } /** * @brief Enable/disable controller interrupt in CPU-APM * * @param path Access path * @param enable True to enable, false to disable */ static inline void apm_ll_cpu_apm_enable_ctrl_intr(apm_ctrl_access_path_t path, bool enable) { if (enable) { REG_SET_BIT(CPU_APM_INT_EN_REG, BIT(path)); } else { REG_CLR_BIT(CPU_APM_INT_EN_REG, BIT(path)); } } /** * @brief Enable/disable controller clock gating in CPU-APM * * @param enable True to enable, false to disable */ static inline void apm_ll_cpu_apm_enable_ctrl_clk_gating(bool enable) { if (enable) { REG_CLR_BIT(CPU_APM_CLOCK_GATE_REG, CPU_APM_CLK_EN); } else { REG_SET_BIT(CPU_APM_CLOCK_GATE_REG, CPU_APM_CLK_EN); } } /** * @brief Get controller interrupt source number from CPU-APM * * @param path Access path * @return Interrupt source number */ static inline int apm_ll_cpu_apm_get_ctrl_intr_src(apm_ctrl_access_path_t path) { return ETS_CPU_APM_M0_INTR_SOURCE + path; } /** * @brief Enable/disable APM reset event bypass * * @param enable True to enable, false to disable */ static inline void apm_ll_enable_reset_event_bypass(bool enable) { if (enable) { REG_SET_BIT(PCR_RESET_EVENT_BYPASS_REG, PCR_RESET_EVENT_BYPASS_APM); } else { REG_CLR_BIT(PCR_RESET_EVENT_BYPASS_REG, PCR_RESET_EVENT_BYPASS_APM); } } #ifdef __cplusplus } #endif