diff --git a/components/esp_hw_support/port/esp32c5/cpu_region_protect.c b/components/esp_hw_support/port/esp32c5/cpu_region_protect.c index 4ad4a33bc2..5d2ccd14bf 100644 --- a/components/esp_hw_support/port/esp32c5/cpu_region_protect.c +++ b/components/esp_hw_support/port/esp32c5/cpu_region_protect.c @@ -51,31 +51,45 @@ static void esp_cpu_configure_invalid_regions(void) PMA_RESET_AND_ENTRY_SET_TOR(3, SOC_IROM_MASK_LOW, PMA_NONE); PMA_RESET_AND_ENTRY_SET_TOR(4, SOC_DROM_MASK_HIGH, PMA_TOR | PMA_RX); - // 3. Gap between ROM & RAM - PMA_RESET_AND_ENTRY_SET_TOR(5, SOC_DROM_MASK_HIGH, PMA_NONE); - PMA_RESET_AND_ENTRY_SET_TOR(6, SOC_IRAM_LOW, PMA_TOR | PMA_NONE); + // 3. Gap between DRAM and I_Cache + PMA_RESET_AND_ENTRY_SET_TOR(5, SOC_IRAM_HIGH, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(6, SOC_IROM_LOW, PMA_TOR | PMA_NONE); - // 4. Gap between DRAM and I_Cache - PMA_RESET_AND_ENTRY_SET_TOR(7, SOC_IRAM_HIGH, PMA_NONE); - PMA_RESET_AND_ENTRY_SET_TOR(8, SOC_IROM_LOW, PMA_TOR | PMA_NONE); - - // 5. ROM has configured the MSPI region with RX permission, we should add W attribute for psram and lock the configuration + // 4. ROM has configured the MSPI region with RX permission, we should add W attribute for psram and lock the configuration // This function sets invalid regions but this is a valid memory region configuration that could have // been configured using PMP as well, but due to insufficient PMP entries we are configuring this using PMA. // This entry is also required to be set using PMA because the region needs to be configured as cacheable. - PMA_RESET_AND_ENTRY_SET_NAPOT(9, SOC_IROM_LOW, (SOC_IROM_HIGH - SOC_IROM_LOW), PMA_NAPOT | PMA_RWX); + PMA_RESET_AND_ENTRY_SET_NAPOT(7, SOC_IROM_LOW, (SOC_IROM_HIGH - SOC_IROM_LOW), PMA_NAPOT | PMA_RWX); - // 6. Gap between D_Cache & LP_RAM - PMA_RESET_AND_ENTRY_SET_TOR(10, SOC_DROM_HIGH, PMA_NONE); - PMA_RESET_AND_ENTRY_SET_TOR(11, SOC_RTC_IRAM_LOW, PMA_TOR | PMA_NONE); + // 5. Gap between D_Cache & LP_RAM + PMA_RESET_AND_ENTRY_SET_TOR(8, SOC_DROM_HIGH, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(9, SOC_RTC_IRAM_LOW, PMA_TOR | PMA_NONE); - // 7. Gap between LP memory & peripheral addresses - PMA_RESET_AND_ENTRY_SET_TOR(12, SOC_RTC_IRAM_HIGH, PMA_NONE); - PMA_RESET_AND_ENTRY_SET_TOR(13, SOC_PERIPHERAL_LOW, PMA_TOR | PMA_NONE); + // 6. End of address space + PMA_RESET_AND_ENTRY_SET_TOR(10, SOC_PERIPHERAL_HIGH, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(11, UINT32_MAX, PMA_TOR | PMA_NONE); - // 8. End of address space - PMA_RESET_AND_ENTRY_SET_TOR(14, SOC_PERIPHERAL_HIGH, PMA_NONE); - PMA_RESET_AND_ENTRY_SET_TOR(15, UINT32_MAX, PMA_TOR | PMA_NONE); + /* NOTE: ESP-TEE [IDF-13827] + * + * Reserving some PMA entries to repurpose them for partitioning the + * TEE SRAM as IRAM (RX) and DRAM (RW). Thus, with ESP-TEE enabled, + * invalid region accesses to the LP memory → peripherals and + * ROM → RAM regions will not raise exceptions. (treated as no-ops) + */ +#if !CONFIG_SECURE_ENABLE_TEE + // 9. Gap between ROM & RAM + PMA_RESET_AND_ENTRY_SET_TOR(12, SOC_DROM_MASK_HIGH, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(13, SOC_IRAM_LOW, PMA_TOR | PMA_NONE); + + // 10. Gap between LP memory & peripheral addresses + PMA_RESET_AND_ENTRY_SET_TOR(14, SOC_RTC_IRAM_HIGH, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(15, SOC_PERIPHERAL_LOW, PMA_TOR | PMA_NONE); +#else + PMA_ENTRY_CFG_RESET(12); + PMA_ENTRY_CFG_RESET(13); + PMA_ENTRY_CFG_RESET(14); + PMA_ENTRY_CFG_RESET(15); +#endif } void esp_cpu_configure_region_protection(void) diff --git a/components/esp_tee/subproject/main/soc/esp32c5/esp_tee_pmp_pma_prot_cfg.c b/components/esp_tee/subproject/main/soc/esp32c5/esp_tee_pmp_pma_prot_cfg.c index 4f08db8df8..25f797fe43 100644 --- a/components/esp_tee/subproject/main/soc/esp32c5/esp_tee_pmp_pma_prot_cfg.c +++ b/components/esp_tee/subproject/main/soc/esp32c5/esp_tee_pmp_pma_prot_cfg.c @@ -12,6 +12,57 @@ #include "esp32c5/rom/rom_layout.h" #include "esp_tee.h" +#define IS_PMA_ENTRY_UNLOCKED(ENTRY) \ + ((RV_READ_CSR((CSR_PMACFG0) + (ENTRY)) & PMA_L) == 0) + +static void esp_tee_configure_invalid_regions(void) +{ + const unsigned PMA_NONE = PMA_L | PMA_EN; + __attribute__((unused)) const unsigned PMA_RW = PMA_L | PMA_EN | PMA_R | PMA_W; + __attribute__((unused)) const unsigned PMA_RX = PMA_L | PMA_EN | PMA_R | PMA_X; + __attribute__((unused)) const unsigned PMA_RWX = PMA_L | PMA_EN | PMA_R | PMA_W | PMA_X; + + // ROM uses some PMA entries, so we need to clear them before using them in ESP-IDF + + // 0. Gap at bottom of address space + PMA_RESET_AND_ENTRY_SET_NAPOT(0, 0, SOC_CPU_SUBSYSTEM_LOW, PMA_NAPOT | PMA_NONE); + + // 1. Gap between debug region & IROM + PMA_RESET_AND_ENTRY_SET_TOR(1, SOC_CPU_SUBSYSTEM_HIGH, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(2, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE); + + // 2. ROM has configured the ROM region to be cacheable, so we just need to lock the configuration + PMA_RESET_AND_ENTRY_SET_TOR(3, SOC_IROM_MASK_LOW, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(4, SOC_DROM_MASK_HIGH, PMA_TOR | PMA_RX); + + // 3. Gap between DRAM and I_Cache + PMA_RESET_AND_ENTRY_SET_TOR(5, SOC_IRAM_HIGH, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(6, SOC_IROM_LOW, PMA_TOR | PMA_NONE); + + // 4. ROM has configured the MSPI region with RX permission, we should add W attribute for psram and lock the configuration + // This function sets invalid regions but this is a valid memory region configuration that could have + // been configured using PMP as well, but due to insufficient PMP entries we are configuring this using PMA. + // This entry is also required to be set using PMA because the region needs to be configured as cacheable. + PMA_RESET_AND_ENTRY_SET_NAPOT(7, SOC_IROM_LOW, (SOC_IROM_HIGH - SOC_IROM_LOW), PMA_NAPOT | PMA_RWX); + + // 5. Gap between D_Cache & LP_RAM + PMA_RESET_AND_ENTRY_SET_TOR(8, SOC_DROM_HIGH, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(9, SOC_RTC_IRAM_LOW, PMA_TOR | PMA_NONE); + + // 6. End of address space + PMA_RESET_AND_ENTRY_SET_TOR(10, SOC_PERIPHERAL_HIGH, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(11, UINT32_MAX, PMA_TOR | PMA_NONE); + + // 7. Using PMA to configure the TEE text and data section access attribute. */ + PMA_ENTRY_CFG_RESET(12); + assert(IS_PMA_ENTRY_UNLOCKED(13)); + assert(IS_PMA_ENTRY_UNLOCKED(14)); + assert(IS_PMA_ENTRY_UNLOCKED(15)); + PMA_RESET_AND_ENTRY_SET_TOR(13, SOC_S_IRAM_START, PMA_NONE); + PMA_RESET_AND_ENTRY_SET_TOR(14, SOC_S_IRAM_END, PMA_TOR | PMA_RX); + PMA_RESET_AND_ENTRY_SET_TOR(15, SOC_S_DRAM_END, PMA_TOR | PMA_RW); +} + void esp_tee_configure_region_protection(void) { /* Notes on implementation: @@ -33,6 +84,13 @@ void esp_tee_configure_region_protection(void) const unsigned RX = PMP_L | PMP_R | PMP_X; const unsigned RWX = PMP_L | PMP_R | PMP_W | PMP_X; + // + // Configure all the invalid address regions using PMA + // + // We lock the PMA entries since they mark the invalid regions and is applicable to both the privilege modes + // + esp_tee_configure_invalid_regions(); + // // Configure all the valid address regions using PMP // @@ -69,7 +127,6 @@ void esp_tee_configure_region_protection(void) PMP_ENTRY_SET(5, SOC_IRAM_HIGH, PMP_TOR | RWX); _Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid RAM region"); } else { - // TODO: [IDF-13827] TEE SRAM region to be partitioned into text and data sections using APM // REE SRAM (D/IRAM) PMP_ENTRY_SET(4, (int)SOC_NS_IRAM_START, NONE); PMP_ENTRY_SET(5, (int)esp_tee_app_config.ns_iram_end, PMP_TOR | RX); diff --git a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_panic.c b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_panic.c index 115ed26010..612c0d475b 100644 --- a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_panic.c +++ b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_panic.c @@ -116,8 +116,6 @@ TEST_CASE("Test TEE-TEE violation: Reserved-X1", "[exception]") TEST_FAIL_MESSAGE("Exception should have been generated"); } -// TODO: [IDF-13827] Enable when TEE SRAM is partitioned as IRAM (RX) and DRAM (RW) -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C5) /* TEE IRAM: Reserved/Vector-table boundary */ TEST_CASE("Test TEE-TEE violation: IRAM-W1", "[exception]") { @@ -145,7 +143,6 @@ TEST_CASE("Test TEE-TEE violation: DRAM-X2", "[exception]") esp_tee_service_call(1, SS_ESP_TEE_TEST_DRAM_REG2_EXEC_VIOLATION); TEST_FAIL_MESSAGE("Exception should have been generated"); } -#endif /* Illegal Instruction */ TEST_CASE("Test TEE-TEE violation: Illegal Instruction", "[exception]")