From 12e2df2d7400ee1a8418d16c026c0d479eafc52d Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Wed, 12 Mar 2025 14:05:06 +0530 Subject: [PATCH] feat(esp_tee): Support for ESP32-H2 - the rest of the components --- .../bootloader_flash/src/bootloader_flash.c | 2 +- .../port/esp32h2/CMakeLists.txt | 4 ++- .../port/esp32h2/cpu_region_protect.c | 10 +++++- .../port/esp32h2/esp_cpu_intr.c | 14 +++++++- .../esp_mm/port/esp32h2/ext_mem_layout.c | 33 ++++++++++++++++--- components/esp_rom/CMakeLists.txt | 6 ++-- components/esp_system/ld/esp32h2/memory.ld.in | 20 ++++++++++- .../esp_system/ld/esp32h2/sections.ld.in | 13 ++++++++ components/esp_system/port/soc/esp32h2/clk.c | 3 ++ components/heap/port/esp32h2/memory_layout.c | 15 ++++++++- components/mbedtls/port/ecdsa/ecdsa_alt.c | 11 ++++--- .../soc/esp32h2/include/soc/interrupt_reg.h | 22 ++++++++++++- .../soc/esp32h2/register/soc/clint_reg.h | 1 + .../soc/esp32h2/register/soc/plic_reg.h | 1 + 14 files changed, 136 insertions(+), 19 deletions(-) diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index c235ab098e..9904fbbc3f 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c @@ -136,7 +136,7 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size) #if ESP_TEE_BUILD #include "esp_fault.h" #include "esp_flash_partitions.h" -#include "esp32c6/rom/spi_flash.h" +#include "rom/spi_flash.h" extern bool esp_tee_flash_check_paddr_in_active_tee_part(size_t paddr); #endif diff --git a/components/esp_hw_support/port/esp32h2/CMakeLists.txt b/components/esp_hw_support/port/esp32h2/CMakeLists.txt index 408601655e..0be7eb5dd9 100644 --- a/components/esp_hw_support/port/esp32h2/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32h2/CMakeLists.txt @@ -1,3 +1,5 @@ +idf_build_get_property(non_os_build NON_OS_BUILD) + set(srcs "rtc_clk_init.c" "rtc_clk.c" "pmu_param.c" @@ -7,7 +9,7 @@ set(srcs "rtc_clk_init.c" "chip_info.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/esp32h2/cpu_region_protect.c b/components/esp_hw_support/port/esp32h2/cpu_region_protect.c index b60dc95d4a..338f421378 100644 --- a/components/esp_hw_support/port/esp32h2/cpu_region_protect.c +++ b/components/esp_hw_support/port/esp32h2/cpu_region_protect.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 */ @@ -112,6 +112,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/esp32h2/esp_cpu_intr.c b/components/esp_hw_support/port/esp32h2/esp_cpu_intr.c index ca63df5141..bace035293 100644 --- a/components/esp_hw_support/port/esp32h2/esp_cpu_intr.c +++ b/components/esp_hw_support/port/esp32h2/esp_cpu_intr.c @@ -6,6 +6,7 @@ #include "esp_cpu.h" #include "esp_riscv_intr.h" +#include "sdkconfig.h" void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_desc_ret) { @@ -15,7 +16,18 @@ void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_ * Interrupts 3, 4 and 7 are unavailable for PULP CPU as they are bound to Core-Local Interrupts (CLINT) */ // [TODO: IDF-2465] - const uint32_t rsvd_mask = BIT(3) | BIT(4) | BIT(6) | BIT(7); + 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 + * 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); +#else + const uint32_t rsvd_mask = base_rsvd_mask; +#endif + intr_desc_ret->priority = 1; intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA; diff --git a/components/esp_mm/port/esp32h2/ext_mem_layout.c b/components/esp_mm/port/esp32h2/ext_mem_layout.c index 9c0004bfdd..64f38a2a4a 100644 --- a/components/esp_mm/port/esp32h2/ext_mem_layout.c +++ b/components/esp_mm/port/esp32h2/ext_mem_layout.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,15 +10,40 @@ #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 */ 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, .caps = MMU_MEM_CAP_EXEC | MMU_MEM_CAP_READ | MMU_MEM_CAP_32BIT | MMU_MEM_CAP_8BIT, diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index ad638e1b1c..1d8c7f1612 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -131,10 +131,8 @@ if(CONFIG_ESP_ROM_HAS_VERSION) endif() if(ESP_TEE_BUILD) - if(target STREQUAL "esp32c6") - rom_linker_script("spiflash") - rom_linker_script("heap") - endif() + rom_linker_script("spiflash") + rom_linker_script("heap") endif() if(BOOTLOADER_BUILD) diff --git a/components/esp_system/ld/esp32h2/memory.ld.in b/components/esp_system/ld/esp32h2/memory.ld.in index 27bb9091cf..ba1e5d9960 100644 --- a/components/esp_system/ld/esp32h2/memory.ld.in +++ b/components/esp_system/ld/esp32h2/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 0x4083EFD0 /* 2nd stage bootloader iram_loader_seg start address */ #define SRAM_SEG_SIZE SRAM_SEG_END - SRAM_SEG_START @@ -35,8 +41,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. @@ -54,8 +66,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/esp32h2/sections.ld.in b/components/esp_system/ld/esp32h2/sections.ld.in index 34fa0ea8cf..be973ed63c 100644 --- a/components/esp_system/ld/esp32h2/sections.ld.in +++ b/components/esp_system/ld/esp32h2/sections.ld.in @@ -173,9 +173,22 @@ SECTIONS /* 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 0x300 from the vector table start. + */ +#if CONFIG_SECURE_ENABLE_TEE + ALIGNED_SYMBOL(0x10, _esp_tee_app_cfg) + ASSERT(ABSOLUTE(.) == _vector_table_start + 0x2e0, "esp_tee_app_cfg must be at an offset 0x2e0 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/soc/esp32h2/clk.c b/components/esp_system/port/soc/esp32h2/clk.c index ac7760a223..4289dbeb3f 100644 --- a/components/esp_system/port/soc/esp32h2/clk.c +++ b/components/esp_system/port/soc/esp32h2/clk.c @@ -277,11 +277,14 @@ __attribute__((weak)) void esp_perip_clk_init(void) periph_ll_disable_clk_set_rst(PERIPH_ASSIST_DEBUG_MODULE); #endif periph_ll_disable_clk_set_rst(PERIPH_RSA_MODULE); +#if !CONFIG_SECURE_ENABLE_TEE + // NOTE: [ESP-TEE] The TEE is responsible for the AES and SHA peripherals periph_ll_disable_clk_set_rst(PERIPH_AES_MODULE); periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE); periph_ll_disable_clk_set_rst(PERIPH_ECC_MODULE); periph_ll_disable_clk_set_rst(PERIPH_HMAC_MODULE); periph_ll_disable_clk_set_rst(PERIPH_DS_MODULE); +#endif periph_ll_disable_clk_set_rst(PERIPH_ECDSA_MODULE); // TODO: Replace with hal implementation diff --git a/components/heap/port/esp32h2/memory_layout.c b/components/heap/port/esp32h2/memory_layout.c index 224e2ec454..05071759e9 100644 --- a/components/heap/port/esp32h2/memory_layout.c +++ b/components/heap/port/esp32h2/memory_layout.c @@ -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 */ @@ -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. @@ -94,6 +99,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/port/ecdsa/ecdsa_alt.c b/components/mbedtls/port/ecdsa/ecdsa_alt.c index fe61d2468f..6f3b849273 100644 --- a/components/mbedtls/port/ecdsa/ecdsa_alt.c +++ b/components/mbedtls/port/ecdsa/ecdsa_alt.c @@ -22,15 +22,18 @@ #if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN #include "esp_tee_sec_storage.h" -#else -#include "hal/ecc_ll.h" +#endif +#if SOC_ECDSA_SUPPORTED #include "hal/ecdsa_ll.h" #include "hal/ecdsa_hal.h" +#include "esp_efuse.h" +#endif +#if SOC_ECC_SUPPORTED +#include "hal/ecc_ll.h" +#endif #if SOC_MPI_SUPPORTED #include "hal/mpi_ll.h" #endif -#include "esp_efuse.h" -#endif #define ECDSA_KEY_MAGIC (short) 0xECD5A #define ECDSA_KEY_MAGIC_TEE (short) 0xA5DCE diff --git a/components/soc/esp32h2/include/soc/interrupt_reg.h b/components/soc/esp32h2/include/soc/interrupt_reg.h index 7e870b5410..3cbbecdbf0 100644 --- a/components/soc/esp32h2/include/soc/interrupt_reg.h +++ b/components/soc/esp32h2/include/soc/interrupt_reg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,16 +9,36 @@ #include "soc/plic_reg.h" #include "soc/soc_caps.h" +#ifdef __has_include +# if __has_include("sdkconfig.h") +# include "sdkconfig.h" +# endif +#endif + +#if CONFIG_SECURE_ENABLE_TEE +#define INTERRUPT_PRIO_REG(n) (PLIC_UXINT0_PRI_REG + (n)*4) +#define INTERRUPT_CURRENT_CORE_INT_THRESH_REG PLIC_UXINT_THRESH_REG +#else #define INTERRUPT_PRIO_REG(n) (PLIC_MXINT0_PRI_REG + (n)*4) #define INTERRUPT_CURRENT_CORE_INT_THRESH_REG PLIC_MXINT_THRESH_REG +#endif /** * ESP32H2 should use the PLIC controller as the interrupt controller instead of INTC (SOC_INT_PLIC_SUPPORTED = y) * Keep the following macros for backward compatibility reasons */ +#if CONFIG_SECURE_ENABLE_TEE +#define INTERRUPT_CORE0_CPU_INT_ENABLE_REG PLIC_UXINT_ENABLE_REG +#define INTERRUPT_CORE0_CPU_INT_THRESH_REG PLIC_UXINT_THRESH_REG +#define INTERRUPT_CORE0_CPU_INT_CLEAR_REG PLIC_UXINT_CLEAR_REG +#define INTERRUPT_CORE0_CPU_INT_TYPE_REG PLIC_UXINT_TYPE_REG +#define INTC_INT_PRIO_REG(n) (PLIC_UXINT0_PRI_REG + (n)*4) +#else #define INTERRUPT_CORE0_CPU_INT_ENABLE_REG PLIC_MXINT_ENABLE_REG #define INTERRUPT_CORE0_CPU_INT_THRESH_REG PLIC_MXINT_THRESH_REG #define INTERRUPT_CORE0_CPU_INT_CLEAR_REG PLIC_MXINT_CLEAR_REG #define INTERRUPT_CORE0_CPU_INT_TYPE_REG PLIC_MXINT_TYPE_REG #define INTC_INT_PRIO_REG(n) (PLIC_MXINT0_PRI_REG + (n)*4) +#endif + #define DR_REG_INTERRUPT_BASE DR_REG_INTMTX_BASE diff --git a/components/soc/esp32h2/register/soc/clint_reg.h b/components/soc/esp32h2/register/soc/clint_reg.h index 828ff818b7..7677ed68cf 100644 --- a/components/soc/esp32h2/register/soc/clint_reg.h +++ b/components/soc/esp32h2/register/soc/clint_reg.h @@ -11,6 +11,7 @@ extern "C" { #define DR_REG_CLINT_M_BASE ( 0x20001800) #define DR_REG_CLINT_U_BASE ( 0x20001C00) +#define DR_REG_CLINT_U_END ( 0x20002000) /*CLINT MINT*/ #define CLINT_MINT_SIP_REG (DR_REG_CLINT_M_BASE + 0x0) diff --git a/components/soc/esp32h2/register/soc/plic_reg.h b/components/soc/esp32h2/register/soc/plic_reg.h index b744601310..8f1944e63f 100644 --- a/components/soc/esp32h2/register/soc/plic_reg.h +++ b/components/soc/esp32h2/register/soc/plic_reg.h @@ -12,6 +12,7 @@ extern "C" { #define DR_REG_PLIC_MX_BASE ( 0x20001000 ) #define DR_REG_PLIC_UX_BASE ( 0x20001400 ) +#define DR_REG_PLIC_UX_END ( 0x20001800 ) #define PLIC_MXINT_CONF_REG ( 0x200013FC ) #define PLIC_UXINT_CONF_REG ( 0x200017FC )