diff --git a/components/bootloader_support/src/bootloader_mem.c b/components/bootloader_support/src/bootloader_mem.c index b8dbd700d6..6ae07f70e6 100644 --- a/components/bootloader_support/src/bootloader_mem.c +++ b/components/bootloader_support/src/bootloader_mem.c @@ -25,20 +25,19 @@ void bootloader_init_mem(void) * So, at boot disabling these filters. They will enable as per the * use case by TEE initialization code. */ -#ifdef SOC_APM_CTRL_FILTER_SUPPORTED - apm_hal_apm_ctrl_filter_enable_all(false); - /* [APM] On power-up, only the HP CPU starts in TEE mode; others default to REE2. - * APM blocks REE0–REE2 access by default. C5 ECO2 adds per-peripheral control - * (default REEx blocking), but config support is pending. As a workaround, - * all masters are set to TEE mode. +#if SOC_APM_CTRL_FILTER_SUPPORTED + apm_hal_enable_ctrl_filter_all(false); + /* [APM] On power-up, only the HP CPU starts in TEE mode; others + * default to REE2. APM blocks REE0–REE2 access by default. + * Thus, all masters are set to TEE mode. */ #if SOC_APM_SUPPORT_TEE_PERI_ACCESS_CTRL - apm_tee_hal_set_master_secure_mode_all(APM_LL_SECURE_MODE_TEE); + apm_hal_set_master_sec_mode_all(APM_SEC_MODE_TEE); #endif // SOC_APM_SUPPORT_TEE_PERI_ACCESS_CTRL #endif // SOC_APM_CTRL_FILTER_SUPPORTED #endif -#ifdef CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE +#if CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE // protect memory region esp_cpu_configure_region_protection(); #endif diff --git a/components/esp_system/port/soc/esp32c5/clk.c b/components/esp_system/port/soc/esp32c5/clk.c index 294f485998..2c14e538b7 100644 --- a/components/esp_system/port/soc/esp32c5/clk.c +++ b/components/esp_system/port/soc/esp32c5/clk.c @@ -311,12 +311,13 @@ __attribute__((weak)) void esp_perip_clk_init(void) ecc_ll_enable_bus_clock(false); hmac_ll_enable_bus_clock(false); ds_ll_enable_bus_clock(false); - apm_tee_ll_clk_gating_enable(false); + apm_ll_hp_tee_enable_clk_gating(true); + apm_ll_lp_tee_enable_clk_gating(true); uhci_ll_enable_bus_clock(0, false); + apm_ll_hp_apm_enable_ctrl_clk_gating(true); + apm_ll_cpu_apm_enable_ctrl_clk_gating(true); // TODO: Replace with hal implementation - REG_CLR_BIT(HP_APM_CLOCK_GATE_REG, HP_APM_CLK_EN); - REG_CLR_BIT(LP_TEE_CLOCK_GATE_REG, LP_TEE_CLK_EN); REG_CLR_BIT(PCR_TRACE_CONF_REG, PCR_TRACE_CLK_EN); REG_CLR_BIT(PCR_TCM_MEM_MONITOR_CONF_REG, PCR_TCM_MEM_MONITOR_CLK_EN); REG_CLR_BIT(PCR_PSRAM_MEM_MONITOR_CONF_REG, PCR_PSRAM_MEM_MONITOR_CLK_EN); @@ -346,8 +347,8 @@ __attribute__((weak)) void esp_perip_clk_init(void) _lp_clkrst_ll_enable_lp_ana_i2c_clock(false); _lp_clkrst_ll_enable_lp_ext_i2c_clock(false); - REG_CLR_BIT(LP_APM_CLOCK_GATE_REG, LP_APM_CLK_EN); - REG_CLR_BIT(LP_APM0_CLOCK_GATE_REG, LP_APM0_CLK_EN); + apm_ll_lp_apm_enable_ctrl_clk_gating(true); + apm_ll_lp_apm0_enable_ctrl_clk_gating(true); WRITE_PERI_REG(LP_CLKRST_LP_CLK_PO_EN_REG, 0); } } diff --git a/components/esp_tee/subproject/main/common/panic/esp_tee_panic.c b/components/esp_tee/subproject/main/common/panic/esp_tee_panic.c index 4e060f2a57..4db95e4768 100644 --- a/components/esp_tee/subproject/main/common/panic/esp_tee_panic.c +++ b/components/esp_tee/subproject/main/common/panic/esp_tee_panic.c @@ -106,23 +106,18 @@ void tee_apm_violation_isr(void *arg) intptr_t exc_sp = RV_READ_CSR(mscratch); RvExcFrame *frame = (RvExcFrame *)exc_sp; - apm_ctrl_path_t *apm_excp_type = (apm_ctrl_path_t *)arg; - apm_ctrl_exception_info_t excp_info = { - .apm_path = { - .apm_ctrl = apm_excp_type->apm_ctrl, - .apm_m_path = apm_excp_type->apm_m_path, - } - }; + apm_hal_ctrl_info_t *ctrl_info = (apm_hal_ctrl_info_t *)arg; + apm_ctrl_exception_info_t excp_info = {}; - apm_hal_apm_ctrl_get_exception_info(&excp_info); - apm_hal_apm_ctrl_exception_clear(apm_excp_type); + apm_hal_get_exception_info(ctrl_info, &excp_info); + apm_hal_clear_exception_status(ctrl_info); int fault_core = esp_cpu_get_core_id(); - panic_print_rsn((const void *)frame, fault_core, esp_tee_apm_excp_type_to_str(excp_info.excp_type)); + panic_print_rsn((const void *)frame, fault_core, esp_tee_apm_excp_type_to_str(excp_info.type)); - tee_panic_print("Access addr: 0x%x | Mode: %s\n", excp_info.excp_addr, esp_tee_apm_excp_mode_to_str(excp_info.excp_mode)); - tee_panic_print("Module: %s | Path: %d\n", esp_tee_apm_excp_ctrl_to_str(excp_info.apm_path.apm_ctrl), excp_info.apm_path.apm_m_path); - tee_panic_print("Master: %s | Region: %d\n", esp_tee_apm_excp_mid_to_str(excp_info.excp_id), (excp_info.excp_regn == 0) ? 0 : (__builtin_ffs(excp_info.excp_regn) - 1)); + tee_panic_print("Access addr: 0x%x | Mode: %s\n", excp_info.addr, esp_tee_apm_excp_mode_to_str(excp_info.mode)); + tee_panic_print("Module: %s | Path: %d\n", esp_tee_apm_excp_ctrl_to_str(ctrl_info->ctrl_mod), ctrl_info->path); + tee_panic_print("Master: %s | Region: %d\n", esp_tee_apm_excp_mid_to_str(excp_info.id), (excp_info.regn == 0) ? 0 : (__builtin_ffs(excp_info.regn) - 1)); panic_print_info((const void *)frame, fault_core); ESP_INFINITE_LOOP(); diff --git a/components/esp_tee/subproject/main/soc/common/esp_tee_apm_intr.c b/components/esp_tee/subproject/main/soc/common/esp_tee_apm_intr.c index d6c4dea1db..744e5dd2d9 100644 --- a/components/esp_tee/subproject/main/soc/common/esp_tee_apm_intr.c +++ b/components/esp_tee/subproject/main/soc/common/esp_tee_apm_intr.c @@ -6,26 +6,42 @@ #include #include "soc/soc_caps.h" +#include "hal/apm_types.h" #include "esp_bit_defs.h" -#include "hal/apm_hal.h" -#include "hal/apm_ll.h" +#include "esp_tee.h" +#include "esp_tee_apm_intr.h" static const char *const excp_mid_strs[] = { - [APM_LL_MASTER_HPCORE] = "HPCORE", - [APM_LL_MASTER_LPCORE] = "LPCORE", - [APM_LL_MASTER_REGDMA] = "REGDMA", - [APM_LL_MASTER_SDIOSLV] = "SDIOSLV", - [APM_LL_MASTER_MODEM] = "MODEM", - [APM_LL_MASTER_MEM_MONITOR] = "MEM_MONITOR", - [APM_LL_MASTER_TRACE] = "TRACE", - [APM_LL_MASTER_GDMA_SPI2] = "GDMA_SPI2", - [APM_LL_MASTER_GDMA_UHCI0] = "GDMA_UHCI0", - [APM_LL_MASTER_GDMA_I2S0] = "GDMA_I2S0", - [APM_LL_MASTER_GDMA_AES] = "GDMA_AES", - [APM_LL_MASTER_GDMA_SHA] = "GDMA_SHA", - [APM_LL_MASTER_GDMA_ADC] = "GDMA_ADC", - [APM_LL_MASTER_GDMA_PARLIO] = "GDMA_PARLIO", + [APM_MASTER_HPCORE] = "HPCORE", +#if SOC_LP_CORE_SUPPORTED + [APM_MASTER_LPCORE] = "LPCORE", +#endif /* SOC_LP_CORE_SUPPORTED */ + [APM_MASTER_REGDMA] = "REGDMA", +#if SOC_SDIO_SLAVE_SUPPORTED + [APM_MASTER_SDIOSLV] = "SDIOSLV", +#endif /* SOC_SDIO_SLAVE_SUPPORTED */ + [APM_MASTER_MODEM] = "MODEM", + [APM_MASTER_MEM_MON] = "MEM_MONITOR", + [APM_MASTER_TRACE] = "TRACE", +#if SOC_SPIRAM_SUPPORTED + [APM_MASTER_PSRAM_MEM_MON] = "PSRAM_MEM_MONITOR", +#endif /* SOC_SPIRAM_SUPPORTED */ +#if SOC_GPSPI_SUPPORTED + [APM_MASTER_GDMA_GPSPI] = "GDMA_GPSPI", +#endif /* SOC_GPSPI_SUPPORTED */ +#if SOC_UHCI_SUPPORTED + [APM_MASTER_GDMA_UHCI] = "GDMA_UHCI", +#endif /* SOC_UHCI_SUPPORTED */ + [APM_MASTER_GDMA_I2S] = "GDMA_I2S", +#if SOC_AES_SUPPORTED + [APM_MASTER_GDMA_AES] = "GDMA_AES", +#endif /* SOC_AES_SUPPORTED */ + [APM_MASTER_GDMA_SHA] = "GDMA_SHA", + [APM_MASTER_GDMA_ADC] = "GDMA_ADC", +#if SOC_PARLIO_SUPPORTED + [APM_MASTER_GDMA_PARLIO] = "GDMA_PARLIO", +#endif /* SOC_PARLIO_SUPPORTED */ }; const char *esp_tee_apm_excp_mid_to_str(uint8_t mid) @@ -49,22 +65,27 @@ const char *esp_tee_apm_excp_type_to_str(uint8_t type) return excp_type; } -const char *esp_tee_apm_excp_ctrl_to_str(apm_ll_apm_ctrl_t apm_ctrl) +const char *esp_tee_apm_excp_ctrl_to_str(apm_ctrl_module_t ctrl_mod) { char *excp_ctrl = NULL; - switch (apm_ctrl) { + switch (ctrl_mod) { + case APM_CTRL_HP_APM: + excp_ctrl = "HP_APM"; + break; + case APM_CTRL_LP_APM: + excp_ctrl = "LP_APM"; + break; #if SOC_APM_LP_APM0_SUPPORTED - case LP_APM0_CTRL: + case APM_CTRL_LP_APM0: excp_ctrl = "LP_APM0"; break; #endif - case HP_APM_CTRL: - excp_ctrl = "HP_APM"; - break; - case LP_APM_CTRL: - excp_ctrl = "LP_APM"; +#if SOC_APM_CPU_APM_SUPPORTED + case APM_CTRL_CPU_APM: + excp_ctrl = "CPU_APM"; break; +#endif default: excp_ctrl = "Unknown"; break; @@ -78,14 +99,14 @@ const char *esp_tee_apm_excp_mode_to_str(uint8_t mode) char *excp_mode = NULL; switch (mode) { - case APM_LL_SECURE_MODE_TEE: - case APM_LL_SECURE_MODE_REE0: + case APM_SEC_MODE_TEE: + case APM_SEC_MODE_REE0: excp_mode = "REE0"; break; - case APM_LL_SECURE_MODE_REE1: + case APM_SEC_MODE_REE1: excp_mode = "REE1"; break; - case APM_LL_SECURE_MODE_REE2: + case APM_SEC_MODE_REE2: excp_mode = "REE2"; break; default: diff --git a/components/esp_tee/subproject/main/soc/common/include/esp_tee_apm_intr.h b/components/esp_tee/subproject/main/soc/common/include/esp_tee_apm_intr.h index 6019df64b3..23f4b88025 100644 --- a/components/esp_tee/subproject/main/soc/common/include/esp_tee_apm_intr.h +++ b/components/esp_tee/subproject/main/soc/common/include/esp_tee_apm_intr.h @@ -5,7 +5,7 @@ */ #pragma once -#include "hal/apm_hal.h" +#include "hal/apm_types.h" #ifdef __cplusplus extern "C" { @@ -15,7 +15,7 @@ const char *esp_tee_apm_excp_mid_to_str(uint8_t mid); const char *esp_tee_apm_excp_type_to_str(uint8_t type); -const char *esp_tee_apm_excp_ctrl_to_str(apm_ll_apm_ctrl_t apm_ctrl); +const char *esp_tee_apm_excp_ctrl_to_str(apm_ctrl_module_t apm_ctrl); const char *esp_tee_apm_excp_mode_to_str(uint8_t mode); diff --git a/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_apm_prot_cfg.c b/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_apm_prot_cfg.c index 352375467f..4dedbc6c17 100644 --- a/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_apm_prot_cfg.c +++ b/components/esp_tee/subproject/main/soc/esp32c6/esp_tee_apm_prot_cfg.c @@ -3,16 +3,22 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include "esp_log.h" -#include "esp_tee.h" -#include "esp_tee_intr.h" +#include -#include "hal/apm_hal.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "soc/spi_mem_reg.h" #include "soc/efuse_reg.h" #include "soc/pcr_reg.h" +#include "soc/apm_defs.h" +#include "hal/apm_types.h" +#include "hal/apm_hal.h" + +#include "esp_log.h" +#include "esp_tee.h" +#include "esp_tee_intr.h" + extern void tee_apm_violation_isr(void *arg); static const char *TAG = "esp_tee_apm_prot_cfg"; @@ -44,125 +50,6 @@ static const char *TAG = "esp_tee_apm_prot_cfg"; #define HP_APM_SPI1_REG_END HP_APM_SPI1_REG_START #endif -/*----------------------- HP APM range and filter configuration -----------------------*/ - -/* HP_APM: TEE mode accessible regions */ -apm_ctrl_region_config_data_t hp_apm_pms_data_tee[] = { - /* Region 0: Entire memory region (RWX)*/ - { - .regn_num = 0, - .regn_start_addr = 0x0, - .regn_end_addr = ~0x0, - .regn_pms = 0x7, - .filter_enable = 1, - }, -}; - -/* HP_APM: REE0 mode accessible regions */ -apm_ctrl_region_config_data_t hp_apm_pms_data[] = { - /* NOTE: Without this entry, the REE SRAM region becomes inaccessible to - * the MODEM master, resulting in an APM violation during Wi-Fi initialization. - */ - /* Region 1: REE SRAM region (RW) */ - { - .regn_num = 1, - .regn_start_addr = SOC_NS_IRAM_START, - .regn_end_addr = SOC_IRAM_HIGH, - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 2: RTC memory (RWX) */ - { - .regn_num = 2, - .regn_start_addr = SOC_RTC_IRAM_LOW, - .regn_end_addr = SOC_RTC_IRAM_HIGH, - .regn_pms = 0x7, - .filter_enable = 1, - }, - /* Region 3: Peripherals [Start - MMU] (RW) */ - /* Protected: MMU */ - { - .regn_num = 3, - .regn_start_addr = SOC_PERIPHERAL_LOW, - .regn_end_addr = (SPI_MEM_MMU_ITEM_CONTENT_REG(0) - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 4: Peripherals [MMU - SPI1] (RW) */ - /* Protected: SPI1 */ - { - .regn_num = 4, - .regn_start_addr = SPI_MEM_MMU_POWER_CTRL_REG(0), - .regn_end_addr = (HP_APM_SPI1_REG_START - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 5: Peripherals [SPI1 - Interrupt Matrix] (RW) */ - /* Protected: Interrupt Matrix */ - { - .regn_num = 5, - .regn_start_addr = HP_APM_SPI1_REG_END, - .regn_end_addr = (DR_REG_INTMTX_BASE - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 6/7: Peripherals [H/W Lock - HMAC] (RW) */ - /* Protected: AES, SHA, ECC, DS, HMAC */ - { - .regn_num = 6, - .regn_start_addr = DR_REG_ATOMIC_BASE, - .regn_end_addr = (DR_REG_AES_BASE - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - { - .regn_num = 7, - .regn_start_addr = DR_REG_RSA_BASE, - .regn_end_addr = (DR_REG_ECC_MULT_BASE - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 8/9/10: Peripherals [IO_MUX - TEE Controller & APM] (RW) */ - /* Protected: AES, SHA, ECC, DS and HMAC PCRs, APM, TEE Controller */ - { - .regn_num = 8, - .regn_start_addr = DR_REG_IO_MUX_BASE, - .regn_end_addr = (PCR_AES_CONF_REG - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - { - .regn_num = 9, - .regn_start_addr = PCR_RSA_CONF_REG, - .regn_end_addr = (PCR_ECC_CONF_REG - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - { - .regn_num = 10, - .regn_start_addr = PCR_IOMUX_CONF_REG, - .regn_end_addr = (DR_REG_TEE_BASE - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 11: Peripherals [Miscellaneous - PMU] (RW) */ - { - .regn_num = 11, - .regn_start_addr = DR_REG_MISC_BASE, - .regn_end_addr = (DR_REG_PMU_BASE - 0x04), - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 12: Peripherals [DEBUG - PWDET] (RW) */ - { - .regn_num = 12, - .regn_start_addr = DR_REG_OPT_DEBUG_BASE, - .regn_end_addr = 0x600D0000, - .regn_pms = 0x6, - .filter_enable = 1, - }, -}; - /* NOTE: Following are the master IDs for setting the security mode and access through APM: * +---------+-------------+ * | Bit | Source | @@ -189,177 +76,176 @@ apm_ctrl_region_config_data_t hp_apm_pms_data[] = { * +---------+-------------+ */ -/* HP_APM: TEE mode masters' configuration */ -apm_ctrl_secure_mode_config_t hp_apm_sec_mode_data_tee = { - .apm_ctrl = HP_APM_CTRL, - .apm_m_cnt = HP_APM_MAX_ACCESS_PATH, - .sec_mode = APM_LL_SECURE_MODE_TEE, - /* Crypto DMA (AES/SHA) and HP_CPU */ - .master_ids = 0xC00001, - .pms_data = hp_apm_pms_data_tee, +#define APM_MASTERS_ALL (0xFFFFFFFFU) +#define APM_MASTERS_HP_CPU (BIT(APM_MASTER_HPCORE)) +#define APM_MASTERS_LP_CPU (BIT(APM_MASTER_LPCORE)) +#define APM_MASTERS_GDMA_CRYPTO (BIT(APM_MASTER_GDMA_AES) | BIT(APM_MASTER_GDMA_SHA)) +#define APM_MASTERS_TEE (APM_MASTERS_HP_CPU | APM_MASTERS_GDMA_CRYPTO) +#define APM_MASTERS_REE (APM_MASTERS_ALL & ~(APM_MASTERS_TEE)) + +/*----------------------- TEE mode configuration -----------------------*/ + +/** + * NOTE: Fixes APM filter behavior to allow unrestricted access for TEE mode. + * + * By default, TEE mode should have unrestricted access to the entire CPU address space. + * However, it has been observed that when APM filters are enabled, TEE mode + * accesses are incorrectly being filtered based on the region configurations and + * access attributes set for REE[0..2] modes. + */ +static void enable_tee_mode_access(void) +{ + uint32_t regn_num = 0; + uint32_t regn_start_addr = 0x00; + uint32_t regn_end_addr = UINT32_MAX; + + /* HP_APM */ + apm_ll_hp_apm_set_region_start_addr(regn_num, regn_start_addr); + apm_ll_hp_apm_set_region_end_addr(regn_num, regn_end_addr); + apm_ll_hp_apm_enable_region_filter(regn_num, true); + /* LP_APM */ + apm_ll_lp_apm_set_region_start_addr(regn_num, regn_start_addr); + apm_ll_lp_apm_set_region_end_addr(regn_num, regn_end_addr); + apm_ll_lp_apm_enable_region_filter(regn_num, true); + /* LP_APM0 */ + apm_ll_lp_apm0_set_region_start_addr(regn_num, regn_start_addr); + apm_ll_lp_apm0_set_region_end_addr(regn_num, regn_end_addr); + apm_ll_lp_apm0_enable_region_filter(regn_num, true); +} + +/*----------------------- REE0 mode configuration -----------------------*/ + +/*----------------------- HP_APM configuration -----------------------*/ + +/* HP_APM: REE0 mode accessible regions */ +static apm_hal_ctrl_region_cfg_t hp_apm_regn_cfg_ree0[] = { + /* Region 1: CPU peripherals (RW) */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M0, 1, DR_REG_TRACE_BASE, 0x600D0000, APM_PERM_R | APM_PERM_W), + + /* NOTE: Without this entry, the REE SRAM region becomes inaccessible to + * the MODEM master, resulting in an APM violation during Wi-Fi initialization. + */ + /* Region 2: REE SRAM region (RW) - for all other masters except LP_CORE */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M1, 2, SOC_NS_IRAM_START, SOC_IRAM_HIGH, APM_PERM_R | APM_PERM_W), + /* Region 2: REE SRAM region (RW) - for all LP_CORE */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M2, 2, SOC_NS_IRAM_START, SOC_IRAM_HIGH, APM_PERM_R | APM_PERM_W), + + /* Region 3: Peripherals [Start - MMU] (RW) */ + /* Protected: MMU */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 3, SOC_PERIPHERAL_LOW, SPI_MEM_MMU_ITEM_CONTENT_REG(0), APM_PERM_R | APM_PERM_W), + + /* Region 4: Peripherals [MMU - SPI1] (RW) */ + /* Protected: SPI1 */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 4, SPI_MEM_MMU_POWER_CTRL_REG(0), HP_APM_SPI1_REG_START, APM_PERM_R | APM_PERM_W), + + /* Region 5: Peripherals [SPI1 - Interrupt Matrix] (RW) */ + /* Protected: Interrupt Matrix */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 5, HP_APM_SPI1_REG_END, DR_REG_INTMTX_BASE, APM_PERM_R | APM_PERM_W), + + /* Region 6/7: Peripherals [H/W Lock - HMAC] (RW) */ + /* Protected: AES, SHA, ECC, DS, HMAC */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 6, DR_REG_ATOMIC_BASE, DR_REG_AES_BASE, APM_PERM_R | APM_PERM_W), + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 7, DR_REG_RSA_BASE, DR_REG_ECC_MULT_BASE, APM_PERM_R | APM_PERM_W), + + /* Region 8/9/10: Peripherals [IO_MUX - TEE Controller & APM] (RW) */ + /* Protected: AES, SHA, ECC, DS and HMAC PCRs, APM, TEE Controller */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 8, DR_REG_IO_MUX_BASE, PCR_AES_CONF_REG, APM_PERM_R | APM_PERM_W), + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 9, PCR_RSA_CONF_REG, PCR_ECC_CONF_REG, APM_PERM_R | APM_PERM_W), + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 10, PCR_IOMUX_CONF_REG, DR_REG_TEE_BASE, APM_PERM_R | APM_PERM_W), + + /* Region 11: Peripherals [Miscellaneous - PMU] (RW) */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 11, DR_REG_MISC_BASE, DR_REG_PMU_BASE, APM_PERM_R | APM_PERM_W), }; /* HP_APM: REE0 mode masters' configuration */ -apm_ctrl_secure_mode_config_t hp_apm_sec_mode_data = { - .apm_ctrl = HP_APM_CTRL, - .apm_m_cnt = HP_APM_MAX_ACCESS_PATH, - .sec_mode = APM_LL_SECURE_MODE_REE0, - /* All masters except crypto DMA (AES/SHA) and HP CPU */ - .master_ids = 0xFF3FFFFE, - .pms_data = hp_apm_pms_data, -}; +static apm_hal_ctrl_sec_mode_cfg_t hp_apm_ctrl_sec_mode_cfg_ree0 = + APM_HAL_SEC_MODE_CFG(APM_CTRL_HP_APM, APM_SEC_MODE_REE0, hp_apm_regn_cfg_ree0); -/*----------------------- LP_APM0 range and filter configuration -----------------------*/ +/*----------------------- LP_APM configuration -----------------------*/ -/* LP_APM0: REE0 mode accessible regions */ -apm_ctrl_region_config_data_t lp_apm0_pms_data[] = { - /* Region 0: RTC memory (RWX) */ - { - .regn_num = 0, - .regn_start_addr = SOC_RTC_IRAM_LOW, - .regn_end_addr = SOC_RTC_IRAM_HIGH, - .regn_pms = 0x7, - .filter_enable = 1, - }, -}; - -/* LP_APM0: REE0 mode masters' configuration */ -apm_ctrl_secure_mode_config_t lp_apm0_sec_mode_data = { - .apm_ctrl = LP_APM0_CTRL, - .apm_m_cnt = LP_APM0_MAX_ACCESS_PATH, - .sec_mode = APM_LL_SECURE_MODE_REE0, - /* LP_CPU */ - .master_ids = 0x2, - .pms_data = lp_apm0_pms_data, -}; - -/*----------------------- LP_APM range and filter configuration -----------------------*/ - -/* LP_APM: TEE mode accessible regions */ -apm_ctrl_region_config_data_t lp_apm_pms_data_tee[] = { - /* Region 0: Entire memory region (RWX) */ - { - .regn_num = 0, - .regn_start_addr = 0x0, - .regn_end_addr = ~0x0, - .regn_pms = 0x7, - .filter_enable = 1, - }, -}; - -/* LP_APM: REE0 mode accessible regions */ -apm_ctrl_region_config_data_t lp_apm_pms_data[] = { +static apm_hal_ctrl_region_cfg_t lp_apm_regn_cfg_ree0[] = { /* Region 1: RTC memory (RWX) */ - { - .regn_num = 1, - .regn_start_addr = SOC_RTC_IRAM_LOW, - .regn_end_addr = SOC_RTC_IRAM_HIGH, - .regn_pms = 0x7, - .filter_enable = 1, - }, + /* NOTE: LP_MEM gets automatically remapped to an offset of 0x20000000 + * when accessed in low-speed mode */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M0, 1, SOC_RTC_IRAM_LOW + 0x20000000, SOC_RTC_IRAM_HIGH + 0x20000000, APM_PERM_ALL), + /* Region 2: LP Peripherals [PMU - eFuse BLK x] (RW) */ /* Protected: eFuse BLK x */ - { - .regn_num = 2, - .regn_start_addr = DR_REG_PMU_BASE, - .regn_end_addr = (LP_APM_EFUSE_REG_START - 0x04), - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 3: LP Peripherals [eFuse - END] (RW) */ - { - .regn_num = 3, - .regn_start_addr = LP_APM_EFUSE_REG_END, - .regn_end_addr = (DR_REG_TRACE_BASE - 0x04), - .regn_pms = 0x6, - .filter_enable = 1, - }, -}; + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M1, 2, DR_REG_PMU_BASE, LP_APM_EFUSE_REG_START, APM_PERM_R | APM_PERM_W), -/* LP_APM0: TEE mode masters' configuration */ -apm_ctrl_secure_mode_config_t lp_apm_sec_mode_data_tee = { - .apm_ctrl = LP_APM_CTRL, - .apm_m_cnt = LP_APM_MAX_ACCESS_PATH, - .sec_mode = APM_LL_SECURE_MODE_TEE, - /* HP_CPU and LP_CPU */ - .master_ids = 0x3, - .pms_data = lp_apm_pms_data_tee, + /* Region 3: LP Peripherals [eFuse - END] (RW) */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M1, 3, LP_APM_EFUSE_REG_END, DR_REG_TRACE_BASE, APM_PERM_R | APM_PERM_W), }; /* LP_APM: REE0 mode masters' configuration */ -apm_ctrl_secure_mode_config_t lp_apm_sec_mode_data = { - .apm_ctrl = LP_APM_CTRL, - .apm_m_cnt = LP_APM_MAX_ACCESS_PATH, - .sec_mode = APM_LL_SECURE_MODE_REE0, - /* HP_CPU and LP_CPU */ - .master_ids = 0x3, - .pms_data = lp_apm_pms_data, +static apm_hal_ctrl_sec_mode_cfg_t lp_apm_ctrl_sec_mode_cfg_ree0 = + APM_HAL_SEC_MODE_CFG(APM_CTRL_LP_APM, APM_SEC_MODE_REE0, lp_apm_regn_cfg_ree0); + +/*----------------------- LP_APM0 configuration -----------------------*/ + +/* LP_APM0: REE0 mode accessible regions */ +static apm_hal_ctrl_region_cfg_t lp_apm0_regn_cfg_ree0[] = { + /* Region 0: RTC memory (RWX) */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M0, 1, SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH, APM_PERM_ALL), }; +/* LP_APM0: REE0 mode masters' configuration */ +static apm_hal_ctrl_sec_mode_cfg_t lp_apm0_ctrl_sec_mode_cfg_ree0 = + APM_HAL_SEC_MODE_CFG(APM_CTRL_LP_APM0, APM_SEC_MODE_REE0, lp_apm0_regn_cfg_ree0); + /*---------------- TEE APM API-----------------------*/ -void esp_tee_apm_int_enable(apm_ctrl_secure_mode_config_t *sec_mode_data) +static void enable_apm_intr(apm_ctrl_module_t ctrl_mod, uint32_t path_count) { - for (int i = 0; i < sec_mode_data->apm_m_cnt; i++) { - apm_ctrl_path_t *apm_excp_data = calloc(1, sizeof(apm_ctrl_path_t)); - assert(apm_excp_data != NULL); + for (uint32_t i = 0; i < path_count; i++) { + apm_hal_ctrl_info_t *ctrl_info = calloc(1, sizeof(apm_hal_ctrl_info_t)); + assert(ctrl_info != NULL); - apm_excp_data->apm_ctrl = sec_mode_data->apm_ctrl; - apm_excp_data->apm_m_path = i; + ctrl_info->ctrl_mod = ctrl_mod; + ctrl_info->path = i; - int intr_src_num = apm_hal_apm_ctrl_get_int_src_num(apm_excp_data); + int intr_src_num = apm_hal_get_intr_src_num(ctrl_info); struct vector_desc_t apm_vd = {0}; apm_vd.source = intr_src_num; apm_vd.isr = tee_apm_violation_isr; - apm_vd.arg = (void *)apm_excp_data; + apm_vd.arg = (void *)ctrl_info; /* Register interrupt handler with TEE. */ esp_tee_intr_register((void *)&apm_vd); - /* Enable APM Ctrl intewrrupt for access path(M[0:n]) */ - apm_hal_apm_ctrl_exception_clear(apm_excp_data); - apm_hal_apm_ctrl_interrupt_enable(apm_excp_data, true); + /* Enable APM Ctrl interrupt for access path(M[0:n]) */ + apm_hal_clear_exception_status(ctrl_info); + apm_hal_enable_intr(ctrl_info, true); } } void esp_tee_configure_apm_protection(void) { /* Disable all control filter first to have full access of address rage. */ - apm_hal_apm_ctrl_filter_enable_all(false); + apm_hal_enable_ctrl_filter_all(false); - /* Switch HP_CPU to TEE mode */ - apm_tee_hal_set_master_secure_mode(HP_APM_CTRL, APM_LL_MASTER_HPCORE, APM_LL_SECURE_MODE_TEE); + /* Enable TEE mode access for all APM modules */ + enable_tee_mode_access(); - /* LP APM0 configuration. */ - lp_apm0_sec_mode_data.regn_count = sizeof(lp_apm0_pms_data) / sizeof(apm_ctrl_region_config_data_t); - apm_hal_apm_ctrl_master_sec_mode_config(&lp_apm0_sec_mode_data); + /* HP_APM REE0 configuration. */ + apm_hal_set_ctrl_sec_mode_cfg(&hp_apm_ctrl_sec_mode_cfg_ree0); + /* HP_APM interrupt configuration. */ + enable_apm_intr(APM_CTRL_HP_APM, APM_CTRL_HP_APM_PATH_NUM); + ESP_LOGD(TAG, "[HP_APM] Configured for REE0"); - /* LP APM0 interrupt configuration. */ - esp_tee_apm_int_enable(&lp_apm0_sec_mode_data); - ESP_LOGD(TAG, "[REE0] LP_APM0 configured"); + /* LP_APM REE0 configuration. */ + apm_hal_set_ctrl_sec_mode_cfg(&lp_apm_ctrl_sec_mode_cfg_ree0); + /* LP_APM interrupt configuration. */ + enable_apm_intr(APM_CTRL_LP_APM, APM_CTRL_LP_APM_PATH_NUM); + ESP_LOGD(TAG, "[LP_APM] Configured for REE0"); - /* LP APM TEE configuration. */ - lp_apm_sec_mode_data_tee.regn_count = sizeof(lp_apm_pms_data_tee) / sizeof(apm_ctrl_region_config_data_t); - apm_hal_apm_ctrl_master_sec_mode_config(&lp_apm_sec_mode_data_tee); - ESP_LOGD(TAG, "[TEE] LP_APM configured"); + /* LP_APM0 REE0 configuration. */ + apm_hal_set_ctrl_sec_mode_cfg(&lp_apm0_ctrl_sec_mode_cfg_ree0); + enable_apm_intr(APM_CTRL_LP_APM0, APM_CTRL_LP_APM0_PATH_NUM); + ESP_LOGD(TAG, "[LP_APM0] Configured for REE0"); - /* LP APM configuration. */ - lp_apm_sec_mode_data.regn_count = sizeof(lp_apm_pms_data) / sizeof(apm_ctrl_region_config_data_t); - apm_hal_apm_ctrl_master_sec_mode_config(&lp_apm_sec_mode_data); - /* LP APM interrupt configuration. */ - esp_tee_apm_int_enable(&lp_apm_sec_mode_data); - ESP_LOGD(TAG, "[REE0] LP_APM configured"); - - /* HP APM TEE configuration. */ - hp_apm_sec_mode_data_tee.regn_count = sizeof(hp_apm_pms_data_tee) / sizeof(apm_ctrl_region_config_data_t); - apm_hal_apm_ctrl_master_sec_mode_config(&hp_apm_sec_mode_data_tee); - ESP_LOGD(TAG, "[TEE] HP_APM configured"); - - /* HP APM configuration. */ - hp_apm_sec_mode_data.regn_count = sizeof(hp_apm_pms_data) / sizeof(apm_ctrl_region_config_data_t); - apm_hal_apm_ctrl_master_sec_mode_config(&hp_apm_sec_mode_data); - /* HP APM interrupt configuration. */ - esp_tee_apm_int_enable(&hp_apm_sec_mode_data); - ESP_LOGD(TAG, "[REE0] HP_APM configured"); + /* Switch HP_CPU to TEE mode and rest of the masters to REE0 mode */ + apm_hal_set_master_sec_mode(APM_MASTERS_TEE, APM_SEC_MODE_TEE); + apm_hal_set_master_sec_mode(APM_MASTERS_REE, APM_SEC_MODE_REE0); } diff --git a/components/esp_tee/subproject/main/soc/esp32h2/esp_tee_apm_prot_cfg.c b/components/esp_tee/subproject/main/soc/esp32h2/esp_tee_apm_prot_cfg.c index af5472b4b5..582cb4700d 100644 --- a/components/esp_tee/subproject/main/soc/esp32h2/esp_tee_apm_prot_cfg.c +++ b/components/esp_tee/subproject/main/soc/esp32h2/esp_tee_apm_prot_cfg.c @@ -3,16 +3,22 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include "esp_log.h" -#include "esp_tee.h" -#include "esp_tee_intr.h" +#include -#include "hal/apm_hal.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "soc/spi_mem_reg.h" #include "soc/efuse_reg.h" #include "soc/pcr_reg.h" +#include "soc/apm_defs.h" +#include "hal/apm_types.h" +#include "hal/apm_hal.h" + +#include "esp_log.h" +#include "esp_tee.h" +#include "esp_tee_intr.h" + extern void tee_apm_violation_isr(void *arg); static const char *TAG = "esp_tee_apm_prot_cfg"; @@ -44,125 +50,6 @@ static const char *TAG = "esp_tee_apm_prot_cfg"; #define HP_APM_SPI1_REG_END HP_APM_SPI1_REG_START #endif -/*----------------------- HP APM range and filter configuration -----------------------*/ - -/* HP_APM: TEE mode accessible regions */ -apm_ctrl_region_config_data_t hp_apm_pms_data_tee[] = { - /* Region 0: Entire memory region (RWX)*/ - { - .regn_num = 0, - .regn_start_addr = 0x0, - .regn_end_addr = ~0x0, - .regn_pms = 0x7, - .filter_enable = 1, - }, -}; - -/* HP_APM: REE0 mode accessible regions */ -apm_ctrl_region_config_data_t hp_apm_pms_data[] = { - /* NOTE: Without this entry, the REE SRAM region becomes inaccessible to - * the MODEM master, resulting in an APM violation during Wi-Fi initialization. - */ - /* Region 1: REE SRAM region (RW) */ - { - .regn_num = 1, - .regn_start_addr = SOC_NS_IRAM_START, - .regn_end_addr = SOC_IRAM_HIGH, - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 2: RTC memory (RWX) */ - { - .regn_num = 2, - .regn_start_addr = SOC_RTC_IRAM_LOW, - .regn_end_addr = SOC_RTC_IRAM_HIGH, - .regn_pms = 0x7, - .filter_enable = 1, - }, - /* Region 3: Peripherals [Start - MMU] (RW) */ - /* Protected: MMU */ - { - .regn_num = 3, - .regn_start_addr = SOC_PERIPHERAL_LOW, - .regn_end_addr = (SPI_MEM_MMU_ITEM_CONTENT_REG(0) - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 4: Peripherals [MMU - SPI1] (RW) */ - /* Protected: SPI1 */ - { - .regn_num = 4, - .regn_start_addr = SPI_MEM_MMU_POWER_CTRL_REG(0), - .regn_end_addr = (HP_APM_SPI1_REG_START - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 5: Peripherals [SPI1 - Interrupt Matrix] (RW) */ - /* Protected: Interrupt Matrix */ - { - .regn_num = 5, - .regn_start_addr = HP_APM_SPI1_REG_END, - .regn_end_addr = (DR_REG_INTMTX_BASE - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 6/7: Peripherals [H/W Lock - HMAC] (RW) */ - /* Protected: AES, SHA, ECC, DS, HMAC */ - { - .regn_num = 6, - .regn_start_addr = DR_REG_PCNT_BASE, - .regn_end_addr = (DR_REG_AES_BASE - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - { - .regn_num = 7, - .regn_start_addr = DR_REG_RSA_BASE, - .regn_end_addr = (DR_REG_ECC_MULT_BASE - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 8/9/10: Peripherals [IO_MUX - TEE Controller & APM] (RW) */ - /* Protected: AES, SHA, ECC, DS and HMAC PCRs, APM, TEE Controller */ - { - .regn_num = 8, - .regn_start_addr = DR_REG_ECDSA_BASE, - .regn_end_addr = (PCR_AES_CONF_REG - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - { - .regn_num = 9, - .regn_start_addr = PCR_RSA_CONF_REG, - .regn_end_addr = (PCR_ECC_CONF_REG - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - { - .regn_num = 10, - .regn_start_addr = PCR_ECDSA_CONF_REG, - .regn_end_addr = (DR_REG_TEE_BASE - 0x4), - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 11: Peripherals [Miscellaneous - PMU] (RW) */ - { - .regn_num = 11, - .regn_start_addr = DR_REG_MISC_BASE, - .regn_end_addr = (DR_REG_PMU_BASE - 0x04), - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 12: Peripherals [DEBUG - PWDET] (RW) */ - { - .regn_num = 12, - .regn_start_addr = DR_REG_TRACE_BASE, - .regn_end_addr = 0x600D0000, - .regn_pms = 0x6, - .filter_enable = 1, - }, -}; - /* NOTE: Following are the master IDs for setting the security mode and access through APM: * +---------+-------------+ * | Bit | Source | @@ -189,115 +76,154 @@ apm_ctrl_region_config_data_t hp_apm_pms_data[] = { * +---------+-------------+ */ -/* HP_APM: TEE mode masters' configuration */ -apm_ctrl_secure_mode_config_t hp_apm_sec_mode_data_tee = { - .apm_ctrl = HP_APM_CTRL, - .apm_m_cnt = HP_APM_MAX_ACCESS_PATH, - .sec_mode = APM_LL_SECURE_MODE_TEE, - /* Crypto DMA (AES/SHA) and HP_CPU */ - .master_ids = 0xC00001, - .pms_data = hp_apm_pms_data_tee, +#define APM_MASTERS_ALL (0xFFFFFFFFU) +#define APM_MASTERS_HP_CPU (BIT(APM_MASTER_HPCORE)) +#define APM_MASTERS_LP_CPU (BIT(APM_MASTER_LPCORE)) +#define APM_MASTERS_GDMA_CRYPTO (BIT(APM_MASTER_GDMA_AES) | BIT(APM_MASTER_GDMA_SHA)) +#define APM_MASTERS_TEE (APM_MASTERS_HP_CPU | APM_MASTERS_GDMA_CRYPTO) +#define APM_MASTERS_REE (APM_MASTERS_ALL & ~(APM_MASTERS_TEE)) + +/*----------------------- TEE mode configuration -----------------------*/ + +/** + * NOTE: Fixes APM filter behavior to allow unrestricted access for TEE mode. + * + * By default, TEE mode should have unrestricted access to the entire CPU address space. + * However, it has been observed that when APM filters are enabled, TEE mode + * accesses are incorrectly being filtered based on the region configurations and + * access attributes set for REE[0..2] modes. + */ +static void enable_tee_mode_access(void) +{ + uint32_t regn_num = 0; + uint32_t regn_start_addr = 0x00; + uint32_t regn_end_addr = UINT32_MAX; + + /* HP_APM */ + apm_ll_hp_apm_set_region_start_addr(regn_num, regn_start_addr); + apm_ll_hp_apm_set_region_end_addr(regn_num, regn_end_addr); + apm_ll_hp_apm_enable_region_filter(regn_num, true); +} + +/*----------------------- REE0 mode configuration -----------------------*/ + +/*----------------------- HP_APM configuration -----------------------*/ + +/* HP_APM: REE0 mode accessible regions */ +static apm_hal_ctrl_region_cfg_t hp_apm_regn_cfg_ree0[] = { + /* Region 1: CPU peripherals (RW) */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M0, 1, DR_REG_TRACE_BASE, 0x600D0000, APM_PERM_R | APM_PERM_W), + + /* Region 2: RTC memory (RWX) */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M1, 2, SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH, APM_PERM_ALL), + + /* NOTE: Without this entry, the REE SRAM region becomes inaccessible to + * the MODEM master, resulting in an APM violation during Wi-Fi initialization. + */ + /* Region 3: REE SRAM region (RW) */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M2, 3, SOC_NS_IRAM_START, SOC_IRAM_HIGH, APM_PERM_R | APM_PERM_W), + + /* Region 4: Peripherals [Start - MMU] (RW) */ + /* Protected: MMU */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 4, SOC_PERIPHERAL_LOW, SPI_MEM_MMU_ITEM_CONTENT_REG(0), APM_PERM_R | APM_PERM_W), + + /* Region 5: Peripherals [MMU - SPI1] (RW) */ + /* Protected: SPI1 */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 5, SPI_MEM_MMU_POWER_CTRL_REG(0), HP_APM_SPI1_REG_START, APM_PERM_R | APM_PERM_W), + + /* Region 6: Peripherals [SPI1 - Interrupt Matrix] (RW) */ + /* Protected: Interrupt Matrix */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 6, HP_APM_SPI1_REG_END, DR_REG_INTMTX_BASE, APM_PERM_R | APM_PERM_W), + + /* Region 7/8: Peripherals [PCNT - HMAC] (RW) */ + /* Protected: AES, SHA, ECC, DS, HMAC */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 7, DR_REG_PCNT_BASE, DR_REG_AES_BASE, APM_PERM_R | APM_PERM_W), + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 8, DR_REG_RSA_BASE, DR_REG_ECC_MULT_BASE, APM_PERM_R | APM_PERM_W), + + /* Region 8/9/10: Peripherals [ECDSA - TEE Controller & APM] (RW) */ + /* Protected: AES, SHA, ECC, DS and HMAC PCRs, APM, TEE Controller */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 9, DR_REG_ECDSA_BASE, PCR_AES_CONF_REG, APM_PERM_R | APM_PERM_W), + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 10, PCR_RSA_CONF_REG, PCR_ECC_CONF_REG, APM_PERM_R | APM_PERM_W), + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 11, PCR_ECDSA_CONF_REG, DR_REG_TEE_BASE, APM_PERM_R | APM_PERM_W), + + /* Region 11: Peripherals [Miscellaneous - PMU] (RW) */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 12, DR_REG_MISC_BASE, DR_REG_PMU_BASE, APM_PERM_R | APM_PERM_W), }; /* HP_APM: REE0 mode masters' configuration */ -apm_ctrl_secure_mode_config_t hp_apm_sec_mode_data = { - .apm_ctrl = HP_APM_CTRL, - .apm_m_cnt = HP_APM_MAX_ACCESS_PATH, - .sec_mode = APM_LL_SECURE_MODE_REE0, - /* All masters except crypto DMA (AES/SHA) and HP CPU */ - .master_ids = 0xFF3FFFFE, - .pms_data = hp_apm_pms_data, -}; +static apm_hal_ctrl_sec_mode_cfg_t hp_apm_ctrl_sec_mode_cfg_ree0 = + APM_HAL_SEC_MODE_CFG(APM_CTRL_HP_APM, APM_SEC_MODE_REE0, hp_apm_regn_cfg_ree0); -/*----------------------- LP_APM range and filter configuration -----------------------*/ +/*----------------------- LP_APM configuration -----------------------*/ /* NOTE: Due to ESP32-H2's limited LP_APM module regions, neither TEE nor REE can directly * access the protected eFuse region. However, since the HMAC peripheral can access the * key stored in eFuse for TEE secure storage, this access restriction does not impact * functionality. */ -/* LP_APM: REE0 mode accessible regions */ -apm_ctrl_region_config_data_t lp_apm_pms_data[] = { +static apm_hal_ctrl_region_cfg_t lp_apm_regn_cfg_ree0[] = { /* Region 0: LP Peripherals [PMU - eFuse BLK x] (RW) */ /* Protected: eFuse BLK x */ - { - .regn_num = 0, - .regn_start_addr = DR_REG_PMU_BASE, - .regn_end_addr = (LP_APM_EFUSE_REG_START - 0x04), - .regn_pms = 0x6, - .filter_enable = 1, - }, - /* Region 1: LP Peripherals [eFuse - END] (RW) */ - { - .regn_num = 1, - .regn_start_addr = LP_APM_EFUSE_REG_END, - .regn_end_addr = (DR_REG_TRACE_BASE - 0x04), - .regn_pms = 0x6, - .filter_enable = 1, - }, -}; + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M0, 0, DR_REG_PMU_BASE, LP_APM_EFUSE_REG_START, APM_PERM_R | APM_PERM_W), -/* LP_APM: REE0 mode masters' configuration */ -apm_ctrl_secure_mode_config_t lp_apm_sec_mode_data = { - .apm_ctrl = LP_APM_CTRL, - .apm_m_cnt = LP_APM_MAX_ACCESS_PATH, - .sec_mode = APM_LL_SECURE_MODE_REE0, - /* HP_CPU */ - .master_ids = 0x1, - .pms_data = lp_apm_pms_data, + /* Region 1: LP Peripherals [eFuse - END] (RW) */ + APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M0, 1, LP_APM_EFUSE_REG_END, DR_REG_TRACE_BASE, APM_PERM_R | APM_PERM_W), }; /*---------------- TEE APM API-----------------------*/ -void esp_tee_apm_int_enable(apm_ctrl_secure_mode_config_t *sec_mode_data) +static void enable_apm_intr(apm_ctrl_module_t ctrl_mod, uint32_t path_count) { - for (int i = 0; i < sec_mode_data->apm_m_cnt; i++) { - apm_ctrl_path_t *apm_excp_data = calloc(1, sizeof(apm_ctrl_path_t)); - assert(apm_excp_data != NULL); + for (uint32_t i = 0; i < path_count; i++) { + apm_hal_ctrl_info_t *ctrl_info = calloc(1, sizeof(apm_hal_ctrl_info_t)); + assert(ctrl_info != NULL); - apm_excp_data->apm_ctrl = sec_mode_data->apm_ctrl; - apm_excp_data->apm_m_path = i; + ctrl_info->ctrl_mod = ctrl_mod; + ctrl_info->path = i; - int intr_src_num = apm_hal_apm_ctrl_get_int_src_num(apm_excp_data); + int intr_src_num = apm_hal_get_intr_src_num(ctrl_info); struct vector_desc_t apm_vd = {0}; apm_vd.source = intr_src_num; apm_vd.isr = tee_apm_violation_isr; - apm_vd.arg = (void *)apm_excp_data; + apm_vd.arg = (void *)ctrl_info; /* Register interrupt handler with TEE. */ esp_tee_intr_register((void *)&apm_vd); - /* Enable APM Ctrl intewrrupt for access path(M[0:n]) */ - apm_hal_apm_ctrl_exception_clear(apm_excp_data); - apm_hal_apm_ctrl_interrupt_enable(apm_excp_data, true); + /* Enable APM Ctrl interrupt for access path(M[0:n]) */ + apm_hal_clear_exception_status(ctrl_info); + apm_hal_enable_intr(ctrl_info, true); } } void esp_tee_configure_apm_protection(void) { /* Disable all control filter first to have full access of address rage. */ - apm_hal_apm_ctrl_filter_enable_all(false); + apm_hal_enable_ctrl_filter_all(false); - /* Switch HP_CPU to TEE mode */ - apm_tee_hal_set_master_secure_mode(HP_APM_CTRL, APM_LL_MASTER_HPCORE, APM_LL_SECURE_MODE_TEE); + /* Enable TEE mode access for all APM modules */ + enable_tee_mode_access(); - /* LP APM TEE configuration. */ - lp_apm_sec_mode_data.regn_count = sizeof(lp_apm_pms_data) / sizeof(apm_ctrl_region_config_data_t); - apm_hal_apm_ctrl_master_sec_mode_config(&lp_apm_sec_mode_data); - /* LP APM interrupt configuration. */ - esp_tee_apm_int_enable(&lp_apm_sec_mode_data); - ESP_LOGD(TAG, "[REE0] LP_APM configured"); + /* HP_APM REE0 configuration. */ + apm_hal_set_ctrl_sec_mode_cfg(&hp_apm_ctrl_sec_mode_cfg_ree0); + /* HP_APM interrupt configuration. */ + enable_apm_intr(APM_CTRL_HP_APM, APM_CTRL_HP_APM_PATH_NUM); + ESP_LOGD(TAG, "[HP_APM] Configured for REE0"); - /* HP APM TEE configuration. */ - hp_apm_sec_mode_data_tee.regn_count = sizeof(hp_apm_pms_data_tee) / sizeof(apm_ctrl_region_config_data_t); - apm_hal_apm_ctrl_master_sec_mode_config(&hp_apm_sec_mode_data_tee); - ESP_LOGD(TAG, "[TEE] HP_APM configured"); + /* LP_APM REE0 configuration. */ + size_t regn_count = sizeof(lp_apm_regn_cfg_ree0) / sizeof(lp_apm_regn_cfg_ree0[0]); + for (uint32_t regn_idx = 0; regn_idx < regn_count; regn_idx++) { + const apm_hal_ctrl_region_cfg_t *region = &lp_apm_regn_cfg_ree0[regn_idx]; + apm_hal_set_region_filter_cfg(APM_CTRL_LP_APM, APM_SEC_MODE_REE0, region); + apm_hal_enable_region_filter(APM_CTRL_LP_APM, region->regn_num, region->filter_en); + } + apm_hal_enable_ctrl_filter(APM_CTRL_LP_APM, APM_CTRL_ACCESS_PATH_M0, true); + /* LP_APM interrupt configuration. */ + enable_apm_intr(APM_CTRL_LP_APM, APM_CTRL_LP_APM_PATH_NUM); + ESP_LOGD(TAG, "[LP_APM] Configured for REE0"); - /* HP APM configuration. */ - hp_apm_sec_mode_data.regn_count = sizeof(hp_apm_pms_data) / sizeof(apm_ctrl_region_config_data_t); - apm_hal_apm_ctrl_master_sec_mode_config(&hp_apm_sec_mode_data); - /* HP APM interrupt configuration. */ - esp_tee_apm_int_enable(&hp_apm_sec_mode_data); - ESP_LOGD(TAG, "[REE0] HP_APM configured"); + /* Switch HP_CPU to TEE mode and rest of the masters to REE0 mode */ + apm_hal_set_master_sec_mode(APM_MASTERS_TEE, APM_SEC_MODE_TEE); + apm_hal_set_master_sec_mode(APM_MASTERS_REE, APM_SEC_MODE_REE0); } diff --git a/components/hal/apm_hal.c b/components/hal/apm_hal.c index e82f491f5e..20325ad8ca 100644 --- a/components/hal/apm_hal.c +++ b/components/hal/apm_hal.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include "hal/assert.h" #include "hal/apm_hal.h" #include "hal/apm_ll.h" @@ -53,192 +54,398 @@ void apm_hal_dma_region_pms(apm_hal_dma_region_config_data_t *pms_data) } #else -void apm_tee_hal_set_master_secure_mode(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_master_id_t master_id, apm_ll_secure_mode_t sec_mode) +void apm_hal_set_master_sec_mode(uint32_t master_mask, apm_security_mode_t mode) { - apm_tee_ll_set_master_secure_mode(apm_ctrl, master_id, sec_mode); -} - -void apm_tee_hal_set_master_secure_mode_all(apm_ll_secure_mode_t sec_mode) -{ - for (int i = 0; i < APM_LL_MASTER_MAX; i++) { - apm_tee_hal_set_master_secure_mode(HP_APM_CTRL, i, sec_mode); - } -#if SOC_LP_CORE_SUPPORTED - apm_tee_hal_set_master_secure_mode(LP_APM_CTRL, APM_LL_MASTER_LPCORE, sec_mode); -#endif -} - -void apm_tee_hal_clk_gating_enable(bool enable) -{ - apm_tee_ll_clk_gating_enable(enable); -} - -void apm_hal_apm_ctrl_region_filter_enable(apm_ll_apm_ctrl_t apm_ctrl, uint32_t regn_num, bool enable) -{ - apm_ll_apm_ctrl_region_filter_enable(apm_ctrl, regn_num, enable); -} - -void apm_hal_apm_ctrl_filter_enable(apm_ctrl_path_t *apm_path, bool enable) -{ - HAL_ASSERT(apm_path || -#if defined(SOC_APM_LP_APM0_SUPPORTED) - ((apm_path->apm_ctrl == LP_APM0_CTRL) && (apm_path->apm_m_path < LP_APM0_MAX_ACCESS_PATH)) || -#endif - ((apm_path->apm_ctrl == HP_APM_CTRL) && (apm_path->apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((apm_path->apm_ctrl == LP_APM_CTRL) && (apm_path->apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - - apm_ll_apm_ctrl_filter_enable(apm_path->apm_ctrl, apm_path->apm_m_path, enable); -} - -void apm_hal_apm_ctrl_filter_enable_all(bool enable) -{ - apm_ctrl_path_t apm_path; - - for (int i = 0; i < HP_APM_MAX_ACCESS_PATH; i++) { - apm_path.apm_ctrl = HP_APM_CTRL; - apm_path.apm_m_path = i; - apm_hal_apm_ctrl_filter_enable(&apm_path, enable); - } - for (int i = 0; i < LP_APM_MAX_ACCESS_PATH; i++) { - apm_path.apm_ctrl = LP_APM_CTRL; - apm_path.apm_m_path = i; - apm_hal_apm_ctrl_filter_enable(&apm_path, enable); - } -#if defined(SOC_APM_LP_APM0_SUPPORTED) - for (int i = 0; i < LP_APM0_MAX_ACCESS_PATH; i++) { - apm_path.apm_ctrl = LP_APM0_CTRL; - apm_path.apm_m_path = i; - apm_hal_apm_ctrl_filter_enable(&apm_path, enable); - } -#endif -} - -void apm_hal_apm_ctrl_region_config(const apm_ctrl_region_config_data_t *pms_data) -{ - HAL_ASSERT(pms_data || - (( -#if defined(SOC_APM_LP_APM0_SUPPORTED) - (pms_data->apm_ctrl == LP_APM0_CTRL) || -#endif - (pms_data->apm_ctrl == LP_APM_CTRL) - ) && - (pms_data->regn_num <= APM_LL_LP_MAX_REGION_NUM) - ) || - ((pms_data->apm_ctrl == HP_APM_CTRL) && (pms_data->regn_num <= APM_LL_HP_MAX_REGION_NUM)) - ); - - apm_ll_apm_ctrl_set_region_start_address(pms_data->apm_ctrl, pms_data->regn_num, pms_data->regn_start_addr); - apm_ll_apm_ctrl_set_region_end_address(pms_data->apm_ctrl, pms_data->regn_num, pms_data->regn_end_addr); - apm_ll_apm_ctrl_sec_mode_region_attr_config(pms_data->apm_ctrl, pms_data->regn_num, pms_data->sec_mode, pms_data->regn_pms); -} - -uint8_t apm_hal_apm_ctrl_exception_status(apm_ctrl_path_t *apm_path) -{ - HAL_ASSERT(apm_path || -#if defined(SOC_APM_LP_APM0_SUPPORTED) - ((apm_path->apm_ctrl == LP_APM0_CTRL) && (apm_path->apm_m_path < LP_APM0_MAX_ACCESS_PATH)) || -#endif - ((apm_path->apm_ctrl == HP_APM_CTRL) && (apm_path->apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((apm_path->apm_ctrl == LP_APM_CTRL) && (apm_path->apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - - return apm_ll_apm_ctrl_exception_status(apm_path->apm_ctrl, apm_path->apm_m_path); -} - -void apm_hal_apm_ctrl_exception_clear(apm_ctrl_path_t *apm_path) -{ - HAL_ASSERT(apm_path || -#if defined(SOC_APM_LP_APM0_SUPPORTED) - ((apm_path->apm_ctrl == LP_APM0_CTRL) && (apm_path->apm_m_path < LP_APM0_MAX_ACCESS_PATH)) || -#endif - ((apm_path->apm_ctrl == HP_APM_CTRL) && (apm_path->apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((apm_path->apm_ctrl == LP_APM_CTRL) && (apm_path->apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - - apm_ll_apm_ctrl_exception_clear(apm_path->apm_ctrl, apm_path->apm_m_path); -} - -void apm_hal_apm_ctrl_get_exception_info(apm_ctrl_exception_info_t *excp_info) -{ - HAL_ASSERT(excp_info || -#if defined(SOC_APM_LP_APM0_SUPPORTED) - ((excp_info->apm_path.apm_ctrl == LP_APM0_CTRL) && (excp_info->apm_path.apm_m_path < LP_APM0_MAX_ACCESS_PATH)) || -#endif - ((excp_info->apm_path.apm_ctrl == HP_APM_CTRL) && (excp_info->apm_path.apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((excp_info->apm_path.apm_ctrl == LP_APM_CTRL) && (excp_info->apm_path.apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - - apm_ll_apm_ctrl_get_exception_info(excp_info); -} - -void apm_hal_apm_ctrl_interrupt_enable(apm_ctrl_path_t *apm_path, bool enable) -{ - HAL_ASSERT(apm_path || -#if defined(SOC_APM_LP_APM0_SUPPORTED) - ((apm_path->apm_ctrl == LP_APM0_CTRL) && (apm_path->apm_m_path < LP_APM0_MAX_ACCESS_PATH)) || -#endif - ((apm_path->apm_ctrl == HP_APM_CTRL) && (apm_path->apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((apm_path->apm_ctrl == LP_APM_CTRL) && (apm_path->apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - - apm_ll_apm_ctrl_interrupt_enable(apm_path->apm_ctrl, apm_path->apm_m_path, enable); -} - -void apm_hal_apm_ctrl_clk_gating_enable(apm_ll_apm_ctrl_t apm_ctrl, bool enable) -{ - apm_ll_apm_ctrl_clk_gating_enable(apm_ctrl, enable); -} - -void apm_hal_apm_ctrl_master_sec_mode_config(apm_ctrl_secure_mode_config_t *sec_mode_data) -{ - apm_ctrl_path_t apm_path; - - /* Configure given secure mode for all specified Masters. */ - for (int i = 0; i < APM_LL_MASTER_MAX; i++) { - if (sec_mode_data->master_ids & (1 << i)) { - apm_tee_hal_set_master_secure_mode(sec_mode_data->apm_ctrl, i, sec_mode_data->sec_mode); + master_mask &= APM_MASTER_MASK_ALL; + while (master_mask) { + uint32_t master = __builtin_ctz(master_mask); + master_mask &= ~(1U << master); + apm_ll_hp_tee_set_master_sec_mode(master, mode); +#if SOC_APM_SUPPORT_LP_TEE_CTRL + if (master == APM_MASTER_LPCORE) { + apm_ll_lp_tee_set_master_sec_mode(master, mode); } - } - - /* Configure the given APM Ctrl for all Masters for the: - * - Secure mode, - * - Regions range, - * - access permissions and - * - region filter - */ - for (int i = 0; i < sec_mode_data->regn_count; i++) { - sec_mode_data->pms_data[i].sec_mode = sec_mode_data->sec_mode; - sec_mode_data->pms_data[i].apm_ctrl = sec_mode_data->apm_ctrl; - apm_hal_apm_ctrl_region_config(&sec_mode_data->pms_data[i]); - apm_hal_apm_ctrl_region_filter_enable(sec_mode_data->pms_data[i].apm_ctrl, - sec_mode_data->pms_data[i].regn_num, - sec_mode_data->pms_data[i].filter_enable); - } - - /* Configure APM Ctrl access path(M[0:n]) */ - for (int i = 0; i < sec_mode_data->apm_m_cnt; i++) { - apm_path.apm_ctrl = sec_mode_data->apm_ctrl; - apm_path.apm_m_path = i; - apm_hal_apm_ctrl_filter_enable(&apm_path, 1); - } -} - -void apm_hal_apm_ctrl_reset_event_enable(bool enable) -{ - apm_ll_apm_ctrl_reset_event_enable(enable); -} - -int apm_hal_apm_ctrl_get_int_src_num(apm_ctrl_path_t *apm_path) -{ - HAL_ASSERT(apm_path || -#if defined(SOC_APM_LP_APM0_SUPPORTED) - ((apm_path->apm_ctrl == LP_APM0_CTRL) && (apm_path->apm_m_path < LP_APM0_MAX_ACCESS_PATH)) || #endif - ((apm_path->apm_ctrl == HP_APM_CTRL) && (apm_path->apm_m_path < HP_APM_MAX_ACCESS_PATH)) || - ((apm_path->apm_ctrl == LP_APM_CTRL) && (apm_path->apm_m_path < LP_APM_MAX_ACCESS_PATH)) - ); - - return apm_ll_apm_ctrl_get_int_src_num(apm_path->apm_ctrl, apm_path->apm_m_path); + } } + +void apm_hal_set_master_sec_mode_all(apm_security_mode_t mode) +{ + apm_hal_set_master_sec_mode(APM_MASTER_MASK_ALL, mode); +} + +#if SOC_APM_SUPPORT_CTRL_CFG_LOCK +void apm_hal_lock_master_sec_mode(uint32_t master_mask) +{ + master_mask &= APM_MASTER_MASK_ALL; + while (master_mask) { + uint32_t master = __builtin_ctz(master_mask); + master_mask &= ~(1U << master); + apm_ll_hp_tee_lock_master_sec_mode(master); +#if SOC_APM_SUPPORT_LP_TEE_CTRL + if (master == APM_MASTER_LPCORE) { + apm_ll_lp_tee_lock_master_sec_mode(master); + } +#endif + } +} + +void apm_hal_lock_master_sec_mode_all(void) +{ + apm_hal_lock_master_sec_mode(APM_MASTER_MASK_ALL); +} +#endif + +#if SOC_APM_SUPPORT_TEE_PERI_ACCESS_CTRL +void apm_hal_tee_set_peri_access(apm_tee_ctrl_module_t ctrl_mod, uint64_t periph_mask, apm_security_mode_t mode, apm_perm_t pms) +{ + switch (ctrl_mod) { + case APM_TEE_CTRL_HP: + uint64_t hp_tee_peri_mask = periph_mask & APM_TEE_HP_PERIPH_MASK_ALL; + for (uint32_t periph = 0; periph < APM_TEE_HP_PERIPH_MAX; periph++) { + if (hp_tee_peri_mask & (1ULL << periph)) { + apm_ll_hp_tee_set_peri_access((apm_tee_hp_periph_t)periph, mode, pms); + } + } + apm_ll_hp_tee_enable_bus_err_resp(true); + break; +#if SOC_APM_SUPPORT_LP_TEE_CTRL + case APM_TEE_CTRL_LP: + uint32_t lp_tee_peri_mask = (uint32_t)periph_mask & (uint32_t)APM_TEE_LP_PERIPH_MASK_ALL; + while (lp_tee_peri_mask) { + uint32_t periph = __builtin_ctz(lp_tee_peri_mask); + apm_ll_lp_tee_set_peri_access((apm_tee_lp_periph_t)periph, mode, pms); + lp_tee_peri_mask &= ~(1U << periph); + } + apm_ll_lp_tee_enable_bus_err_resp(true); + break; +#endif + default: + break; + } +} + +void apm_hal_tee_set_peri_access_all(apm_tee_ctrl_module_t ctrl_mod, apm_security_mode_t mode, apm_perm_t pms) +{ + switch (ctrl_mod) { + case APM_TEE_CTRL_HP: + apm_hal_tee_set_peri_access(APM_TEE_CTRL_HP, (uint64_t)(APM_TEE_HP_PERIPH_MASK_ALL), mode, pms); + break; +#if SOC_APM_SUPPORT_LP_TEE_CTRL + case APM_TEE_CTRL_LP: + apm_hal_tee_set_peri_access(APM_TEE_CTRL_LP, (uint64_t)(APM_TEE_LP_PERIPH_MASK_ALL), mode, pms); + break; +#endif + default: + break; + } +} +#endif + +void apm_hal_tee_enable_clk_gating(apm_tee_ctrl_module_t ctrl_mod, bool enable) +{ + switch (ctrl_mod) { + case APM_TEE_CTRL_HP: + apm_ll_hp_tee_enable_clk_gating(enable); + break; +#if SOC_APM_SUPPORT_LP_TEE_CTRL + case APM_TEE_CTRL_LP: + apm_ll_lp_tee_enable_clk_gating(enable); + break; +#endif + default: + break; + } +} + +void apm_hal_enable_ctrl_filter(apm_ctrl_module_t ctrl_mod, apm_ctrl_access_path_t path, bool enable) +{ + switch (ctrl_mod) { + case APM_CTRL_HP_APM: + apm_ll_hp_apm_enable_ctrl_filter(path, enable); + break; +#if SOC_APM_LP_APM0_SUPPORTED + case APM_CTRL_LP_APM0: + apm_ll_lp_apm0_enable_ctrl_filter(path, enable); + break; +#endif + case APM_CTRL_LP_APM: + apm_ll_lp_apm_enable_ctrl_filter(path, enable); + break; +#if SOC_APM_CPU_APM_SUPPORTED + case APM_CTRL_CPU_APM: + apm_ll_cpu_apm_enable_ctrl_filter(path, enable); + break; +#endif + default: + break; + } +} + +void apm_hal_enable_ctrl_filter_all(bool enable) +{ + apm_ll_hp_apm_enable_ctrl_filter_all(enable); +#if SOC_APM_LP_APM0_SUPPORTED + apm_ll_lp_apm0_enable_ctrl_filter_all(enable); +#endif + apm_ll_lp_apm_enable_ctrl_filter_all(enable); +#if SOC_APM_CPU_APM_SUPPORTED + apm_ll_cpu_apm_enable_ctrl_filter_all(enable); +#endif +} + +void apm_hal_enable_region_filter(apm_ctrl_module_t ctrl_mod, uint32_t regn_num, bool enable) +{ + switch (ctrl_mod) { + case APM_CTRL_HP_APM: + apm_ll_hp_apm_enable_region_filter(regn_num, enable); + break; +#if SOC_APM_LP_APM0_SUPPORTED + case APM_CTRL_LP_APM0: + apm_ll_lp_apm0_enable_region_filter(regn_num, enable); + break; +#endif + case APM_CTRL_LP_APM: + apm_ll_lp_apm_enable_region_filter(regn_num, enable); + break; +#if SOC_APM_CPU_APM_SUPPORTED + case APM_CTRL_CPU_APM: + apm_ll_cpu_apm_enable_region_filter(regn_num, enable); + break; +#endif + default: + break; + } +} + +void apm_hal_set_region_filter_cfg(apm_ctrl_module_t ctrl_mod, apm_security_mode_t mode, const apm_hal_ctrl_region_cfg_t *regn_cfg) +{ + HAL_ASSERT(regn_cfg); + + switch (ctrl_mod) { + case APM_CTRL_HP_APM: + apm_ll_hp_apm_set_region_start_addr(regn_cfg->regn_num, regn_cfg->regn_start_addr); + apm_ll_hp_apm_set_region_end_addr(regn_cfg->regn_num, regn_cfg->regn_end_addr); + apm_ll_hp_apm_set_sec_mode_region_attr(regn_cfg->regn_num, mode, regn_cfg->regn_pms); + break; +#if SOC_APM_LP_APM0_SUPPORTED + case APM_CTRL_LP_APM0: + apm_ll_lp_apm0_set_region_start_addr(regn_cfg->regn_num, regn_cfg->regn_start_addr); + apm_ll_lp_apm0_set_region_end_addr(regn_cfg->regn_num, regn_cfg->regn_end_addr); + apm_ll_lp_apm0_set_sec_mode_region_attr(regn_cfg->regn_num, mode, regn_cfg->regn_pms); + break; +#endif + case APM_CTRL_LP_APM: + apm_ll_lp_apm_set_region_start_addr(regn_cfg->regn_num, regn_cfg->regn_start_addr); + apm_ll_lp_apm_set_region_end_addr(regn_cfg->regn_num, regn_cfg->regn_end_addr); + apm_ll_lp_apm_set_sec_mode_region_attr(regn_cfg->regn_num, mode, regn_cfg->regn_pms); + break; +#if SOC_APM_CPU_APM_SUPPORTED + case APM_CTRL_CPU_APM: + apm_ll_cpu_apm_set_region_start_addr(regn_cfg->regn_num, regn_cfg->regn_start_addr); + apm_ll_cpu_apm_set_region_end_addr(regn_cfg->regn_num, regn_cfg->regn_end_addr); + apm_ll_cpu_apm_set_sec_mode_region_attr(regn_cfg->regn_num, mode, regn_cfg->regn_pms); + break; +#endif + default: + break; + } +} + +#if SOC_APM_SUPPORT_CTRL_CFG_LOCK +void apm_hal_lock_region_filter_cfg(apm_ctrl_module_t ctrl_mod, uint32_t regn_num) +{ + switch (ctrl_mod) { + case APM_CTRL_HP_APM: + apm_ll_hp_apm_lock_sec_mode_region_attr(regn_num); + break; +#if SOC_APM_LP_APM0_SUPPORTED + case APM_CTRL_LP_APM0: + apm_ll_lp_apm0_lock_sec_mode_region_attr(regn_num); + break; +#endif + case APM_CTRL_LP_APM: + apm_ll_lp_apm_lock_sec_mode_region_attr(regn_num); + break; +#if SOC_APM_CPU_APM_SUPPORTED + case APM_CTRL_CPU_APM: + apm_ll_cpu_apm_lock_sec_mode_region_attr(regn_num); + break; +#endif + default: + break; + } +} +#endif + +void apm_hal_set_ctrl_sec_mode_cfg(const apm_hal_ctrl_sec_mode_cfg_t *cfg) +{ + HAL_ASSERT(cfg); + HAL_ASSERT(cfg->regions); + + for (uint32_t regn_idx = 0; regn_idx < cfg->regn_count; regn_idx++) { + const apm_hal_ctrl_region_cfg_t *region = &cfg->regions[regn_idx]; + apm_hal_set_region_filter_cfg(cfg->ctrl_mod, cfg->mode, region); + apm_hal_enable_region_filter(cfg->ctrl_mod, region->regn_num, region->filter_en); +#if SOC_APM_SUPPORT_CTRL_CFG_LOCK + if (region->lock_en) { + apm_hal_lock_region_filter_cfg(cfg->ctrl_mod, region->regn_num); + } +#endif + apm_hal_enable_ctrl_filter(cfg->ctrl_mod, region->path_id, true); + } +} + +uint32_t apm_hal_get_exception_type(apm_hal_ctrl_info_t *ctrl_info) +{ + HAL_ASSERT(ctrl_info); + + switch (ctrl_info->ctrl_mod) { + case APM_CTRL_HP_APM: + return apm_ll_hp_apm_get_excp_type(ctrl_info->path); +#if SOC_APM_LP_APM0_SUPPORTED + case APM_CTRL_LP_APM0: + return apm_ll_lp_apm0_get_excp_type(ctrl_info->path); +#endif + case APM_CTRL_LP_APM: + return apm_ll_lp_apm_get_excp_type(ctrl_info->path); +#if SOC_APM_CPU_APM_SUPPORTED + case APM_CTRL_CPU_APM: + return apm_ll_cpu_apm_get_excp_type(ctrl_info->path); +#endif + default: + return UINT8_MAX; + } +} + +void apm_hal_clear_exception_status(apm_hal_ctrl_info_t *ctrl_info) +{ + HAL_ASSERT(ctrl_info); + + switch (ctrl_info->ctrl_mod) { + case APM_CTRL_HP_APM: + apm_ll_hp_apm_clear_ctrl_excp_status(ctrl_info->path); + break; +#if SOC_APM_LP_APM0_SUPPORTED + case APM_CTRL_LP_APM0: + apm_ll_lp_apm0_clear_ctrl_excp_status(ctrl_info->path); + break; +#endif + case APM_CTRL_LP_APM: + apm_ll_lp_apm_clear_ctrl_excp_status(ctrl_info->path); + break; +#if SOC_APM_CPU_APM_SUPPORTED + case APM_CTRL_CPU_APM: + apm_ll_cpu_apm_clear_ctrl_excp_status(ctrl_info->path); + break; +#endif + default: + break; + } +} + +void apm_hal_get_exception_info(apm_hal_ctrl_info_t *ctrl_info, apm_ctrl_exception_info_t *excp_info) +{ + HAL_ASSERT(ctrl_info); + HAL_ASSERT(excp_info); + + switch (ctrl_info->ctrl_mod) { + case APM_CTRL_HP_APM: + apm_ll_hp_apm_get_excp_info(ctrl_info->path, excp_info); + break; +#if SOC_APM_LP_APM0_SUPPORTED + case APM_CTRL_LP_APM0: + apm_ll_lp_apm0_get_excp_info(ctrl_info->path, excp_info); + break; +#endif + case APM_CTRL_LP_APM: + apm_ll_lp_apm_get_excp_info(ctrl_info->path, excp_info); + break; +#if SOC_APM_CPU_APM_SUPPORTED + case APM_CTRL_CPU_APM: + apm_ll_cpu_apm_get_excp_info(ctrl_info->path, excp_info); + break; +#endif + default: + break; + } +} + +void apm_hal_enable_intr(apm_hal_ctrl_info_t *ctrl_info, bool enable) +{ + HAL_ASSERT(ctrl_info); + + switch (ctrl_info->ctrl_mod) { + case APM_CTRL_HP_APM: + apm_ll_hp_apm_enable_ctrl_intr(ctrl_info->path, enable); + break; +#if SOC_APM_LP_APM0_SUPPORTED + case APM_CTRL_LP_APM0: + apm_ll_lp_apm0_enable_ctrl_intr(ctrl_info->path, enable); + break; +#endif + case APM_CTRL_LP_APM: + apm_ll_lp_apm_enable_ctrl_intr(ctrl_info->path, enable); + break; +#if SOC_APM_CPU_APM_SUPPORTED + case APM_CTRL_CPU_APM: + apm_ll_cpu_apm_enable_ctrl_intr(ctrl_info->path, enable); + break; +#endif + default: + break; + } +} + +int apm_hal_get_intr_src_num(apm_hal_ctrl_info_t *ctrl_info) +{ + HAL_ASSERT(ctrl_info); + + switch (ctrl_info->ctrl_mod) { + case APM_CTRL_HP_APM: + return apm_ll_hp_apm_get_ctrl_intr_src(ctrl_info->path); +#if SOC_APM_LP_APM0_SUPPORTED + case APM_CTRL_LP_APM0: + return apm_ll_lp_apm0_get_ctrl_intr_src(ctrl_info->path); +#endif + case APM_CTRL_LP_APM: + return apm_ll_lp_apm_get_ctrl_intr_src(ctrl_info->path); +#if SOC_APM_CPU_APM_SUPPORTED + case APM_CTRL_CPU_APM: + return apm_ll_cpu_apm_get_ctrl_intr_src(ctrl_info->path); +#endif + default: + return -1; + } +} + +void apm_hal_enable_reset_event_bypass(bool enable) +{ + apm_ll_enable_reset_event_bypass(enable); +} + +void apm_hal_enable_ctrl_clk_gating(apm_ctrl_module_t ctrl_mod, bool enable) +{ + switch (ctrl_mod) { + case APM_CTRL_HP_APM: + apm_ll_hp_apm_enable_ctrl_clk_gating(enable); + break; +#if SOC_APM_LP_APM0_SUPPORTED + case APM_CTRL_LP_APM0: + apm_ll_lp_apm0_enable_ctrl_clk_gating(enable); + break; +#endif + case APM_CTRL_LP_APM: + apm_ll_lp_apm_enable_ctrl_clk_gating(enable); + break; +#if SOC_APM_CPU_APM_SUPPORTED + case APM_CTRL_CPU_APM: + apm_ll_cpu_apm_enable_ctrl_clk_gating(enable); + break; +#endif + default: + break; + } +} + #endif //CONFIG_IDF_TARGET_ESP32P4 diff --git a/components/hal/esp32c5/include/hal/apm_ll.h b/components/hal/esp32c5/include/hal/apm_ll.h index d735bb922a..f3176340dc 100644 --- a/components/hal/esp32c5/include/hal/apm_ll.h +++ b/components/hal/esp32c5/include/hal/apm_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,396 +7,952 @@ #include #include -#include "esp_err.h" -#include "soc/pcr_reg.h" + +#include "soc/apm_defs.h" #include "soc/tee_reg.h" #include "soc/lp_tee_reg.h" -#include "soc/lp_apm0_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/assert.h" +#include "hal/apm_types.h" #ifdef __cplusplus extern "C" { #endif -#define APM_LL_CTRL_EXCEPTION_ID 0x0000001FU -#define APM_LL_CTRL_EXCEPTION_ID_S 18 -#define APM_LL_CTRL_EXCEPTION_ID_V 0x0000001FU -#define APM_LL_CTRL_EXCEPTION_MODE 0x00000003U -#define APM_LL_CTRL_EXCEPTION_MODE_S 16 -#define APM_LL_CTRL_EXCEPTION_MODE_V 0x00000003U -#define APM_LL_CTRL_EXCEPTION_REGION 0x0000FFFFU -#define APM_LL_CTRL_EXCEPTION_REGION_S 0 -#define APM_LL_CTRL_EXCEPTION_REGION_V 0x0000FFFFU - -#define APM_LL_HP_MAX_REGION_NUM 15 -#define APM_LL_LP_MAX_REGION_NUM 3 -#define APM_LL_MASTER_MAX 32 - -#define LP_APM0_MAX_ACCESS_PATH 0x1 -#define HP_APM_MAX_ACCESS_PATH 0x5 -#define LP_APM_MAX_ACCESS_PATH 0x2 - -#define APM_CTRL_REGION_FILTER_EN_REG(apm_ctrl) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION_FILTER_EN_REG) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION_FILTER_EN_REG) : \ - (LP_APM_REGION_FILTER_EN_REG)); \ - }) - -#define TEE_LL_MODE_CTRL_REG(master_id) (TEE_M0_MODE_CTRL_REG + 4 * (master_id)) - -#define APM_LL_REGION_ADDR_START_REG(apm_ctrl, regn_num) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION0_ADDR_START_REG + 0xC * (regn_num)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num)) : \ - (LP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num))); \ - }) - -#define APM_LL_REGION_ADDR_END_REG(apm_ctrl, regn_num) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION0_ADDR_END_REG + 0xC * (regn_num)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num)) : \ - (LP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num))); \ - }) - -#define APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION0_ATTR_REG + 0xC * (regn_num)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION0_ATTR_REG + 0xC * (regn_num)) : \ - (LP_APM_REGION0_ATTR_REG + 0xC * (regn_num))); \ - }) - -#define APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path))); \ - }) - -#define APM_CTRL_M_REGION_STATUS_CLR (BIT(0)) -#define APM_LL_APM_CTRL_EXCP_CLR_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)) : \ - (LP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path))); \ - }) - -#define APM_LL_TEE_EXCP_INFO0_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)) : \ - (LP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path))); \ - }) - -#define APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path))); \ - }) - -#define APM_LL_TEE_EXCP_INFO1_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)) : \ - (LP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path))); \ - }) - -#define APM_LL_SEC_MODE_REGION_ATTR(sec_mode, regn_pms) ((regn_pms) << (4 * (sec_mode - 1))) -#define APM_LL_SEC_MODE_REGION_ATTR_V 0x00000003U -#define APM_LL_SEC_MODE_REGION_ATTR_M(sec_mode) (APM_LL_SEC_MODE_REGION_ATTR_V << (4 * (sec_mode - 1))) - -#define APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_INT_EN_REG) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_INT_EN_REG) : \ - (LP_APM_INT_EN_REG)); \ - }) - -#define APM_CTRL_CLK_EN (BIT(0)) -#define APM_LL_APM_CTRL_CLOCK_GATE_REG(apm_ctrl) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_CLOCK_GATE_REG) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_CLOCK_GATE_REG) : \ - (LP_APM_CLOCK_GATE_REG)); \ - }) - -#define APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_FUNC_CTRL_REG) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_FUNC_CTRL_REG) : \ - (LP_APM_FUNC_CTRL_REG)); \ - }) +/* 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 APM Master ID - */ -typedef enum { - APM_LL_MASTER_HPCORE = 0, - APM_LL_MASTER_LPCORE = 1, - APM_LL_MASTER_REGDMA = 2, - APM_LL_MASTER_SDIOSLV = 3, - APM_LL_MASTER_MODEM = 4, - APM_LL_MASTER_MEM_MONITOR = 5, - APM_LL_MASTER_TRACE = 6, - APM_LL_MASTER_GDMA = 16, // The beginning of GDMA master ID - APM_LL_MASTER_GDMA_SPI2 = 16, - APM_LL_MASTER_GDMA_UHCI0 = 18, - APM_LL_MASTER_GDMA_I2S0 = 19, - APM_LL_MASTER_GDMA_AES = 22, - APM_LL_MASTER_GDMA_SHA = 23, - APM_LL_MASTER_GDMA_ADC = 24, - APM_LL_MASTER_GDMA_PARLIO = 25, -} apm_ll_master_id_t; - -/** - * @brief APM Controller - */ -typedef enum { - LP_APM0_CTRL = 0, - HP_APM_CTRL = 1, - LP_APM_CTRL = 2, -} apm_ll_apm_ctrl_t; - -/** - * @brief APM Secure Mode - */ -typedef enum { - APM_LL_SECURE_MODE_TEE = 0, /* Trusted execution environment mode */ - APM_LL_SECURE_MODE_REE0 = 1, /* Rich execution environment mode0 */ - APM_LL_SECURE_MODE_REE1 = 2, /* Rich execution environment mode1 */ - APM_LL_SECURE_MODE_REE2 = 3, /* Rich execution environment mode2 */ -} apm_ll_secure_mode_t; - -/** - * @brief APM Ctrl access path - */ -typedef enum { - APM_CTRL_ACCESS_PATH_M0 = 0x0, - APM_CTRL_ACCESS_PATH_M1 = 0x1, - APM_CTRL_ACCESS_PATH_M2 = 0x2, - APM_CTRL_ACCESS_PATH_M3 = 0x3, - APM_CTRL_ACCESS_PATH_M4 = 0x4, -} apm_ll_ctrl_access_path_t; - -/** - * @brief APM Ctrl path. - */ -typedef struct { - apm_ll_apm_ctrl_t apm_ctrl; /* APM Ctrl: LP APM0/HP APM/LP APM. */ - apm_ll_ctrl_access_path_t apm_m_path; /* APM Ctrl access path M[0:n]. */ -} apm_ctrl_path_t; - -/** - * @brief APM exception information - */ -typedef struct { - apm_ctrl_path_t apm_path; - uint8_t excp_regn; - uint8_t excp_mode; - uint8_t excp_id; - uint8_t excp_type; - uint32_t excp_addr; -} apm_ctrl_exception_info_t; - -/** - * @brief Set secure mode + * @brief Set security mode for a specific master in HP-TEE * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param master_id APM master ID - * @param sec_mode Secure mode + * @param id Master ID + * @param mode Security mode to set */ -static inline void apm_tee_ll_set_master_secure_mode(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_master_id_t master_id, - apm_ll_secure_mode_t sec_mode) +static inline void apm_ll_hp_tee_set_master_sec_mode(apm_master_id_t id, apm_security_mode_t mode) { - if (apm_ctrl == HP_APM_CTRL) { - REG_WRITE(TEE_LL_MODE_CTRL_REG(master_id), sec_mode); - } else if ((apm_ctrl == LP_APM0_CTRL) || (apm_ctrl == LP_APM_CTRL)) { - REG_WRITE(LP_TEE_M0_MODE_CTRL_REG, sec_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 TEE controller clock auto gating enable + * @brief Enable/disable clock gating for HP-TEE * - * @param enable Flag for HP clock auto gating enable/disable + * @param enable True to enable, false to disable */ -static inline void apm_tee_ll_clk_gating_enable(bool enable) +static inline void apm_ll_hp_tee_enable_clk_gating(bool enable) { if (enable) { - REG_SET_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); - } else { REG_CLR_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); + } else { + REG_SET_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); } } /** - * @brief enable/disable APM Ctrl Region access permission filter + * @brief Set security mode for a specific master in LP-TEE * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param regn_num Memory Region number - * @param enable Flag for Region access filter enable/disable + * @param id Master ID (unused) + * @param mode Security mode to set */ -static inline void apm_ll_apm_ctrl_region_filter_enable(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, bool enable) +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(APM_CTRL_REGION_FILTER_EN_REG(apm_ctrl), BIT(regn_num)); + REG_SET_BIT(LP_TEE_BUS_ERR_CONF_REG, LP_TEE_BUS_ERR_RESP_EN); } else { - REG_CLR_BIT(APM_CTRL_REGION_FILTER_EN_REG(apm_ctrl), BIT(regn_num)); + REG_CLR_BIT(LP_TEE_BUS_ERR_CONF_REG, LP_TEE_BUS_ERR_RESP_EN); } } /** - * @brief enable/disable APM Ctrl access path(M[0:n]) + * @brief Enable/disable clock gating for LP-TEE * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param apm_m_path APM Ctrl access path - * @param enable Flag for LP APM0 M path filter enable/disable + * @param enable True to enable, false to disable */ -static inline void apm_ll_apm_ctrl_filter_enable(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path, bool enable) +static inline void apm_ll_lp_tee_enable_clk_gating(bool enable) { if (enable) { - REG_SET_BIT(APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl), BIT(apm_m_path)); + REG_CLR_BIT(LP_TEE_CLOCK_GATE_REG, LP_TEE_CLK_EN); } else { - REG_CLR_BIT(APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl), BIT(apm_m_path)); + REG_SET_BIT(LP_TEE_CLOCK_GATE_REG, LP_TEE_CLK_EN); } } /** - * @brief APM Ctrl Region start address configuration + * @brief Enable/disable forced HP memory access for LP-TEE * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param regn_num Region number to be configured - * @param addr Region start address + * @param enable True to enable, false to disable */ -static inline void apm_ll_apm_ctrl_set_region_start_address(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, uint32_t addr) -{ - REG_WRITE(APM_LL_REGION_ADDR_START_REG(apm_ctrl, regn_num), addr); -} - -/** - * @brief APM Ctrl Region end address configuration - * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param regn_num Region number to be configured - * @param addr Region end address - */ -static inline void apm_ll_apm_ctrl_set_region_end_address(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, uint32_t addr) -{ - REG_WRITE(APM_LL_REGION_ADDR_END_REG(apm_ctrl, regn_num), addr); -} - -/** - * @brief HP Region pms attributes configuration - * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param regn_num Region number to be configured - * @param sec_mode Secure mode of the Master - * @param regn_pms XWR permissions for the given secure mode and Region number - */ -static inline void apm_ll_apm_ctrl_sec_mode_region_attr_config(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, apm_ll_secure_mode_t sec_mode, uint32_t regn_pms) -{ - uint32_t val = 0; - val = REG_READ(APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num)); - val &= ~APM_LL_SEC_MODE_REGION_ATTR_M(sec_mode); - val |= APM_LL_SEC_MODE_REGION_ATTR(sec_mode, regn_pms); - REG_WRITE(APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num), val); -} - -/** - * @brief Get APM Ctrl access path(M[0:n]) exception status - * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param apm_m_path APM Ctrl access path - */ -static inline uint8_t apm_ll_apm_ctrl_exception_status(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path) -{ - return REG_READ(APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path)); -} - -/** - * @brief Clear APM Ctrl access path(M[0:n]) exception - * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param amp_m_path APM Ctrl access path - */ -static inline void apm_ll_apm_ctrl_exception_clear(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path) -{ - REG_SET_BIT(APM_LL_APM_CTRL_EXCP_CLR_REG(apm_ctrl, apm_m_path), - APM_CTRL_M_REGION_STATUS_CLR); -} - -/** - * @brief Get APM Ctrl access path(M[0:n]) exception information - * - * @param excp_info Exception related information like addr, - * region, apm_ctrl, apm_m_path, sec_mode and master id - */ -static inline void apm_ll_apm_ctrl_get_exception_info(apm_ctrl_exception_info_t *excp_info) -{ - excp_info->excp_id = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), - APM_LL_CTRL_EXCEPTION_ID); - excp_info->excp_mode = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), - APM_LL_CTRL_EXCEPTION_MODE); - excp_info->excp_regn = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), - APM_LL_CTRL_EXCEPTION_REGION); - excp_info->excp_type = apm_ll_apm_ctrl_exception_status(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path); - excp_info->excp_addr = REG_READ(APM_LL_TEE_EXCP_INFO1_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path)); -} - -/** - * @brief Interrupt enable for APM Ctrl at access path(M[0:n]) - * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param apm_m_path APM Ctrl access patch(M[0:n]) - * @param enable Flag for access path interrupt enable/disable - */ -static inline void apm_ll_apm_ctrl_interrupt_enable(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path, bool enable) +static inline void apm_ll_lp_tee_enable_force_hp_mem_access(bool enable) { if (enable) { - REG_SET_BIT(APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl), BIT(apm_m_path)); + REG_SET_BIT(LP_TEE_FORCE_ACC_HP_REG, LP_TEE_FORCE_ACC_HPMEM_EN); } else { - REG_CLR_BIT(APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl), BIT(apm_m_path)); + REG_CLR_BIT(LP_TEE_FORCE_ACC_HP_REG, LP_TEE_FORCE_ACC_HPMEM_EN); } } /** - * @brief APM Ctrl clock auto gating enable + * @brief Enable/disable controller filter for specific path in HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param enable Flag for HP clock auto gating enable/disable + * @param path Access path + * @param enable True to enable, false to disable */ -static inline void apm_ll_apm_ctrl_clk_gating_enable(apm_ll_apm_ctrl_t apm_ctrl, bool enable) +static inline void apm_ll_hp_apm_enable_ctrl_filter(apm_ctrl_access_path_t path, bool enable) { if (enable) { - REG_SET_BIT(APM_LL_APM_CTRL_CLOCK_GATE_REG(apm_ctrl), APM_CTRL_CLK_EN); + REG_SET_BIT(HP_APM_FUNC_CTRL_REG, BIT(path)); } else { - REG_CLR_BIT(APM_LL_APM_CTRL_CLOCK_GATE_REG(apm_ctrl), APM_CTRL_CLK_EN); + REG_CLR_BIT(HP_APM_FUNC_CTRL_REG, BIT(path)); } } /** - * @brief APM/TEE/HP System Reg reset event bypass enable + * @brief Enable/disable all controller filters in HP-APM * - * Disable: tee_reg/apm_reg/hp_system_reg will not only be reset by power-reset, - * but also some reset events. - * Enable: tee_reg/apm_reg/hp_system_reg will only be reset by power-reset. - * Some reset events will be bypassed. - * - * @param enable Flag for event bypass enable/disable + * @param enable True to enable, false to disable */ -static inline void apm_ll_apm_ctrl_reset_event_enable(bool enable) +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); @@ -405,26 +961,6 @@ static inline void apm_ll_apm_ctrl_reset_event_enable(bool enable) } } -/** - * @brief Return APM Ctrl interrupt source number. - * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param apm_m_path APM Ctrl access patch(M[0:n]) - */ -static inline int apm_ll_apm_ctrl_get_int_src_num(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path) -{ - switch (apm_ctrl) { - case LP_APM0_CTRL : - return (ETS_LP_APM0_INTR_SOURCE); - case HP_APM_CTRL : - return (ETS_HP_APM_M0_INTR_SOURCE + apm_m_path); - case LP_APM_CTRL : - return (ETS_LP_APM_M0_INTR_SOURCE + apm_m_path); - } - - return -1; -} - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c6/include/hal/apm_ll.h b/components/hal/esp32c6/include/hal/apm_ll.h index 0288568707..6859dc7f2c 100644 --- a/components/hal/esp32c6/include/hal/apm_ll.h +++ b/components/hal/esp32c6/include/hal/apm_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,394 +7,644 @@ #include #include -#include "esp_err.h" -#include "soc/pcr_reg.h" + +#include "soc/apm_defs.h" #include "soc/tee_reg.h" #include "soc/lp_tee_reg.h" -#include "soc/lp_apm0_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/pcr_reg.h" #include "soc/interrupts.h" +#include "hal/apm_types.h" #ifdef __cplusplus extern "C" { #endif -#define APM_LL_CTRL_EXCEPTION_ID 0x0000001FU -#define APM_LL_CTRL_EXCEPTION_ID_S 18 -#define APM_LL_CTRL_EXCEPTION_ID_V 0x0000001FU -#define APM_LL_CTRL_EXCEPTION_MODE 0x00000003U -#define APM_LL_CTRL_EXCEPTION_MODE_S 16 -#define APM_LL_CTRL_EXCEPTION_MODE_V 0x00000003U -#define APM_LL_CTRL_EXCEPTION_REGION 0x0000FFFFU -#define APM_LL_CTRL_EXCEPTION_REGION_S 0 -#define APM_LL_CTRL_EXCEPTION_REGION_V 0x0000FFFFU - -#define APM_LL_HP_MAX_REGION_NUM 15 -#define APM_LL_LP_MAX_REGION_NUM 3 -#define APM_LL_MASTER_MAX 32 - -#define LP_APM0_MAX_ACCESS_PATH 0x1 -#define HP_APM_MAX_ACCESS_PATH 0x4 -#define LP_APM_MAX_ACCESS_PATH 0x2 - -#define APM_CTRL_REGION_FILTER_EN_REG(apm_ctrl) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION_FILTER_EN_REG) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION_FILTER_EN_REG) : \ - (LP_APM_REGION_FILTER_EN_REG)); \ - }) - -#define TEE_LL_MODE_CTRL_REG(master_id) (TEE_M0_MODE_CTRL_REG + 4 * (master_id)) - -#define APM_LL_REGION_ADDR_START_REG(apm_ctrl, regn_num) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION0_ADDR_START_REG + 0xC * (regn_num)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num)) : \ - (LP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num))); \ - }) - -#define APM_LL_REGION_ADDR_END_REG(apm_ctrl, regn_num) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION0_ADDR_END_REG + 0xC * (regn_num)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num)) : \ - (LP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num))); \ - }) - -#define APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_REGION0_PMS_ATTR_REG + 0xC * (regn_num)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_REGION0_PMS_ATTR_REG + 0xC * (regn_num)) : \ - (LP_APM_REGION0_PMS_ATTR_REG + 0xC * (regn_num))); \ - }) - -#define APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path))); \ - }) - -#define APM_CTRL_M_REGION_STATUS_CLR (BIT(0)) -#define APM_LL_APM_CTRL_EXCP_CLR_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)) : \ - (LP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path))); \ - }) - -#define APM_LL_TEE_EXCP_INFO0_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)) : \ - (LP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path))); \ - }) - -#define APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path))); \ - }) - -#define APM_LL_TEE_EXCP_INFO1_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)) : \ - (LP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path))); \ - }) - -#define APM_LL_SEC_MODE_REGION_ATTR(sec_mode, regn_pms) ((regn_pms) << (4 * (sec_mode - 1))) -#define APM_LL_SEC_MODE_REGION_ATTR_V 0x00000003U -#define APM_LL_SEC_MODE_REGION_ATTR_M(sec_mode) (APM_LL_SEC_MODE_REGION_ATTR_V << (4 * (sec_mode - 1))) - -#define APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_INT_EN_REG) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_INT_EN_REG) : \ - (LP_APM_INT_EN_REG)); \ - }) - -#define APM_CTRL_CLK_EN (BIT(0)) -#define APM_LL_APM_CTRL_CLOCK_GATE_REG(apm_ctrl) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_CLOCK_GATE_REG) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_CLOCK_GATE_REG) : \ - (LP_APM_CLOCK_GATE_REG)); \ - }) - -#define APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl) \ - ({\ - (LP_APM0_CTRL == apm_ctrl) ? (LP_APM0_FUNC_CTRL_REG) : \ - ((HP_APM_CTRL == apm_ctrl) ? (HP_APM_FUNC_CTRL_REG) : \ - (LP_APM_FUNC_CTRL_REG)); \ - }) +/* Helper macros for calculating pms attr field position for given security mode */ +#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)) /** - * @brief APM Master ID - */ -typedef enum { - APM_LL_MASTER_HPCORE = 0, - APM_LL_MASTER_LPCORE = 1, - APM_LL_MASTER_REGDMA = 2, - APM_LL_MASTER_SDIOSLV = 3, - APM_LL_MASTER_MODEM = 4, - APM_LL_MASTER_MEM_MONITOR = 5, - APM_LL_MASTER_TRACE = 6, - APM_LL_MASTER_GDMA = 16, // The beginning of GDMA master ID - APM_LL_MASTER_GDMA_SPI2 = 16, - APM_LL_MASTER_GDMA_UHCI0 = 18, - APM_LL_MASTER_GDMA_I2S0 = 19, - APM_LL_MASTER_GDMA_AES = 22, - APM_LL_MASTER_GDMA_SHA = 23, - APM_LL_MASTER_GDMA_ADC = 24, - APM_LL_MASTER_GDMA_PARLIO = 25, -} apm_ll_master_id_t; - -/** - * @brief APM Controller - */ -typedef enum { - LP_APM0_CTRL = 0, - HP_APM_CTRL = 1, - LP_APM_CTRL = 2, -} apm_ll_apm_ctrl_t; - -/** - * @brief APM Secure Mode - */ -typedef enum { - APM_LL_SECURE_MODE_TEE = 0, /* Trusted execution environment mode */ - APM_LL_SECURE_MODE_REE0 = 1, /* Rich execution environment mode0 */ - APM_LL_SECURE_MODE_REE1 = 2, /* Rich execution environment mode1 */ - APM_LL_SECURE_MODE_REE2 = 3, /* Rich execution environment mode2 */ -} apm_ll_secure_mode_t; - -/** - * @brief APM Ctrl access path - */ -typedef enum { - APM_CTRL_ACCESS_PATH_M0 = 0x0, - APM_CTRL_ACCESS_PATH_M1 = 0x1, - APM_CTRL_ACCESS_PATH_M2 = 0x2, - APM_CTRL_ACCESS_PATH_M3 = 0x3, -} apm_ll_ctrl_access_path_t; - -/** - * @brief APM Ctrl path. - */ -typedef struct { - apm_ll_apm_ctrl_t apm_ctrl; /* APM Ctrl: LP APM0/HP APM/LP APM. */ - apm_ll_ctrl_access_path_t apm_m_path; /* APM Ctrl access path M[0:n]. */ -} apm_ctrl_path_t; - -/** - * @brief APM exception information - */ -typedef struct { - apm_ctrl_path_t apm_path; - uint8_t excp_regn; - uint8_t excp_mode; - uint8_t excp_id; - uint8_t excp_type; - uint32_t excp_addr; -} apm_ctrl_exception_info_t; - -/** - * @brief Set secure mode + * @brief Set security mode for a specific master in HP-TEE * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param master_id APM master ID - * @param sec_mode Secure mode + * @param id Master ID + * @param mode Security mode to set */ -static inline void apm_tee_ll_set_master_secure_mode(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_master_id_t master_id, - apm_ll_secure_mode_t sec_mode) +static inline void apm_ll_hp_tee_set_master_sec_mode(apm_master_id_t id, apm_security_mode_t mode) { - if (apm_ctrl == HP_APM_CTRL) { - REG_WRITE(TEE_LL_MODE_CTRL_REG(master_id), sec_mode); - } else if ((apm_ctrl == LP_APM0_CTRL) || (apm_ctrl == LP_APM_CTRL)) { - REG_WRITE(LP_TEE_M0_MODE_CTRL_REG, sec_mode); - } + REG_WRITE(TEE_M0_MODE_CTRL_REG + APM_TEE_MODE_CTRL_OFFSET * id, mode); } /** - * @brief TEE controller clock auto gating enable + * @brief Enable/disable clock gating for HP-TEE * - * @param enable Flag for HP clock auto gating enable/disable + * @param enable True to enable, false to disable */ -static inline void apm_tee_ll_clk_gating_enable(bool enable) +static inline void apm_ll_hp_tee_enable_clk_gating(bool enable) { if (enable) { - REG_SET_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); - } else { REG_CLR_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); + } else { + REG_SET_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); } } /** - * @brief enable/disable APM Ctrl Region access permission filter + * @brief Set security mode for a specific master in LP-TEE * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param regn_num Memory Region number - * @param enable Flag for Region access filter enable/disable + * @param id Master ID (unused) + * @param mode Security mode to set */ -static inline void apm_ll_apm_ctrl_region_filter_enable(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, bool enable) +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 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_SET_BIT(APM_CTRL_REGION_FILTER_EN_REG(apm_ctrl), BIT(regn_num)); + REG_CLR_BIT(LP_TEE_CLOCK_GATE_REG, LP_TEE_CLK_EN); } else { - REG_CLR_BIT(APM_CTRL_REGION_FILTER_EN_REG(apm_ctrl), BIT(regn_num)); + REG_SET_BIT(LP_TEE_CLOCK_GATE_REG, LP_TEE_CLK_EN); } } /** - * @brief enable/disable APM Ctrl access path(M[0:n]) + * @brief Enable/disable forced HP memory access for LP-TEE * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param apm_m_path APM Ctrl access path - * @param enable Flag for LP APM0 M path filter enable/disable + * @param enable True to enable, false to disable */ -static inline void apm_ll_apm_ctrl_filter_enable(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path, bool enable) +static inline void apm_ll_lp_tee_enable_force_hp_mem_access(bool enable) { if (enable) { - REG_SET_BIT(APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl), BIT(apm_m_path)); + REG_SET_BIT(LP_TEE_FORCE_ACC_HP_REG, LP_TEE_FORCE_ACC_HPMEM_EN); } else { - REG_CLR_BIT(APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl), BIT(apm_m_path)); + REG_CLR_BIT(LP_TEE_FORCE_ACC_HP_REG, LP_TEE_FORCE_ACC_HPMEM_EN); } } /** - * @brief APM Ctrl Region start address configuration + * @brief Enable/disable all controller filters in HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param regn_num Region number to be configured - * @param addr Region start address + * @param enable True to enable, false to disable */ -static inline void apm_ll_apm_ctrl_set_region_start_address(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, uint32_t addr) +static inline void apm_ll_hp_apm_enable_ctrl_filter_all(bool enable) { - REG_WRITE(APM_LL_REGION_ADDR_START_REG(apm_ctrl, regn_num), addr); + REG_WRITE(HP_APM_FUNC_CTRL_REG, enable ? UINT32_MAX : 0); } /** - * @brief APM Ctrl Region end address configuration + * @brief Enable/disable region filter in HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param regn_num Region number to be configured - * @param addr Region end address + * @param regn_num Region number + * @param enable True to enable, false to disable */ -static inline void apm_ll_apm_ctrl_set_region_end_address(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, uint32_t addr) -{ - REG_WRITE(APM_LL_REGION_ADDR_END_REG(apm_ctrl, regn_num), addr); -} - -/** - * @brief HP Region pms attributes configuration - * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param regn_num Region number to be configured - * @param sec_mode Secure mode of the Master - * @param regn_pms XWR permissions for the given secure mode and Region number - */ -static inline void apm_ll_apm_ctrl_sec_mode_region_attr_config(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, apm_ll_secure_mode_t sec_mode, uint32_t regn_pms) -{ - uint32_t val = 0; - val = REG_READ(APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num)); - val &= ~APM_LL_SEC_MODE_REGION_ATTR_M(sec_mode); - val |= APM_LL_SEC_MODE_REGION_ATTR(sec_mode, regn_pms); - REG_WRITE(APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num), val); -} - -/** - * @brief Get APM Ctrl access path(M[0:n]) exception status - * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param apm_m_path APM Ctrl access path - */ -static inline uint8_t apm_ll_apm_ctrl_exception_status(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path) -{ - return REG_READ(APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path)); -} - -/** - * @brief Clear APM Ctrl access path(M[0:n]) exception - * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param amp_m_path APM Ctrl access path - */ -static inline void apm_ll_apm_ctrl_exception_clear(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path) -{ - REG_SET_BIT(APM_LL_APM_CTRL_EXCP_CLR_REG(apm_ctrl, apm_m_path), - APM_CTRL_M_REGION_STATUS_CLR); -} - -/** - * @brief Get APM Ctrl access path(M[0:n]) exception information - * - * @param excp_info Exception related information like addr, - * region, apm_ctrl, apm_m_path, sec_mode and master id - */ -static inline void apm_ll_apm_ctrl_get_exception_info(apm_ctrl_exception_info_t *excp_info) -{ - excp_info->excp_id = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), - APM_LL_CTRL_EXCEPTION_ID); - excp_info->excp_mode = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), - APM_LL_CTRL_EXCEPTION_MODE); - excp_info->excp_regn = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), - APM_LL_CTRL_EXCEPTION_REGION); - excp_info->excp_type = apm_ll_apm_ctrl_exception_status(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path); - excp_info->excp_addr = REG_READ(APM_LL_TEE_EXCP_INFO1_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path)); -} - -/** - * @brief Interrupt enable for APM Ctrl at access path(M[0:n]) - * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param apm_m_path APM Ctrl access patch(M[0:n]) - * @param enable Flag for access path interrupt enable/disable - */ -static inline void apm_ll_apm_ctrl_interrupt_enable(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path, bool enable) +static inline void apm_ll_hp_apm_enable_region_filter(uint32_t regn_num, bool enable) { if (enable) { - REG_SET_BIT(APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl), BIT(apm_m_path)); + REG_SET_BIT(HP_APM_REGION_FILTER_EN_REG, BIT(regn_num)); } else { - REG_CLR_BIT(APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl), BIT(apm_m_path)); + REG_CLR_BIT(HP_APM_REGION_FILTER_EN_REG, BIT(regn_num)); } } /** - * @brief APM Ctrl clock auto gating enable + * @brief Set region start address in HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param enable Flag for HP clock auto gating enable/disable + * @param regn_num Region number + * @param addr Start address */ -static inline void apm_ll_apm_ctrl_clk_gating_enable(apm_ll_apm_ctrl_t apm_ctrl, bool enable) +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_PMS_ATTR_REG + APM_REGION_PMS_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 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(APM_LL_APM_CTRL_CLOCK_GATE_REG(apm_ctrl), APM_CTRL_CLK_EN); + REG_SET_BIT(HP_APM_INT_EN_REG, BIT(path)); } else { - REG_CLR_BIT(APM_LL_APM_CTRL_CLOCK_GATE_REG(apm_ctrl), APM_CTRL_CLK_EN); + REG_CLR_BIT(HP_APM_INT_EN_REG, BIT(path)); } } /** - * @brief APM/TEE/HP System Reg reset event bypass enable + * @brief Get controller interrupt source number from HP-APM * - * Disable: tee_reg/apm_reg/hp_system_reg will not only be reset by power-reset, - * but also some reset events. - * Enable: tee_reg/apm_reg/hp_system_reg will only be reset by power-reset. - * Some reset events will be bypassed. - * - * @param enable Flag for event bypass enable/disable + * @param path Access path + * @return Interrupt source number */ -static inline void apm_ll_apm_ctrl_reset_event_enable(bool enable) +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_PMS_ATTR_REG + APM_REGION_PMS_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 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 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 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_PMS_ATTR_REG + APM_REGION_PMS_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 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 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); @@ -403,26 +653,6 @@ static inline void apm_ll_apm_ctrl_reset_event_enable(bool enable) } } -/** - * @brief Fetch the APM Ctrl interrupt source number. - * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param apm_m_path APM Ctrl access patch(M[0:n]) - */ -static inline int apm_ll_apm_ctrl_get_int_src_num(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path) -{ - switch (apm_ctrl) { - case LP_APM0_CTRL : - return (ETS_LP_APM0_INTR_SOURCE); - case HP_APM_CTRL : - return (ETS_HP_APM_M0_INTR_SOURCE + apm_m_path); - case LP_APM_CTRL : - return (ETS_LP_APM_M0_INTR_SOURCE + apm_m_path); - } - - return -1; -} - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c61/include/hal/apm_ll.h b/components/hal/esp32c61/include/hal/apm_ll.h index 664160ec2e..8f730df5e6 100644 --- a/components/hal/esp32c61/include/hal/apm_ll.h +++ b/components/hal/esp32c61/include/hal/apm_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,375 +7,453 @@ #include #include -#include "soc/pcr_reg.h" + +#include "soc/apm_defs.h" #include "soc/tee_reg.h" #include "soc/hp_apm_reg.h" +#include "soc/hp_apm_struct.h" #include "soc/lp_apm_reg.h" +#include "soc/lp_apm_struct.h" + +#include "soc/pcr_reg.h" #include "soc/interrupts.h" +#include "hal/apm_types.h" #ifdef __cplusplus extern "C" { #endif -#define APM_LL_CTRL_EXCEPTION_ID 0x0000001FU -#define APM_LL_CTRL_EXCEPTION_ID_S 18 -#define APM_LL_CTRL_EXCEPTION_ID_V 0x0000001FU -#define APM_LL_CTRL_EXCEPTION_MODE 0x00000003U -#define APM_LL_CTRL_EXCEPTION_MODE_S 16 -#define APM_LL_CTRL_EXCEPTION_MODE_V 0x00000003U -#define APM_LL_CTRL_EXCEPTION_REGION 0x0000FFFFU -#define APM_LL_CTRL_EXCEPTION_REGION_S 0 -#define APM_LL_CTRL_EXCEPTION_REGION_V 0x0000FFFFU - -#define APM_LL_HP_MAX_REGION_NUM 15 -#define APM_LL_LP_MAX_REGION_NUM 3 -#define APM_LL_MASTER_MAX 32 - -#define HP_APM_MAX_ACCESS_PATH 0x4 -#define LP_APM_MAX_ACCESS_PATH 0x1 - -#define APM_CTRL_REGION_FILTER_EN_REG(apm_ctrl) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION_FILTER_EN_REG) : \ - (HP_APM_REGION_FILTER_EN_REG); \ - }) - -#define TEE_LL_MODE_CTRL_REG(master_id) (TEE_M0_MODE_CTRL_REG + 4 * (master_id)) - -#define APM_LL_REGION_ADDR_START_REG(apm_ctrl, regn_num) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num)) : \ - (HP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num)); \ - }) - -#define APM_LL_REGION_ADDR_END_REG(apm_ctrl, regn_num) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num)) : \ - (HP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num)); \ - }) - -#define APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION0_ATTR_REG + 0xC * (regn_num)) : \ - (HP_APM_REGION0_ATTR_REG + 0xC * (regn_num)); \ - }) - -#define APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)); \ - }) - -#define APM_CTRL_M_REGION_STATUS_CLR (BIT(0)) -#define APM_LL_APM_CTRL_EXCP_CLR_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)) : \ - (HP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)); \ - }) - -#define APM_LL_TEE_EXCP_INFO0_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)) : \ - (HP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)); \ - }) - -#define APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)); \ - }) - -#define APM_LL_TEE_EXCP_INFO1_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)) : \ - (HP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)); \ - }) - -#define APM_LL_SEC_MODE_REGION_ATTR(sec_mode, regn_pms) ((regn_pms) << (4 * (sec_mode - 1))) -#define APM_LL_SEC_MODE_REGION_ATTR_V 0x00000003U -#define APM_LL_SEC_MODE_REGION_ATTR_M(sec_mode) (APM_LL_SEC_MODE_REGION_ATTR_V << (4 * (sec_mode - 1))) - -#define APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_INT_EN_REG) : \ - (HP_APM_INT_EN_REG); \ - }) - -#define APM_CTRL_CLK_EN (BIT(0)) -#define APM_LL_APM_CTRL_CLOCK_GATE_REG(apm_ctrl) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_CLOCK_GATE_REG) : \ - (HP_APM_CLOCK_GATE_REG); \ - }) - -#define APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_FUNC_CTRL_REG) : \ - (HP_APM_FUNC_CTRL_REG); \ - }) +/* Helper macros for getting pms attributes field mask for given security mode */ +#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)) /** - * @brief APM Master ID - */ -typedef enum { - APM_LL_MASTER_HPCORE = 0, - APM_LL_MASTER_LPCORE = 1, - APM_LL_MASTER_REGDMA = 2, - APM_LL_MASTER_SDIOSLV = 3, - APM_LL_MASTER_MODEM = 4, - APM_LL_MASTER_MEM_MONITOR = 5, - APM_LL_MASTER_TRACE = 6, - APM_LL_MASTER_GDMA = 16, // The beginning of GDMA master ID - APM_LL_MASTER_GDMA_SPI2 = 16, - APM_LL_MASTER_GDMA_UHCI0 = 18, - APM_LL_MASTER_GDMA_I2S0 = 19, - APM_LL_MASTER_GDMA_AES = 22, - APM_LL_MASTER_GDMA_SHA = 23, - APM_LL_MASTER_GDMA_ADC = 24, - APM_LL_MASTER_GDMA_PARLIO = 25, -} apm_ll_master_id_t; - -/** - * @brief APM Controller - */ -typedef enum { - LP_APM_CTRL = 0, - HP_APM_CTRL = 1, -} apm_ll_apm_ctrl_t; - -/** - * @brief APM Secure Mode - */ -typedef enum { - APM_LL_SECURE_MODE_TEE = 0, /* Trusted execution environment mode */ - APM_LL_SECURE_MODE_REE0 = 1, /* Rich execution environment mode0 */ - APM_LL_SECURE_MODE_REE1 = 2, /* Rich execution environment mode1 */ - APM_LL_SECURE_MODE_REE2 = 3, /* Rich execution environment mode2 */ -} apm_ll_secure_mode_t; - -/** - * @brief APM Ctrl access path - */ -typedef enum { - APM_CTRL_ACCESS_PATH_M0 = 0x0, - APM_CTRL_ACCESS_PATH_M1 = 0x1, - APM_CTRL_ACCESS_PATH_M2 = 0x2, - APM_CTRL_ACCESS_PATH_M3 = 0x3, -} apm_ll_ctrl_access_path_t; - -/** - * @brief APM Ctrl path. - */ -typedef struct { - apm_ll_apm_ctrl_t apm_ctrl; /* APM Ctrl: LP APM/HP APM. */ - apm_ll_ctrl_access_path_t apm_m_path; /* APM Ctrl access path M[0:n]. */ -} apm_ctrl_path_t; - -/** - * @brief APM exception information - */ -typedef struct { - apm_ctrl_path_t apm_path; - uint8_t excp_regn; - uint8_t excp_mode; - uint8_t excp_id; - uint8_t excp_type; - uint32_t excp_addr; -} apm_ctrl_exception_info_t; - -/** - * @brief Set secure mode + * @brief Set security mode for a specific master in HP-TEE * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param master_id APM master ID - * @param sec_mode Secure mode + * @param id Master ID + * @param mode Security mode to set */ -static inline void apm_tee_ll_set_master_secure_mode(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_master_id_t master_id, - apm_ll_secure_mode_t sec_mode) +static inline void apm_ll_hp_tee_set_master_sec_mode(apm_master_id_t id, apm_security_mode_t mode) { - if (apm_ctrl == HP_APM_CTRL) { - REG_WRITE(TEE_LL_MODE_CTRL_REG(master_id), sec_mode); - } + REG_WRITE(TEE_M0_MODE_CTRL_REG + APM_TEE_MODE_CTRL_OFFSET * id, mode); } /** - * @brief TEE controller clock auto gating enable + * @brief Lock master security mode for HP-TEE * - * @param enable Flag for HP clock auto gating enable/disable + * @param id Master ID */ -static inline void apm_tee_ll_clk_gating_enable(bool enable) +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 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_SET_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); - } else { REG_CLR_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); + } else { + REG_SET_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); } } /** - * @brief enable/disable APM Ctrl Region access permission filter + * @brief Enable/disable controller filter for specific path in HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param regn_num Memory Region number - * @param enable Flag for Region access filter enable/disable + * @param path Access path + * @param enable True to enable, false to disable */ -static inline void apm_ll_apm_ctrl_region_filter_enable(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, bool enable) +static inline void apm_ll_hp_apm_enable_ctrl_filter(apm_ctrl_access_path_t path, bool enable) { if (enable) { - REG_SET_BIT(APM_CTRL_REGION_FILTER_EN_REG(apm_ctrl), BIT(regn_num)); + REG_SET_BIT(HP_APM_FUNC_CTRL_REG, BIT(path)); } else { - REG_CLR_BIT(APM_CTRL_REGION_FILTER_EN_REG(apm_ctrl), BIT(regn_num)); + REG_CLR_BIT(HP_APM_FUNC_CTRL_REG, BIT(path)); } } /** - * @brief enable/disable APM Ctrl access path(M[0:n]) + * @brief Enable/disable all controller filters in HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param apm_m_path APM Ctrl access path - * @param enable Flag for APM Ctrl M path filter enable/disable + * @param enable True to enable, false to disable */ -static inline void apm_ll_apm_ctrl_filter_enable(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path, bool enable) +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(APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl), BIT(apm_m_path)); + REG_SET_BIT(HP_APM_REGION_FILTER_EN_REG, BIT(regn_num)); } else { - REG_CLR_BIT(APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl), BIT(apm_m_path)); + REG_CLR_BIT(HP_APM_REGION_FILTER_EN_REG, BIT(regn_num)); } } /** - * @brief APM Ctrl Region start address configuration + * @brief Set region start address in HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param regn_num Region number to be configured - * @param addr Region start address + * @param regn_num Region number + * @param addr Start address */ -static inline void apm_ll_apm_ctrl_set_region_start_address(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, uint32_t addr) +static inline void apm_ll_hp_apm_set_region_start_addr(uint32_t regn_num, uint32_t addr) { - REG_WRITE(APM_LL_REGION_ADDR_START_REG(apm_ctrl, regn_num), addr); + REG_WRITE(HP_APM_REGION0_ADDR_START_REG + APM_REGION_ADDR_OFFSET * regn_num, addr); } /** - * @brief APM Ctrl Region end address configuration + * @brief Set region end address in HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param regn_num Region number to be configured - * @param addr Region end address + * @param regn_num Region number + * @param addr End address */ -static inline void apm_ll_apm_ctrl_set_region_end_address(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, uint32_t addr) +static inline void apm_ll_hp_apm_set_region_end_addr(uint32_t regn_num, uint32_t addr) { - REG_WRITE(APM_LL_REGION_ADDR_END_REG(apm_ctrl, regn_num), addr); + REG_WRITE(HP_APM_REGION0_ADDR_END_REG + APM_REGION_ADDR_OFFSET * regn_num, addr); } /** - * @brief HP Region pms attributes configuration + * @brief Set security mode region attributes in HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param regn_num Region number to be configured - * @param sec_mode Secure mode of the Master - * @param regn_pms XWR permissions for the given secure mode and Region number + * @param regn_num Region number + * @param mode Security mode + * @param regn_pms Region PMS attributes */ -static inline void apm_ll_apm_ctrl_sec_mode_region_attr_config(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, apm_ll_secure_mode_t sec_mode, uint32_t regn_pms) +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 val = 0; - val = REG_READ(APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num)); - val &= ~APM_LL_SEC_MODE_REGION_ATTR_M(sec_mode); - val |= APM_LL_SEC_MODE_REGION_ATTR(sec_mode, regn_pms); - REG_WRITE(APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num), val); + 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 Get APM Ctrl access path(M[0:n]) exception status + * @brief Lock security mode region attributes in HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param apm_m_path APM Ctrl access path + * @param regn_num Region number */ -static inline uint8_t apm_ll_apm_ctrl_exception_status(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path) +static inline void apm_ll_hp_apm_lock_sec_mode_region_attr(uint32_t regn_num) { - return REG_READ(APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path)); + REG_SET_BIT(HP_APM_REGION0_ATTR_REG + APM_REGION_ATTR_OFFSET * regn_num, APM_REGION_LOCK_BIT); } /** - * @brief Clear APM Ctrl access path(M[0:n]) exception + * @brief Get exception data (regn, master, security mode) from HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param amp_m_path APM Ctrl access path + * @param path Access path + * @return Exception data */ -static inline void apm_ll_apm_ctrl_exception_clear(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path) +static inline uint32_t apm_ll_hp_apm_get_excp_data(apm_ctrl_access_path_t path) { - REG_SET_BIT(APM_LL_APM_CTRL_EXCP_CLR_REG(apm_ctrl, apm_m_path), - APM_CTRL_M_REGION_STATUS_CLR); + return REG_READ(HP_APM_M0_EXCEPTION_INFO0_REG + APM_EXCP_INFO_OFFSET * path); } /** - * @brief Get APM Ctrl access path(M[0:n]) exception information + * @brief Get exception status from HP-APM * - * @param excp_info Exception related information like addr, - * region, apm_ctrl, apm_m_path, sec_mode and master id + * @param path Access path + * @return Exception type */ -static inline void apm_ll_apm_ctrl_get_exception_info(apm_ctrl_exception_info_t *excp_info) +static inline uint32_t apm_ll_hp_apm_get_excp_type(apm_ctrl_access_path_t path) { - excp_info->excp_id = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), - APM_LL_CTRL_EXCEPTION_ID); - excp_info->excp_mode = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), - APM_LL_CTRL_EXCEPTION_MODE); - excp_info->excp_regn = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), - APM_LL_CTRL_EXCEPTION_REGION); - excp_info->excp_type = apm_ll_apm_ctrl_exception_status(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path); - excp_info->excp_addr = REG_READ(APM_LL_TEE_EXCP_INFO1_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path)); + return REG_READ(HP_APM_M0_STATUS_REG + APM_EXCP_INFO_OFFSET * path); } /** - * @brief Interrupt enable for APM Ctrl at access path(M[0:n]) + * @brief Get exception address from HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param apm_m_path APM Ctrl access patch(M[0:n]) - * @param enable Flag for access path interrupt enable/disable + * @param path Access path + * @return Exception address */ -static inline void apm_ll_apm_ctrl_interrupt_enable(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path, bool enable) +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(APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl), BIT(apm_m_path)); + REG_SET_BIT(HP_APM_INT_EN_REG, BIT(path)); } else { - REG_CLR_BIT(APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl), BIT(apm_m_path)); + REG_CLR_BIT(HP_APM_INT_EN_REG, BIT(path)); } } /** - * @brief APM Ctrl clock auto gating enable + * @brief Get controller interrupt source number from HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param enable Flag for HP clock auto gating enable/disable + * @param path Access path + * @return Interrupt source number */ -static inline void apm_ll_apm_ctrl_clk_gating_enable(apm_ll_apm_ctrl_t apm_ctrl, bool enable) +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_SET_BIT(APM_LL_APM_CTRL_CLOCK_GATE_REG(apm_ctrl), APM_CTRL_CLK_EN); + REG_CLR_BIT(HP_APM_CLOCK_GATE_REG, HP_APM_CLK_EN); } else { - REG_CLR_BIT(APM_LL_APM_CTRL_CLOCK_GATE_REG(apm_ctrl), APM_CTRL_CLK_EN); + REG_SET_BIT(HP_APM_CLOCK_GATE_REG, HP_APM_CLK_EN); } } /** - * @brief APM/TEE/HP System Reg reset event bypass enable + * @brief Enable/disable controller filter for specific path in LP-APM * - * Disable: tee_reg/apm_reg/hp_system_reg will not only be reset by power-reset, - * but also some reset events. - * Enable: tee_reg/apm_reg/hp_system_reg will only be reset by power-reset. - * Some reset events will be bypassed. - * - * @param enable Flag for event bypass enable/disable + * @param path Access path + * @param enable True to enable, false to disable */ -static inline void apm_ll_apm_ctrl_reset_event_enable(bool enable) +static inline void apm_ll_lp_apm_enable_ctrl_filter(apm_ctrl_access_path_t path, bool enable) +{ + (void)path; + if (enable) { + REG_SET_BIT(LP_APM_FUNC_CTRL_REG, LP_APM_M0_FUNC_EN); + } else { + REG_CLR_BIT(LP_APM_FUNC_CTRL_REG, LP_APM_M0_FUNC_EN); + } +} + +/** + * @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) +{ + (void)path; + return REG_READ(LP_APM_M0_EXCEPTION_INFO0_REG); +} + +/** + * @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) +{ + (void)path; + return REG_READ(LP_APM_M0_STATUS_REG); +} + +/** + * @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) +{ + (void)path; + return REG_READ(LP_APM_M0_EXCEPTION_INFO1_REG); +} + +/** + * @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) +{ + (void)path; + REG_SET_BIT(LP_APM_M0_STATUS_CLR_REG, LP_APM_M0_EXCEPTION_STATUS_CLR); +} + +/** + * @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) +{ + (void)path; + if (enable) { + REG_SET_BIT(LP_APM_INT_EN_REG, LP_APM_M0_APM_INT_EN); + } else { + REG_CLR_BIT(LP_APM_INT_EN_REG, LP_APM_M0_APM_INT_EN); + } +} + +/** + * @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) +{ + (void)path; + return ETS_LP_APM_M0_INTR_SOURCE; +} + +/** + * @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); @@ -384,24 +462,6 @@ static inline void apm_ll_apm_ctrl_reset_event_enable(bool enable) } } -/** - * @brief Fetch the APM Ctrl interrupt source number. - * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param apm_m_path APM Ctrl access patch(M[0:n]) - */ -static inline int apm_ll_apm_ctrl_get_int_src_num(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path) -{ - switch (apm_ctrl) { - case HP_APM_CTRL : - return (ETS_HP_APM_M0_INTR_SOURCE + apm_m_path); - case LP_APM_CTRL : - return (ETS_LP_APM_M0_INTR_SOURCE + apm_m_path); - } - - return -1; -} - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32h2/include/hal/apm_ll.h b/components/hal/esp32h2/include/hal/apm_ll.h index cc0046ce27..3428628ffe 100644 --- a/components/hal/esp32h2/include/hal/apm_ll.h +++ b/components/hal/esp32h2/include/hal/apm_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,377 +7,423 @@ #include #include -#include "esp_err.h" -#include "soc/pcr_reg.h" + +#include "soc/apm_defs.h" #include "soc/tee_reg.h" -#include "soc/lp_apm0_reg.h" #include "soc/hp_apm_reg.h" +#include "soc/hp_apm_struct.h" #include "soc/lp_apm_reg.h" +#include "soc/lp_apm_struct.h" + +#include "soc/pcr_reg.h" #include "soc/interrupts.h" +#include "hal/apm_types.h" #ifdef __cplusplus extern "C" { #endif -#define APM_LL_CTRL_EXCEPTION_ID 0x0000001FU -#define APM_LL_CTRL_EXCEPTION_ID_S 18 -#define APM_LL_CTRL_EXCEPTION_ID_V 0x0000001FU -#define APM_LL_CTRL_EXCEPTION_MODE 0x00000003U -#define APM_LL_CTRL_EXCEPTION_MODE_S 16 -#define APM_LL_CTRL_EXCEPTION_MODE_V 0x00000003U -#define APM_LL_CTRL_EXCEPTION_REGION 0x0000FFFFU -#define APM_LL_CTRL_EXCEPTION_REGION_S 0 -#define APM_LL_CTRL_EXCEPTION_REGION_V 0x0000FFFFU - -#define APM_LL_HP_MAX_REGION_NUM 15 -#define APM_LL_LP_MAX_REGION_NUM 3 -#define APM_LL_MASTER_MAX 32 - -#define HP_APM_MAX_ACCESS_PATH 0x4 -#define LP_APM_MAX_ACCESS_PATH 0x1 - -#define APM_CTRL_REGION_FILTER_EN_REG(apm_ctrl) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION_FILTER_EN_REG) : \ - (HP_APM_REGION_FILTER_EN_REG); \ - }) - -#define TEE_LL_MODE_CTRL_REG(master_id) (TEE_M0_MODE_CTRL_REG + 4 * (master_id)) - -#define APM_LL_REGION_ADDR_START_REG(apm_ctrl, regn_num) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num)) : \ - (HP_APM_REGION0_ADDR_START_REG + 0xC * (regn_num)); \ - }) - -#define APM_LL_REGION_ADDR_END_REG(apm_ctrl, regn_num) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num)) : \ - (HP_APM_REGION0_ADDR_END_REG + 0xC * (regn_num)); \ - }) - -#define APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_REGION0_PMS_ATTR_REG + 0xC * (regn_num)) : \ - (HP_APM_REGION0_PMS_ATTR_REG + 0xC * (regn_num)); \ - }) - -#define APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)); \ - }) - -#define APM_CTRL_M_REGION_STATUS_CLR (BIT(0)) -#define APM_LL_APM_CTRL_EXCP_CLR_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)) : \ - (HP_APM_M0_STATUS_CLR_REG + 0x10 * (apm_m_path)); \ - }) - -#define APM_LL_TEE_EXCP_INFO0_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)) : \ - (HP_APM_M0_EXCEPTION_INFO0_REG + 0x10 * (apm_m_path)); \ - }) - -#define APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)) : \ - (HP_APM_M0_STATUS_REG + 0x10 * (apm_m_path)); \ - }) - -#define APM_LL_TEE_EXCP_INFO1_REG(apm_ctrl, apm_m_path) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)) : \ - (HP_APM_M0_EXCEPTION_INFO1_REG + 0x10 * (apm_m_path)); \ - }) - -#define APM_LL_SEC_MODE_REGION_ATTR(sec_mode, regn_pms) ((regn_pms) << (4 * (sec_mode - 1))) -#define APM_LL_SEC_MODE_REGION_ATTR_V 0x00000003U -#define APM_LL_SEC_MODE_REGION_ATTR_M(sec_mode) (APM_LL_SEC_MODE_REGION_ATTR_V << (4 * (sec_mode - 1))) - -#define APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_INT_EN_REG) : \ - (HP_APM_INT_EN_REG); \ - }) - -#define APM_CTRL_CLK_EN (BIT(0)) -#define APM_LL_APM_CTRL_CLOCK_GATE_REG(apm_ctrl) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_CLOCK_GATE_REG) : \ - (HP_APM_CLOCK_GATE_REG); \ - }) - -#define APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl) \ - ({\ - (LP_APM_CTRL == apm_ctrl) ? (LP_APM_FUNC_CTRL_REG) : \ - (HP_APM_FUNC_CTRL_REG); \ - }) +/* Helper macros for calculating pms attr field position for given security mode */ +#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)) /** - * @brief APM Master ID - */ -typedef enum { - APM_LL_MASTER_HPCORE = 0, - APM_LL_MASTER_LPCORE = 1, - APM_LL_MASTER_REGDMA = 2, - APM_LL_MASTER_SDIOSLV = 3, - APM_LL_MASTER_MODEM = 4, - APM_LL_MASTER_MEM_MONITOR = 5, - APM_LL_MASTER_TRACE = 6, - APM_LL_MASTER_GDMA = 16, // The beginning of GDMA master ID - APM_LL_MASTER_GDMA_SPI2 = 16, - APM_LL_MASTER_GDMA_UHCI0 = 18, - APM_LL_MASTER_GDMA_I2S0 = 19, - APM_LL_MASTER_GDMA_AES = 22, - APM_LL_MASTER_GDMA_SHA = 23, - APM_LL_MASTER_GDMA_ADC = 24, - APM_LL_MASTER_GDMA_PARLIO = 25, -} apm_ll_master_id_t; - -/** - * @brief APM Controller - */ -typedef enum { - LP_APM_CTRL = 0, - HP_APM_CTRL = 1, -} apm_ll_apm_ctrl_t; - -/** - * @brief APM Secure Mode - */ -typedef enum { - APM_LL_SECURE_MODE_TEE = 0, /* Trusted execution environment mode */ - APM_LL_SECURE_MODE_REE0 = 1, /* Rich execution environment mode0 */ - APM_LL_SECURE_MODE_REE1 = 2, /* Rich execution environment mode1 */ - APM_LL_SECURE_MODE_REE2 = 3, /* Rich execution environment mode2 */ -} apm_ll_secure_mode_t; - -/** - * @brief APM Ctrl access path - */ -typedef enum { - APM_CTRL_ACCESS_PATH_M0 = 0x0, - APM_CTRL_ACCESS_PATH_M1 = 0x1, - APM_CTRL_ACCESS_PATH_M2 = 0x2, - APM_CTRL_ACCESS_PATH_M3 = 0x3, -} apm_ll_ctrl_access_path_t; - -/** - * @brief APM Ctrl path. - */ -typedef struct { - apm_ll_apm_ctrl_t apm_ctrl; /* APM Ctrl: LP APM/HP APM. */ - apm_ll_ctrl_access_path_t apm_m_path; /* APM Ctrl access path M[0:n]. */ -} apm_ctrl_path_t; - -/** - * @brief APM exception information - */ -typedef struct { - apm_ctrl_path_t apm_path; - uint8_t excp_regn; - uint8_t excp_mode; - uint8_t excp_id; - uint8_t excp_type; - uint32_t excp_addr; -} apm_ctrl_exception_info_t; - -/** - * @brief Set secure mode + * @brief Set security mode for a specific master in HP-TEE * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param master_id APM master ID - * @param sec_mode Secure mode + * @param id Master ID + * @param mode Security mode to set */ -static inline void apm_tee_ll_set_master_secure_mode(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_master_id_t master_id, - apm_ll_secure_mode_t sec_mode) +static inline void apm_ll_hp_tee_set_master_sec_mode(apm_master_id_t id, apm_security_mode_t mode) { - if (apm_ctrl == HP_APM_CTRL) { - REG_WRITE(TEE_LL_MODE_CTRL_REG(master_id), sec_mode); - } + REG_WRITE(TEE_M0_MODE_CTRL_REG + APM_TEE_MODE_CTRL_OFFSET * id, mode); } /** - * @brief TEE controller clock auto gating enable + * @brief Enable/disable clock gating for HP-TEE * - * @param enable Flag for HP clock auto gating enable/disable + * @param enable True to enable, false to disable */ -static inline void apm_tee_ll_clk_gating_enable(bool enable) +static inline void apm_ll_hp_tee_enable_clk_gating(bool enable) { if (enable) { - REG_SET_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); - } else { REG_CLR_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); + } else { + REG_SET_BIT(TEE_CLOCK_GATE_REG, TEE_CLK_EN); } } /** - * @brief enable/disable APM Ctrl Region access permission filter + * @brief Enable/disable controller filter for specific path in HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param regn_num Memory Region number - * @param enable Flag for Region access filter enable/disable + * @param path Access path + * @param enable True to enable, false to disable */ -static inline void apm_ll_apm_ctrl_region_filter_enable(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, bool enable) +static inline void apm_ll_hp_apm_enable_ctrl_filter(apm_ctrl_access_path_t path, bool enable) { if (enable) { - REG_SET_BIT(APM_CTRL_REGION_FILTER_EN_REG(apm_ctrl), BIT(regn_num)); + REG_SET_BIT(HP_APM_FUNC_CTRL_REG, BIT(path)); } else { - REG_CLR_BIT(APM_CTRL_REGION_FILTER_EN_REG(apm_ctrl), BIT(regn_num)); + REG_CLR_BIT(HP_APM_FUNC_CTRL_REG, BIT(path)); } } /** - * @brief enable/disable APM Ctrl access path(M[0:n]) + * @brief Enable/disable all controller filters in HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param apm_m_path APM Ctrl access path - * @param enable Flag for APM Ctrl M path filter enable/disable + * @param enable True to enable, false to disable */ -static inline void apm_ll_apm_ctrl_filter_enable(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path, bool enable) +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(APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl), BIT(apm_m_path)); + REG_SET_BIT(HP_APM_REGION_FILTER_EN_REG, BIT(regn_num)); } else { - REG_CLR_BIT(APM_LL_APM_CTRL_FUNC_CTRL_REG(apm_ctrl), BIT(apm_m_path)); + REG_CLR_BIT(HP_APM_REGION_FILTER_EN_REG, BIT(regn_num)); } } /** - * @brief APM Ctrl Region start address configuration + * @brief Set region start address in HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param regn_num Region number to be configured - * @param addr Region start address + * @param regn_num Region number + * @param addr Start address */ -static inline void apm_ll_apm_ctrl_set_region_start_address(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, uint32_t addr) +static inline void apm_ll_hp_apm_set_region_start_addr(uint32_t regn_num, uint32_t addr) { - REG_WRITE(APM_LL_REGION_ADDR_START_REG(apm_ctrl, regn_num), addr); + REG_WRITE(HP_APM_REGION0_ADDR_START_REG + APM_REGION_ADDR_OFFSET * regn_num, addr); } /** - * @brief APM Ctrl Region end address configuration + * @brief Set region end address in HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param regn_num Region number to be configured - * @param addr Region end address + * @param regn_num Region number + * @param addr End address */ -static inline void apm_ll_apm_ctrl_set_region_end_address(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, uint32_t addr) +static inline void apm_ll_hp_apm_set_region_end_addr(uint32_t regn_num, uint32_t addr) { - REG_WRITE(APM_LL_REGION_ADDR_END_REG(apm_ctrl, regn_num), addr); + REG_WRITE(HP_APM_REGION0_ADDR_END_REG + APM_REGION_ADDR_OFFSET * regn_num, addr); } /** - * @brief HP Region pms attributes configuration + * @brief Set security mode region attributes in HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param regn_num Region number to be configured - * @param sec_mode Secure mode of the Master - * @param regn_pms XWR permissions for the given secure mode and Region number + * @param regn_num Region number + * @param mode Security mode + * @param regn_pms Region PMS attributes */ -static inline void apm_ll_apm_ctrl_sec_mode_region_attr_config(apm_ll_apm_ctrl_t apm_ctrl, - uint32_t regn_num, apm_ll_secure_mode_t sec_mode, uint32_t regn_pms) +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 val = 0; - val = REG_READ(APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num)); - val &= ~APM_LL_SEC_MODE_REGION_ATTR_M(sec_mode); - val |= APM_LL_SEC_MODE_REGION_ATTR(sec_mode, regn_pms); - REG_WRITE(APM_LL_REGION_ADDR_ATTR_REG(apm_ctrl, regn_num), val); + uint32_t reg = HP_APM_REGION0_PMS_ATTR_REG + APM_REGION_PMS_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 Get APM Ctrl access path(M[0:n]) exception status + * @brief Get exception data (regn, master, security mode) from HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param apm_m_path APM Ctrl access path + * @param path Access path + * @return Exception data */ -static inline uint8_t apm_ll_apm_ctrl_exception_status(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path) +static inline uint32_t apm_ll_hp_apm_get_excp_data(apm_ctrl_access_path_t path) { - return REG_READ(APM_LL_APM_CTRL_EXCP_STATUS_REG(apm_ctrl, apm_m_path)); + return REG_READ(HP_APM_M0_EXCEPTION_INFO0_REG + APM_EXCP_INFO_OFFSET * path); } /** - * @brief Clear APM Ctrl access path(M[0:n]) exception + * @brief Get exception status from HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param amp_m_path APM Ctrl access path + * @param path Access path + * @return Exception type */ -static inline void apm_ll_apm_ctrl_exception_clear(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path) +static inline uint32_t apm_ll_hp_apm_get_excp_type(apm_ctrl_access_path_t path) { - REG_SET_BIT(APM_LL_APM_CTRL_EXCP_CLR_REG(apm_ctrl, apm_m_path), - APM_CTRL_M_REGION_STATUS_CLR); + return REG_READ(HP_APM_M0_STATUS_REG + APM_EXCP_INFO_OFFSET * path); } /** - * @brief Get APM Ctrl access path(M[0:n]) exception information + * @brief Get exception address from HP-APM * - * @param excp_info Exception related information like addr, - * region, apm_ctrl, apm_m_path, sec_mode and master id + * @param path Access path + * @return Exception address */ -static inline void apm_ll_apm_ctrl_get_exception_info(apm_ctrl_exception_info_t *excp_info) +static inline uint32_t apm_ll_hp_apm_get_excp_addr(apm_ctrl_access_path_t path) { - excp_info->excp_id = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), - APM_LL_CTRL_EXCEPTION_ID); - excp_info->excp_mode = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), - APM_LL_CTRL_EXCEPTION_MODE); - excp_info->excp_regn = REG_GET_FIELD(APM_LL_TEE_EXCP_INFO0_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path), - APM_LL_CTRL_EXCEPTION_REGION); - excp_info->excp_type = apm_ll_apm_ctrl_exception_status(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path); - excp_info->excp_addr = REG_READ(APM_LL_TEE_EXCP_INFO1_REG(excp_info->apm_path.apm_ctrl, excp_info->apm_path.apm_m_path)); + return REG_READ(HP_APM_M0_EXCEPTION_INFO1_REG + APM_EXCP_INFO_OFFSET * path); } /** - * @brief Interrupt enable for APM Ctrl at access path(M[0:n]) + * @brief Get exception information from HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param apm_m_path APM Ctrl access patch(M[0:n]) - * @param enable Flag for access path interrupt enable/disable + * @param path Access path + * @param info Pointer to store exception information */ -static inline void apm_ll_apm_ctrl_interrupt_enable(apm_ll_apm_ctrl_t apm_ctrl, - apm_ll_ctrl_access_path_t apm_m_path, bool enable) +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(APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl), BIT(apm_m_path)); + REG_SET_BIT(HP_APM_INT_EN_REG, BIT(path)); } else { - REG_CLR_BIT(APM_LL_APM_CTRL_INT_EN_REG(apm_ctrl), BIT(apm_m_path)); + REG_CLR_BIT(HP_APM_INT_EN_REG, BIT(path)); } } /** - * @brief APM Ctrl clock auto gating enable + * @brief Get controller interrupt source number from HP-APM * - * @param apm_ctrl APM Ctrl (LP_APM/HP_APM) - * @param enable Flag for HP clock auto gating enable/disable + * @param path Access path + * @return Interrupt source number */ -static inline void apm_ll_apm_ctrl_clk_gating_enable(apm_ll_apm_ctrl_t apm_ctrl, bool enable) +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_SET_BIT(APM_LL_APM_CTRL_CLOCK_GATE_REG(apm_ctrl), APM_CTRL_CLK_EN); + REG_CLR_BIT(HP_APM_CLOCK_GATE_REG, HP_APM_CLK_EN); } else { - REG_CLR_BIT(APM_LL_APM_CTRL_CLOCK_GATE_REG(apm_ctrl), APM_CTRL_CLK_EN); + REG_SET_BIT(HP_APM_CLOCK_GATE_REG, HP_APM_CLK_EN); } } /** - * @brief APM/TEE/HP System Reg reset event bypass enable + * @brief Enable/disable controller filter for specific path in LP-APM * - * Disable: tee_reg/apm_reg/hp_system_reg will not only be reset by power-reset, - * but also some reset events. - * Enable: tee_reg/apm_reg/hp_system_reg will only be reset by power-reset. - * Some reset events will be bypassed. - * - * @param enable Flag for event bypass enable/disable + * @param path Access path + * @param enable True to enable, false to disable */ -static inline void apm_ll_apm_ctrl_reset_event_enable(bool enable) +static inline void apm_ll_lp_apm_enable_ctrl_filter(apm_ctrl_access_path_t path, bool enable) +{ + (void)path; + if (enable) { + REG_SET_BIT(LP_APM_FUNC_CTRL_REG, LP_APM_M0_PMS_FUNC_EN); + } else { + REG_CLR_BIT(LP_APM_FUNC_CTRL_REG, LP_APM_M0_PMS_FUNC_EN); + } +} + +/** + * @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_PMS_ATTR_REG + APM_REGION_PMS_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 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) +{ + (void)path; + return REG_READ(LP_APM_M0_EXCEPTION_INFO0_REG); +} + +/** + * @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) +{ + (void)path; + return REG_READ(LP_APM_M0_STATUS_REG); +} + +/** + * @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) +{ + (void)path; + return REG_READ(LP_APM_M0_EXCEPTION_INFO1_REG); +} + +/** + * @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) +{ + (void)path; + REG_SET_BIT(LP_APM_M0_STATUS_CLR_REG, LP_APM_M0_REGION_STATUS_CLR); +} + +/** + * @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) +{ + (void)path; + if (enable) { + REG_SET_BIT(LP_APM_INT_EN_REG, LP_APM_M0_APM_INT_EN); + } else { + REG_CLR_BIT(LP_APM_INT_EN_REG, LP_APM_M0_APM_INT_EN); + } +} + +/** + * @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) +{ + (void)path; + return ETS_LP_APM_M0_INTR_SOURCE; +} + +/** + * @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); @@ -386,24 +432,6 @@ static inline void apm_ll_apm_ctrl_reset_event_enable(bool enable) } } -/** - * @brief Fetch the APM Ctrl interrupt source number. - * - * @param apm_ctrl APM Ctrl (LP_APM0/HP_APM/LP_APM) - * @param apm_m_path APM Ctrl access patch(M[0:n]) - */ -static inline int apm_ll_apm_ctrl_get_int_src_num(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_ctrl_access_path_t apm_m_path) -{ - switch (apm_ctrl) { - case HP_APM_CTRL : - return (ETS_HP_APM_M0_INTR_SOURCE + apm_m_path); - case LP_APM_CTRL : - return (ETS_LP_APM_M0_INTR_SOURCE + apm_m_path); - } - - return -1; -} - #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/apm_hal.h b/components/hal/include/hal/apm_hal.h index 6f95b26af4..3e9bf80771 100644 --- a/components/hal/include/hal/apm_hal.h +++ b/components/hal/include/hal/apm_hal.h @@ -9,10 +9,12 @@ extern "C" { #endif +#include #include "esp_err.h" #include "soc/soc_caps.h" #if SOC_APM_SUPPORTED #include "hal/apm_ll.h" +#include "hal/apm_types.h" #if CONFIG_IDF_TARGET_ESP32P4 @@ -102,158 +104,234 @@ void apm_hal_dma_region_pms(apm_hal_dma_region_config_data_t *pms_data); #else /** - * @brief Region configuration data. + * @brief Helper macro to create a region entry configuration + * + */ +#define APM_HAL_REGION_ENTRY_BASE(PATH,NUM, START, END, PMS) \ + .path_id = (PATH), \ + .regn_num = (NUM), \ + .regn_start_addr = ((START) & ~0x03U), \ + .regn_end_addr = (((END) - 1U) & ~0x03U), \ + .regn_pms = (PMS), \ + .filter_en = true + + +#if SOC_APM_SUPPORT_CTRL_CFG_LOCK +#define APM_HAL_REGION_ENTRY(PATH, NUM, START, END, PMS, LOCK) \ + { APM_HAL_REGION_ENTRY_BASE(PATH, NUM, START, END, PMS), .lock_en = LOCK } +#else +#define APM_HAL_REGION_ENTRY(PATH, NUM, START, END, PMS) \ + { APM_HAL_REGION_ENTRY_BASE(PATH, NUM, START, END, PMS) } +#endif + +/** + * @brief Helper macro to create a security mode configuration + * + */ +#define APM_HAL_SEC_MODE_CFG(CTRL_MOD, MODE, REGNS) \ + { \ + .ctrl_mod = (CTRL_MOD), \ + .mode = (MODE), \ + .regn_count = sizeof(REGNS) / sizeof((REGNS)[0]), \ + .regions = (REGNS), \ + } + +/** + * @brief APM controller info structure */ typedef struct { - uint32_t regn_num; /* Address Region number cover by this configuration data. */ - uint32_t regn_start_addr; /* Address Region start address. */ - uint32_t regn_end_addr; /* Address Region end address. */ - uint32_t regn_pms; /* Access Permission for Master in different secure mode. */ - bool filter_enable; /* Address Region Filter enable/disable. */ - apm_ll_apm_ctrl_t apm_ctrl; /* APM Ctrl: LP APM0/HP APM/LP APM. */ - apm_ll_secure_mode_t sec_mode; /* Master secure mode: TEE/REE[0-2].*/ -} apm_ctrl_region_config_data_t; + apm_ctrl_module_t ctrl_mod; /*!< APM controller module */ + apm_ctrl_access_path_t path; /*!< Access path */ +} apm_hal_ctrl_info_t; /** - * @brief Secure mode(TEE/REE[0:2] configuration data. + * @brief APM region configuration structure */ typedef struct { - apm_ll_apm_ctrl_t apm_ctrl; /* APM Ctrl: LP APM0/HP APM/LP APM. */ - apm_ll_secure_mode_t sec_mode; /* Secure mode to be configured TEE/REE[0:2]. */ - uint8_t apm_m_cnt; /* Access path M count. */ - uint32_t regn_count; /* Access Ctrl region count. */ - uint32_t master_ids; /* Bit mask for masters to be part of this secure mode. */ - apm_ctrl_region_config_data_t *pms_data; /* Region configuration data. */ -} apm_ctrl_secure_mode_config_t; + apm_ctrl_access_path_t path_id; /*!< Path identifier */ + uint32_t regn_num; /*!< Region number */ + uint32_t regn_start_addr; /*!< Region start address */ + uint32_t regn_end_addr; /*!< Region end address */ + uint32_t regn_pms; /*!< Region permissions */ + bool filter_en; /*!< Filter enable flag */ +#if SOC_APM_SUPPORT_CTRL_CFG_LOCK + bool lock_en; /*!< Lock enable flag */ +#endif +} apm_hal_ctrl_region_cfg_t; /** - * @brief Set secure mode - * - * @param apm_ctrl APM Ctrl to be configured - * @param master_id APM master ID - * @param sec_mode Secure mode + * @brief APM security mode configuration structure */ -void apm_tee_hal_set_master_secure_mode(apm_ll_apm_ctrl_t apm_ctrl, apm_ll_master_id_t master_id, - apm_ll_secure_mode_t sec_mode); +typedef struct { + apm_ctrl_module_t ctrl_mod; /*!< APM controller module */ + apm_security_mode_t mode; /*!< Security mode */ + uint32_t regn_count; /*!< Number of regions */ + apm_hal_ctrl_region_cfg_t *regions; /*!< Array of region configurations */ +} apm_hal_ctrl_sec_mode_cfg_t; /** - * @brief Set all masters to a given secure mode + * @brief Set security mode for specified masters * - * @param sec_mode Secure mode + * @param master_mask Mask of masters to configure + * @param mode Security mode to set */ -void apm_tee_hal_set_master_secure_mode_all(apm_ll_secure_mode_t sec_mode); +void apm_hal_set_master_sec_mode(uint32_t master_mask, apm_security_mode_t mode); /** - * @brief TEE controller clock auto gating enable + * @brief Set security mode for all masters * - * @param enable Flag for HP clock auto gating enable/disable + * @param mode Security mode to set */ -void apm_tee_hal_clk_gating_enable(bool enable); +void apm_hal_set_master_sec_mode_all(apm_security_mode_t mode); + +#if SOC_APM_SUPPORT_CTRL_CFG_LOCK +/** + * @brief Lock security mode for specified masters + * + * @param master_mask Mask of masters to configure + */ +void apm_hal_lock_master_sec_mode(uint32_t master_mask); /** - * @brief enable/disable APM Ctrl Region access permission filter + * @brief Lock security mode for all masters * - * @param apm_ctrl APM Ctrl to be configured - * @param regn_num Memory Region number - * @param enable Flag for Region access filter enable/disable */ -void apm_hal_apm_ctrl_region_filter_enable(apm_ll_apm_ctrl_t apm_ctrl, uint32_t regn_num, bool enable); +void apm_hal_lock_master_sec_mode_all(void); +#endif + +#if SOC_APM_SUPPORT_TEE_PERI_ACCESS_CTRL +/** + * @brief Set access permissions for the specified peripherals in the given TEE ctrl module + * + * @param ctrl_mod TEE ctrl module + * @param periph_mask Peripheral mask + * @param mode Security mode + * @param pms Access permissions + */ +void apm_hal_tee_set_peri_access(apm_tee_ctrl_module_t ctrl_mod, uint64_t periph_mask, apm_security_mode_t mode, apm_perm_t pms); /** - * @brief enable/disable APM Ctrl access path(M[0:n]) + * @brief Set access permissions for all peripherals in the given TEE ctrl module * - * @param apm_path APM controller and access path to be configured - * @param enable Flag for M path filter enable/disable + * @param ctrl_mod TEE ctrl module + * @param mode Security mode + * @param pms Access permissions */ -void apm_hal_apm_ctrl_filter_enable(apm_ctrl_path_t *apm_path, bool enable); +void apm_hal_tee_set_peri_access_all(apm_tee_ctrl_module_t ctrl_mod, apm_security_mode_t mode, apm_perm_t pms); +#endif /** - * @brief enable/disable all available APM Ctrl access path(M[0:n]) + * @brief Enable/disable TEE clock gating for a APM controller module * - * @param enable Flag for M path filter enable/disable + * @param ctrl_mod TEE controller module + * @param enable True to enable, false to disable */ -void apm_hal_apm_ctrl_filter_enable_all(bool enable); +void apm_hal_tee_enable_clk_gating(apm_tee_ctrl_module_t ctrl_mod, bool enable); /** - * @brief Region configuration + * @brief Enable/disable controller filter for specific path * - * @param pms_data Region configuration data + * @param ctrl_mod APM controller module + * @param path Access path + * @param enable True to enable, false to disable */ -void apm_hal_apm_ctrl_region_config(const apm_ctrl_region_config_data_t *pms_data); +void apm_hal_enable_ctrl_filter(apm_ctrl_module_t ctrl_mod, apm_ctrl_access_path_t path, bool enable); /** - * @brief Get APM Ctrl access path(M[0:n]) exception status + * @brief Enable/disable all controller filters * - * @param apm_path APM controller and access path to be configured + * @param enable True to enable, false to disable */ -uint8_t apm_hal_apm_ctrl_exception_status(apm_ctrl_path_t *apm_path); +void apm_hal_enable_ctrl_filter_all(bool enable); /** - * @brief Clear APM Ctrl access path(M[0:n]) exception + * @brief Enable/disable region filter * - * @param apm_path APM controller and access path to be configured + * @param ctrl_mod APM controller module + * @param regn_num Region number + * @param enable True to enable, false to disable */ -void apm_hal_apm_ctrl_exception_clear(apm_ctrl_path_t *apm_path); +void apm_hal_enable_region_filter(apm_ctrl_module_t ctrl_mod, uint32_t regn_num, bool enable); /** - * @brief Get APM Ctrl access path exception information + * @brief Set region filter configuration * - * @param excp_info Exception related information like addr, - * region, amp_ctrl, apm_m_path, sec_mode and master id + * @param ctrl_mod APM controller module + * @param mode Security mode + * @param regn_cfg Region configuration */ -void apm_hal_apm_ctrl_get_exception_info(apm_ctrl_exception_info_t *excp_info); +void apm_hal_set_region_filter_cfg(apm_ctrl_module_t ctrl_mod, apm_security_mode_t mode, const apm_hal_ctrl_region_cfg_t *regn_cfg); + +#if SOC_APM_SUPPORT_CTRL_CFG_LOCK +/** + * @brief Lock region filter configuration + * + * @param ctrl_mod APM controller module + * @param regn_num Region number + */ +void apm_hal_lock_region_filter_cfg(apm_ctrl_module_t ctrl_mod, uint32_t regn_num); +#endif /** - * @brief APM Ctrl interrupt enable for access path(M[0:n]) + * @brief Set controller security mode configuration * - * @param apm_path APM controller and access path to be configured - * @param enable Flag for access path interrupt enable/disable + * @param cfg Security mode configuration */ -void apm_hal_apm_ctrl_interrupt_enable(apm_ctrl_path_t *apm_path, bool enable); +void apm_hal_set_ctrl_sec_mode_cfg(const apm_hal_ctrl_sec_mode_cfg_t *cfg); /** - * @brief APM Ctrl clock auto gating enable + * @brief Get exception type * - * @apm_ctrl APM Ctrl - * @param enable Flag for HP clock auto gating enable/disable + * @param ctrl_info Controller information + * @return Exception type */ -void apm_hal_apm_ctrl_clk_gating_enable(apm_ll_apm_ctrl_t apm_ctrl, bool enable); +uint32_t apm_hal_get_exception_type(apm_hal_ctrl_info_t *ctrl_info); /** - * @brief TEE/REE execution environment configuration. + * @brief Clear exception status * - * This API will be called from TEE mode initialization code which is - * responsible to setup TEE/REE execution environment. - * It includes, allocation of all bus masters, memory ranges and other - * peripherals to the given secure mode. - * All this information should be passed by the TEE mode initialization code. - * - * @sec_mode_data APM Ctl configuration data. + * @param ctrl_info Controller information */ -void apm_hal_apm_ctrl_master_sec_mode_config(apm_ctrl_secure_mode_config_t *sec_mode_data); +void apm_hal_clear_exception_status(apm_hal_ctrl_info_t *ctrl_info); /** - * @brief APM/TEE/HP System Reg reset event bypass enable + * @brief Get exception information * - * Disable: tee_reg/apm_reg/hp_system_reg will not only be reset by power-reset, - * but also some reset events. - * Enable: tee_reg/apm_reg/hp_system_reg will only be reset by power-reset. - * Some reset events will be bypassed. - * - * @param enable Flag for event bypass enable/disable + * @param ctrl_info Controller information + * @param excp_info Exception information structure to fill */ -void apm_hal_apm_ctrl_reset_event_enable(bool enable); +void apm_hal_get_exception_info(apm_hal_ctrl_info_t *ctrl_info, apm_ctrl_exception_info_t *excp_info); /** - * @brief Fetch the APM Ctrl access path interrupt source number. + * @brief Enable/disable interrupt * - * @param apm_path APM controller and access path to be configured - * - * @return - * - valid interrupt source number on success - * - -1: invalid interrupt source + * @param ctrl_info Controller information + * @param enable True to enable, false to disable */ -int apm_hal_apm_ctrl_get_int_src_num(apm_ctrl_path_t *apm_path); +void apm_hal_enable_intr(apm_hal_ctrl_info_t *ctrl_info, bool enable); + +/** + * @brief Get interrupt source number + * + * @param ctrl_info Controller information + * @return Interrupt source number + */ +int apm_hal_get_intr_src_num(apm_hal_ctrl_info_t *ctrl_info); + +/** + * @brief Enable/disable reset event bypass + * + * @param enable True to enable, false to disable + */ +void apm_hal_enable_reset_event_bypass(bool enable); + +/** + * @brief Enable/disable controller clock gating + * + * @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 //CONFIG_IDF_TARGET_ESP32P4 @@ -261,14 +339,14 @@ int apm_hal_apm_ctrl_get_int_src_num(apm_ctrl_path_t *apm_path); #if CONFIG_IDF_TARGET_ESP32H4 #include "soc/hp_apm_reg.h" -#define apm_hal_apm_ctrl_filter_enable_all(en) \ +#define apm_hal_enable_ctrl_filter_all(en) \ REG_WRITE(HP_APM_FUNC_CTRL_REG, en ? 0xFFFFFFFF : 0); #else #include "soc/hp_apm_reg.h" #include "soc/lp_apm_reg.h" #include "soc/lp_apm0_reg.h" -#define apm_hal_apm_ctrl_filter_enable_all(en) \ +#define apm_hal_enable_ctrl_filter_all(en) \ REG_WRITE(LP_APM_FUNC_CTRL_REG, en ? 0xFFFFFFFF : 0); \ REG_WRITE(LP_APM0_FUNC_CTRL_REG, en ? 0xFFFFFFFF : 0); \ REG_WRITE(HP_APM_FUNC_CTRL_REG, en ? 0xFFFFFFFF : 0); diff --git a/components/hal/include/hal/apm_types.h b/components/hal/include/hal/apm_types.h index 26a474faf8..b01633c3f7 100644 --- a/components/hal/include/hal/apm_types.h +++ b/components/hal/include/hal/apm_types.h @@ -1,22 +1,121 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once +#include +#include "soc/soc_caps.h" + #ifdef __cplusplus extern "C" { #endif /** - * @brief APM Region PMS authority + * @brief Master IDs for APM */ typedef enum { - APM_REGION_PMS_X = 0x1, /*!< Region executive authority. */ - APM_REGION_PMS_W = 0x2, /*!< Region write authority. */ - APM_REGION_PMS_R = 0x4, /*!< Region read authority. */ -} apm_region_pms_t; + APM_MASTER_HPCORE = 0, /*!< HP CPU */ +#if SOC_LP_CORE_SUPPORTED + APM_MASTER_LPCORE = 1, /*!< LP CPU */ +#endif /* SOC_LP_CORE_SUPPORTED */ + APM_MASTER_REGDMA = 2, +#if SOC_SDIO_SLAVE_SUPPORTED + APM_MASTER_SDIOSLV = 3, /*!< SDIO slave */ +#endif /* SOC_SDIO_SLAVE_SUPPORTED */ + APM_MASTER_MODEM = 4, /*!< Modem */ + APM_MASTER_MEM_MON = 5, /*!< Memory monitor */ + APM_MASTER_TRACE = 6, /*!< Trace */ +#if SOC_SPIRAM_SUPPORTED + APM_MASTER_PSRAM_MEM_MON = 8, /*!< PSRAM memory monitor */ +#endif /* SOC_SPIRAM_SUPPORTED */ +#if SOC_GPSPI_SUPPORTED && SOC_AHB_GDMA_VERSION == 1 + APM_MASTER_GDMA_GPSPI = 16, /*!< GDMA for GPSPI/SPI2 */ +#elif SOC_GPSPI_SUPPORTED && SOC_AHB_GDMA_VERSION == 2 + APM_MASTER_GDMA_GPSPI = 17, +#endif /* SOC_GPSPI_SUPPORTED */ +#if SOC_UHCI_SUPPORTED + APM_MASTER_GDMA_UHCI = 18, /*!< GDMA for UHCI */ +#endif /* SOC_UHCI_SUPPORTED */ + APM_MASTER_GDMA_I2S = 19, /*!< GDMA for I2S */ +#if SOC_AES_SUPPORTED + APM_MASTER_GDMA_AES = 22, /*!< GDMA for AES */ +#endif /* SOC_AES_SUPPORTED */ + APM_MASTER_GDMA_SHA = 23, /*!< GDMA for SHA */ + APM_MASTER_GDMA_ADC = 24, /*!< GDMA for ADC */ +#if SOC_PARLIO_SUPPORTED + APM_MASTER_GDMA_PARLIO = 25, /*!< GDMA for PARLIO */ +#endif /* SOC_PARLIO_SUPPORTED */ + APM_MASTER_MAX = 32, /*!< Maximum master ID */ +} apm_master_id_t; + +/** + * @brief APM controller modules + */ +typedef enum { + APM_CTRL_HP_APM = 0, /*!< High-performance APM controller */ +#if SOC_APM_LP_APM0_SUPPORTED + APM_CTRL_LP_APM0, /*!< Low-power APM0 controller */ +#endif + APM_CTRL_LP_APM, /*!< Low-power APM controller */ +#if SOC_APM_CPU_APM_SUPPORTED + APM_CTRL_CPU_APM, /*!< CPU APM controller */ +#endif +} apm_ctrl_module_t; + +/** + * @brief TEE controller modules + */ +typedef enum { + APM_TEE_CTRL_HP = 0, /*!< High-performance TEE controller */ +#if SOC_APM_SUPPORT_LP_TEE_CTRL + APM_TEE_CTRL_LP = 1, /*!< Low-power TEE controller */ +#endif +} apm_tee_ctrl_module_t; + +/** + * @brief APM controller access paths + */ +typedef enum { + APM_CTRL_ACCESS_PATH_M0 = 0, /*!< Access path M0 */ + APM_CTRL_ACCESS_PATH_M1 = 1, /*!< Access path M1 */ + APM_CTRL_ACCESS_PATH_M2 = 2, /*!< Access path M2 */ + APM_CTRL_ACCESS_PATH_M3 = 3, /*!< Access path M3 */ + APM_CTRL_ACCESS_PATH_M4 = 4, /*!< Access path M4 */ +} apm_ctrl_access_path_t; + +/** + * @brief Security modes for APM + */ +typedef enum { + APM_SEC_MODE_TEE = 0, /*!< Trusted Execution Environment mode */ + APM_SEC_MODE_REE0 = 1, /*!< Rich Execution Environment mode 0 */ + APM_SEC_MODE_REE1 = 2, /*!< Rich Execution Environment mode 1 */ + APM_SEC_MODE_REE2 = 3, /*!< Rich Execution Environment mode 2 */ +} apm_security_mode_t; + +/** + * @brief Access permission flags + */ +typedef enum { + APM_PERM_NONE = 0, /*!< No permissions */ + APM_PERM_X = 1, /*!< Execute */ + APM_PERM_W = 2, /*!< Write */ + APM_PERM_R = 4, /*!< Read */ + 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 } diff --git a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in index 8d4f1df11e..9d8d2d9c39 100644 --- a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in @@ -1443,6 +1443,18 @@ config SOC_APM_LP_APM0_SUPPORTED bool default y +config SOC_APM_CPU_APM_SUPPORTED + bool + default y + +config SOC_APM_SUPPORT_LP_TEE_CTRL + bool + default y + +config SOC_APM_SUPPORT_CTRL_CFG_LOCK + bool + default y + config SOC_APM_SUPPORT_TEE_PERI_ACCESS_CTRL bool default y diff --git a/components/soc/esp32c5/include/soc/apm_defs.h b/components/soc/esp32c5/include/soc/apm_defs.h new file mode 100644 index 0000000000..0095add7b4 --- /dev/null +++ b/components/soc/esp32c5/include/soc/apm_defs.h @@ -0,0 +1,127 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_bit_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Number of paths for each supported APM controller */ +#define APM_CTRL_HP_APM_PATH_NUM (5) +#define APM_CTRL_LP_APM0_PATH_NUM (1) +#define APM_CTRL_LP_APM_PATH_NUM (2) +#define APM_CTRL_CPU_APM_PATH_NUM (2) +/* Number of regions for each supported APM controller */ +#define APM_CTRL_HP_APM_REGION_NUM (16) +#define APM_CTRL_LP_APM0_REGION_NUM (8) +#define APM_CTRL_LP_APM_REGION_NUM (8) +#define APM_CTRL_CPU_APM_REGION_NUM (8) + +/* Register offset for TEE mode control */ +#define APM_TEE_MODE_CTRL_OFFSET (0x04) +/* Register offset between TEE ctrl periph registers */ +#define APM_TEE_PERI_CTRL_OFFSET (0x04) +/* Register offset between region bound address registers */ +#define APM_REGION_ADDR_OFFSET (0x0C) +/* Register offset between region pms attribute registers */ +#define APM_REGION_ATTR_OFFSET (0x0C) +/* Register offset between exception info registers */ +#define APM_EXCP_INFO_OFFSET (0x10) + +/* Bit to clear exception status */ +#define APM_EXCP_STATUS_CLR_BIT (BIT(0)) +/* Bit to lock TEE mode */ +#define APM_TEE_MODE_LOCK_BIT (BIT(2)) +/* Bit to lock region pms attributes */ +#define APM_REGION_LOCK_BIT (BIT(11)) + +/* APM controller masters mask */ +#define APM_MASTER_MASK_ALL (0x03CE017FU) +/* HP-TEE controller peripherals mask */ +#define APM_TEE_HP_PERIPH_MASK_ALL (0x0017FF7FFC7DFEEFULL) +/* LP-TEE controller peripherals mask */ +#define APM_TEE_LP_PERIPH_MASK_ALL (0x0007B4FFULL) + +/** + * @brief HP-TEE Controller Peripherals + */ +typedef enum { + APM_TEE_HP_PERIPH_UART0 = 0, /*!< UART0 */ + APM_TEE_HP_PERIPH_UART1, /*!< UART1 */ + APM_TEE_HP_PERIPH_UHCI0, /*!< UHCI0 */ + APM_TEE_HP_PERIPH_I2C_EXT0, /*!< I2C0 */ + APM_TEE_HP_PERIPH_I2S = 5, /*!< I2S */ + APM_TEE_HP_PERIPH_PARL_IO, /*!< Parallel IO */ + APM_TEE_HP_PERIPH_PWM, /*!< PWM */ + APM_TEE_HP_PERIPH_LEDC = 9, /*!< LED Control */ + APM_TEE_HP_PERIPH_TWAI0, /*!< TWAI0 */ + APM_TEE_HP_PERIPH_USB_SJ, /*!< USB Serial JTAG */ + APM_TEE_HP_PERIPH_RMT, /*!< RMT */ + APM_TEE_HP_PERIPH_GDMA, /*!< GDMA */ + APM_TEE_HP_PERIPH_REGDMA, /*!< REGDMA */ + APM_TEE_HP_PERIPH_ETM, /*!< Event Task Matrix */ + APM_TEE_HP_PERIPH_INTMTX, /*!< Interrupt Matrix */ + APM_TEE_HP_PERIPH_APB_ADC = 18, /*!< ADC */ + APM_TEE_HP_PERIPH_TG0, /*!< Timer Group 0 */ + APM_TEE_HP_PERIPH_TG1, /*!< Timer Group 1 */ + APM_TEE_HP_PERIPH_SYSTIMER, /*!< Systimer */ + APM_TEE_HP_PERIPH_MISC, /*!< Misc */ + APM_TEE_HP_PERIPH_PVT_MON = 26, /*!< PVT Monitor */ + APM_TEE_HP_PERIPH_PCNT, /*!< Pulse Counter */ + APM_TEE_HP_PERIPH_IOMUX, /*!< IO MUX */ + APM_TEE_HP_PERIPH_PSRAM_MON, /*!< PSRAM Monitor */ + APM_TEE_HP_PERIPH_MEM_MON, /*!< Memory Monitor */ + APM_TEE_HP_PERIPH_SYSTEM_REG, /*!< System registers */ + APM_TEE_HP_PERIPH_PCR_REG, /*!< PCR registers */ + APM_TEE_HP_PERIPH_MSPI, /*!< MSPI */ + APM_TEE_HP_PERIPH_HP_APM, /*!< HP APM */ + APM_TEE_HP_PERIPH_CPU_APM, /*!< CPU APM */ + APM_TEE_HP_PERIPH_TEE, /*!< TEE */ + APM_TEE_HP_PERIPH_CRYPTO, /*!< Crypto */ + APM_TEE_HP_PERIPH_TRACE, /*!< Trace */ + APM_TEE_HP_PERIPH_CPU_BUS_MON = 40, /*!< CPU Bus Monitor */ + APM_TEE_HP_PERIPH_INTPRI_REG, /*!< Interrupt Priority registers */ + APM_TEE_HP_PERIPH_CACHE_CFG, /*!< Cache */ + APM_TEE_HP_PERIPH_MODEM, /*!< Modem */ + APM_TEE_HP_PERIPH_TWAI1, /*!< TWAI1 */ + APM_TEE_HP_PERIPH_SPI2, /*!< SPI2 */ + APM_TEE_HP_PERIPH_BIT_SCRAMBLER, /*!< Bit Scrambler */ + APM_TEE_HP_PERIPH_KEY_MANAGER, /*!< Key Manager */ + APM_TEE_HP_PERIPH_MODEM_PWR, /*!< Modem Power */ + APM_TEE_HP_PERIPH_HINF, /*!< Host Interface */ + APM_TEE_HP_PERIPH_SLC, /*!< SLC */ + APM_TEE_HP_PERIPH_SLC_HOST = 52, /*!< SLC Host */ + APM_TEE_HP_PERIPH_MAX /*!< Maximum ID */ +} apm_tee_hp_periph_t; + +/** + * @brief LP-TEE Controller Peripherals + */ +typedef enum { + APM_TEE_LP_PERIPH_EFUSE = 0, /*!< EFUSE */ + APM_TEE_LP_PERIPH_PMU, /*!< PMU */ + APM_TEE_LP_PERIPH_CLKRST, /*!< CLKRST */ + APM_TEE_LP_PERIPH_LP_AON_CTRL, /*!< LP_AON_CTRL */ + APM_TEE_LP_PERIPH_LP_TIMER, /*!< LP_TIMER */ + APM_TEE_LP_PERIPH_LP_WDT, /*!< LP_WDT */ + APM_TEE_LP_PERIPH_LP_PERI, /*!< LP_PERI */ + APM_TEE_LP_PERIPH_LP_ANA_PERI, /*!< LP_ANA_PERI */ + APM_TEE_LP_PERIPH_LP_IO = 10, /*!< LP_IO */ + APM_TEE_LP_PERIPH_LP_TEE = 12, /*!< LP_TEE */ + APM_TEE_LP_PERIPH_UART, /*!< UART */ + APM_TEE_LP_PERIPH_I2C_EXT = 15, /*!< I2C_EXT */ + APM_TEE_LP_PERIPH_I2C_ANA_MST, /*!< I2C_ANA_MST */ + APM_TEE_LP_PERIPH_HUK, /*!< HUK */ + APM_TEE_LP_PERIPH_LP_APM, /*!< LP_APM */ + APM_TEE_LP_PERIPH_MAX /*!< Max ID */ +} apm_tee_lp_periph_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c5/include/soc/soc_caps.h b/components/soc/esp32c5/include/soc/soc_caps.h index e10357be40..ce7be2a876 100644 --- a/components/soc/esp32c5/include/soc/soc_caps.h +++ b/components/soc/esp32c5/include/soc/soc_caps.h @@ -562,9 +562,12 @@ #define SOC_BOOTLOADER_ANTI_ROLLBACK_SUPPORTED (0) /*-------------------------- APM CAPS-----------------------------------------*/ -#define SOC_APM_CTRL_FILTER_SUPPORTED 1 /*!< Support for APM control filter */ -#define SOC_APM_LP_APM0_SUPPORTED 1 /*!< Support for LP APM0 control filter */ -#define SOC_APM_SUPPORT_TEE_PERI_ACCESS_CTRL 1 /*!< Support for TEE controller per-peripheral access control */ +#define SOC_APM_CTRL_FILTER_SUPPORTED 1 /*!< Support for APM control filter */ +#define SOC_APM_LP_APM0_SUPPORTED 1 /*!< Support for LP APM0 control filter */ +#define SOC_APM_CPU_APM_SUPPORTED 1 /*!< Support for CPU APM control filter */ +#define SOC_APM_SUPPORT_LP_TEE_CTRL 1 /*!< Support for LP TEE controller */ +#define SOC_APM_SUPPORT_CTRL_CFG_LOCK 1 /*!< Support for APM controller configuration lock */ +#define SOC_APM_SUPPORT_TEE_PERI_ACCESS_CTRL 1 /*!< Support for TEE controller per-peripheral access control */ /*------------------------ Anti DPA (Security) CAPS --------------------------*/ #define SOC_CRYPTO_DPA_PROTECTION_SUPPORTED 1 diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index ad161377a5..5ce5ce225a 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -1299,6 +1299,10 @@ config SOC_APM_LP_APM0_SUPPORTED bool default y +config SOC_APM_SUPPORT_LP_TEE_CTRL + bool + default y + config SOC_CRYPTO_DPA_PROTECTION_SUPPORTED bool default y diff --git a/components/soc/esp32c6/include/soc/apm_defs.h b/components/soc/esp32c6/include/soc/apm_defs.h new file mode 100644 index 0000000000..f1d0278238 --- /dev/null +++ b/components/soc/esp32c6/include/soc/apm_defs.h @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_bit_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Number of paths for each supported APM controller */ +#define APM_CTRL_HP_APM_PATH_NUM (4) +#define APM_CTRL_LP_APM0_PATH_NUM (1) +#define APM_CTRL_LP_APM_PATH_NUM (2) +/* Number of regions for each supported APM controller */ +#define APM_CTRL_HP_APM_REGION_NUM (16) +#define APM_CTRL_LP_APM0_REGION_NUM (4) +#define APM_CTRL_LP_APM_REGION_NUM (4) + +/* Register offset for TEE mode control */ +#define APM_TEE_MODE_CTRL_OFFSET (0x04) +/* Register offset between region bound address registers */ +#define APM_REGION_ADDR_OFFSET (0x0C) +/* Register offset between region pms attribute registers */ +#define APM_REGION_PMS_ATTR_OFFSET (0x0C) +/* Register offset between exception info registers */ +#define APM_EXCP_INFO_OFFSET (0x10) + +/* Bit to clear exception status */ +#define APM_EXCP_STATUS_CLR_BIT (BIT(0)) + +/* APM controller masters mask */ +#define APM_MASTER_MASK_ALL (0x03CD007FU) + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 13981837e8..69ee2751bb 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -498,8 +498,9 @@ #define SOC_FLASH_ENCRYPTION_XTS_AES_128 1 /*-------------------------- APM CAPS ----------------------------------------*/ -#define SOC_APM_CTRL_FILTER_SUPPORTED 1 /*!< Support for APM control filter */ -#define SOC_APM_LP_APM0_SUPPORTED 1 /*!< Support for LP APM0 control filter */ +#define SOC_APM_CTRL_FILTER_SUPPORTED 1 /*!< Support for APM control filter */ +#define SOC_APM_LP_APM0_SUPPORTED 1 /*!< Support for LP APM0 control filter */ +#define SOC_APM_SUPPORT_LP_TEE_CTRL 1 /*!< Support for LP TEE controller */ /*------------------------ Anti DPA (Security) CAPS --------------------------*/ #define SOC_CRYPTO_DPA_PROTECTION_SUPPORTED 1 diff --git a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in index 123eae8110..e4a7c84796 100644 --- a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in @@ -967,6 +967,10 @@ config SOC_APM_CTRL_FILTER_SUPPORTED bool default y +config SOC_APM_SUPPORT_CTRL_CFG_LOCK + bool + default y + config SOC_CRYPTO_DPA_PROTECTION_SUPPORTED bool default y diff --git a/components/soc/esp32c61/include/soc/apm_defs.h b/components/soc/esp32c61/include/soc/apm_defs.h new file mode 100644 index 0000000000..a239f3b8b1 --- /dev/null +++ b/components/soc/esp32c61/include/soc/apm_defs.h @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_bit_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Number of paths for each supported APM controller */ +#define APM_CTRL_HP_APM_PATH_NUM (4) +#define APM_CTRL_LP_APM_PATH_NUM (1) +/* Number of regions for each supported APM controller */ +#define APM_CTRL_HP_APM_REGION_NUM (16) +#define APM_CTRL_LP_APM_REGION_NUM (4) + +/* Register offset for TEE mode control */ +#define APM_TEE_MODE_CTRL_OFFSET (0x04) +/* Register offset between region bound address registers */ +#define APM_REGION_ADDR_OFFSET (0x0C) +/* Register offset between region pms attribute registers */ +#define APM_REGION_ATTR_OFFSET (0x0C) +/* Register offset between exception info registers */ +#define APM_EXCP_INFO_OFFSET (0x10) + +/* Bit to clear exception status */ +#define APM_EXCP_STATUS_CLR_BIT (BIT(0)) +/* Bit to lock TEE mode */ +#define APM_TEE_MODE_LOCK_BIT (BIT(2)) +/* Bit to lock region pms attributes */ +#define APM_REGION_LOCK_BIT (BIT(11)) + +/* APM controller masters mask */ +#define APM_MASTER_MASK_ALL (0x018E0175U) + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c61/include/soc/soc_caps.h b/components/soc/esp32c61/include/soc/soc_caps.h index 489c91b559..bcddd1ddca 100644 --- a/components/soc/esp32c61/include/soc/soc_caps.h +++ b/components/soc/esp32c61/include/soc/soc_caps.h @@ -402,6 +402,7 @@ /*-------------------------- APM CAPS ----------------------------------------*/ #define SOC_APM_CTRL_FILTER_SUPPORTED 1 /*!< Support for APM control filter */ +#define SOC_APM_SUPPORT_CTRL_CFG_LOCK 1 /*!< Support for APM controller configuration lock */ /*------------------------ Anti DPA (Security) CAPS --------------------------*/ #define SOC_CRYPTO_DPA_PROTECTION_SUPPORTED 1 diff --git a/components/soc/esp32h2/include/soc/apm_defs.h b/components/soc/esp32h2/include/soc/apm_defs.h new file mode 100644 index 0000000000..8abbce9bac --- /dev/null +++ b/components/soc/esp32h2/include/soc/apm_defs.h @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_bit_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Number of paths for each supported APM controller */ +#define APM_CTRL_HP_APM_PATH_NUM (4) +#define APM_CTRL_LP_APM_PATH_NUM (1) +/* Number of regions for each supported APM controller */ +#define APM_CTRL_HP_APM_REGION_NUM (16) +#define APM_CTRL_LP_APM_REGION_NUM (2) + +/* Register offset for TEE mode control */ +#define APM_TEE_MODE_CTRL_OFFSET (0x04) +/* Register offset between region bound address registers */ +#define APM_REGION_ADDR_OFFSET (0x0C) +/* Register offset between region pms attribute registers */ +#define APM_REGION_PMS_ATTR_OFFSET (0x0C) +/* Register offset between exception info registers */ +#define APM_EXCP_INFO_OFFSET (0x10) + +/* Bit to clear exception status */ +#define APM_EXCP_STATUS_CLR_BIT (BIT(0)) + +/* APM controller masters mask */ +#define APM_MASTER_MASK_ALL (0x03CD0075U) + +#ifdef __cplusplus +} +#endif