From 3acb4a3e0cab031b810e3cf12b3bd6cb82865e60 Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Fri, 6 Feb 2026 15:52:49 +0530 Subject: [PATCH] refactor(hal): Refactor and update the ESP32-P4 APM LL/HAL APIs --- components/esp_hal_security/apm_hal.c | 346 +++++++-- .../esp32p4/include/hal/apm_ll.h | 676 +++++++++--------- .../esp_hal_security/include/hal/apm_hal.h | 306 +++++--- .../esp_hal_security/include/hal/apm_types.h | 239 ++++++- .../hal/esp32p4/include/hal/axi_icm_ll.h | 128 +++- .../hal/esp32p4/include/hal/lp_sys_ll.h | 77 ++ components/soc/esp32p4/include/soc/apm_defs.h | 53 ++ 7 files changed, 1333 insertions(+), 492 deletions(-) create mode 100644 components/soc/esp32p4/include/soc/apm_defs.h diff --git a/components/esp_hal_security/apm_hal.c b/components/esp_hal_security/apm_hal.c index 6cc45772a99..2b85269da1e 100644 --- a/components/esp_hal_security/apm_hal.c +++ b/components/esp_hal_security/apm_hal.c @@ -1,59 +1,22 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include "soc/soc_caps.h" +#include "soc/interrupts.h" #include "hal/assert.h" #include "hal/apm_hal.h" #include "hal/apm_ll.h" #include "hal/log.h" +#if !SOC_APM_CTRL_FILTER_SUPPORTED +#include "hal/axi_icm_ll.h" +#include "hal/lp_sys_ll.h" +#endif -#if SOC_IS(ESP32P4) -void apm_hal_hp_peri_access_enable(apm_ll_master_id_t master_id, apm_ll_hp_peri_t hp_peri, - apm_ll_secure_mode_t sec_mode, bool enable) -{ - apm_ll_hp_peri_access_enable(master_id, hp_peri, sec_mode, enable); -} - -void apm_hal_lp_peri_access_enable(apm_ll_lp_peri_t lp_peri, bool enable) -{ - apm_ll_lp_peri_access_enable(lp_peri, enable); -} - -void apm_hal_peri_region_config(uint32_t regn_num, uint32_t regn_low_addr, uint32_t regn_high_addr) -{ - apm_ll_peri_region_config(regn_num, regn_low_addr, regn_high_addr); -} - -int apm_hal_peri_region_pms(apm_ll_master_id_t master_id, apm_ll_secure_mode_t sec_mode, - uint32_t regn_num, uint32_t regn_pms) -{ - return apm_ll_peri_region_pms(master_id, sec_mode, regn_num, regn_pms); -} - -int apm_hal_apm_ctrl_clk_gating_enable(apm_ll_apm_ctrl_t apm_ctrl, bool enable) -{ - return apm_ll_apm_ctrl_clk_gating_enable(apm_ctrl, enable); -} - -void apm_hal_dma_region_config(uint32_t regn_num, uint32_t regn_low_addr, uint32_t regn_high_addr) -{ - apm_ll_dma_region_set_low_address(regn_num, regn_low_addr); - apm_ll_dma_region_set_high_address(regn_num, regn_high_addr); -} - -void apm_hal_dma_region_pms(apm_hal_dma_region_config_data_t *pms_data) -{ - HAL_ASSERT(pms_data); - - apm_ll_dma_region_r_pms(pms_data->dma_master, pms_data->pms_r_mask); - apm_ll_dma_region_w_pms(pms_data->dma_master, pms_data->pms_w_mask); -} -#else - +#if SOC_APM_CTRL_FILTER_SUPPORTED void apm_hal_set_master_sec_mode(uint32_t master_mask, apm_security_mode_t mode) { master_mask &= APM_MASTER_MASK_ALL; @@ -522,5 +485,298 @@ void apm_hal_enable_ctrl_clk_gating(apm_ctrl_module_t ctrl_mod, bool enable) break; } } +#else +void apm_hal_dma_pms_set_region_bounds(uint32_t regn_num, uint32_t start_addr, uint32_t end_addr) +{ + apm_ll_dma_pms_set_region_start_addr(regn_num, start_addr); + apm_ll_dma_pms_set_region_end_addr(regn_num, end_addr); +} -#endif //SOC_IS(ESP32P4) +void apm_hal_dma_pms_set_master_region_attr(apm_master_dma_id_t mid, uint32_t regn_rd_mask, uint32_t regn_wr_mask) +{ + apm_ll_dma_pms_set_region_attr_r(mid, regn_rd_mask); + apm_ll_dma_pms_set_region_attr_w(mid, regn_wr_mask); +} + +void apm_hal_dma_pms_set_region_cfg(uint32_t regn_count, const apm_hal_pms_regn_cfg_t *regn_cfg) +{ + HAL_ASSERT(regn_cfg); + + for (uint32_t idx = 0; idx < regn_count; idx++) { + const apm_hal_pms_regn_cfg_t *region = ®n_cfg[idx]; + apm_hal_dma_pms_set_region_bounds(region->regn_num, region->regn_start_addr, region->regn_end_addr); + } +} + +void apm_hal_dma_pms_set_master_cfg(uint32_t master_count, const apm_hal_pms_master_cfg_t *master_cfg) +{ + HAL_ASSERT(master_cfg); + + for (uint32_t idx = 0; idx < master_count; idx++) { + const apm_hal_pms_master_cfg_t *master = &master_cfg[idx]; + apm_ll_dma_pms_set_region_attr_r(master->dma.id, master->dma.regn_pms_rd); + apm_ll_dma_pms_set_region_attr_w(master->dma.id, master->dma.regn_pms_wr); + } +} + +void apm_hal_hp2lp_peri_pms_set_hpcpu_access(int core_id, apm_security_mode_t mode, uint32_t enable_mask) +{ + HAL_ASSERT(core_id < SOC_CPU_CORES_NUM); + + enable_mask &= APM_SLAVE_LP_PERI_ALL_MASK; + for (int sid = 0; sid < APM_SLAVE_LP_PERIPH_MAX; sid++) { + apm_ll_hp2lp_peri_pms_enable_hpcpu_access(core_id, mode, (apm_slave_lp_periph_t)sid, + (enable_mask >> sid) & 1U); + } +} + +void apm_hal_lp_peri_pms_set_lpcpu_access(uint32_t enable_mask) +{ + enable_mask &= APM_SLAVE_LP_PERI_ALL_MASK; + for (int sid = 0; sid < APM_SLAVE_LP_PERIPH_MAX; sid++) { + apm_ll_lp_peri_pms_enable_lpcpu_access((apm_slave_lp_periph_t)sid, + (enable_mask >> sid) & 1U); + } +} + +void apm_hal_hp_peri_pms_set_hpcpu_access(int core_id, apm_security_mode_t mode, const apm_hal_pms_hp_peri_cfg_t *cfg) +{ + HAL_ASSERT(core_id < SOC_CPU_CORES_NUM); + HAL_ASSERT(cfg); + + const uint32_t cpu_peri = cfg->cpu_peri & APM_SLAVE_CPU_PERI_ALL_MASK; + const uint32_t hp_peri0 = cfg->hp_peri0 & APM_SLAVE_HP_PERI0_ALL_MASK; + const uint64_t hp_peri1 = cfg->hp_peri1 & APM_SLAVE_HP_PERI1_ALL_MASK; + + /* CPU_PERI */ + for (int sid = 0; sid < APM_SLAVE_CPU_PERIPH_MAX; sid++) { + apm_ll_hp_peri_pms_enable_hpcpu_cpu_peri_access(core_id, mode, (apm_slave_cpu_periph_id_t)sid, + (cpu_peri >> sid) & 1U); + } + /* HP_PERI0 */ + for (int sid = 0; sid < APM_SLAVE_HP_PERIPH0_MAX; sid++) { + apm_ll_hp_peri_pms_enable_hpcpu_hp_peri0_access(core_id, mode, (apm_slave_hp_periph0_id_t)sid, + (hp_peri0 >> sid) & 1U); + } + /* HP_PERI1 */ + for (int sid = 0; sid < APM_SLAVE_HP_PERIPH1_MAX; sid++) { + apm_ll_hp_peri_pms_enable_hpcpu_hp_peri1_access(core_id, mode, (apm_slave_hp_periph1_id_t)sid, + (hp_peri1 >> sid) & 1ULL); + } +} + +void apm_hal_lp2hp_peri_pms_set_lpcpu_access(const apm_hal_pms_hp_peri_cfg_t *cfg) +{ + HAL_ASSERT(cfg); + + const uint32_t cpu_peri = cfg->cpu_peri & APM_SLAVE_CPU_PERI_ALL_MASK; + const uint32_t hp_peri0 = cfg->hp_peri0 & APM_SLAVE_HP_PERI0_ALL_MASK; + const uint64_t hp_peri1 = cfg->hp_peri1 & APM_SLAVE_HP_PERI1_ALL_MASK; + + /* CPU_PERI */ + for (int sid = 0; sid < APM_SLAVE_CPU_PERIPH_MAX; sid++) { + apm_ll_lp2hp_peri_pms_enable_lpcpu_cpu_peri_access((apm_slave_cpu_periph_id_t)sid, + (cpu_peri >> sid) & 1U); + } + /* HP_PERI0 */ + for (int sid = 0; sid < APM_SLAVE_HP_PERIPH0_MAX; sid++) { + apm_ll_lp2hp_peri_pms_enable_lpcpu_hp_peri0_access((apm_slave_hp_periph0_id_t)sid, + (hp_peri0 >> sid) & 1U); + } + /* HP_PERI1 */ + for (int sid = 0; sid < APM_SLAVE_HP_PERIPH1_MAX; sid++) { + apm_ll_lp2hp_peri_pms_enable_lpcpu_hp_peri1_access((apm_slave_hp_periph1_id_t)sid, + (hp_peri1 >> sid) & 1ULL); + } +} + +void apm_hal_lp_peri_pms_set_region_bounds(uint32_t regn_num, uint32_t start_addr, uint32_t end_addr) +{ + apm_ll_lp_peri_pms_set_region_start_addr(regn_num, start_addr); + apm_ll_lp_peri_pms_set_region_end_addr(regn_num, end_addr); +} + +void apm_hal_lp_peri_pms_set_master_region_attr(apm_master_id_t mid, apm_security_mode_t mode, uint32_t regn_pms_mask) +{ + switch (mid) { + case APM_MASTER_HPCPU0: + apm_ll_lp_peri_pms_hpcpu0_set_region_access(mode, regn_pms_mask); + break; + case APM_MASTER_HPCPU1: + apm_ll_lp_peri_pms_hpcpu1_set_region_access(mode, regn_pms_mask); + break; + case APM_MASTER_LPCPU: + apm_ll_lp_peri_pms_lpcpu_set_region_access(regn_pms_mask); + break; + default: + break; + } +} + +void apm_hal_lp_peri_pms_set_region_cfg(uint32_t regn_count, const apm_hal_pms_regn_cfg_t *regn_cfg) +{ + HAL_ASSERT(regn_cfg); + + for (uint32_t idx = 0; idx < regn_count; idx++) { + const apm_hal_pms_regn_cfg_t *region = ®n_cfg[idx]; + apm_hal_lp_peri_pms_set_region_bounds(region->regn_num, region->regn_start_addr, region->regn_end_addr); + } +} + +void apm_hal_lp_peri_pms_set_master_cfg(uint32_t master_count, const apm_hal_pms_master_cfg_t *master_cfg) +{ + HAL_ASSERT(master_cfg); + + for (int idx = 0; idx < master_count; idx++) { + const apm_hal_pms_master_cfg_t *master = &master_cfg[idx]; + apm_hal_lp_peri_pms_set_master_region_attr(master->lp_peri.id, master->lp_peri.mode, master->lp_peri.regn_pms); + } +} + +void apm_hal_enable_intr(apm_ctrl_module_t ctrl_mod, bool enable) +{ + uint32_t mask = 0; + + switch (ctrl_mod) { + case APM_CTRL_DMA_PMS: + case APM_CTRL_HP_PERI_PMS: + case APM_CTRL_LP2HP_PERI_PMS: + mask = BIT(AXI_ICM_INTR_SYS_ADDRHOLE) | BIT(AXI_ICM_INTR_CPU_ADDRHOLE); + axi_icm_ll_enable_intr(mask, enable); + break; + case APM_CTRL_LP_PERI_PMS: + case APM_CTRL_HP2LP_PERI_PMS: + mask = BIT(LP_SYS_INTR_LP_ADDRHOLE) | BIT(LP_SYS_INTR_IDBUS_ADDRHOLE); + lp_sys_ll_enable_intr(mask, enable); + break; + default: + (void)mask; + break; + } +} + +void apm_hal_clear_intr(apm_ctrl_module_t ctrl_mod) +{ + uint32_t mask = 0; + + switch (ctrl_mod) { + case APM_CTRL_DMA_PMS: + case APM_CTRL_HP_PERI_PMS: + case APM_CTRL_LP2HP_PERI_PMS: + mask = BIT(AXI_ICM_INTR_SYS_ADDRHOLE) | BIT(AXI_ICM_INTR_CPU_ADDRHOLE); + axi_icm_ll_clear_intr(mask); + break; + case APM_CTRL_LP_PERI_PMS: + case APM_CTRL_HP2LP_PERI_PMS: + mask = BIT(LP_SYS_INTR_LP_ADDRHOLE) | BIT(LP_SYS_INTR_IDBUS_ADDRHOLE); + lp_sys_ll_clear_intr(mask); + break; + default: + (void)mask; + break; + } +} + +uint32_t apm_hal_get_intr_status(void) +{ + uint32_t status = 0, mask = 0; + + mask = BIT(AXI_ICM_INTR_SYS_ADDRHOLE) | BIT(AXI_ICM_INTR_CPU_ADDRHOLE); + uint32_t hp_intr_st = axi_icm_ll_get_intr_status(mask); + if (hp_intr_st & BIT(AXI_ICM_INTR_SYS_ADDRHOLE)) { + status |= APM_EXCP_HP_AXI; + } + if (hp_intr_st & BIT(AXI_ICM_INTR_CPU_ADDRHOLE)) { + status |= APM_EXCP_HP_AHB; + } + + mask = BIT(LP_SYS_INTR_LP_ADDRHOLE) | BIT(LP_SYS_INTR_IDBUS_ADDRHOLE); + uint32_t lp_intr_st = lp_sys_ll_get_intr_status(mask); + if (lp_intr_st & BIT(LP_SYS_INTR_LP_ADDRHOLE)) { + status |= APM_EXCP_LP_AHB; + } + if (lp_intr_st & BIT(LP_SYS_INTR_IDBUS_ADDRHOLE)) { + status |= APM_EXCP_LP_IDBUS; + } + + return status; +} + +void apm_hal_get_exception_info(apm_ctrl_exception_type type, apm_ctrl_exception_info_t *excp_info) +{ + HAL_ASSERT(excp_info); + + switch (type) { + case APM_EXCP_HP_AXI: + case APM_EXCP_HP_AHB: { + axi_icm_ll_excp_info_t info = {0}; + if (type == APM_EXCP_HP_AXI) { + axi_icm_ll_get_sys_excp_info(&info); + /* NOTE: Master ID = 4-bit CID + 4-bit UID, extracting only CID here */ + info.id = (info.id >> 0x04U) & 0x0FU; + } else { + axi_icm_ll_get_cpu_excp_info(&info); + } + excp_info->addr = info.addr; + excp_info->id = info.id; + excp_info->is_wr = info.is_wr; + excp_info->is_secure = info.is_secure; + break; + } + case APM_EXCP_LP_AHB: + case APM_EXCP_LP_IDBUS: { + lp_sys_ll_excp_info_t info = {0}; + if (type == APM_EXCP_LP_AHB) { + lp_sys_ll_get_ahb_excp_info(&info); + } else { + lp_sys_ll_get_idbus_excp_info(&info); + } + excp_info->addr = info.addr; + excp_info->id = info.id; + excp_info->is_wr = info.is_wr; + excp_info->is_secure = info.is_secure; + break; + } + default: + break; + } +} + +int apm_hal_get_intr_src_num(apm_ctrl_module_t ctrl_mod) +{ + switch (ctrl_mod) { + case APM_CTRL_DMA_PMS: + case APM_CTRL_HP_PERI_PMS: + case APM_CTRL_LP2HP_PERI_PMS: + return ETS_SYS_ICM_INTR_SOURCE; + case APM_CTRL_LP_PERI_PMS: + case APM_CTRL_HP2LP_PERI_PMS: + return ETS_LP_SYSREG_INTR_SOURCE; + default: + return -1; + } +} + +void apm_hal_enable_ctrl_clk_gating(apm_ctrl_module_t ctrl_mod, bool enable) +{ + switch (ctrl_mod) { + case APM_CTRL_DMA_PMS: + apm_ll_dma_pms_enable_clk_gating(enable); + break; + case APM_CTRL_HP_PERI_PMS: + apm_ll_hp_peri_pms_enable_clk_gating(enable); + break; + case APM_CTRL_HP2LP_PERI_PMS: + apm_ll_hp2lp_peri_pms_enable_clk_gating(enable); + break; + case APM_CTRL_LP_PERI_PMS: + apm_ll_lp_peri_pms_enable_clk_gating(enable); + break; + case APM_CTRL_LP2HP_PERI_PMS: + apm_ll_lp2hp_peri_pms_enable_clk_gating(enable); + break; + default: + break; + } +} +#endif // SOC_APM_CTRL_FILTER_SUPPORTED diff --git a/components/esp_hal_security/esp32p4/include/hal/apm_ll.h b/components/esp_hal_security/esp32p4/include/hal/apm_ll.h index 8cdf5412f84..374c496bfce 100644 --- a/components/esp_hal_security/esp32p4/include/hal/apm_ll.h +++ b/components/esp_hal_security/esp32p4/include/hal/apm_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,419 +8,425 @@ #include #include #include "hal/assert.h" +#include "hal/config.h" #include "soc/dma_pms_reg.h" #include "soc/hp2lp_peri_pms_reg.h" #include "soc/hp_peri_pms_reg.h" #include "soc/lp2hp_peri_pms_reg.h" #include "soc/lp_peri_pms_reg.h" +#include "hal/apm_types.h" +#include "soc/apm_defs.h" + #ifdef __cplusplus extern "C" { #endif -/** - * @brief Master Secure Mode - */ -typedef enum { - APM_LL_SECURE_MODE_TEE = 0, /* Trusted execution environment mode (Machine mode). */ - APM_LL_SECURE_MODE_REE = 1, /* Rich execution environment mode (User mode). */ - APM_LL_SECURE_MODE_INV = 2, /* Invalid mode. */ -} apm_ll_secure_mode_t; +/* Offsets for indexing R/W attribute registers for DMA masters */ +#define APM_LL_DMA_PMS_ATTR_RD_OFFSET 0x04U +#define APM_LL_DMA_PMS_ATTR_WR_OFFSET_1 0x04U +#define APM_LL_DMA_PMS_ATTR_WR_OFFSET_2 0x14U + +/* Offsets for indexing HP2LP_PERI_PMS registers by CPU core and security mode */ +#define APM_LL_HP2LP_PERI_PMS_CORE_OFFSET 0x08U +#define APM_LL_HP2LP_PERI_PMS_MODE_OFFSET 0x04U + +/* Bit-field masks/shifts for extracting LP_PERI_PMS region permission fields */ +#define APM_LL_LP_PERI_PMS_REGN0_1_MASK 0x03U +#define APM_LL_LP_PERI_PMS_REGN2_7_SHIFT 2U +#define APM_LL_LP_PERI_PMS_REGN2_7_MASK 0x3FU + +/* Helper macro for indexing HP_PERI_PMS registers by core, mode, and register index */ +#define APM_LL_HP_PERI_PMS_CORE_OFFSET 0x20U +#define APM_LL_HP_PERI_PMS_MODE_OFFSET 0x10U +#define APM_LL_HP_PERI_PMS_REG_OFFSET 0x04U + +#define HP_PERI_PMS_COREn_xM_REGk_REG(cid, mode, regk) \ + (PMS_CORE0_MM_HP_PERI_PMS_REG0_REG \ + + ((cid) * APM_LL_HP_PERI_PMS_CORE_OFFSET) \ + + ((mode) * APM_LL_HP_PERI_PMS_MODE_OFFSET) \ + + ((regk) * APM_LL_HP_PERI_PMS_REG_OFFSET)) + +/* Helper macros for indexing LP_PERI_PMS configurable region address registers */ +#define APM_LL_LP_PERI_PMS_REGION_OFFSET 0x08U +#define APM_LL_LP_PERI_PMS_REGION_GAP 0x08U + +#define PMS_PERI_REGION_LOW_REG(regn) \ + (PMS_PERI_REGION0_LOW_REG \ + + ((regn) * APM_LL_LP_PERI_PMS_REGION_OFFSET) \ + + (((regn) >= 2U) ? APM_LL_LP_PERI_PMS_REGION_GAP : 0U)) + +#define PMS_PERI_REGION_HIGH_REG(regn) \ + (PMS_PERI_REGION0_HIGH_REG \ + + ((regn) * APM_LL_LP_PERI_PMS_REGION_OFFSET) \ + + (((regn) >= 2U) ? APM_LL_LP_PERI_PMS_REGION_GAP : 0U)) /** - * @brief Bus Masters. - */ -typedef enum { - APM_LL_MASTER_LPCPU = 0, - APM_LL_MASTER_HPCPU0, - APM_LL_MASTER_HPCPU1, - APM_LL_MASTER_DMA, -} apm_ll_master_id_t; - -/** - * @brief APM Controller - */ -typedef enum { - LP_APM_CTRL = 0, - HP2LP_APM_CTRL, - HP_APM_CTRL, - LP2HP_APM_CTRL, - DMA_APM_CTRL, - MAX_APM_CTRL, -} apm_ll_apm_ctrl_t; - -/** - * @brief HP CPU Peripherals. - */ -typedef enum { - PMS_COREn_XM_PSRAM_ALLOW = 0, - PMS_COREn_XM_FLASH_ALLOW, - PMS_COREn_XM_L2MEM_ALLOW, - PMS_COREn_XM_L2ROM_ALLOW, - PMS_COREn_XM_TRACE0_ALLOW = 6, - PMS_COREn_XM_TRACE1_ALLOW, - PMS_COREn_XM_CPU_BUS_MON_ALLOW, - PMS_COREn_XM_L2MEM_MON_ALLOW, - PMS_COREn_XM_TCM_MON_ALLOW, - PMS_COREn_XM_CACHE_ALLOW, - - PMS_COREn_XM_HP_USBOTG_ALLOW = 32, - PMS_COREn_XM_HP_USBOTG11_ALLOW, - PMS_COREn_XM_HP_USBOTG11_WRAP_ALLOW, - PMS_COREn_XM_HP_GDMA_ALLOW, - PMS_COREn_XM_HP_SDMMC_ALLOW = 37, - PMS_COREn_XM_HP_AHB_PDMA_ALLOW, - PMS_COREn_XM_HP_JPEG_ALLOW, - PMS_COREn_XM_HP_PPA_ALLOW, - PMS_COREn_XM_HP_DMA2D_ALLOW, - PMS_COREn_XM_HP_KEY_MANAGER_ALLOW, - PMS_COREn_XM_HP_AXI_PDMA_ALLOW, - PMS_COREn_XM_HP_FLASH_ALLOW, - PMS_COREn_XM_HP_PSRAM_ALLOW, - PMS_COREn_XM_HP_CRYPTO_ALLOW, - PMS_COREn_XM_HP_GMAC_ALLOW, - PMS_COREn_XM_HP_USB_PHY_ALLOW, - PMS_COREn_XM_HP_CSI_HOST_ALLOW = 50, - PMS_COREn_XM_HP_DSI_HOST_ALLOW, - PMS_COREn_XM_HP_ISP_ALLOW, - PMS_COREn_XM_HP_H264_CORE_ALLOW, - PMS_COREn_XM_HP_RMT_ALLOW, - PMS_COREn_XM_HP_BITSCRAMBLER_ALLOW, - PMS_COREn_XM_HP_AXI_ICM_ALLOW, - PMS_COREn_XM_HP_PERI_PMS_ALLOW, - PMS_COREn_XM_LP2HP_PERI_PMS_ALLOW, - PMS_COREn_XM_DMA_PMS_ALLOW, - PMS_COREn_XM_HP_H264_DMA2D_ALLOW = 60, - - PMS_COREn_XM_HP_MCPWM0_ALLOW = 64, - PMS_COREn_XM_HP_MCPWM1_ALLOW, - PMS_COREn_XM_HP_TIMER_GROUP0_ALLOW, - PMS_COREn_XM_HP_TIMER_GROUP1_ALLOW, - PMS_COREn_XM_HP_I2C0_ALLOW, - PMS_COREn_XM_HP_I2C1_ALLOW, - PMS_COREn_XM_HP_I2S0_ALLOW, - PMS_COREn_XM_HP_I2S1_ALLOW, - PMS_COREn_XM_HP_I2S2_ALLOW, - PMS_COREn_XM_HP_PCNT_ALLOW, - PMS_COREn_XM_HP_UART0_ALLOW, - PMS_COREn_XM_HP_UART1_ALLOW, - PMS_COREn_XM_HP_UART2_ALLOW, - PMS_COREn_XM_HP_UART3_ALLOW, - PMS_COREn_XM_HP_UART4_ALLOW, - PMS_COREn_XM_HP_PARLIO_ALLOW269, - PMS_COREn_XM_HP_GPSPI2_ALLOW270, - PMS_COREn_XM_HP_GPSPI3_ALLOW271, - PMS_COREn_XM_HP_USBDEVICE_ALLOW, - PMS_COREn_XM_HP_LEDC_ALLOW, - PMS_COREn_XM_HP_ETM_ALLOW = 85, - PMS_COREn_XM_HP_INTRMTX_ALLOW, - PMS_COREn_XM_HP_TWAI0_ALLOW, - PMS_COREn_XM_HP_TWAI1_ALLOW, - PMS_COREn_XM_HP_TWAI2_ALLOW, - PMS_COREn_XM_HP_I3C_MST_ALLOW, - PMS_COREn_XM_HP_I3C_SLV_ALLOW, - PMS_COREn_XM_HP_LCDCAM_ALLOW, - PMS_COREn_XM_HP_ADC_ALLOW = 94, - PMS_COREn_XM_HP_UHCI_ALLOW, - - PMS_COREn_XM_HP_GPIO_ALLOW = 96, - PMS_COREn_XM_HP_IOMUX_ALLOW, - PMS_COREn_XM_HP_SYSTIMER_ALLOW, - PMS_COREn_XM_HP_SYS_REG_ALLOW, - PMS_COREn_XM_HP_CLKRST_ALLOW, - PMS_COREn_XM_HP_PERI_MAX, -} apm_ll_hp_peri_t; - -/** - * @brief LP CPU Peripherals. - */ -typedef enum { - PMS_MM_LP_SYSREG_ALLOW = 0, - PMS_MM_LP_AONCLKRST_ALLOW, - PMS_MM_LP_TIMER_ALLOW, - PMS_MM_LP_ANAPERI_ALLOW, - PMS_MM_LP_PMU_ALLOW, - PMS_MM_LP_WDT_ALLOW, - PMS_MM_LP_MAILBOX_ALLOW, - PMS_MM_LP_PERICLKRST_ALLOW = 8, - PMS_MM_LP_UART_ALLOW, - PMS_MM_LP_I2C_ALLOW, - PMS_MM_LP_SPI_ALLOW, - PMS_MM_LP_I2CMST_ALLOW, - PMS_MM_LP_I2S_ALLOW, - PMS_MM_LP_ADC_ALLOW, - PMS_MM_LP_TOUCH_ALLOW, - PMS_MM_LP_IOMUX_ALLOW, - PMS_MM_LP_INTR_ALLOW, - PMS_MM_LP_EFUSE_ALLOW, - PMS_MM_LP_PMS_ALLOW, - PMS_MM_HP2LP_PMS_ALLOW, - PMS_MM_LP_TSENS_ALLOW, - PMS_MM_LP_HUK_ALLOW, - PMS_HP_COREn_MM_LP_SRAM_ALLOW, - PMS_LP_MM_PERI_MAX, -} apm_ll_lp_peri_t; - -/** - * @brief LP CPU Peripherals. - */ -typedef enum { - PMS_DMA_GDMA_CH0 = 0, - PMS_DMA_GDMA_CH1, - PMS_DMA_GDMA_CH2, - PMS_DMA_GDMA_CH3, - PMS_DMA_AHB_PDMA_ADC, - PMS_DMA_AHB_PDMA_I2S0, - PMS_DMA_AHB_PDMA_I2S1, - PMS_DMA_AHB_PDMA_I2S2, - PMS_DMA_AHB_PDMA_I3C_MST, - PMS_DMA_AHB_PDMA_UHCI0, - PMS_DMA_AHB_PDMA_RMT, - PMS_DMA_AXI_PDMA_LCDCAM, - PMS_DMA_AXI_PDMA_GPSPI2, - PMS_DMA_AXI_PDMA_GPSPI3, - PMS_DMA_AXI_PDMA_PARLIO, - PMS_DMA_AXI_PDMA_AES, - PMS_DMA_AXI_PDMA_SHA, - PMS_DMA_DMA2D_JPEG, - PMS_DMA_USB, - PMS_DMA_GMAC, - PMS_DMA_SDMMC, - PMS_DMA_USBOTG11, - PMS_DMA_TRACE0, - PMS_DMA_TRACE1, - PMS_DMA_L2MEM_MON, - PMS_DMA_TCM_MON, - PMS_DMA_H264, - PMS_DMA_DMA2D_PPA, - PMS_DMA_DMA2D_DUMMY, - PMS_DMA_AHB_PDMA_DUMMY, - PMS_DMA_AXI_PDMA_DUMMY, - PMS_DMA_MAX, -} apm_ll_dma_master_t; - -#define PMS_PERI_MAX_REGION_NUM 2 -#define PMS_DMA_MAX_REGION_NUM 32 - -#define PMS_COREn_XM_PMS_REGn_REG(master_id, sec_mode, hp_peri) \ - ({\ - (PMS_CORE0_MM_HP_PERI_PMS_REG0_REG + (master_id * 0x20) \ - + (sec_mode * 0x10) + ((hp_peri/32) * 0x4) ); \ - }) - -#define PMS_PERI_REGION_LOW_REG(regn_num) \ - ({\ - (PMS_PERI_REGION0_LOW_REG + (regn_num * 8)); \ - }) - -#define PMS_PERI_REGION_HIGH_REG(regn_num) \ - ({\ - (PMS_PERI_REGION0_HIGH_REG + (regn_num * 8)); \ - }) - -#define PMS_DMA_PMS_R_REG(dma_master) \ - ({\ - (PMS_DMA_GDMA_CH0_R_PMS_REG + (dma_master * 8)); \ - }) - -#define PMS_DMA_PMS_W_REG(dma_master) \ - ({\ - (PMS_DMA_GDMA_CH0_W_PMS_REG + (dma_master * 8)); \ - }) - -/** - * @brief Configure HP peripherals access permission for the HP CPU0/1. + * @brief Enable/disable clock gating for DMA_PMS * - * @param master_id HP CPU0/1 - * @param hp_peri HP peripheral whose access permission to be configured. - * @param enable Permission enable/disable + * @param enable True to enable, false to disable */ -static inline void apm_ll_hp_peri_access_enable(apm_ll_master_id_t master_id, apm_ll_hp_peri_t hp_peri, - apm_ll_secure_mode_t sec_mode, bool enable) +static inline void apm_ll_dma_pms_enable_clk_gating(bool enable) { - HAL_ASSERT((master_id > APM_LL_MASTER_LPCPU) && (master_id < APM_LL_MASTER_DMA) - && (hp_peri < PMS_COREn_XM_HP_PERI_MAX) && (sec_mode < APM_LL_SECURE_MODE_INV)); - if (enable) { - REG_SET_BIT(PMS_COREn_XM_PMS_REGn_REG(master_id, sec_mode, hp_peri), BIT(hp_peri % 32)); + REG_CLR_BIT(PMS_DMA_CLK_EN_REG, PMS_DMA_CLK_EN); } else { - REG_CLR_BIT(PMS_COREn_XM_PMS_REGn_REG(master_id, sec_mode, hp_peri), BIT(hp_peri % 32)); + REG_SET_BIT(PMS_DMA_CLK_EN_REG, PMS_DMA_CLK_EN); } } /** - * @brief Configure LP peripherals access permission for the LP CPU. + * @brief Set region start address in DMA_PMS * - * @param lp_peri LP peripheral whose access permission to be configured. - * @param enable Permission enable/disable + * @param regn_num Region number + * @param addr Start address */ -static inline void apm_ll_lp_peri_access_enable(apm_ll_lp_peri_t lp_peri, bool enable) +static inline void apm_ll_dma_pms_set_region_start_addr(uint32_t regn_num, uint32_t addr) { - HAL_ASSERT(lp_peri < PMS_LP_MM_PERI_MAX); + REG_WRITE(PMS_DMA_REGION0_LOW_REG + APM_DMA_PMS_REGION_ADDR_OFFSET * regn_num, addr); +} +/** + * @brief Set region end address in DMA_PMS + * + * @param regn_num Region number + * @param addr End address + */ +static inline void apm_ll_dma_pms_set_region_end_addr(uint32_t regn_num, uint32_t addr) +{ + REG_WRITE(PMS_DMA_REGION0_HIGH_REG + APM_DMA_PMS_REGION_ADDR_OFFSET * regn_num, addr); +} + +/** + * @brief Set read-access region mask for a DMA master in DMA_PMS + * + * @param mid DMA master ID + * @param regn_mask Bitmask of regions the master is permitted to read + */ +static inline void apm_ll_dma_pms_set_region_attr_r(apm_master_dma_id_t mid, uint32_t regn_mask) +{ + uint32_t offs = APM_DMA_PMS_REGION_ATTR_OFFSET * (uint32_t)mid; + if (mid >= APM_MASTER_DMA_AXI_PDMA_LCDCAM) { + offs += APM_LL_DMA_PMS_ATTR_RD_OFFSET; + } + + REG_WRITE(PMS_DMA_GDMA_CH0_R_PMS_REG + offs, regn_mask); +} + +/** + * @brief Set write-access region mask for a DMA master in DMA_PMS + * + * @param mid DMA master ID + * @param regn_mask Bitmask of regions the master is permitted to write + */ +static inline void apm_ll_dma_pms_set_region_attr_w(apm_master_dma_id_t mid, uint32_t regn_mask) +{ + uint32_t offs = APM_DMA_PMS_REGION_ATTR_OFFSET * (uint32_t)mid; + if (mid == APM_MASTER_DMA_AHB_PDMA_RMT) { + offs += APM_LL_DMA_PMS_ATTR_WR_OFFSET_2; + } else if (mid >= APM_MASTER_DMA_AXI_PDMA_LCDCAM) { + offs += APM_LL_DMA_PMS_ATTR_WR_OFFSET_1; + } + + REG_WRITE(PMS_DMA_GDMA_CH0_W_PMS_REG + offs, regn_mask); +} + +/** + * @brief Enable/disable clock gating for HP_PERI_PMS + * + * @param enable True to enable, false to disable + */ +static inline void apm_ll_hp_peri_pms_enable_clk_gating(bool enable) +{ if (enable) { - REG_SET_BIT(PMS_LP_MM_LP_PERI_PMS_REG0_REG, BIT(lp_peri)); + REG_CLR_BIT(PMS_HP_PERI_PMS_CLK_EN_REG, PMS_HP_PERI_PMS_CLK_EN); } else { - REG_CLR_BIT(PMS_LP_MM_LP_PERI_PMS_REG0_REG, BIT(lp_peri)); + REG_SET_BIT(PMS_HP_PERI_PMS_CLK_EN_REG, PMS_HP_PERI_PMS_CLK_EN); } } /** - * @brief Configure peripherals configurable address ranges. + * @brief Enable/disable HP CPU access to a CPU peripheral in HP_PERI_PMS * - * @param regn_num Configurable address range number. - * @param regn_low_addr Configurable address range start address. - * @param regn_high_addr Configurable address range end address. + * @param core_id CPU core ID + * @param mode Security mode + * @param sid CPU peripheral slave ID + * @param enable True to enable access, false to disable */ -static inline void apm_ll_peri_region_config(uint32_t regn_num, uint32_t regn_low_addr, - uint32_t regn_high_addr) +static inline void apm_ll_hp_peri_pms_enable_hpcpu_cpu_peri_access(const int core_id, apm_security_mode_t mode, apm_slave_cpu_periph_id_t sid, bool enable) { - HAL_ASSERT(regn_num < PMS_PERI_MAX_REGION_NUM); - - REG_WRITE(PMS_PERI_REGION_LOW_REG(regn_num), regn_low_addr); - REG_WRITE(PMS_PERI_REGION_HIGH_REG(regn_num), regn_high_addr); + if (enable) { + REG_SET_BIT(HP_PERI_PMS_COREn_xM_REGk_REG(core_id, mode, 0), BIT(sid)); + } else { + REG_CLR_BIT(HP_PERI_PMS_COREn_xM_REGk_REG(core_id, mode, 0), BIT(sid)); + } } /** - * @brief Configure peripherals configurable address ranges. + * @brief Enable/disable HP CPU access to an HP peripheral (group 0) in HP_PERI_PMS * - * @param master_id LP CPU and HP CPU0/1 - * @param sec_mode CPU privilege mode (Machine/User) which corresponds to (TEE/REE). - * @param regn_num Configurable address range number. - * @param regn_pms Configurable address range permission setting(2-bits field). - * Bit 0: Region 0 permission enable/disable. - * Bit 1: Region 1 permission enable/disable. - * @return Configuration performed successfully? + * @param core_id CPU core ID + * @param mode Security mode + * @param sid HP peripheral group 0 slave ID + * @param enable True to enable access, false to disable */ -static inline int apm_ll_peri_region_pms(apm_ll_master_id_t master_id, apm_ll_secure_mode_t sec_mode, - uint32_t regn_num, uint32_t regn_pms) +static inline void apm_ll_hp_peri_pms_enable_hpcpu_hp_peri0_access(const int core_id, apm_security_mode_t mode, apm_slave_hp_periph0_id_t sid, bool enable) { - HAL_ASSERT((master_id < APM_LL_MASTER_DMA) && (sec_mode < APM_LL_SECURE_MODE_INV)); + if (enable) { + REG_SET_BIT(HP_PERI_PMS_COREn_xM_REGk_REG(core_id, mode, 1), BIT(sid)); + } else { + REG_CLR_BIT(HP_PERI_PMS_COREn_xM_REGk_REG(core_id, mode, 1), BIT(sid)); + } +} - regn_pms &= 0x3; +/** + * @brief Enable/disable HP CPU access to an HP peripheral (group 1) in HP_PERI_PMS + * + * @param core_id CPU core ID + * @param mode Security mode + * @param sid HP peripheral group 1 slave ID + * @param enable True to enable access, false to disable + */ +static inline void apm_ll_hp_peri_pms_enable_hpcpu_hp_peri1_access(const int core_id, apm_security_mode_t mode, apm_slave_hp_periph1_id_t sid, bool enable) +{ + uint32_t regk = (sid < 32) ? 2U : 3U; + if (enable) { + REG_SET_BIT(HP_PERI_PMS_COREn_xM_REGk_REG(core_id, mode, regk), BIT(sid & 0x1FU)); + } else { + REG_CLR_BIT(HP_PERI_PMS_COREn_xM_REGk_REG(core_id, mode, regk), BIT(sid & 0x1FU)); + } +} - switch (master_id) { - case APM_LL_MASTER_LPCPU: - REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_LP_CORE_REGION_PMS, regn_pms); +/** + * @brief Enable/disable clock gating for HP2LP_PERI_PMS + * + * @param enable True to enable, false to disable + */ +static inline void apm_ll_hp2lp_peri_pms_enable_clk_gating(bool enable) +{ + if (enable) { + REG_CLR_BIT(PMS_HP2LP_PERI_PMS_CLK_EN_REG, PMS_HP2LP_PERI_PMS_CLK_EN); + } else { + REG_SET_BIT(PMS_HP2LP_PERI_PMS_CLK_EN_REG, PMS_HP2LP_PERI_PMS_CLK_EN); + } +} + +/** + * @brief Enable/disable HP CPU access to an LP peripheral in HP2LP_PERI_PMS + * + * @param core_id CPU core ID + * @param mode Security mode + * @param sid LP peripheral slave ID + * @param enable True to enable access, false to disable + */ +static inline void apm_ll_hp2lp_peri_pms_enable_hpcpu_access(const int core_id, apm_security_mode_t mode, apm_slave_lp_periph_t sid, bool enable) +{ + uint32_t reg = PMS_HP_CORE0_MM_PMS_REG0_REG + + (core_id * APM_LL_HP2LP_PERI_PMS_CORE_OFFSET) + + (mode * APM_LL_HP2LP_PERI_PMS_MODE_OFFSET); + if (enable) { + REG_SET_BIT(reg, BIT(sid)); + } else { + REG_CLR_BIT(reg, BIT(sid)); + } +} + +/** + * @brief Enable/disable clock gating for LP_PERI_PMS + * + * @param enable True to enable, false to disable + */ +static inline void apm_ll_lp_peri_pms_enable_clk_gating(bool enable) +{ + if (enable) { + REG_CLR_BIT(PMS_LP_PERI_PMS_CLK_EN_REG, PMS_LP_PERI_PMS_CLK_EN); + } else { + REG_SET_BIT(PMS_LP_PERI_PMS_CLK_EN_REG, PMS_LP_PERI_PMS_CLK_EN); + } +} + +/** + * @brief Enable/disable LP CPU access to an LP peripheral in LP_PERI_PMS + * + * @param sid LP peripheral slave ID + * @param enable True to enable access, false to disable + */ +static inline void apm_ll_lp_peri_pms_enable_lpcpu_access(apm_slave_lp_periph_t sid, bool enable) +{ + if (enable) { + REG_SET_BIT(PMS_LP_MM_LP_PERI_PMS_REG0_REG, BIT(sid)); + } else { + REG_CLR_BIT(PMS_LP_MM_LP_PERI_PMS_REG0_REG, BIT(sid)); + } +} + +/** + * @brief Set region start address in LP_PERI_PMS + * + * @param regn_num Region number + * @param addr Start address + */ +static inline void apm_ll_lp_peri_pms_set_region_start_addr(uint32_t regn_num, uint32_t addr) +{ + REG_WRITE(PMS_PERI_REGION_LOW_REG(regn_num), addr); +} + +/** + * @brief Set region end address in LP_PERI_PMS + * + * @param regn_num Region number + * @param addr End address + */ +static inline void apm_ll_lp_peri_pms_set_region_end_addr(uint32_t regn_num, uint32_t addr) +{ + REG_WRITE(PMS_PERI_REGION_HIGH_REG(regn_num), addr); +} + +/** + * @brief Set LP_PERI_PMS region access permissions for HP CPU core 0 + * + * @param mode Security mode + * @param regn_mask Bitmask of regions the core is permitted to access + */ +static inline void apm_ll_lp_peri_pms_hpcpu0_set_region_access(apm_security_mode_t mode, uint32_t regn_mask) +{ + uint32_t regn01 = regn_mask & APM_LL_LP_PERI_PMS_REGN0_1_MASK; +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 + uint32_t regn27 = (regn_mask >> APM_LL_LP_PERI_PMS_REGN2_7_SHIFT) & APM_LL_LP_PERI_PMS_REGN2_7_MASK; +#endif + + switch (mode) { + case APM_SEC_MODE_TEE: + /* regions 0–1 */ + REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE0_MM_REGION_PMS, regn01); +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 + /* regions 2–7 */ + REG_SET_FIELD(PMS_PERI_REGION_2_TO_7_PMS_REG, PMS_HP_CORE0_MM_REGION_2_TO_7_PMS, regn27); +#endif break; - case APM_LL_MASTER_HPCPU0: - if (sec_mode) { - REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE0_UM_REGION_PMS, regn_pms); - } else { - REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE0_MM_REGION_PMS, regn_pms); - } - break; - case APM_LL_MASTER_HPCPU1: - if (sec_mode) { - REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE1_UM_REGION_PMS, regn_pms); - } else { - REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE1_MM_REGION_PMS, regn_pms); - } + case APM_SEC_MODE_REE: + /* regions 0–1 */ + REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE0_UM_REGION_PMS, regn01); +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 + /* regions 2–7 */ + REG_SET_FIELD(PMS_PERI_REGION_2_TO_7_PMS_REG, PMS_HP_CORE0_UM_REGION_2_TO_7_PMS, regn27); +#endif break; default: - return -1; + break; } - - return 0; } /** - * @brief Configure APM controller clock gating. + * @brief Set LP_PERI_PMS region access permissions for HP CPU core 1 * - * @param apm_ctrl APM controller (LP_PERI/HP_PERI/HP_DMA/LP2HP_PERI/HP2LP_PERI). - * @param enable Permission enable/disable. - * enable: Enable automatic clock gating. - * disable: Keep the clock always on. + * @param mode Security mode + * @param regn_mask Bitmask of regions the core is permitted to access */ -static inline int apm_ll_apm_ctrl_clk_gating_enable(apm_ll_apm_ctrl_t apm_ctrl, bool enable) +static inline void apm_ll_lp_peri_pms_hpcpu1_set_region_access(apm_security_mode_t mode, uint32_t regn_mask) { - uint32_t reg = 0; + uint32_t regn01 = regn_mask & APM_LL_LP_PERI_PMS_REGN0_1_MASK; +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 + uint32_t regn27 = (regn_mask >> APM_LL_LP_PERI_PMS_REGN2_7_SHIFT) & APM_LL_LP_PERI_PMS_REGN2_7_MASK; +#endif - HAL_ASSERT(apm_ctrl < MAX_APM_CTRL); - - switch (apm_ctrl) { - case LP_APM_CTRL: - reg = PMS_LP_PERI_PMS_CLK_EN_REG; + switch (mode) { + case APM_SEC_MODE_TEE: + /* regions 0–1 */ + REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE1_MM_REGION_PMS, regn01); +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 + /* regions 2–7 */ + REG_SET_FIELD(PMS_PERI_REGION_2_TO_7_PMS_REG, PMS_HP_CORE1_MM_REGION_2_TO_7_PMS, regn27); +#endif break; - case HP2LP_APM_CTRL: - reg = PMS_HP2LP_PERI_PMS_CLK_EN_REG; - break; - case HP_APM_CTRL: - reg = PMS_HP_PERI_PMS_CLK_EN_REG; - break; - case LP2HP_APM_CTRL: - reg = PMS_LP2HP_PERI_PMS_CLK_EN_REG; - break; - case DMA_APM_CTRL: - reg = PMS_DMA_CLK_EN_REG; + case APM_SEC_MODE_REE: + /* regions 0–1 */ + REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE1_UM_REGION_PMS, regn01); +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 + /* regions 2–7 */ + REG_SET_FIELD(PMS_PERI_REGION_2_TO_7_PMS_REG, PMS_HP_CORE1_UM_REGION_2_TO_7_PMS, regn27); +#endif break; default: - return -1; + break; } +} +/** + * @brief Set LP_PERI_PMS region access permissions for LP CPU + * + * @param regn_mask Bitmask of regions the LP CPU is permitted to access + */ +static inline void apm_ll_lp_peri_pms_lpcpu_set_region_access(uint32_t regn_mask) +{ + /* regions 0–1 */ + REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_LP_CORE_REGION_PMS, regn_mask & APM_LL_LP_PERI_PMS_REGN0_1_MASK); + +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 + /* regions 2–7 */ + REG_SET_FIELD(PMS_PERI_REGION_2_TO_7_PMS_REG, PMS_LP_CORE_REGION_2_TO_7_PMS, + (regn_mask >> APM_LL_LP_PERI_PMS_REGN2_7_SHIFT) & APM_LL_LP_PERI_PMS_REGN2_7_MASK); +#endif +} + +/** + * @brief Enable/disable clock gating for LP2HP_PERI_PMS + * + * @param enable True to enable, false to disable + */ +static inline void apm_ll_lp2hp_peri_pms_enable_clk_gating(bool enable) +{ if (enable) { - REG_CLR_BIT(reg, BIT(0)); + REG_CLR_BIT(PMS_LP2HP_PERI_PMS_CLK_EN_REG, PMS_LP2HP_PERI_PMS_CLK_EN); } else { - REG_SET_BIT(reg, BIT(0)); + REG_SET_BIT(PMS_LP2HP_PERI_PMS_CLK_EN_REG, PMS_LP2HP_PERI_PMS_CLK_EN); } - - return 0; } /** - * @brief Configure DMA configurable address range low address. + * @brief Enable/disable LP CPU access to a CPU peripheral in LP2HP_PERI_PMS * - * @param regn_num Configurable DMA address range number. - * @param regn_low_addr Configurable DMA address range start address. + * @param sid CPU peripheral slave ID + * @param enable True to enable access, false to disable */ -static inline void apm_ll_dma_region_set_low_address(uint32_t regn_num, uint32_t regn_low_addr) +static inline void apm_ll_lp2hp_peri_pms_enable_lpcpu_cpu_peri_access(apm_slave_cpu_periph_id_t sid, bool enable) { - HAL_ASSERT(regn_num < PMS_DMA_MAX_REGION_NUM); - - REG_WRITE((PMS_DMA_REGION0_LOW_REG + (regn_num * 8)), regn_low_addr); + if (enable) { + REG_SET_BIT(PMS_LP_MM_PMS_REG0_REG, BIT(sid)); + } else { + REG_CLR_BIT(PMS_LP_MM_PMS_REG0_REG, BIT(sid)); + } } /** - * @brief Configure DMA configurable address range high address. + * @brief Enable/disable LP CPU access to an HP peripheral (group 0) in LP2HP_PERI_PMS * - * @param regn_num Configurable DMA address range number. - * @param regn_high_addr Configurable DMA address range end address. + * @param sid HP peripheral group 0 slave ID + * @param enable True to enable access, false to disable */ -static inline void apm_ll_dma_region_set_high_address(uint32_t regn_num, uint32_t regn_high_addr) +static inline void apm_ll_lp2hp_peri_pms_enable_lpcpu_hp_peri0_access(apm_slave_hp_periph0_id_t sid, bool enable) { - HAL_ASSERT(regn_num < PMS_DMA_MAX_REGION_NUM); - - REG_WRITE((PMS_DMA_REGION0_HIGH_REG + (regn_num * 8)), regn_high_addr); + if (enable) { + REG_SET_BIT(PMS_LP_MM_PMS_REG1_REG, BIT(sid)); + } else { + REG_CLR_BIT(PMS_LP_MM_PMS_REG1_REG, BIT(sid)); + } } /** - * @brief Configure DMA configurable address range read permission. + * @brief Enable/disable LP CPU access to an HP peripheral (group 1) in LP2HP_PERI_PMS * - * @param dma_master DMA master whose access permission to be configured. - * @param regn_mask 32-bits field, each bit for corresponding DMA configurable address range permission. - * 0: Disable read permission. - * 1: Enable read permission. + * @param sid HP peripheral group 1 slave ID + * @param enable True to enable access, false to disable */ -static inline void apm_ll_dma_region_r_pms(apm_ll_dma_master_t dma_master, uint32_t regn_mask) +static inline void apm_ll_lp2hp_peri_pms_enable_lpcpu_hp_peri1_access(apm_slave_hp_periph1_id_t sid, bool enable) { - HAL_ASSERT(dma_master < PMS_DMA_MAX); - - REG_WRITE(PMS_DMA_PMS_R_REG(dma_master), regn_mask); -} - -/** - * @brief Configure DMA configurable address range write permission. - * - * @param dma_master DMA master whose access permission to be configured. - * @param regn_mask 32-bits field, each bit for corresponding DMA configurable address range permission. - * 0: Disable write permission. - * 1: Enable write permission. - */ -static inline void apm_ll_dma_region_w_pms(apm_ll_dma_master_t dma_master, uint32_t regn_mask) -{ - HAL_ASSERT(dma_master < PMS_DMA_MAX); - - REG_WRITE(PMS_DMA_PMS_W_REG(dma_master), regn_mask); + uint32_t reg = (sid < 32U) ? PMS_LP_MM_PMS_REG2_REG : PMS_LP_MM_PMS_REG3_REG; + if (enable) { + REG_SET_BIT(reg, BIT(sid & 0x1FU)); + } else { + REG_CLR_BIT(reg, BIT(sid & 0x1FU)); + } } #ifdef __cplusplus diff --git a/components/esp_hal_security/include/hal/apm_hal.h b/components/esp_hal_security/include/hal/apm_hal.h index 637009c3343..d4c2dee2e07 100644 --- a/components/esp_hal_security/include/hal/apm_hal.h +++ b/components/esp_hal_security/include/hal/apm_hal.h @@ -16,92 +16,7 @@ extern "C" { #include "hal/apm_ll.h" #include "hal/apm_types.h" -#if SOC_IS(ESP32P4) - -/** - * @brief DMA configurable region configuration data. - */ -typedef struct { - apm_ll_dma_master_t dma_master; /* DMA master whose access permission to be configured.*/ - uint32_t pms_r_mask; /* Read permission mask. */ - uint32_t pms_w_mask; /* Write permission mask. */ -} apm_hal_dma_region_config_data_t; - -/** - * @brief Configure HP peripherals access permission for the HP CPU0/1. - * - * @param master_id HP CPU0/1 - * @param hp_peri HP peripheral whose access permission to be configured. - * @param enable Permission enable/disable - */ -void apm_hal_hp_peri_access_enable(apm_ll_master_id_t master_id, apm_ll_hp_peri_t hp_peri, - apm_ll_secure_mode_t sec_mode, bool enable); - -/** - * @brief Configure LP peripherals access permission for the LP CPU. - * - * @param lp_peri LP peripheral whose access permission to be configured. - * @param enable Permission enable/disable - */ -void apm_hal_lp_peri_access_enable(apm_ll_lp_peri_t lp_peri, bool enable); - -/** - * @brief Configure peripherals configurable address ranges. - * - * @param regn_num Configurable address range number. - * @param regn_low_addr Configurable address range start address. - * @param regn_high_addr Configurable address range end address. - */ -void apm_hal_peri_region_config(uint32_t regn_num, uint32_t regn_low_addr, - uint32_t regn_high_addr); - -/** - * @brief Configure peripherals configurable address ranges. - * - * @param master_id LP CPU and HP CPU0/1 - * @param sec_mode CPU privilege mode (Machine/User) which corresponds to (TEE/REE). - * @param regn_num Configurable address range number. - * @param regn_pms Configurable address range permission setting(2-bits field). - * Bit 0: Region 0 permission enable/disable. - * Bit 1: Region 1 permission enable/disable. - * @return Configuration performed successfully? - */ -int apm_hal_peri_region_pms(apm_ll_master_id_t master_id, apm_ll_secure_mode_t sec_mode, - uint32_t regn_num, uint32_t regn_pms); - -/** - * @brief Configure APM controller clock gating. - * - * @param apm_ctrl APM controller (LP_PERI/HP_PERI/HP_DMA/LP2HP_PERI/HP2LP_PERI). - * @param enable Permission enable/disable. - * enable: Enable automatic clock gating. - * disable: Keep the clock always on. - * @return Clock gating set successfully? - */ -int apm_hal_apm_ctrl_clk_gating_enable(apm_ll_apm_ctrl_t apm_ctrl, bool enable); - -/** - * @brief Configure DMA configurable address range low address. - * - * @param regn_num Configurable DMA address range number. - * @param regn_low_addr Configurable DMA address range start address. - * @param regn_high_addr Configurable DMA address range end address. - */ -void apm_hal_dma_region_config(uint32_t regn_num, uint32_t regn_low_addr, uint32_t regn_high_addr); - -/** - * @brief Configure DMA configurable address range read permission. - * - * @param pms_data DMA configurable region configuration data. - * @param dma_master DMA master whose access permission to be configured. - * @param regn_mask 32-bits field, each bit for corresponding DMA configurable address range permission. - * 0: Disable read permission. - * 1: Enable read permission. - */ -void apm_hal_dma_region_pms(apm_hal_dma_region_config_data_t *pms_data); - -#else - +#if SOC_APM_CTRL_FILTER_SUPPORTED /** * @brief Helper macro to create a region entry configuration * @@ -357,10 +272,225 @@ void apm_hal_enable_reset_event_bypass(bool enable); * @param enable True to enable, false to disable */ void apm_hal_enable_ctrl_clk_gating(apm_ctrl_module_t ctrl_mod, bool enable); +#else +/** + * @brief HP_PERI_PMS permission configuration structure + */ +typedef struct { + uint32_t cpu_peri; /*!< Bitmask for CPU_PERIPH slaves */ + uint32_t hp_peri0; /*!< Bitmask for HP_PERIPH0 slaves */ + uint64_t hp_peri1; /*!< Bitmask for HP_PERIPH1 slaves */ +} apm_hal_pms_hp_peri_cfg_t; -#endif //SOC_IS(ESP32P4) +/** + * @brief PMS region configuration structure + */ +typedef struct { + uint32_t regn_num; /*!< Region number */ + uint32_t regn_start_addr; /*!< Region start address */ + uint32_t regn_end_addr; /*!< Region end address */ +} apm_hal_pms_regn_cfg_t; -#elif SOC_APM_CTRL_FILTER_SUPPORTED //!SOCKconfig_APM_SUPPORTED +/** + * @brief PMS master configuration structure + */ +typedef struct { + union { + struct { + apm_master_dma_id_t id; /*!< DMA master ID */ + uint32_t regn_pms_rd; /*!< Bitmask of regions the master is permitted to read */ + uint32_t regn_pms_wr; /*!< Bitmask of regions the master is permitted to write */ + } dma; + struct { + apm_master_id_t id; /*!< Master ID */ + apm_security_mode_t mode; /*!< Security mode */ + uint32_t regn_pms; /*!< Bitmask of regions the master is permitted to access */ + } lp_peri; + }; +} apm_hal_pms_master_cfg_t; + +/** + * @brief Helper macro to create a PMS region entry configuration + */ +#define APM_HAL_PMS_REGION_ENTRY(NUM, START, END) \ + { \ + .regn_num = (NUM), \ + .regn_start_addr = (START), \ + .regn_end_addr = (END), \ + } + +/** + * @brief Helper macro to create a DMA_PMS master entry configuration + */ +#define APM_HAL_DMA_PMS_MASTER_ENTRY(ID, R_PMS, W_PMS) \ + { \ + .dma = { \ + .id = (ID), \ + .regn_pms_rd = (R_PMS), \ + .regn_pms_wr = (W_PMS), \ + }, \ + } + +/** + * @brief Helper macro to create an LP_PERI_PMS master entry configuration + */ +#define APM_HAL_LP_PERI_PMS_MASTER_ENTRY(ID, MODE, REGN_PMS) \ + { \ + .lp_peri = { \ + .id = (ID), \ + .mode = (MODE), \ + .regn_pms = (REGN_PMS), \ + }, \ + } + +/** + * @brief Set DMA_PMS region address bounds + * + * @param regn_num Region number + * @param start_addr Region start address + * @param end_addr Region end address + */ +void apm_hal_dma_pms_set_region_bounds(uint32_t regn_num, uint32_t start_addr, uint32_t end_addr); + +/** + * @brief Set DMA_PMS read/write region access mask for a DMA master + * + * @param mid DMA master ID + * @param regn_rd_mask Bitmask of regions the master is permitted to read + * @param regn_wr_mask Bitmask of regions the master is permitted to write + */ +void apm_hal_dma_pms_set_master_region_attr(apm_master_dma_id_t mid, uint32_t regn_rd_mask, uint32_t regn_wr_mask); + +/** + * @brief Set DMA_PMS region configurations + * + * @param regn_count Number of regions to configure + * @param regn_cfg Array of region configurations + */ +void apm_hal_dma_pms_set_region_cfg(uint32_t regn_count, const apm_hal_pms_regn_cfg_t *regn_cfg); + +/** + * @brief Set DMA_PMS master configurations + * + * @param master_count Number of masters to configure + * @param cfg Array of master configurations + */ +void apm_hal_dma_pms_set_master_cfg(uint32_t master_count, const apm_hal_pms_master_cfg_t *cfg); + +/** + * @brief Set HP2LP_PERI_PMS access permissions for HP CPU + * + * @param core_id CPU core ID + * @param mode Security mode + * @param enable_mask Bitmask of LP peripherals to enable access to + */ +void apm_hal_hp2lp_peri_pms_set_hpcpu_access(int core_id, apm_security_mode_t mode, uint32_t enable_mask); + +/** + * @brief Set LP_PERI_PMS access permissions for LP CPU + * + * @param enable_mask Bitmask of LP peripherals to enable access to + */ +void apm_hal_lp_peri_pms_set_lpcpu_access(uint32_t enable_mask); + +/** + * @brief Set HP_PERI PMS access permissions for HP CPU + * + * @param core_id CPU core ID + * @param mode Security mode + * @param cfg HP peripheral permission configuration + */ +void apm_hal_hp_peri_pms_set_hpcpu_access(int core_id, apm_security_mode_t mode, const apm_hal_pms_hp_peri_cfg_t *cfg); + +/** + * @brief Set LP2HP_PERI PMS access permissions for LP CPU + * + * @param cfg HP peripheral permission configuration + */ +void apm_hal_lp2hp_peri_pms_set_lpcpu_access(const apm_hal_pms_hp_peri_cfg_t *cfg); + +/** + * @brief Set LP_PERI_PMS region address bounds + * + * @param regn_num Region number + * @param start_addr Region start address + * @param end_addr Region end address + */ +void apm_hal_lp_peri_pms_set_region_bounds(uint32_t regn_num, uint32_t start_addr, uint32_t end_addr); + +/** + * @brief Set LP_PERI_PMS region access mask for a master + * + * @param mid Master ID + * @param mode Security mode + * @param regn_pms_mask Bitmask of regions the master is permitted to access + */ +void apm_hal_lp_peri_pms_set_master_region_attr(apm_master_id_t mid, apm_security_mode_t mode, uint32_t regn_pms_mask); + +/** + * @brief Set LP_PERI_PMS region configurations + * + * @param regn_count Number of regions to configure + * @param regn_cfg Array of region configurations + */ +void apm_hal_lp_peri_pms_set_region_cfg(uint32_t regn_count, const apm_hal_pms_regn_cfg_t *regn_cfg); + +/** + * @brief Set LP_PERI_PMS master configurations + * + * @param master_count Number of masters to configure + * @param master_cfg Array of master configurations + */ +void apm_hal_lp_peri_pms_set_master_cfg(uint32_t master_count, const apm_hal_pms_master_cfg_t *master_cfg); + +/** + * @brief Enable/disable PMS violation interrupt for a controller module + * + * @param ctrl_mod APM controller module + * @param enable True to enable, false to disable + */ +void apm_hal_enable_intr(apm_ctrl_module_t ctrl_mod, bool enable); + +/** + * @brief Clear PMS violation interrupt for a controller module + * + * @param ctrl_mod APM controller module + */ +void apm_hal_clear_intr(apm_ctrl_module_t ctrl_mod); + +/** + * @brief Get the combined interrupt status for all PMS controller modules + * + * @return Bitmask of modules with a pending interrupt + */ +uint32_t apm_hal_get_intr_status(void); + +/** + * @brief Get PMS violation exception information + * + * @param type Exception type identifier + * @param excp_info Pointer to structure to fill with exception details + */ +void apm_hal_get_exception_info(apm_ctrl_exception_type type, apm_ctrl_exception_info_t *excp_info); + +/** + * @brief Get interrupt source number for a PMS controller module + * + * @param ctrl_mod APM controller module + * @return Interrupt source number + */ +int apm_hal_get_intr_src_num(apm_ctrl_module_t ctrl_mod); + +/** + * @brief Enable/disable clock gating for a PMS controller module + * + * @param ctrl_mod APM controller module + * @param enable True to enable, false to disable + */ +void apm_hal_enable_ctrl_clk_gating(apm_ctrl_module_t ctrl_mod, bool enable); +#endif // SOC_APM_CTRL_FILTER_SUPPORTED + +#elif SOC_APM_CTRL_FILTER_SUPPORTED // SOC_APM_CTRL_FILTER_SUPPORTED #if SOC_IS(ESP32H4) #include "soc/hp_apm_reg.h" diff --git a/components/esp_hal_security/include/hal/apm_types.h b/components/esp_hal_security/include/hal/apm_types.h index b01633c3f75..8e84d78d489 100644 --- a/components/esp_hal_security/include/hal/apm_types.h +++ b/components/esp_hal_security/include/hal/apm_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,11 +7,14 @@ #include #include "soc/soc_caps.h" +#include "esp_bit_defs.h" +#include "hal/config.h" #ifdef __cplusplus extern "C" { #endif +#if SOC_APM_CTRL_FILTER_SUPPORTED /** * @brief Master IDs for APM */ @@ -95,6 +98,229 @@ typedef enum { APM_SEC_MODE_REE2 = 3, /*!< Rich Execution Environment mode 2 */ } apm_security_mode_t; +/** + * @brief APM controller exception info structure + */ +typedef struct { + uint32_t regn; /*!< Region number */ + uint32_t mode; /*!< Security mode */ + uint32_t id; /*!< Master ID */ + uint32_t type; /*!< Exception type */ + uint32_t addr; /*!< Exception address */ +} apm_ctrl_exception_info_t; +#else +/** + * @brief Security modes for APM + */ +typedef enum { + APM_SEC_MODE_TEE = 0, /*!< Trusted Execution Environment mode (M-mode) */ + APM_SEC_MODE_REE = 1, /*!< Rich Execution Environment mode (U-mode) */ +} apm_security_mode_t; + +/** + * @brief APM controller modules + */ +typedef enum { + APM_CTRL_DMA_PMS = 0, /*!< DMA APM controller */ + APM_CTRL_HP_PERI_PMS, /*!< High-performance APM controller */ + APM_CTRL_HP2LP_PERI_PMS, /*!< High-performance to Low-power APM controller */ + APM_CTRL_LP_PERI_PMS, /*!< Low-power APM controller */ + APM_CTRL_LP2HP_PERI_PMS, /*!< Low-power to High-performance APM controller */ +} apm_ctrl_module_t; + +/** + * @brief Master IDs for APM + */ +typedef enum { + APM_MASTER_HPCPU0 = 0, /*!< High-performance CPU core 0 */ + APM_MASTER_HPCPU1, /*!< High-performance CPU core 1 */ + APM_MASTER_LPCPU, /*!< Low-power CPU */ + APM_MASTER_DMA, /*!< DMA masters */ +} apm_master_id_t; + +/** + * @brief DMA master IDs for APM + */ +typedef enum { + APM_MASTER_DMA_GDMA_CH0 = 0, + APM_MASTER_DMA_GDMA_CH1, + APM_MASTER_DMA_GDMA_CH2, + APM_MASTER_DMA_GDMA_CH3, + APM_MASTER_DMA_AHB_PDMA_ADC, + APM_MASTER_DMA_AHB_PDMA_I2S0, + APM_MASTER_DMA_AHB_PDMA_I2S1, + APM_MASTER_DMA_AHB_PDMA_I2S2, + APM_MASTER_DMA_AHB_PDMA_I3C_MST, + APM_MASTER_DMA_AHB_PDMA_UHCI0, + APM_MASTER_DMA_AHB_PDMA_RMT, + APM_MASTER_DMA_AXI_PDMA_LCDCAM = 13, + APM_MASTER_DMA_AXI_PDMA_GPSPI2, + APM_MASTER_DMA_AXI_PDMA_GPSPI3, + APM_MASTER_DMA_AXI_PDMA_PARLIO, + APM_MASTER_DMA_AXI_PDMA_AES, + APM_MASTER_DMA_AXI_PDMA_SHA, + APM_MASTER_DMA_DMA2D_JPEG, + APM_MASTER_DMA_USBOTG_HS, + APM_MASTER_DMA_GMAC, + APM_MASTER_DMA_SDMMC, + APM_MASTER_DMA_USBOTG_FS, + APM_MASTER_DMA_TRACE0, + APM_MASTER_DMA_TRACE1, + APM_MASTER_DMA_L2MEM_MON, + APM_MASTER_DMA_SPM_MON, + APM_MASTER_DMA_H264 = 30, + APM_MASTER_DMA_DMA2D_PPA, + APM_MASTER_DMA_DMA2D_DUMMY, + APM_MASTER_DMA_AHB_PDMA_DUMMY, + APM_MASTER_DMA_AXI_PDMA_DUMMY, + APM_MASTER_DMA_MAX, +} apm_master_dma_id_t; + +/** + * @brief HP peripheral slave IDs for APM + */ +typedef enum { + APM_SLAVE_PSRAM = 0, + APM_SLAVE_FLASH, + APM_SLAVE_L2MEM, + APM_SLAVE_L2ROM, + APM_SLAVE_TRACE0 = 6, + APM_SLAVE_TRACE1, + APM_SLAVE_CPU_BUS_MON, + APM_SLAVE_L2MEM_MON, + APM_SLAVE_SPM_MON, + APM_SLAVE_CACHE, + APM_SLAVE_CPU_PERIPH_MAX, +} apm_slave_cpu_periph_id_t; + +typedef enum { + APM_SLAVE_HP_USBOTG_HS = 0, + APM_SLAVE_HP_USBOTG_FS, + APM_SLAVE_HP_USBOTG_FS_WRAP, + APM_SLAVE_HP_GDMA, + APM_SLAVE_HP_SDMMC = 5, + APM_SLAVE_HP_AHB_PDMA, + APM_SLAVE_HP_JPEG, + APM_SLAVE_HP_PPA, + APM_SLAVE_HP_DMA2D, + APM_SLAVE_HP_KEY_MANAGER, + APM_SLAVE_HP_AXI_PDMA, + APM_SLAVE_HP_FLASH_MSPI, + APM_SLAVE_HP_PSRAM_MSPI, + APM_SLAVE_HP_CRYPTO, + APM_SLAVE_HP_GMAC, + APM_SLAVE_HP_USB_PHY, + APM_SLAVE_HP_PVT, + APM_SLAVE_HP_CSI_HOST, + APM_SLAVE_HP_DSI_HOST, + APM_SLAVE_HP_ISP, + APM_SLAVE_HP_H264_CORE, + APM_SLAVE_HP_RMT, + APM_SLAVE_HP_BITSCRAMBLER, + APM_SLAVE_HP_AXI_ICM, + APM_SLAVE_HP_PERI_PMS, + APM_SLAVE_LP2HP_PERI_PMS, + APM_SLAVE_DMA_PMS, + APM_SLAVE_HP_H264_DMA2D, + APM_SLAVE_AXI_PERF_MON, + APM_SLAVE_HP_PERIPH0_MAX, +} apm_slave_hp_periph0_id_t; + +typedef enum { + APM_SLAVE_HP_MCPWM0, + APM_SLAVE_HP_MCPWM1, + APM_SLAVE_HP_TG0, + APM_SLAVE_HP_TG1, + APM_SLAVE_HP_I2C0, + APM_SLAVE_HP_I2C1, + APM_SLAVE_HP_I2S0, + APM_SLAVE_HP_I2S1, + APM_SLAVE_HP_I2S2, + APM_SLAVE_HP_PCNT, + APM_SLAVE_HP_UART0, + APM_SLAVE_HP_UART1, + APM_SLAVE_HP_UART2, + APM_SLAVE_HP_UART3, + APM_SLAVE_HP_UART4, + APM_SLAVE_HP_PARLIO, + APM_SLAVE_HP_GPSPI2, + APM_SLAVE_HP_GPSPI3, + APM_SLAVE_HP_USBDEVICE, + APM_SLAVE_HP_LEDC, + APM_SLAVE_HP_ETM = 21, + APM_SLAVE_HP_INTMTX, + APM_SLAVE_HP_TWAI0, + APM_SLAVE_HP_TWAI1, + APM_SLAVE_HP_TWAI2, + APM_SLAVE_HP_I3C_MST, + APM_SLAVE_HP_I3C_SLV, + APM_SLAVE_HP_LCDCAM, + APM_SLAVE_HP_ADC = 30, + APM_SLAVE_HP_UHCI, + APM_SLAVE_HP_GPIO = 32, + APM_SLAVE_HP_IOMUX, + APM_SLAVE_HP_SYSTIMER, + APM_SLAVE_HP_SYS_REG, + APM_SLAVE_HP_CLKRST, + APM_SLAVE_HP_PERIPH1_MAX, +} apm_slave_hp_periph1_id_t; + +/** + * @brief LP peripheral slave IDs for APM + */ +typedef enum { + APM_SLAVE_LP_SYSREG = 0, + APM_SLAVE_LP_AONCLKRST, + APM_SLAVE_LP_TIMER, + APM_SLAVE_LP_ANAPERI, + APM_SLAVE_LP_PMU, + APM_SLAVE_LP_WDT, + APM_SLAVE_LP_MAILBOX, + APM_SLAVE_LP_RTC, + APM_SLAVE_LP_PERICLKRST, + APM_SLAVE_LP_UART, + APM_SLAVE_LP_I2C, + APM_SLAVE_LP_SPI, + APM_SLAVE_LP_I2CMST, + APM_SLAVE_LP_I2S, + APM_SLAVE_LP_ADC, + APM_SLAVE_LP_TOUCH, + APM_SLAVE_LP_IOMUX, + APM_SLAVE_LP_INTR, + APM_SLAVE_LP_EFUSE, + APM_SLAVE_LP_PERI_PMS, + APM_SLAVE_HP2LP_PERI_PMS, + APM_SLAVE_LP_TSENS, + APM_SLAVE_LP_HUK, + APM_SLAVE_LP_SRAM, +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 + APM_SLAVE_LP_TRNG, +#endif + APM_SLAVE_LP_PERIPH_MAX, +} apm_slave_lp_periph_t; + +/** + * @brief APM ADDRHOLE exception types + */ +typedef enum { + APM_EXCP_NONE = 0, /*!< No exception */ + APM_EXCP_HP_AXI = BIT(0), /*!< Exception from illegal access in HP AXI matrix */ + APM_EXCP_HP_AHB = BIT(1), /*!< Exception from illegal access in HP CPU and AHB matrix */ + APM_EXCP_LP_AHB = BIT(2), /*!< Exception from illegal access in LP AHB matrix */ + APM_EXCP_LP_IDBUS = BIT(3), /*!< Exception from illegal access on LP CPU IBUS or DBUS */ +} apm_ctrl_exception_type; + +/** + * @brief Exception info structure + */ +typedef struct { + uint32_t addr; /*!< Faulting address */ + uint8_t id; /*!< Master ID */ + bool is_wr; /*!< True indicates Write transaction, else Read transaction */ + bool is_secure; /*!< True indicates illegal address access (space exception), else access without permission (authority exception) */ +} apm_ctrl_exception_info_t; +#endif + /** * @brief Access permission flags */ @@ -106,17 +332,6 @@ typedef enum { APM_PERM_ALL = 7, /*!< All access */ } apm_perm_t; -/** - * @brief APM controller exception info structure - */ -typedef struct { - uint32_t regn; /*!< Region number */ - uint32_t mode; /*!< Security mode */ - uint32_t id; /*!< Master ID */ - uint32_t type; /*!< Exception type */ - uint32_t addr; /*!< Exception address */ -} apm_ctrl_exception_info_t; - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32p4/include/hal/axi_icm_ll.h b/components/hal/esp32p4/include/hal/axi_icm_ll.h index bfeb5225b95..18ce0dee579 100644 --- a/components/hal/esp32p4/include/hal/axi_icm_ll.h +++ b/components/hal/esp32p4/include/hal/axi_icm_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,15 +17,38 @@ extern "C" { #endif typedef enum { - AXI_ICM_MASTER_CPU = 0, // An aggregate master port for other users, like HP CPU, LP CPU, USB, EMAC, SDMMC, AHB-GDMA, etc - AXI_ICM_MASTER_CACHE = 1, // Cache master port - AXI_ICM_MASTER_DW_GDMA_M0 = 5, // DW-GDMA master port 0 - AXI_ICM_MASTER_DW_GDMA_M1 = 6, // DW-GDMA master port 1 - AXI_ICM_MASTER_GDMA = 8, // AXI-GDMA - AXI_ICM_MASTER_DMA2D = 10, // DMA2D - AXI_ICM_MASTER_H264_M0 = 11, // H264 master port 0 - AXI_ICM_MASTER_H264_M1 = 12, // H264 master port 1 -} axi_icm_ll_master_id_t; + AXI_ICM_MASTER_CPU = 0, // An aggregate master port for other users, like HP CPU, LP CPU, USB, EMAC, SDMMC, AHB-GDMA, etc + AXI_ICM_MASTER_CACHE = 1, // Cache master port + AXI_ICM_MASTER_DW_GDMA_M0 = 5, // DW-GDMA master port 0 + AXI_ICM_MASTER_DW_GDMA_M1 = 6, // DW-GDMA master port 1 + AXI_ICM_MASTER_GDMA = 8, // AXI-GDMA + AXI_ICM_MASTER_DMA2D = 10, // DMA2D + AXI_ICM_MASTER_H264_M0 = 11, // H264 master port 0 + AXI_ICM_MASTER_H264_M1 = 12, // H264 master port 1 +} axi_icm_ll_sys_master_id_t; + +typedef enum { + AXI_ICM_CPU_MASTER_HP_CPU0 = 0, // HP CPU core 0 + AXI_ICM_CPU_MASTER_HP_CPU1 = 1, // HP CPU core 1 + AXI_ICM_CPU_MASTER_LP_CPU = 2, // LP CPU + AXI_ICM_CPU_MASTER_USBOTG_FS = 3, // USB OTG full-speed + AXI_ICM_CPU_MASTER_REGDMA = 4, // REGDMA + AXI_ICM_CPU_MASTER_GMAC = 5, // GMAC + AXI_ICM_CPU_MASTER_SDMMC = 6, // SDMMC + AXI_ICM_CPU_MASTER_USBOTG_HS = 7, // USB OTG high-speed + AXI_ICM_CPU_MASTER_TRACE0 = 8, // Trace 0 + AXI_ICM_CPU_MASTER_TRACE1 = 9, // Trace 1 + AXI_ICM_CPU_MASTER_TCM_MON = 10, // TCM monitor + AXI_ICM_CPU_MASTER_L2MEM_MON = 11, // L2MEM monitor + AXI_ICM_CPU_MASTER_AHB_PDMA_I3C = 16, // AHB PDMA I3C + AXI_ICM_CPU_MASTER_AHB_PDMA_UHCI = 18, // AHB PDMA UHCI + AXI_ICM_CPU_MASTER_AHB_PDMA_I2S0 = 19, // AHB PDMA I2S0 + AXI_ICM_CPU_MASTER_AHB_PDMA_I2S1 = 20, // AHB PDMA I2S1 + AXI_ICM_CPU_MASTER_AHB_PDMA_I2S2 = 21, // AHB PDMA I2S + AXI_ICM_CPU_MASTER_AHB_PDMA_ADC = 24, // AHB PDMA ADC + AXI_ICM_CPU_MASTER_AHB_PDMA_RMT = 26, // AHB PDMA RMT + AXI_ICM_CPU_MASTER_MAX = 31, +} axi_icm_ll_cpu_master_id_t; /** * @brief AXI ICM has independent channels for read and write access. @@ -35,6 +58,25 @@ typedef enum { AXI_ICM_ACCESS_WRITE = 1, } axi_icm_ll_access_type_t; +/** + * @brief AXI ICM interrupt types + */ +typedef enum { + AXI_ICM_INTR_DEADLOCK = 0, /*!< Deadlock interrupt */ + AXI_ICM_INTR_SYS_ADDRHOLE = 1, /*!< System addrhole interrupt */ + AXI_ICM_INTR_CPU_ADDRHOLE = 2, /*!< CPU addrhole interrupt */ +} axi_icm_ll_intr_type_t; + +/** + * @brief AXI ICM addrhole exception info + */ +typedef struct { + uint32_t addr; /*!< Faulting address */ + uint8_t id; /*!< Master ID */ + bool is_wr; /*!< Write access */ + bool is_secure; /*!< Secure access */ +} axi_icm_ll_excp_info_t; + /** * @brief Set QoS burstiness for a master port, also enable the regulator * @@ -42,7 +84,7 @@ typedef enum { * @param burstiness Burstiness value. It represents the depth of the token bucket. * @param access_type 0: read, 1: write */ -static inline void axi_icm_ll_set_qos_burstiness(axi_icm_ll_master_id_t mid, uint32_t burstiness, axi_icm_ll_access_type_t access_type) +static inline void axi_icm_ll_set_qos_burstiness(axi_icm_ll_sys_master_id_t mid, uint32_t burstiness, axi_icm_ll_access_type_t access_type) { HAL_ASSERT(burstiness >= 1 && burstiness <= 256); // wait for the previous command to finish @@ -80,7 +122,7 @@ static inline void axi_icm_ll_set_qos_burstiness(axi_icm_ll_master_id_t mid, uin * @param transaction_level Transaction level, lower value means higher rate * @param access_type 0: read, 1: write */ -static inline void axi_icm_ll_set_qos_peak_transaction_rate(axi_icm_ll_master_id_t mid, uint32_t peak_level, +static inline void axi_icm_ll_set_qos_peak_transaction_rate(axi_icm_ll_sys_master_id_t mid, uint32_t peak_level, uint32_t transaction_level, axi_icm_ll_access_type_t access_type) { HAL_ASSERT(peak_level < transaction_level && transaction_level <= 11); @@ -186,6 +228,68 @@ static inline void axi_icm_ll_set_cpu_qos_arbiter_prio(uint32_t write_prio, uint AXI_ICM.mst_arqos_reg0.reg_cpu_arqos = read_prio; } +/** + * @brief Enable/disable AXI ICM interrupt + * + * @param mask Interrupt mask (use BIT(axi_icm_ll_intr_type_t)) + * @param enable true to enable, false to disable + */ +static inline void axi_icm_ll_enable_intr(uint32_t mask, bool enable) +{ + if (enable) { + AXI_ICM.int_ena.val |= mask; + } else { + AXI_ICM.int_ena.val &= ~mask; + } +} + +/** + * @brief Get AXI ICM interrupt status + * + * @param mask Interrupt mask + * @return Status mask + */ +static inline uint32_t axi_icm_ll_get_intr_status(uint32_t mask) +{ + return AXI_ICM.int_st.val & mask; +} + +/** + * @brief Clear AXI ICM interrupt + * + * @param mask Interrupt mask + */ +static inline void axi_icm_ll_clear_intr(uint32_t mask) +{ + AXI_ICM.int_clr.val = mask; +} + +/** + * @brief Get SYS addrhole exception info + * + * @param[out] info Pointer to store exception information + */ +static inline void axi_icm_ll_get_sys_excp_info(axi_icm_ll_excp_info_t *info) +{ + info->addr = AXI_ICM.sys_addrhole_addr.reg_icm_sys_addrhole_addr; + info->id = AXI_ICM.sys_addrhole_info.reg_icm_sys_addrhole_id; + info->is_wr = AXI_ICM.sys_addrhole_info.reg_icm_sys_addrhole_wr; + info->is_secure = AXI_ICM.sys_addrhole_info.reg_icm_sys_addrhole_secure; +} + +/** + * @brief Get CPU addrhole exception info + * + * @param[out] info Pointer to store exception information + */ +static inline void axi_icm_ll_get_cpu_excp_info(axi_icm_ll_excp_info_t *info) +{ + info->addr = AXI_ICM.cpu_addrhole_addr.reg_icm_cpu_addrhole_addr; + info->id = AXI_ICM.cpu_addrhole_info.reg_icm_cpu_addrhole_id; + info->is_wr = AXI_ICM.cpu_addrhole_info.reg_icm_cpu_addrhole_wr; + info->is_secure = AXI_ICM.cpu_addrhole_info.reg_icm_cpu_addrhole_secure; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32p4/include/hal/lp_sys_ll.h b/components/hal/esp32p4/include/hal/lp_sys_ll.h index 71d5371e9ac..0f630c658fa 100644 --- a/components/hal/esp32p4/include/hal/lp_sys_ll.h +++ b/components/hal/esp32p4/include/hal/lp_sys_ll.h @@ -25,6 +25,29 @@ extern "C" { #define MEM_AUX_LIGHTSLEEP BIT(1) #define MEM_AUX_DEEPSLEEP BIT(2) +/** + * @brief LP SYS interrupt types + */ +typedef enum { + LP_SYS_INTR_LP_ADDRHOLE = 0, /*!< LP addrhole interrupt (LP peri, LP RAM TEE APM, LP matrix default slave) */ + LP_SYS_INTR_IDBUS_ADDRHOLE = 1, /*!< IDBUS addrhole interrupt (LP CPU ibus and dbus) */ + LP_SYS_INTR_LP_CORE_AHB_TOUT = 2, /*!< LP core AHB bus timeout interrupt */ + LP_SYS_INTR_LP_CORE_IBUS_TOUT = 3, /*!< LP core ibus timeout interrupt */ + LP_SYS_INTR_LP_CORE_DBUS_TOUT = 4, /*!< LP core dbus timeout interrupt */ + LP_SYS_INTR_ETM_TASK_ULP = 5, /*!< ETM task ULP interrupt */ + LP_SYS_INTR_SLOW_CLK_TICK = 6, /*!< Slow clock tick interrupt */ +} lp_sys_ll_intr_type_t; + +/** + * @brief LP SYS addrhole exception info + */ +typedef struct { + uint32_t addr; /*!< Faulting address */ + uint8_t id; /*!< Master ID */ + bool is_wr; /*!< Write access */ + bool is_secure; /*!< Secure access */ +} lp_sys_ll_excp_info_t; + /** * @brief ROM obtains the wake-up type through LP_SYS_STORE9_REG[0]. * Set the flag to inform @@ -100,6 +123,60 @@ static inline uint32_t lp_sys_ll_load_wakeup_cause(void) return REG_READ(RTC_LP_CORE_STORE_WAKEUP_REG); } +FORCE_INLINE_ATTR void lp_sys_ll_enable_intr(uint32_t mask, bool enable) +{ + if (enable) { + LP_SYS.int_ena.val |= mask; + } else { + LP_SYS.int_ena.val &= ~mask; + } +} + +FORCE_INLINE_ATTR uint32_t lp_sys_ll_get_intr_status(uint32_t mask) +{ + return LP_SYS.int_st.val & mask; +} + +FORCE_INLINE_ATTR void lp_sys_ll_clear_intr(uint32_t mask) +{ + LP_SYS.int_clr.val = mask; +} + +FORCE_INLINE_ATTR uint32_t lp_sys_ll_get_ahb_excp_addr(void) +{ + return LP_SYS.lp_addrhole_addr.lp_addrhole_addr; +} + +FORCE_INLINE_ATTR void lp_sys_ll_get_ahb_excp_info(lp_sys_ll_excp_info_t *info) +{ + info->addr = LP_SYS.lp_addrhole_addr.lp_addrhole_addr; + info->id = LP_SYS.lp_addrhole_info.lp_addrhole_id; + info->is_wr = LP_SYS.lp_addrhole_info.lp_addrhole_wr; + info->is_secure = LP_SYS.lp_addrhole_info.lp_addrhole_secure; +} + +FORCE_INLINE_ATTR uint32_t lp_sys_ll_get_idbus_excp_addr(void) +{ + return LP_SYS.idbus_addrhole_addr.idbus_addrhole_addr; +} + +FORCE_INLINE_ATTR void lp_sys_ll_get_idbus_excp_info(lp_sys_ll_excp_info_t *info) +{ + info->addr = LP_SYS.idbus_addrhole_addr.idbus_addrhole_addr; + info->id = LP_SYS.idbus_addrhole_info.idbus_addrhole_id; + info->is_wr = LP_SYS.idbus_addrhole_info.idbus_addrhole_wr; + info->is_secure = LP_SYS.idbus_addrhole_info.idbus_addrhole_secure; +} + +FORCE_INLINE_ATTR void lp_sys_ll_enable_lp_core_err_resp(bool enable) +{ + if (enable) { + LP_SYS.lp_core_err_resp_dis.val = 0x00U; + } else { + LP_SYS.lp_core_err_resp_dis.val = 0x07U; + } +} + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32p4/include/soc/apm_defs.h b/components/soc/esp32p4/include/soc/apm_defs.h new file mode 100644 index 00000000000..2461baacb6f --- /dev/null +++ b/components/soc/esp32p4/include/soc/apm_defs.h @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + */ + +#pragma once + +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Number of configurable DMA_PMS regions */ +#define APM_DMA_PMS_REGION_NUM (32) +/* Alignment required for start/end addresses for DMA_PMS regions */ +#define APM_DMA_PMS_REGION_ADDR_ALIGN (0x1000) +/* Register offset between DMA_PMS region bound address registers */ +#define APM_DMA_PMS_REGION_ADDR_OFFSET (0x08) +/* Register offset between DMA_PMS region attribute registers */ +#define APM_DMA_PMS_REGION_ATTR_OFFSET (0x08) + +/* Number of configurable LP_PERI_PMS regions */ +#if CONFIG_ESP32P4_SELECTS_REV_LESS_V3 +#define APM_LP_PERI_PMS_REGION_NUM (2) +#else +#define APM_LP_PERI_PMS_REGION_NUM (8) +#endif +/* Alignment required for start/end addresses for LP_PERI_PMS regions */ +#define APM_LP_PERI_PMS_REGION_ADDR_ALIGN (4) + +/* Number of configurable MSPI PMS regions (flash/PSRAM) */ +#define APM_MSPI_PMS_REGION_NUM (4) +/* Alignment required for start/end addresses for MSPI_PMS regions */ +#define APM_MSPI_PMS_REGION_ADDR_ALIGN (0x1000) + +/* CPU_PERIPH slave mask */ +#define APM_SLAVE_CPU_PERI_ALL_MASK (0x0FCFU) +/* HP_PERIPH0 slave mask */ +#define APM_SLAVE_HP_PERI0_ALL_MASK (0x3FFFFFEFU) +/* HP_PERIPH1 slave mask */ +#define APM_SLAVE_HP_PERI1_ALL_MASK (0x1FDFEFFFFFULL) +/* LP_PERIPH slave mask */ +#if CONFIG_ESP32P4_SELECTS_REV_LESS_V3 +#define APM_SLAVE_LP_PERI_ALL_MASK (0x00FFFFFFU) +#else +#define APM_SLAVE_LP_PERI_ALL_MASK (0x01FFFFFFU) +#endif + +#ifdef __cplusplus +} +#endif