From 340de9823aa43b462b33794294a38fa0d016f1b4 Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Wed, 30 Apr 2025 19:43:30 +0530 Subject: [PATCH] feat(esp_tee): Support for ESP32-C5 - the rest of the components --- components/esp_hw_support/include/esp_cpu.h | 25 ++++- .../port/esp32c5/mspi_timing_tuning_configs.h | 8 +- .../port/esp32c5/CMakeLists.txt | 4 +- .../port/esp32c5/cpu_region_protect.c | 8 ++ .../port/esp32c5/esp_cpu_intr.c | 17 ++- .../port/esp32c6/esp_cpu_intr.c | 4 +- .../port/esp32h2/cpu_region_protect.c | 4 + .../port/esp32h2/esp_cpu_intr.c | 4 +- .../esp_mm/port/esp32c5/ext_mem_layout.c | 33 +++++- components/esp_rom/CMakeLists.txt | 9 +- components/esp_rom/esp32c5/ld/esp32c5.rom.ld | 2 +- components/esp_rom/include/esp_rom_tlsf.h | 16 ++- .../esp_rom/patches/esp_rom_cache_esp32c5.c | 32 ++++++ components/esp_rom/patches/esp_rom_sys.c | 2 +- components/esp_system/ld/esp32c5/memory.ld.in | 20 +++- .../esp_system/ld/esp32c5/sections.ld.in | 13 +++ components/esp_system/port/cpu_start.c | 32 ++++-- components/esp_system/port/soc/esp32c5/clk.c | 6 +- components/hal/spi_flash_hal_common.inc | 13 ++- .../priv_include/esp32c5/test_rv_utils.h | 4 - .../priv_include/esp32c61/test_rv_utils.h | 4 - components/heap/port/esp32c5/memory_layout.c | 15 ++- .../esp_tee/esp_tee_crypto_shared_gdma.c | 105 +++++++++++------- .../mbedtls/esp_tee/esp_tee_mbedtls_config.h | 12 ++ components/riscv/CMakeLists.txt | 2 + .../include/esp_private/interrupt_clic.h | 56 ++++++++-- components/riscv/include/riscv/interrupt.h | 2 +- components/riscv/include/riscv/rv_utils.h | 16 ++- components/riscv/interrupt_clic.c | 43 ++++++- components/riscv/vectors.S | 23 ++++ components/soc/esp32c5/register/soc/tee_reg.h | 1 - 31 files changed, 437 insertions(+), 98 deletions(-) create mode 100644 components/esp_rom/patches/esp_rom_cache_esp32c5.c diff --git a/components/esp_hw_support/include/esp_cpu.h b/components/esp_hw_support/include/esp_cpu.h index 1ae8d4daa2..cbecbafff6 100644 --- a/components/esp_hw_support/include/esp_cpu.h +++ b/components/esp_hw_support/include/esp_cpu.h @@ -271,15 +271,33 @@ FORCE_INLINE_ATTR void esp_cpu_intr_set_mtvt_addr(const void *mtvt_addr) { rv_utils_set_mtvt((uint32_t)mtvt_addr); } + +/** + * @brief Set the base address of the current CPU's Interrupt Vector Table (XTVT), based + * on the current privilege level + * + * @param xtvt_addr Interrupt Vector Table's base address + * + * @note The XTVT table is only applicable when CLIC is supported + */ +FORCE_INLINE_ATTR void esp_cpu_intr_set_xtvt_addr(const void *xtvt_addr) +{ + rv_utils_set_xtvt((uint32_t)xtvt_addr); +} #endif //#if SOC_INT_CLIC_SUPPORTED #if SOC_CPU_SUPPORT_WFE /** * @brief Disable the WFE (wait for event) feature for CPU. */ -FORCE_INLINE_ATTR void rv_utils_disable_wfe_mode(void) +FORCE_INLINE_ATTR void esp_cpu_disable_wfe_mode(void) { +#if CONFIG_SECURE_ENABLE_TEE && !NON_OS_BUILD + extern esprv_int_mgmt_t esp_tee_intr_sec_srv_cb; + esp_tee_intr_sec_srv_cb(2, SS_RV_UTILS_WFE_MODE_ENABLE, false); +#else rv_utils_wfe_mode_enable(false); +#endif } #endif @@ -450,9 +468,14 @@ FORCE_INLINE_ATTR uint32_t esp_cpu_intr_get_enabled_mask(void) { #ifdef __XTENSA__ return xt_utils_intr_get_enabled_mask(); +#else +#if CONFIG_SECURE_ENABLE_TEE && !NON_OS_BUILD && CONFIG_IDF_TARGET_ESP32C5 + extern esprv_int_mgmt_t esp_tee_intr_sec_srv_cb; + return esp_tee_intr_sec_srv_cb(1, SS_RV_UTILS_INTR_GET_ENABLED_MASK); #else return rv_utils_intr_get_enabled_mask(); #endif +#endif } /** diff --git a/components/esp_hw_support/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h b/components/esp_hw_support/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h index a4a623e598..82558dbb9e 100644 --- a/components/esp_hw_support/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h +++ b/components/esp_hw_support/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h @@ -28,7 +28,10 @@ #define MSPI_TIMING_FLASH_MODULE_CLOCK 120 #endif //------------------------------------FLASH Needs Tuning or not-------------------------------------// -#if MSPI_TIMING_FLASH_STR_MODE +/* TODO: [ESP-TEE | IDF-10425] The SPI1 controller is protected by APM when ESP-TEE is enabled. + * MSPI tuning requires access to this controller, so it is currently disabled. + */ +#if MSPI_TIMING_FLASH_STR_MODE && !CONFIG_SECURE_ENABLE_TEE #define MSPI_TIMING_FLASH_NEEDS_TUNING (MSPI_TIMING_FLASH_MODULE_CLOCK > 40) #endif @@ -45,7 +48,8 @@ #define MSPI_TIMING_PSRAM_MODULE_CLOCK 10 //Define this to 10MHz #endif //------------------------------------PSRAM Needs Tuning or not-------------------------------------// -#if MSPI_TIMING_PSRAM_STR_MODE +/* TODO: [ESP-TEE | IDF-10425] */ +#if MSPI_TIMING_PSRAM_STR_MODE && !CONFIG_SECURE_ENABLE_TEE #define MSPI_TIMING_PSRAM_NEEDS_TUNING (MSPI_TIMING_PSRAM_MODULE_CLOCK > 40) #endif diff --git a/components/esp_hw_support/port/esp32c5/CMakeLists.txt b/components/esp_hw_support/port/esp32c5/CMakeLists.txt index 3d96ad1e1c..e1c7e438aa 100644 --- a/components/esp_hw_support/port/esp32c5/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32c5/CMakeLists.txt @@ -1,3 +1,5 @@ +idf_build_get_property(non_os_build NON_OS_BUILD) + set(srcs "rtc_clk_init.c" "rtc_time.c" "rtc_clk.c" @@ -8,7 +10,7 @@ set(srcs "rtc_clk_init.c" "ocode_init.c" ) -if(NOT BOOTLOADER_BUILD) +if(NOT non_os_build) list(APPEND srcs "sar_periph_ctrl.c") endif() 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 91e2e00783..7b3a6dc369 100644 --- a/components/esp_hw_support/port/esp32c5/cpu_region_protect.c +++ b/components/esp_hw_support/port/esp32c5/cpu_region_protect.c @@ -126,6 +126,14 @@ void esp_cpu_configure_region_protection(void) // esp_cpu_configure_invalid_regions(); + /* NOTE: When ESP-TEE is active, only configure invalid memory regions in bootloader + * to prevent errors before TEE initialization. TEE will handle all other + * memory protection. + */ +#if CONFIG_SECURE_ENABLE_TEE && BOOTLOADER_BUILD + return; +#endif + // // Configure all the valid address regions using PMP // diff --git a/components/esp_hw_support/port/esp32c5/esp_cpu_intr.c b/components/esp_hw_support/port/esp32c5/esp_cpu_intr.c index ded3030aeb..65d5b02e68 100644 --- a/components/esp_hw_support/port/esp32c5/esp_cpu_intr.c +++ b/components/esp_hw_support/port/esp32c5/esp_cpu_intr.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,20 @@ void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_ * Reserve interrupt line 1 for the Wifi controller. * Reserve interrupt line 6 since it is used for disabling interrupts in the interrupt allocator (INT_MUX_DISABLED_INTNO) */ - const uint32_t rsvd_mask = BIT(1) | BIT(6); + const uint32_t base_rsvd_mask = BIT(1) | BIT(6); + + /* On the ESP32-C5, interrupt 31 is reserved for ESP-TEE + * for operations related to secure peripherals under its control + * (e.g. AES, SHA, APM) + * + * Interrupt 30 is reserved for handling REE interrupts occurring in TEE. + */ +#if CONFIG_SECURE_ENABLE_TEE + const uint32_t rsvd_mask = base_rsvd_mask | BIT(30) | BIT(31); +#else + const uint32_t rsvd_mask = base_rsvd_mask; +#endif + intr_desc_ret->priority = 1; intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA; intr_desc_ret->flags = esp_riscv_intr_num_flags(intr_num, rsvd_mask); diff --git a/components/esp_hw_support/port/esp32c6/esp_cpu_intr.c b/components/esp_hw_support/port/esp32c6/esp_cpu_intr.c index 2eb79bdd3a..6cb8c037ef 100644 --- a/components/esp_hw_support/port/esp32c6/esp_cpu_intr.c +++ b/components/esp_hw_support/port/esp32c6/esp_cpu_intr.c @@ -19,12 +19,12 @@ void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_ // [TODO: IDF-2465] const uint32_t base_rsvd_mask = BIT(1) | BIT(3) | BIT(4) | BIT(6) | BIT(7); - /* On the ESP32-C6, interrupt 14 is reserved for ESP-TEE + /* On the ESP32-C6, interrupt 31 is reserved for ESP-TEE * for operations related to secure peripherals under its control * (e.g. AES, SHA, APM) */ #if CONFIG_SECURE_ENABLE_TEE - const uint32_t rsvd_mask = base_rsvd_mask | BIT(14); + const uint32_t rsvd_mask = base_rsvd_mask | BIT(31); #else const uint32_t rsvd_mask = base_rsvd_mask; #endif diff --git a/components/esp_hw_support/port/esp32h2/cpu_region_protect.c b/components/esp_hw_support/port/esp32h2/cpu_region_protect.c index a222a60318..698295b018 100644 --- a/components/esp_hw_support/port/esp32h2/cpu_region_protect.c +++ b/components/esp_hw_support/port/esp32h2/cpu_region_protect.c @@ -62,6 +62,10 @@ static void esp_cpu_configure_invalid_regions(void) // 7. End of address space PMA_ENTRY_SET_TOR(11, SOC_PERIPHERAL_HIGH, PMA_NONE); PMA_ENTRY_SET_TOR(12, UINT32_MAX, PMA_TOR | PMA_NONE); + + PMA_ENTRY_CFG_RESET(13); + PMA_ENTRY_CFG_RESET(14); + PMA_ENTRY_CFG_RESET(15); } void esp_cpu_configure_region_protection(void) diff --git a/components/esp_hw_support/port/esp32h2/esp_cpu_intr.c b/components/esp_hw_support/port/esp32h2/esp_cpu_intr.c index bace035293..5114ae24a8 100644 --- a/components/esp_hw_support/port/esp32h2/esp_cpu_intr.c +++ b/components/esp_hw_support/port/esp32h2/esp_cpu_intr.c @@ -18,12 +18,12 @@ void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_ // [TODO: IDF-2465] const uint32_t base_rsvd_mask = BIT(3) | BIT(4) | BIT(6) | BIT(7); - /* On the ESP32-H2, interrupt 14 is reserved for ESP-TEE + /* On the ESP32-H2, interrupt 31 is reserved for ESP-TEE * for operations related to secure peripherals under its control * (e.g. AES, SHA, APM) */ #if CONFIG_SECURE_ENABLE_TEE - const uint32_t rsvd_mask = base_rsvd_mask | BIT(14); + const uint32_t rsvd_mask = base_rsvd_mask | BIT(31); #else const uint32_t rsvd_mask = base_rsvd_mask; #endif diff --git a/components/esp_mm/port/esp32c5/ext_mem_layout.c b/components/esp_mm/port/esp32c5/ext_mem_layout.c index 5797513f45..7bd1b804cd 100644 --- a/components/esp_mm/port/esp32c5/ext_mem_layout.c +++ b/components/esp_mm/port/esp32c5/ext_mem_layout.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +10,31 @@ #include "../ext_mem_layout.h" #include "hal/mmu_types.h" +/* NOTE: With ESP-TEE enabled: + * - The start address is moved by the size of TEE IDROM segments since these + * segments are placed at the start of the linear address space + * - TEE IROM and DROM segments are both 64KB (CONFIG_SECURE_TEE_IROM_SIZE, + * CONFIG_SECURE_TEE_DROM_SIZE) for now. Thus, the number of reserved entries + * from the start would be (64KB + 64KB)/MMU_PAGE_SIZE + * - The last few MMU entries are reserved for TEE flash operations. The number + * of reserved entries matches the size of TEE IDROM segments (IROM + DROM) + * plus one additional entry, i.e. (64KB + 64KB)/MMU_PAGE_SIZE + 1 + */ +#if CONFIG_SECURE_ENABLE_TEE +#define TEE_MMU_MEM_REG_START_OFFS (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE) +#define TEE_MMU_RESV_PAGES ((CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE) / CONFIG_MMU_PAGE_SIZE) +#define TEE_MMU_MEM_REG_END_OFFS ((TEE_MMU_RESV_PAGES + 1) * CONFIG_MMU_PAGE_SIZE) + +#define MMU_MEM_REG_START_ADDR_W_TEE (SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW + TEE_MMU_MEM_REG_START_OFFS) +#define MMU_MEM_REG_END_ADDR_W_TEE (SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH - TEE_MMU_MEM_REG_END_OFFS) + +#define MMU_IRAM0_LINEAR_ADDRESS_LOW MMU_MEM_REG_START_ADDR_W_TEE +#define MMU_IRAM0_LINEAR_ADDRESS_HIGH MMU_MEM_REG_END_ADDR_W_TEE +#else +#define MMU_IRAM0_LINEAR_ADDRESS_LOW SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW +#define MMU_IRAM0_LINEAR_ADDRESS_HIGH SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH +#endif + /** * The start addresses in this list should always be sorted from low to high, as MMU driver will need to * coalesce adjacent regions @@ -17,9 +42,9 @@ // TODO: [ESP32C5] IDF-8658 const mmu_mem_region_t g_mmu_mem_regions[SOC_MMU_LINEAR_ADDRESS_REGION_NUM] = { [0] = { - .start = SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW, - .end = SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH, - .size = SOC_BUS_SIZE(SOC_MMU_IRAM0_LINEAR), + .start = MMU_IRAM0_LINEAR_ADDRESS_LOW, + .end = MMU_IRAM0_LINEAR_ADDRESS_HIGH, + .size = MMU_IRAM0_LINEAR_ADDRESS_HIGH - MMU_IRAM0_LINEAR_ADDRESS_LOW, .bus_id = CACHE_BUS_IBUS0 | CACHE_BUS_DBUS0, .targets = MMU_TARGET_FLASH0 | MMU_TARGET_PSRAM0, .caps = MMU_MEM_CAP_EXEC | MMU_MEM_CAP_READ | MMU_MEM_CAP_WRITE | MMU_MEM_CAP_32BIT | MMU_MEM_CAP_8BIT, diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index aa575b9256..69e01d0abd 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -75,6 +75,10 @@ if(CONFIG_ESP_ROM_NO_USB_SERIAL_OUTPUT_API) list(APPEND sources "patches/esp_rom_usb_serial.c") endif() +if(CONFIG_SECURE_ENABLE_TEE AND CONFIG_IDF_TARGET_ESP32C5 AND NOT ESP_TEE_BUILD) + list(APPEND sources "patches/esp_rom_cache_esp32c5.c") +endif() + idf_component_register(SRCS ${sources} INCLUDE_DIRS ${include_dirs} PRIV_REQUIRES ${private_required_comp} @@ -142,6 +146,9 @@ endif() if(ESP_TEE_BUILD) rom_linker_script("spiflash") rom_linker_script("heap") + if(CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT) + rom_linker_script("newlib-nano") + endif() endif() if(BOOTLOADER_BUILD) @@ -388,7 +395,7 @@ else() # Regular app build endif() endif() - if(CONFIG_ESP_ROM_DELAY_US_PATCH AND + if(CONFIG_ESP_ROM_DELAY_US_PATCH AND CONFIG_SECURE_ENABLE_TEE AND (CONFIG_ESP32C5_REV_MIN_FULL LESS_EQUAL 100 OR CONFIG_ESP32C61_REV_MIN_FULL LESS_EQUAL 100)) # Force the linker to include esp_rom_sys.c for ets_ops_set_rom_patches constructor target_link_libraries(${COMPONENT_LIB} PRIVATE "-u ets_ops_set_rom_patches") diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.ld index 7abce52964..a4bb7e2ddf 100644 --- a/components/esp_rom/esp32c5/ld/esp32c5.rom.ld +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.ld @@ -219,7 +219,7 @@ Cache_Suspend_Cache = 0x400006b4; Cache_Resume_Cache = 0x400006b8; Cache_Freeze_Enable = 0x400006bc; Cache_Freeze_Disable = 0x400006c0; -Cache_Set_IDROM_MMU_Size = 0x400006c4; +PROVIDE ( Cache_Set_IDROM_MMU_Size = 0x400006c4 ); Cache_Get_IROM_MMU_End = 0x400006c8; Cache_Get_DROM_MMU_End = 0x400006cc; Cache_MMU_Init = 0x400006d0; diff --git a/components/esp_rom/include/esp_rom_tlsf.h b/components/esp_rom/include/esp_rom_tlsf.h index dc9481d0e2..89fdfb7533 100644 --- a/components/esp_rom/include/esp_rom_tlsf.h +++ b/components/esp_rom/include/esp_rom_tlsf.h @@ -6,6 +6,7 @@ #pragma once #include #include +#include "sdkconfig.h" #ifdef __cplusplus extern "C" { @@ -17,8 +18,17 @@ typedef void* tlsf_t; typedef void* pool_t; /* Create/destroy a memory pool. */ +#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 tlsf_t tlsf_create(void* mem); tlsf_t tlsf_create_with_pool(void* mem, size_t bytes); +size_t tlsf_size(void); +#else +tlsf_t tlsf_create(void* mem, size_t max_bytes); +tlsf_t tlsf_create_with_pool(void* mem, size_t pool_bytes, size_t max_bytes); +size_t tlsf_size(tlsf_t tlsf); +#endif + +void tlsf_destroy(tlsf_t tlsf); pool_t tlsf_get_pool(tlsf_t tlsf); /* Add/remove memory pools. */ @@ -36,7 +46,6 @@ void tlsf_free(tlsf_t tlsf, void* ptr); size_t tlsf_block_size(void* ptr); /* Overheads/limits of internal structures. */ -size_t tlsf_size(void); size_t tlsf_pool_overhead(void); size_t tlsf_alloc_overhead(void); @@ -47,7 +56,12 @@ size_t tlsf_alloc_overhead(void); */ size_t tlsf_align_size(void); size_t tlsf_block_size_min(void); +#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 size_t tlsf_block_size_max(void); +#else +size_t tlsf_block_size_max(tlsf_t tlsf); +#endif +size_t tlsf_fit_size(tlsf_t tlsf, size_t size); /* NOTE: The consumer of this callback function (tlsf_walk_pool) is patched * in IDF builds to address issues in the ROM implementation. For TEE build, diff --git a/components/esp_rom/patches/esp_rom_cache_esp32c5.c b/components/esp_rom/patches/esp_rom_cache_esp32c5.c new file mode 100644 index 0000000000..7115c54a1e --- /dev/null +++ b/components/esp_rom/patches/esp_rom_cache_esp32c5.c @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp32c5/rom/cache.h" + +/** + * @brief Dummy implementation of Cache_Set_IDROM_MMU_Size from ROM. + * + * NOTE: This ROM-provided API is intended to configure the Cache MMU size for + * instruction (irom) and rodata (drom) sections in flash. + * + * On ESP32-C5, it also sets the start pages for flash irom and drom sections, + * which involves accessing MMU registers directly. However, these MMU registers + * are protected by the APM and direct access from the REE results in a fault. + * + * To prevent this: + * - Mark this symbol with the `PROVIDE` attribute in the ROM linker script. + * - Define this dummy function as a stub implementation. + * - Wrap this function to be routed as a TEE service call + * + * @param irom_size Size of the instruction ROM region. + * @param drom_size Size of the data ROM region. + */ +void Cache_Set_IDROM_MMU_Size(uint32_t irom_size, uint32_t drom_size) +{ + (void)irom_size; + (void)drom_size; +} diff --git a/components/esp_rom/patches/esp_rom_sys.c b/components/esp_rom/patches/esp_rom_sys.c index 8c5c897d05..b645ee0648 100644 --- a/components/esp_rom/patches/esp_rom_sys.c +++ b/components/esp_rom/patches/esp_rom_sys.c @@ -117,7 +117,7 @@ uint32_t esp_rom_get_bootloader_offset(void) } #endif // SOC_RECOVERY_BOOTLOADER_SUPPORTED -#if ESP_ROM_DELAY_US_PATCH && !NON_OS_BUILD +#if ESP_ROM_DELAY_US_PATCH && CONFIG_SECURE_ENABLE_TEE && !NON_OS_BUILD #if CONFIG_ESP32C5_REV_MIN_FULL <= 100 || CONFIG_ESP32C61_REV_MIN_FULL <= 100 #include "riscv/rv_utils.h" diff --git a/components/esp_system/ld/esp32c5/memory.ld.in b/components/esp_system/ld/esp32c5/memory.ld.in index 8fcc73f037..160b3232a4 100644 --- a/components/esp_system/ld/esp32c5/memory.ld.in +++ b/components/esp_system/ld/esp32c5/memory.ld.in @@ -15,7 +15,13 @@ #include "sdkconfig.h" #include "ld.common" -#define SRAM_SEG_START 0x40800000 +#if !CONFIG_SECURE_ENABLE_TEE +#define SRAM_SEG_START (0x40800000) +#else +#define SRAM_SEG_START (0x40800000 + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE) +#define FLASH_SEG_OFFSET (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE) +#endif // CONFIG_SECURE_ENABLE_TEE + #define SRAM_SEG_END 0x4084E5A0 /* 2nd stage bootloader iram_loader_seg start address */ #define SRAM_SEG_SIZE SRAM_SEG_END - SRAM_SEG_START @@ -33,8 +39,14 @@ MEMORY */ #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS +#if CONFIG_SECURE_ENABLE_TEE + /* Flash mapped instruction data */ + irom_seg (RX) : org = 0x42000020 + FLASH_SEG_OFFSET, + len = IDRAM0_2_SEG_SIZE - FLASH_SEG_OFFSET - 0x20 +#else /* Flash mapped instruction data */ irom_seg (RX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20 +#endif /** * (0x20 offset above is a convenience for the app binary image generation. @@ -52,8 +64,14 @@ MEMORY sram_seg (RWX) : org = SRAM_SEG_START, len = SRAM_SEG_SIZE #if CONFIG_APP_BUILD_USE_FLASH_SECTIONS +#if CONFIG_SECURE_ENABLE_TEE /* Flash mapped constant data */ + drom_seg (R) : org = 0x42000020 + FLASH_SEG_OFFSET, + len = IDRAM0_2_SEG_SIZE - FLASH_SEG_OFFSET - 0x20 +#else + /* Flash mapped instruction data */ drom_seg (R) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20 +#endif /* (See irom_seg for meaning of 0x20 offset in the above.) */ #endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS diff --git a/components/esp_system/ld/esp32c5/sections.ld.in b/components/esp_system/ld/esp32c5/sections.ld.in index 74bf089be3..43be52efc7 100644 --- a/components/esp_system/ld/esp32c5/sections.ld.in +++ b/components/esp_system/ld/esp32c5/sections.ld.in @@ -158,9 +158,22 @@ SECTIONS _iram_start = ABSOLUTE(.); /* Vectors go to start of IRAM */ ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned"); + _vector_table_start = ABSOLUTE(.); KEEP(*(.exception_vectors_table.text)); KEEP(*(.exception_vectors.text)); + ALIGNED_SYMBOL(4, _invalid_pc_placeholder) + + /* esp_tee_config_t structure: used to share information between the TEE and REE + * (e.g. interrupt handler addresses, REE flash text-rodata boundaries, etc.) + * This symbol is expected by the TEE at an offset of 0x2b0 from the vector table start. + */ +#if CONFIG_SECURE_ENABLE_TEE + ALIGNED_SYMBOL(0x10, _esp_tee_app_cfg) + ASSERT(ABSOLUTE(.) == _vector_table_start + 0x2b0, "esp_tee_app_cfg must be at an offset 0x2b0 from the vector table start"); + *libesp_tee.a:(.esp_tee_app_cfg); +#endif + /* Code marked as running out of IRAM */ _iram_text_start = ABSOLUTE(.); diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 807eeabe52..dae1e0dbd2 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -172,8 +172,13 @@ static volatile bool s_resume_cores; static void core_intr_matrix_clear(void) { - uint32_t core_id = esp_cpu_get_core_id(); + __attribute__((unused)) uint32_t core_id = esp_cpu_get_core_id(); + /* NOTE: With ESP-TEE enabled, each iteration in this loop results in a service call. + * To accelerate the boot-up process, the interrupt configuration is pre-cleared in the TEE, + * allowing this step to be safely skipped here. + */ +#if !CONFIG_SECURE_ENABLE_TEE for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) { #if SOC_INT_CLIC_SUPPORTED interrupt_clic_ll_route(core_id, i, ETS_INVALID_INUM); @@ -181,6 +186,7 @@ static void core_intr_matrix_clear(void) esp_rom_route_intr_matrix(core_id, i, ETS_INVALID_INUM); #endif // SOC_INT_CLIC_SUPPORTED } +#endif // !CONFIG_SECURE_ENABLE_TEE #if SOC_INT_CLIC_SUPPORTED for (int i = 0; i < 32; i++) { @@ -382,6 +388,15 @@ FORCE_INLINE_ATTR IRAM_ATTR void init_cpu(void) ); #endif + /* NOTE: When ESP-TEE is enabled, this sets up the callback function + * which redirects all the interrupt management for the REE (user app) + * to the TEE by raising the appropriate service calls. + */ +#if CONFIG_SECURE_ENABLE_TEE + extern uint32_t esp_tee_service_call(int argc, ...); + esprv_int_setup_mgmt_cb((void *)esp_tee_service_call); +#endif + #if SOC_BRANCH_PREDICTOR_SUPPORTED esp_cpu_branch_prediction_enable(); #endif @@ -391,19 +406,12 @@ FORCE_INLINE_ATTR IRAM_ATTR void init_cpu(void) /* When hardware vectored interrupts are enabled in CLIC, * the CPU jumps to this base address + 4 * interrupt_id. */ - esp_cpu_intr_set_mtvt_addr(&_mtvt_table); + /* NOTE: When ESP-TEE is enabled, this sets up the U-mode + * interrupt vector table (UTVT) */ + esp_cpu_intr_set_xtvt_addr(&_mtvt_table); #endif #if SOC_CPU_SUPPORT_WFE - rv_utils_disable_wfe_mode(); -#endif - - /* NOTE: When ESP-TEE is enabled, this sets up the callback function - * which redirects all the interrupt management for the REE (user app) - * to the TEE by raising the appropriate service calls. - */ -#if CONFIG_SECURE_ENABLE_TEE - extern uint32_t esp_tee_service_call(int argc, ...); - esprv_int_setup_mgmt_cb((void *)esp_tee_service_call); + esp_cpu_disable_wfe_mode(); #endif } diff --git a/components/esp_system/port/soc/esp32c5/clk.c b/components/esp_system/port/soc/esp32c5/clk.c index 49afeba1eb..07a9890ae5 100644 --- a/components/esp_system/port/soc/esp32c5/clk.c +++ b/components/esp_system/port/soc/esp32c5/clk.c @@ -305,6 +305,7 @@ __attribute__((weak)) void esp_perip_clk_init(void) assist_debug_ll_enable_bus_clock(false); #endif mpi_ll_enable_bus_clock(false); +#if !CONFIG_SECURE_ENABLE_TEE aes_ll_enable_bus_clock(false); sha_ll_enable_bus_clock(false); ecc_ll_enable_bus_clock(false); @@ -312,9 +313,10 @@ __attribute__((weak)) void esp_perip_clk_init(void) ds_ll_enable_bus_clock(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); +#endif + uhci_ll_enable_bus_clock(0, false); // TODO: Replace with hal implementation REG_CLR_BIT(PCR_TRACE_CONF_REG, PCR_TRACE_CLK_EN); @@ -346,8 +348,10 @@ __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); +#if !CONFIG_SECURE_ENABLE_TEE apm_ll_lp_apm_enable_ctrl_clk_gating(true); apm_ll_lp_apm0_enable_ctrl_clk_gating(true); +#endif WRITE_PERI_REG(LP_CLKRST_LP_CLK_PO_EN_REG, 0); } } diff --git a/components/hal/spi_flash_hal_common.inc b/components/hal/spi_flash_hal_common.inc index 83757d8dd9..9146fbd202 100644 --- a/components/hal/spi_flash_hal_common.inc +++ b/components/hal/spi_flash_hal_common.inc @@ -131,7 +131,15 @@ esp_err_t spi_flash_hal_configure_host_io_mode( addr_bitlen += SPI_FLASH_LL_CONTINUOUS_MODE_BIT_NUMS; #endif spi_flash_ll_set_extra_address(dev, 0); -#if SOC_SPI_MEM_SUPPORT_WB_MODE_INDEPENDENT_CONTROL + // TODO: [IDF-13582] + // Currently, REE and TEE use different sets of APIs for flash operations - + // REE uses the IDF SPI flash driver while TEE call the ROM APIs. This inconsistency + // leads to compatibility issues on ESP32-C5. + // One specific issue arises when esp_flash_read() is used in REE, which internally + // calls spi_flash_ll_wb_mode_enable(). This function enables the WB mode bit in + // the flash write operation. However, the ROM API does not support this + // feature, resulting in failures when TEE attempts to access flash after this call. +#if SOC_SPI_MEM_SUPPORT_WB_MODE_INDEPENDENT_CONTROL && !CONFIG_SECURE_ENABLE_TEE spi_flash_ll_wb_mode_enable(dev, true); #endif } @@ -208,7 +216,8 @@ esp_err_t spi_flash_hal_common_command(spi_flash_host_inst_t *host, spi_flash_tr if (trans->miso_len > 0) { spi_flash_ll_get_buffer_data(dev, trans->miso_data, trans->miso_len); } -#if SOC_SPI_MEM_SUPPORT_WB_MODE_INDEPENDENT_CONTROL + // TODO: [IDF-13582] +#if SOC_SPI_MEM_SUPPORT_WB_MODE_INDEPENDENT_CONTROL && !CONFIG_SECURE_ENABLE_TEE spi_flash_ll_wb_mode_enable(dev, false); #endif return ESP_OK; diff --git a/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c5/test_rv_utils.h b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c5/test_rv_utils.h index 8865e9076b..39218839f3 100644 --- a/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c5/test_rv_utils.h +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c5/test_rv_utils.h @@ -22,10 +22,6 @@ #include "sdkconfig.h" -#define UTVT_CSR (0x007) -#define UINTSTATUS_CSR (0xCB1) -#define UINTTHRESH_CSR (0x047) - #ifdef __cplusplus extern "C" { #endif diff --git a/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c61/test_rv_utils.h b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c61/test_rv_utils.h index 8865e9076b..39218839f3 100644 --- a/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c61/test_rv_utils.h +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c61/test_rv_utils.h @@ -22,10 +22,6 @@ #include "sdkconfig.h" -#define UTVT_CSR (0x007) -#define UINTSTATUS_CSR (0xCB1) -#define UINTTHRESH_CSR (0x047) - #ifdef __cplusplus extern "C" { #endif diff --git a/components/heap/port/esp32c5/memory_layout.c b/components/heap/port/esp32c5/memory_layout.c index 4fbc9b6f1f..797c4b0a88 100644 --- a/components/heap/port/esp32c5/memory_layout.c +++ b/components/heap/port/esp32c5/memory_layout.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,11 @@ #include "heap_memory_layout.h" #include "esp_heap_caps.h" +#if CONFIG_SECURE_ENABLE_TEE +#define SRAM_DIRAM_TEE_ORG (SOC_DIRAM_IRAM_LOW) +#define SRAM_DIRAM_TEE_END (SRAM_DIRAM_TEE_ORG + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE) +#endif + /** * @brief Memory type descriptors. These describe the capabilities of a type of memory in the SoC. * Each type of memory map consists of one or more regions in the address space. @@ -97,6 +102,14 @@ SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_d // Target has a shared D/IRAM virtual address, no need to calculate I_D_OFFSET like previous chips SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code); +/* NOTE: When ESP-TEE is enabled, the start of the internal SRAM +* is used by the TEE and is protected from any REE access using +* memory protection mechanisms employed by ESP-TEE. +*/ +#if CONFIG_SECURE_ENABLE_TEE +SOC_RESERVE_MEMORY_REGION((intptr_t)SRAM_DIRAM_TEE_ORG, (intptr_t)(SRAM_DIRAM_TEE_END), tee_diram); +#endif + #ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_slow_end, rtcram_data); #endif diff --git a/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.c b/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.c index 78e71c24ac..29b55762e5 100644 --- a/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.c +++ b/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.c @@ -10,15 +10,10 @@ #include "mbedtls/aes.h" #include "esp_crypto_dma.h" -#include "hal/clk_gate_ll.h" -#include "hal/gdma_ll.h" #include "hal/gdma_types.h" #include "hal/aes_hal.h" -#include "soc/lldesc.h" -#include "soc/periph_defs.h" #include "soc/gdma_channel.h" -#include "soc/gdma_struct.h" #include "soc/soc_caps.h" #include "esp_tee_crypto_shared_gdma.h" @@ -27,6 +22,38 @@ #define TEE_CRYPTO_GDMA_CH (0) +#if SOC_AHB_GDMA_VERSION == 2 +#include "hal/ahb_dma_ll.h" +#include "soc/ahb_dma_struct.h" +#define DMA_DEV (AHB_DMA) +#define DMA_LL_FUNC(func) ahb_dma_ll_##func +#elif SOC_AHB_GDMA_VERSION == 1 +#include "hal/gdma_ll.h" +#include "soc/gdma_struct.h" +#define DMA_DEV (GDMA) +#define DMA_LL_FUNC(func) gdma_ll_##func +#endif + +#define dma_ll_force_enable_reg_clock DMA_LL_FUNC(force_enable_reg_clock) +#define dma_ll_tx_enable_data_burst DMA_LL_FUNC(tx_enable_data_burst) +#define dma_ll_tx_enable_descriptor_burst DMA_LL_FUNC(tx_enable_descriptor_burst) +#define dma_ll_rx_enable_data_burst DMA_LL_FUNC(rx_enable_data_burst) +#define dma_ll_rx_enable_descriptor_burst DMA_LL_FUNC(rx_enable_descriptor_burst) +#define dma_ll_tx_reset_channel DMA_LL_FUNC(tx_reset_channel) +#define dma_ll_tx_connect_to_periph DMA_LL_FUNC(tx_connect_to_periph) +#define dma_ll_rx_reset_channel DMA_LL_FUNC(rx_reset_channel) +#define dma_ll_rx_connect_to_periph DMA_LL_FUNC(rx_connect_to_periph) +#define dma_ll_tx_disconnect_from_periph DMA_LL_FUNC(tx_disconnect_from_periph) +#define dma_ll_rx_disconnect_from_periph DMA_LL_FUNC(rx_disconnect_from_periph) +#define dma_ll_tx_set_desc_addr DMA_LL_FUNC(tx_set_desc_addr) +#define dma_ll_tx_start DMA_LL_FUNC(tx_start) +#define dma_ll_rx_set_desc_addr DMA_LL_FUNC(rx_set_desc_addr) +#define dma_ll_rx_start DMA_LL_FUNC(rx_start) +#define dma_ll_tx_stop DMA_LL_FUNC(tx_stop) +#define dma_ll_rx_stop DMA_LL_FUNC(rx_stop) +#define dma_ll_tx_set_priority DMA_LL_FUNC(tx_set_priority) +#define dma_ll_rx_set_priority DMA_LL_FUNC(rx_set_priority) + /* * NOTE: [ESP-TEE] This is a low-level (LL), non-OS version of * port/crypto_shared_gdma/esp_crypto_shared_gdma.c that defines @@ -37,30 +64,23 @@ static void crypto_shared_gdma_init(void) { - // enable APB to access GDMA registers - periph_ll_enable_clk_clear_rst(PERIPH_GDMA_MODULE); - // enable gdma clock - gdma_ll_force_enable_reg_clock(&GDMA, true); + gdma_ll_enable_bus_clock(0, true); + gdma_ll_reset_register(0); + dma_ll_force_enable_reg_clock(&DMA_DEV, true); // setting the transfer ability - gdma_ll_tx_enable_data_burst(&GDMA, TEE_CRYPTO_GDMA_CH, true); - gdma_ll_tx_enable_descriptor_burst(&GDMA, TEE_CRYPTO_GDMA_CH, true); + dma_ll_tx_enable_data_burst(&DMA_DEV, TEE_CRYPTO_GDMA_CH, true); + dma_ll_tx_enable_descriptor_burst(&DMA_DEV, TEE_CRYPTO_GDMA_CH, true); - gdma_ll_rx_enable_data_burst(&GDMA, TEE_CRYPTO_GDMA_CH, false); - gdma_ll_rx_enable_descriptor_burst(&GDMA, TEE_CRYPTO_GDMA_CH, true); + dma_ll_rx_enable_data_burst(&DMA_DEV, TEE_CRYPTO_GDMA_CH, false); + dma_ll_rx_enable_descriptor_burst(&DMA_DEV, TEE_CRYPTO_GDMA_CH, true); -#if SOC_GDMA_SUPPORT_PSRAM - gdma_ll_tx_set_block_size_psram(&GDMA, TEE_CRYPTO_GDMA_CH, GDMA_LL_EXT_MEM_BK_SIZE_16B); - gdma_ll_rx_set_block_size_psram(&GDMA, TEE_CRYPTO_GDMA_CH, GDMA_LL_EXT_MEM_BK_SIZE_16B); -#endif // SOC_GDMA_SUPPORT_PSRAM - - gdma_ll_tx_reset_channel(&GDMA, TEE_CRYPTO_GDMA_CH); - gdma_ll_tx_connect_to_periph(&GDMA, TEE_CRYPTO_GDMA_CH, GDMA_TRIG_PERIPH_M2M, SOC_GDMA_TRIG_PERIPH_M2M0); - - gdma_ll_rx_reset_channel(&GDMA, TEE_CRYPTO_GDMA_CH); - gdma_ll_rx_connect_to_periph(&GDMA, TEE_CRYPTO_GDMA_CH, GDMA_TRIG_PERIPH_M2M, SOC_GDMA_TRIG_PERIPH_M2M0); + dma_ll_tx_reset_channel(&DMA_DEV, TEE_CRYPTO_GDMA_CH); + dma_ll_tx_connect_to_periph(&DMA_DEV, TEE_CRYPTO_GDMA_CH, GDMA_TRIG_PERIPH_M2M, SOC_GDMA_TRIG_PERIPH_M2M0); + dma_ll_rx_reset_channel(&DMA_DEV, TEE_CRYPTO_GDMA_CH); + dma_ll_rx_connect_to_periph(&DMA_DEV, TEE_CRYPTO_GDMA_CH, GDMA_TRIG_PERIPH_M2M, SOC_GDMA_TRIG_PERIPH_M2M0); } esp_err_t esp_tee_crypto_shared_gdma_start(const crypto_dma_desc_t *input, const crypto_dma_desc_t *output, gdma_trigger_peripheral_t periph) @@ -76,40 +96,39 @@ esp_err_t esp_tee_crypto_shared_gdma_start(const crypto_dma_desc_t *input, const crypto_shared_gdma_init(); - gdma_ll_tx_disconnect_from_periph(&GDMA, TEE_CRYPTO_GDMA_CH); - gdma_ll_rx_disconnect_from_periph(&GDMA, TEE_CRYPTO_GDMA_CH); + dma_ll_tx_disconnect_from_periph(&DMA_DEV, TEE_CRYPTO_GDMA_CH); + dma_ll_rx_disconnect_from_periph(&DMA_DEV, TEE_CRYPTO_GDMA_CH); - gdma_ll_tx_reset_channel(&GDMA, TEE_CRYPTO_GDMA_CH); - gdma_ll_tx_connect_to_periph(&GDMA, TEE_CRYPTO_GDMA_CH, periph, periph_inst_id); + dma_ll_tx_reset_channel(&DMA_DEV, TEE_CRYPTO_GDMA_CH); + dma_ll_tx_connect_to_periph(&DMA_DEV, TEE_CRYPTO_GDMA_CH, periph, periph_inst_id); - gdma_ll_rx_reset_channel(&GDMA, TEE_CRYPTO_GDMA_CH); - gdma_ll_rx_connect_to_periph(&GDMA, TEE_CRYPTO_GDMA_CH, periph, periph_inst_id); + dma_ll_rx_reset_channel(&DMA_DEV, TEE_CRYPTO_GDMA_CH); + dma_ll_rx_connect_to_periph(&DMA_DEV, TEE_CRYPTO_GDMA_CH, periph, periph_inst_id); - gdma_ll_tx_set_desc_addr(&GDMA, TEE_CRYPTO_GDMA_CH, (intptr_t)input); - gdma_ll_tx_start(&GDMA, TEE_CRYPTO_GDMA_CH); + dma_ll_tx_set_desc_addr(&DMA_DEV, TEE_CRYPTO_GDMA_CH, (intptr_t)input); + dma_ll_tx_start(&DMA_DEV, TEE_CRYPTO_GDMA_CH); - gdma_ll_rx_set_desc_addr(&GDMA, TEE_CRYPTO_GDMA_CH, (intptr_t)output); - gdma_ll_rx_start(&GDMA, TEE_CRYPTO_GDMA_CH); + dma_ll_rx_set_desc_addr(&DMA_DEV, TEE_CRYPTO_GDMA_CH, (intptr_t)output); + dma_ll_rx_start(&DMA_DEV, TEE_CRYPTO_GDMA_CH); return ESP_OK; } void esp_tee_crypto_shared_gdma_free(void) { - gdma_ll_tx_stop(&GDMA, TEE_CRYPTO_GDMA_CH); - gdma_ll_rx_stop(&GDMA, TEE_CRYPTO_GDMA_CH); + dma_ll_tx_stop(&DMA_DEV, TEE_CRYPTO_GDMA_CH); + dma_ll_rx_stop(&DMA_DEV, TEE_CRYPTO_GDMA_CH); - gdma_ll_tx_disconnect_from_periph(&GDMA, TEE_CRYPTO_GDMA_CH); - gdma_ll_rx_disconnect_from_periph(&GDMA, TEE_CRYPTO_GDMA_CH); + dma_ll_tx_disconnect_from_periph(&DMA_DEV, TEE_CRYPTO_GDMA_CH); + dma_ll_rx_disconnect_from_periph(&DMA_DEV, TEE_CRYPTO_GDMA_CH); - gdma_ll_tx_set_priority(&GDMA, TEE_CRYPTO_GDMA_CH, 0); - gdma_ll_rx_set_priority(&GDMA, TEE_CRYPTO_GDMA_CH, 0); + dma_ll_tx_set_priority(&DMA_DEV, TEE_CRYPTO_GDMA_CH, 0); + dma_ll_rx_set_priority(&DMA_DEV, TEE_CRYPTO_GDMA_CH, 0); // disable gdma clock - gdma_ll_force_enable_reg_clock(&GDMA, false); - - // disable APB for GDMA registers - periph_ll_disable_clk_set_rst(PERIPH_GDMA_MODULE); + gdma_ll_enable_bus_clock(0, false); + gdma_ll_reset_register(0); + dma_ll_force_enable_reg_clock(&DMA_DEV, false); } /* ---------------------------------------------- DMA Implementations: AES ------------------------------------------------- */ diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h index 14078e2bd2..5021e43c92 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h @@ -22,6 +22,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "soc/soc_caps.h" #include "sdkconfig.h" #ifndef ESP_TEE_MBEDTLS_CONFIG_H @@ -50,13 +51,24 @@ #define MBEDTLS_ECP_C #define MBEDTLS_ECDSA_C +#if CONFIG_MBEDTLS_SHA1_C #define MBEDTLS_SHA1_C +#endif #define MBEDTLS_SHA224_C #define MBEDTLS_SHA256_C +#if SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C +#define MBEDTLS_SHA384_C +#define MBEDTLS_SHA512_C +#endif #if CONFIG_MBEDTLS_HARDWARE_SHA +#if CONFIG_MBEDTLS_SHA1_C #define MBEDTLS_SHA1_ALT +#endif #define MBEDTLS_SHA256_ALT +#if SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C +#define MBEDTLS_SHA512_ALT +#endif #endif #ifdef CONFIG_MBEDTLS_HARDWARE_ECC diff --git a/components/riscv/CMakeLists.txt b/components/riscv/CMakeLists.txt index 1db27908e9..12872530fe 100644 --- a/components/riscv/CMakeLists.txt +++ b/components/riscv/CMakeLists.txt @@ -15,6 +15,8 @@ elseif(esp_tee_build) set(srcs "rv_utils.c") if(CONFIG_SOC_INT_PLIC_SUPPORTED) list(APPEND srcs "interrupt_plic.c") + elseif(CONFIG_SOC_INT_CLIC_SUPPORTED) + list(APPEND srcs "interrupt_clic.c") endif() else() set(priv_requires soc hal) diff --git a/components/riscv/include/esp_private/interrupt_clic.h b/components/riscv/include/esp_private/interrupt_clic.h index 83fa3e3505..695edf9c17 100644 --- a/components/riscv/include/esp_private/interrupt_clic.h +++ b/components/riscv/include/esp_private/interrupt_clic.h @@ -44,6 +44,7 @@ extern "C" { * @brief CSR to set the interrupt jump table address is MTVT. */ #define MTVT_CSR 0x307 +#define UTVT_CSR 0x007 #if CONFIG_IDF_TARGET_ESP32P4 && CONFIG_ESP32P4_SELECTS_REV_LESS_V2 @@ -61,7 +62,9 @@ extern "C" { /* The ESP32-C5 (MP), C61, H4 and P4 (since REV2) use the standard CLIC specification, for example, it defines the mintthresh CSR */ #define INTTHRESH_STANDARD 1 #define MINTSTATUS_CSR 0xFB1 +#define UINTSTATUS_CSR 0xCB1 #define MINTTHRESH_CSR 0x347 +#define UINTTHRESH_CSR 0x047 #else #error "Check the implementation of the CLIC on this target." @@ -114,7 +117,11 @@ extern "C" { #define RVHAL_INTR_ENABLE_THRESH_CLIC (CLIC_INT_THRESH(RVHAL_INTR_ENABLE_THRESH)) - +#if CONFIG_SECURE_ENABLE_TEE +#define IS_PRV_M_MODE() (RV_READ_CSR(CSR_PRV_MODE) == PRV_M) +#else +#define IS_PRV_M_MODE() (1UL) +#endif FORCE_INLINE_ATTR void assert_valid_rv_int_num(int rv_int_num) @@ -132,7 +139,12 @@ FORCE_INLINE_ATTR void assert_valid_rv_int_num(int rv_int_num) FORCE_INLINE_ATTR uint32_t rv_utils_get_interrupt_threshold(void) { #if INTTHRESH_STANDARD - uint32_t threshold = RV_READ_CSR(MINTTHRESH_CSR); + uint32_t threshold; + if (IS_PRV_M_MODE()) { + threshold = RV_READ_CSR(MINTTHRESH_CSR); + } else { + threshold = RV_READ_CSR(UINTTHRESH_CSR); + } #else uint32_t threshold = REG_READ(CLIC_INT_THRESH_REG); #endif @@ -148,6 +160,19 @@ FORCE_INLINE_ATTR void rv_utils_set_mtvt(uint32_t mtvt_val) RV_WRITE_CSR(MTVT_CSR, mtvt_val); } +/** + * @brief Set the XTVT CSR value (based on the current privilege mode), + * used as a base address for the interrupt jump table + */ +FORCE_INLINE_ATTR void rv_utils_set_xtvt(uint32_t xtvt_val) +{ + if (IS_PRV_M_MODE()) { + RV_WRITE_CSR(MTVT_CSR, xtvt_val); + } else { + RV_WRITE_CSR(UTVT_CSR, xtvt_val); + } +} + #if SOC_CPU_SUPPORT_WFE /** * @brief Set the MEXSTATUS_WFFEN value, used to enable/disable wait for event mode. @@ -167,7 +192,11 @@ FORCE_INLINE_ATTR void rv_utils_wfe_mode_enable(bool en) */ FORCE_INLINE_ATTR uint32_t rv_utils_get_interrupt_level_regval(void) { - return RV_READ_CSR(MINTSTATUS_CSR); + if (IS_PRV_M_MODE()) { + return RV_READ_CSR(MINTSTATUS_CSR); + } else { + return RV_READ_CSR(UINTSTATUS_CSR); + } } /** @@ -175,9 +204,14 @@ FORCE_INLINE_ATTR uint32_t rv_utils_get_interrupt_level_regval(void) */ FORCE_INLINE_ATTR uint32_t rv_utils_get_interrupt_level(void) { - const uint32_t mintstatus = RV_READ_CSR(MINTSTATUS_CSR); + uint32_t xintstatus; + if (IS_PRV_M_MODE()) { + xintstatus = RV_READ_CSR(MINTSTATUS_CSR); + } else { + xintstatus = RV_READ_CSR(UINTSTATUS_CSR); + } /* Extract the level from this field */ - return CLIC_STATUS_TO_INT(mintstatus); + return CLIC_STATUS_TO_INT(xintstatus); } /** @@ -190,7 +224,11 @@ FORCE_INLINE_ATTR uint32_t rv_utils_get_interrupt_level(void) FORCE_INLINE_ATTR void rv_utils_restore_intlevel_regval(uint32_t restoreval) { #if INTTHRESH_STANDARD - RV_WRITE_CSR(MINTTHRESH_CSR, restoreval); + if (IS_PRV_M_MODE()) { + RV_WRITE_CSR(MINTTHRESH_CSR, restoreval); + } else { + RV_WRITE_CSR(UINTTHRESH_CSR, restoreval); + } #else REG_WRITE(CLIC_INT_THRESH_REG, restoreval); /** @@ -224,7 +262,11 @@ FORCE_INLINE_ATTR void rv_utils_restore_intlevel(uint32_t restoreval) FORCE_INLINE_ATTR uint32_t rv_utils_set_intlevel_regval(uint32_t intlevel) { #if INTTHRESH_STANDARD - return RV_SWAP_CSR(MINTTHRESH_CSR, intlevel); + if (IS_PRV_M_MODE()) { + return RV_SWAP_CSR(MINTTHRESH_CSR, intlevel); + } else { + return RV_SWAP_CSR(UINTTHRESH_CSR, intlevel); + } #else // !INTTHRESH_STANDARD uint32_t old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE); uint32_t old_thresh = REG_READ(CLIC_INT_THRESH_REG); diff --git a/components/riscv/include/riscv/interrupt.h b/components/riscv/include/riscv/interrupt.h index f500b6174b..a487c1c34b 100644 --- a/components/riscv/include/riscv/interrupt.h +++ b/components/riscv/include/riscv/interrupt.h @@ -149,7 +149,7 @@ void esprv_int_set_vectored(int rv_int_num, bool vectored); /*************************** ESP-TEE specific ***************************/ /** Function prototype executing interrupt configuration APIs as service calls */ -typedef void (*esprv_int_mgmt_t)(int argc, ...); +typedef uint32_t (*esprv_int_mgmt_t)(int argc, ...); /** * @brief Setup the callback function which executes the interrupt diff --git a/components/riscv/include/riscv/rv_utils.h b/components/riscv/include/riscv/rv_utils.h index 7a0ebbfcef..a4e533f443 100644 --- a/components/riscv/include/riscv/rv_utils.h +++ b/components/riscv/include/riscv/rv_utils.h @@ -118,7 +118,11 @@ FORCE_INLINE_ATTR uint32_t __attribute__((always_inline)) rv_utils_get_cycle_cou FORCE_INLINE_ATTR void __attribute__((always_inline)) rv_utils_set_cycle_count(uint32_t ccount) { #if !SOC_CPU_HAS_CSR_PC +#if CONFIG_SECURE_ENABLE_TEE && !NON_OS_BUILD + esp_tee_intr_sec_srv_cb(2, SS_RV_UTILS_SET_CYCLE_COUNT, ccount); +#else RV_WRITE_CSR(mcycle, ccount); +#endif #else if (IS_PRV_M_MODE()) { RV_WRITE_CSR(CSR_PCCR_MACHINE, ccount); @@ -404,8 +408,8 @@ FORCE_INLINE_ATTR void rv_utils_clear_breakpoint(int bp_num) { RV_WRITE_CSR(tselect, bp_num); /* tdata1 is a WARL(write any read legal) register - * We can just write 0 to it - */ + * We can just write 0 to it + */ RV_WRITE_CSR(tdata1, 0); } @@ -481,12 +485,20 @@ FORCE_INLINE_ATTR bool rv_utils_compare_and_set(volatile uint32_t *addr, uint32_ #if SOC_BRANCH_PREDICTOR_SUPPORTED FORCE_INLINE_ATTR void rv_utils_en_branch_predictor(void) { +#if CONFIG_SECURE_ENABLE_TEE && !NON_OS_BUILD + esp_tee_intr_sec_srv_cb(1, SS_RV_UTILS_EN_BRANCH_PREDICTOR); +#else RV_SET_CSR(MHCR, MHCR_RS|MHCR_BFE|MHCR_BTB); +#endif } FORCE_INLINE_ATTR void rv_utils_dis_branch_predictor(void) { +#if CONFIG_SECURE_ENABLE_TEE && !NON_OS_BUILD + esp_tee_intr_sec_srv_cb(1, SS_RV_UTILS_DIS_BRANCH_PREDICTOR); +#else RV_CLEAR_CSR(MHCR, MHCR_RS|MHCR_BFE|MHCR_BTB); +#endif } #endif diff --git a/components/riscv/interrupt_clic.c b/components/riscv/interrupt_clic.c index d6a98618f4..95d48a3cc4 100644 --- a/components/riscv/interrupt_clic.c +++ b/components/riscv/interrupt_clic.c @@ -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 */ @@ -40,3 +40,44 @@ void esprv_int_set_vectored(int rv_int_num, bool vectored) { interrupt_clic_ll_set_vectored(rv_int_num + RV_EXTERNAL_INT_OFFSET, vectored); } + + +#if CONFIG_SECURE_ENABLE_TEE && !NON_OS_BUILD +DRAM_ATTR esprv_int_mgmt_t esp_tee_intr_sec_srv_cb = NULL; + +void esprv_int_setup_mgmt_cb(void *fptr) +{ + esp_tee_intr_sec_srv_cb = (esprv_int_mgmt_t)fptr; +} + + +/* NOTE: Overriding ROM-based interrupt configuration symbols */ +void esprv_int_enable(uint32_t unmask) +{ + rv_utils_intr_enable(unmask); +} + + +void esprv_int_disable(uint32_t mask) +{ + rv_utils_intr_disable(mask); +} + + +void esprv_int_set_type(int intr_num, enum intr_type type) +{ + rv_utils_intr_set_type(intr_num, type); +} + + +void esprv_int_set_priority(int rv_int_num, int priority) +{ + rv_utils_intr_set_priority(rv_int_num, priority); +} + + +void esprv_int_set_threshold(int priority_threshold) +{ + rv_utils_intr_set_threshold(priority_threshold); +} +#endif diff --git a/components/riscv/vectors.S b/components/riscv/vectors.S index 47d0b372d9..56542f2505 100644 --- a/components/riscv/vectors.S +++ b/components/riscv/vectors.S @@ -17,6 +17,8 @@ .equ EXC_ILLEGAL_INSTRUCTION, 0x2 .equ panic_from_exception, xt_unhandled_exception .equ panic_from_isr, panicHandler + .equ CSR_UINTSTATUS, 0xCB1 + .equ CSR_UINTTHRESH, 0x047 #if ( SOC_CPU_COPROC_NUM > 0 ) /* Targets with coprocessors present a special CSR to get Illegal Instruction exception reason */ @@ -90,8 +92,11 @@ sw t0, RV_STK_MSTATUS(sp) csrr t0, utvec sw t0, RV_STK_MTVEC(sp) + /* NOTE: C6 and H2 possess the utval CSR, but rest of the SoCs don't */ + #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 csrr t0, utval sw t0, RV_STK_MTVAL(sp) + #endif #else csrr t0, mstatus sw t0, RV_STK_MSTATUS(sp) @@ -467,6 +472,24 @@ _tee_interrupt_handler: li t0, INTERRUPT_CURRENT_CORE_INT_THRESH_REG sw s3, 0(t0) fence +#elif CONFIG_SECURE_ENABLE_TEE + /* Restore the U-mode interrupt threshold level. + * + * If uintstatus == 0, it means we have returned here after servicing a + * U-mode interrupt that was delegated via M-mode. In this case, we should + * reset the threshold to the minimum valid level. + * + * If uintstatus != 0, we are currently handling a U-mode interrupt that + * either originated directly in U-mode or is a nested U-mode interrupt. + * In this case, the threshold must be retained, so we skip the reset. + */ + csrr t0, CSR_UINTSTATUS + bnez t0, _skip_thresh_reset + csrr t0, CSR_UINTTHRESH + li t1, (1 << (8 - NLBITS) - 1) + beq t0, t1, _skip_thresh_reset + csrw CSR_UINTTHRESH, t1 +_skip_thresh_reset: #endif // !SOC_INT_HW_NESTED_SUPPORTED /* The RTOS will restore the current TCB stack pointer. This routine will preserve s1 and s2. diff --git a/components/soc/esp32c5/register/soc/tee_reg.h b/components/soc/esp32c5/register/soc/tee_reg.h index 398d4bc235..0b17fa32c6 100644 --- a/components/soc/esp32c5/register/soc/tee_reg.h +++ b/components/soc/esp32c5/register/soc/tee_reg.h @@ -5,7 +5,6 @@ */ #pragma once -#include #include "soc/soc.h" #ifdef __cplusplus extern "C" {