mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 10:00:57 +02:00
Merge branch 'feature/esp_tee_c5' into 'master'
feat(esp_tee): Initial support for ESP32-C5 Closes IDF-10426, IDF-10427, IDF-10428, IDF-10429, and IDF-10430 See merge request espressif/esp-idf!38807
This commit is contained in:
@@ -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);
|
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
|
#endif //#if SOC_INT_CLIC_SUPPORTED
|
||||||
|
|
||||||
#if SOC_CPU_SUPPORT_WFE
|
#if SOC_CPU_SUPPORT_WFE
|
||||||
/**
|
/**
|
||||||
* @brief Disable the WFE (wait for event) feature for CPU.
|
* @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);
|
rv_utils_wfe_mode_enable(false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -450,9 +468,14 @@ FORCE_INLINE_ATTR uint32_t esp_cpu_intr_get_enabled_mask(void)
|
|||||||
{
|
{
|
||||||
#ifdef __XTENSA__
|
#ifdef __XTENSA__
|
||||||
return xt_utils_intr_get_enabled_mask();
|
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
|
#else
|
||||||
return rv_utils_intr_get_enabled_mask();
|
return rv_utils_intr_get_enabled_mask();
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -28,7 +28,10 @@
|
|||||||
#define MSPI_TIMING_FLASH_MODULE_CLOCK 120
|
#define MSPI_TIMING_FLASH_MODULE_CLOCK 120
|
||||||
#endif
|
#endif
|
||||||
//------------------------------------FLASH Needs Tuning or not-------------------------------------//
|
//------------------------------------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)
|
#define MSPI_TIMING_FLASH_NEEDS_TUNING (MSPI_TIMING_FLASH_MODULE_CLOCK > 40)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -45,7 +48,8 @@
|
|||||||
#define MSPI_TIMING_PSRAM_MODULE_CLOCK 10 //Define this to 10MHz
|
#define MSPI_TIMING_PSRAM_MODULE_CLOCK 10 //Define this to 10MHz
|
||||||
#endif
|
#endif
|
||||||
//------------------------------------PSRAM Needs Tuning or not-------------------------------------//
|
//------------------------------------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)
|
#define MSPI_TIMING_PSRAM_NEEDS_TUNING (MSPI_TIMING_PSRAM_MODULE_CLOCK > 40)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
idf_build_get_property(non_os_build NON_OS_BUILD)
|
||||||
|
|
||||||
set(srcs "rtc_clk_init.c"
|
set(srcs "rtc_clk_init.c"
|
||||||
"rtc_time.c"
|
"rtc_time.c"
|
||||||
"rtc_clk.c"
|
"rtc_clk.c"
|
||||||
@@ -8,7 +10,7 @@ set(srcs "rtc_clk_init.c"
|
|||||||
"ocode_init.c"
|
"ocode_init.c"
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT BOOTLOADER_BUILD)
|
if(NOT non_os_build)
|
||||||
list(APPEND srcs "sar_periph_ctrl.c")
|
list(APPEND srcs "sar_periph_ctrl.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@@ -126,6 +126,14 @@ void esp_cpu_configure_region_protection(void)
|
|||||||
//
|
//
|
||||||
esp_cpu_configure_invalid_regions();
|
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
|
// Configure all the valid address regions using PMP
|
||||||
//
|
//
|
||||||
|
@@ -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
|
* 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 1 for the Wifi controller.
|
||||||
* Reserve interrupt line 6 since it is used for disabling interrupts in the interrupt allocator (INT_MUX_DISABLED_INTNO)
|
* 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->priority = 1;
|
||||||
intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA;
|
intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA;
|
||||||
intr_desc_ret->flags = esp_riscv_intr_num_flags(intr_num, rsvd_mask);
|
intr_desc_ret->flags = esp_riscv_intr_num_flags(intr_num, rsvd_mask);
|
||||||
|
@@ -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]
|
// [TODO: IDF-2465]
|
||||||
const uint32_t base_rsvd_mask = BIT(1) | BIT(3) | BIT(4) | BIT(6) | BIT(7);
|
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
|
* for operations related to secure peripherals under its control
|
||||||
* (e.g. AES, SHA, APM)
|
* (e.g. AES, SHA, APM)
|
||||||
*/
|
*/
|
||||||
#if CONFIG_SECURE_ENABLE_TEE
|
#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
|
#else
|
||||||
const uint32_t rsvd_mask = base_rsvd_mask;
|
const uint32_t rsvd_mask = base_rsvd_mask;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -62,6 +62,10 @@ static void esp_cpu_configure_invalid_regions(void)
|
|||||||
// 7. End of address space
|
// 7. End of address space
|
||||||
PMA_ENTRY_SET_TOR(11, SOC_PERIPHERAL_HIGH, PMA_NONE);
|
PMA_ENTRY_SET_TOR(11, SOC_PERIPHERAL_HIGH, PMA_NONE);
|
||||||
PMA_ENTRY_SET_TOR(12, UINT32_MAX, PMA_TOR | 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)
|
void esp_cpu_configure_region_protection(void)
|
||||||
|
@@ -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]
|
// [TODO: IDF-2465]
|
||||||
const uint32_t base_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
|
/* On the ESP32-H2, interrupt 31 is reserved for ESP-TEE
|
||||||
* for operations related to secure peripherals under its control
|
* for operations related to secure peripherals under its control
|
||||||
* (e.g. AES, SHA, APM)
|
* (e.g. AES, SHA, APM)
|
||||||
*/
|
*/
|
||||||
#if CONFIG_SECURE_ENABLE_TEE
|
#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
|
#else
|
||||||
const uint32_t rsvd_mask = base_rsvd_mask;
|
const uint32_t rsvd_mask = base_rsvd_mask;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -10,6 +10,31 @@
|
|||||||
#include "../ext_mem_layout.h"
|
#include "../ext_mem_layout.h"
|
||||||
#include "hal/mmu_types.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
|
* The start addresses in this list should always be sorted from low to high, as MMU driver will need to
|
||||||
* coalesce adjacent regions
|
* coalesce adjacent regions
|
||||||
@@ -17,9 +42,9 @@
|
|||||||
// TODO: [ESP32C5] IDF-8658
|
// TODO: [ESP32C5] IDF-8658
|
||||||
const mmu_mem_region_t g_mmu_mem_regions[SOC_MMU_LINEAR_ADDRESS_REGION_NUM] = {
|
const mmu_mem_region_t g_mmu_mem_regions[SOC_MMU_LINEAR_ADDRESS_REGION_NUM] = {
|
||||||
[0] = {
|
[0] = {
|
||||||
.start = SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW,
|
.start = MMU_IRAM0_LINEAR_ADDRESS_LOW,
|
||||||
.end = SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH,
|
.end = MMU_IRAM0_LINEAR_ADDRESS_HIGH,
|
||||||
.size = SOC_BUS_SIZE(SOC_MMU_IRAM0_LINEAR),
|
.size = MMU_IRAM0_LINEAR_ADDRESS_HIGH - MMU_IRAM0_LINEAR_ADDRESS_LOW,
|
||||||
.bus_id = CACHE_BUS_IBUS0 | CACHE_BUS_DBUS0,
|
.bus_id = CACHE_BUS_IBUS0 | CACHE_BUS_DBUS0,
|
||||||
.targets = MMU_TARGET_FLASH0 | MMU_TARGET_PSRAM0,
|
.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,
|
.caps = MMU_MEM_CAP_EXEC | MMU_MEM_CAP_READ | MMU_MEM_CAP_WRITE | MMU_MEM_CAP_32BIT | MMU_MEM_CAP_8BIT,
|
||||||
|
@@ -75,6 +75,10 @@ if(CONFIG_ESP_ROM_NO_USB_SERIAL_OUTPUT_API)
|
|||||||
list(APPEND sources "patches/esp_rom_usb_serial.c")
|
list(APPEND sources "patches/esp_rom_usb_serial.c")
|
||||||
endif()
|
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}
|
idf_component_register(SRCS ${sources}
|
||||||
INCLUDE_DIRS ${include_dirs}
|
INCLUDE_DIRS ${include_dirs}
|
||||||
PRIV_REQUIRES ${private_required_comp}
|
PRIV_REQUIRES ${private_required_comp}
|
||||||
@@ -142,6 +146,9 @@ endif()
|
|||||||
if(ESP_TEE_BUILD)
|
if(ESP_TEE_BUILD)
|
||||||
rom_linker_script("spiflash")
|
rom_linker_script("spiflash")
|
||||||
rom_linker_script("heap")
|
rom_linker_script("heap")
|
||||||
|
if(CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT)
|
||||||
|
rom_linker_script("newlib-nano")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(BOOTLOADER_BUILD)
|
if(BOOTLOADER_BUILD)
|
||||||
@@ -388,7 +395,7 @@ else() # Regular app build
|
|||||||
endif()
|
endif()
|
||||||
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))
|
(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
|
# 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")
|
target_link_libraries(${COMPONENT_LIB} PRIVATE "-u ets_ops_set_rom_patches")
|
||||||
|
@@ -219,7 +219,7 @@ Cache_Suspend_Cache = 0x400006b4;
|
|||||||
Cache_Resume_Cache = 0x400006b8;
|
Cache_Resume_Cache = 0x400006b8;
|
||||||
Cache_Freeze_Enable = 0x400006bc;
|
Cache_Freeze_Enable = 0x400006bc;
|
||||||
Cache_Freeze_Disable = 0x400006c0;
|
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_IROM_MMU_End = 0x400006c8;
|
||||||
Cache_Get_DROM_MMU_End = 0x400006cc;
|
Cache_Get_DROM_MMU_End = 0x400006cc;
|
||||||
Cache_MMU_Init = 0x400006d0;
|
Cache_MMU_Init = 0x400006d0;
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -17,8 +18,17 @@ typedef void* tlsf_t;
|
|||||||
typedef void* pool_t;
|
typedef void* pool_t;
|
||||||
|
|
||||||
/* Create/destroy a memory pool. */
|
/* Create/destroy a memory pool. */
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
|
||||||
tlsf_t tlsf_create(void* mem);
|
tlsf_t tlsf_create(void* mem);
|
||||||
tlsf_t tlsf_create_with_pool(void* mem, size_t bytes);
|
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);
|
pool_t tlsf_get_pool(tlsf_t tlsf);
|
||||||
|
|
||||||
/* Add/remove memory pools. */
|
/* Add/remove memory pools. */
|
||||||
@@ -36,7 +46,6 @@ void tlsf_free(tlsf_t tlsf, void* ptr);
|
|||||||
size_t tlsf_block_size(void* ptr);
|
size_t tlsf_block_size(void* ptr);
|
||||||
|
|
||||||
/* Overheads/limits of internal structures. */
|
/* Overheads/limits of internal structures. */
|
||||||
size_t tlsf_size(void);
|
|
||||||
size_t tlsf_pool_overhead(void);
|
size_t tlsf_pool_overhead(void);
|
||||||
size_t tlsf_alloc_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_align_size(void);
|
||||||
size_t tlsf_block_size_min(void);
|
size_t tlsf_block_size_min(void);
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
|
||||||
size_t tlsf_block_size_max(void);
|
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
|
/* 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,
|
* in IDF builds to address issues in the ROM implementation. For TEE build,
|
||||||
|
32
components/esp_rom/patches/esp_rom_cache_esp32c5.c
Normal file
32
components/esp_rom/patches/esp_rom_cache_esp32c5.c
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#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;
|
||||||
|
}
|
@@ -117,7 +117,7 @@ uint32_t esp_rom_get_bootloader_offset(void)
|
|||||||
}
|
}
|
||||||
#endif // SOC_RECOVERY_BOOTLOADER_SUPPORTED
|
#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
|
#if CONFIG_ESP32C5_REV_MIN_FULL <= 100 || CONFIG_ESP32C61_REV_MIN_FULL <= 100
|
||||||
|
|
||||||
#include "riscv/rv_utils.h"
|
#include "riscv/rv_utils.h"
|
||||||
|
@@ -15,7 +15,13 @@
|
|||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "ld.common"
|
#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_END 0x4084E5A0 /* 2nd stage bootloader iram_loader_seg start address */
|
||||||
#define SRAM_SEG_SIZE SRAM_SEG_END - SRAM_SEG_START
|
#define SRAM_SEG_SIZE SRAM_SEG_END - SRAM_SEG_START
|
||||||
|
|
||||||
@@ -33,8 +39,14 @@ MEMORY
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
#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 */
|
/* Flash mapped instruction data */
|
||||||
irom_seg (RX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20
|
irom_seg (RX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (0x20 offset above is a convenience for the app binary image generation.
|
* (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
|
sram_seg (RWX) : org = SRAM_SEG_START, len = SRAM_SEG_SIZE
|
||||||
|
|
||||||
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||||
|
#if CONFIG_SECURE_ENABLE_TEE
|
||||||
/* Flash mapped constant data */
|
/* 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
|
drom_seg (R) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20
|
||||||
|
#endif
|
||||||
|
|
||||||
/* (See irom_seg for meaning of 0x20 offset in the above.) */
|
/* (See irom_seg for meaning of 0x20 offset in the above.) */
|
||||||
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||||
|
@@ -158,9 +158,22 @@ SECTIONS
|
|||||||
_iram_start = ABSOLUTE(.);
|
_iram_start = ABSOLUTE(.);
|
||||||
/* Vectors go to start of IRAM */
|
/* Vectors go to start of IRAM */
|
||||||
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
|
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
|
||||||
|
_vector_table_start = ABSOLUTE(.);
|
||||||
KEEP(*(.exception_vectors_table.text));
|
KEEP(*(.exception_vectors_table.text));
|
||||||
KEEP(*(.exception_vectors.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 */
|
/* Code marked as running out of IRAM */
|
||||||
_iram_text_start = ABSOLUTE(.);
|
_iram_text_start = ABSOLUTE(.);
|
||||||
|
|
||||||
|
@@ -172,8 +172,13 @@ static volatile bool s_resume_cores;
|
|||||||
|
|
||||||
static void core_intr_matrix_clear(void)
|
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++) {
|
for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) {
|
||||||
#if SOC_INT_CLIC_SUPPORTED
|
#if SOC_INT_CLIC_SUPPORTED
|
||||||
interrupt_clic_ll_route(core_id, i, ETS_INVALID_INUM);
|
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);
|
esp_rom_route_intr_matrix(core_id, i, ETS_INVALID_INUM);
|
||||||
#endif // SOC_INT_CLIC_SUPPORTED
|
#endif // SOC_INT_CLIC_SUPPORTED
|
||||||
}
|
}
|
||||||
|
#endif // !CONFIG_SECURE_ENABLE_TEE
|
||||||
|
|
||||||
#if SOC_INT_CLIC_SUPPORTED
|
#if SOC_INT_CLIC_SUPPORTED
|
||||||
for (int i = 0; i < 32; i++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
@@ -382,6 +388,15 @@ FORCE_INLINE_ATTR IRAM_ATTR void init_cpu(void)
|
|||||||
);
|
);
|
||||||
#endif
|
#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
|
#if SOC_BRANCH_PREDICTOR_SUPPORTED
|
||||||
esp_cpu_branch_prediction_enable();
|
esp_cpu_branch_prediction_enable();
|
||||||
#endif
|
#endif
|
||||||
@@ -391,19 +406,12 @@ FORCE_INLINE_ATTR IRAM_ATTR void init_cpu(void)
|
|||||||
/* When hardware vectored interrupts are enabled in CLIC,
|
/* When hardware vectored interrupts are enabled in CLIC,
|
||||||
* the CPU jumps to this base address + 4 * interrupt_id.
|
* 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
|
#endif
|
||||||
#if SOC_CPU_SUPPORT_WFE
|
#if SOC_CPU_SUPPORT_WFE
|
||||||
rv_utils_disable_wfe_mode();
|
esp_cpu_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);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -305,6 +305,7 @@ __attribute__((weak)) void esp_perip_clk_init(void)
|
|||||||
assist_debug_ll_enable_bus_clock(false);
|
assist_debug_ll_enable_bus_clock(false);
|
||||||
#endif
|
#endif
|
||||||
mpi_ll_enable_bus_clock(false);
|
mpi_ll_enable_bus_clock(false);
|
||||||
|
#if !CONFIG_SECURE_ENABLE_TEE
|
||||||
aes_ll_enable_bus_clock(false);
|
aes_ll_enable_bus_clock(false);
|
||||||
sha_ll_enable_bus_clock(false);
|
sha_ll_enable_bus_clock(false);
|
||||||
ecc_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);
|
ds_ll_enable_bus_clock(false);
|
||||||
apm_ll_hp_tee_enable_clk_gating(true);
|
apm_ll_hp_tee_enable_clk_gating(true);
|
||||||
apm_ll_lp_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_hp_apm_enable_ctrl_clk_gating(true);
|
||||||
apm_ll_cpu_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
|
// TODO: Replace with hal implementation
|
||||||
REG_CLR_BIT(PCR_TRACE_CONF_REG, PCR_TRACE_CLK_EN);
|
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_ana_i2c_clock(false);
|
||||||
_lp_clkrst_ll_enable_lp_ext_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_apm_enable_ctrl_clk_gating(true);
|
||||||
apm_ll_lp_apm0_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);
|
WRITE_PERI_REG(LP_CLKRST_LP_CLK_PO_EN_REG, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,8 +6,10 @@ idf_build_get_property(target IDF_TARGET)
|
|||||||
# headers & sources here are compiled into the app, not the esp_tee binary
|
# headers & sources here are compiled into the app, not the esp_tee binary
|
||||||
# (see subproject/ for the esp_tee binary build files)
|
# (see subproject/ for the esp_tee binary build files)
|
||||||
|
|
||||||
# ESP-TEE is currently supported only on the ESP32-C6 and ESP32-H2 SoCs
|
# ESP-TEE is currently supported only on the ESP32-C6, H2 and C5 SoCs
|
||||||
if(NOT ${target} STREQUAL "esp32c6" AND NOT ${target} STREQUAL "esp32h2")
|
set(SUPPORTED_TARGETS "esp32c6" "esp32h2" "esp32c5")
|
||||||
|
if(NOT target IN_LIST SUPPORTED_TARGETS)
|
||||||
|
message(STATUS "ESP-TEE is currently supported only on the ${SUPPORTED_TARGETS} SoCs")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
menu "ESP-TEE (Trusted Execution Environment)"
|
menu "ESP-TEE (Trusted Execution Environment)"
|
||||||
depends on IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2
|
depends on IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2 || IDF_TARGET_ESP32C5
|
||||||
|
|
||||||
config SECURE_ENABLE_TEE
|
config SECURE_ENABLE_TEE
|
||||||
bool "Enable the ESP-TEE framework"
|
bool "Enable the ESP-TEE framework"
|
||||||
|
@@ -10,13 +10,17 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
/* Declarations used inside TEE binary, only */
|
/* Declarations used inside TEE binary, only */
|
||||||
|
|
||||||
#define portNUM_PROCESSORS (1)
|
#define portNUM_PROCESSORS (1)
|
||||||
#define configNUM_CORES (portNUM_PROCESSORS)
|
#define configNUM_CORES (portNUM_PROCESSORS)
|
||||||
#define TEE_SECURE_INUM (14)
|
#define TEE_SECURE_INUM (31)
|
||||||
|
#if SOC_INT_CLIC_SUPPORTED
|
||||||
|
#define TEE_PASS_INUM (30)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ESP_TEE_M2U_SWITCH_MAGIC 0xfedef
|
#define ESP_TEE_M2U_SWITCH_MAGIC 0xfedef
|
||||||
|
|
||||||
|
332
components/esp_tee/scripts/esp32c5/sec_srv_tbl_default.yml
Normal file
332
components/esp_tee/scripts/esp32c5/sec_srv_tbl_default.yml
Normal file
@@ -0,0 +1,332 @@
|
|||||||
|
secure_services:
|
||||||
|
- family: misc
|
||||||
|
entries:
|
||||||
|
- id: 0
|
||||||
|
type: custom
|
||||||
|
function: invalid_secure_service
|
||||||
|
args: 0
|
||||||
|
# ID: 1-4 (4) - External memory (Flash) protection [SPI0]
|
||||||
|
- family: flash_protection_spi0
|
||||||
|
entries:
|
||||||
|
- id: 1
|
||||||
|
type: IDF
|
||||||
|
function: mmu_hal_map_region
|
||||||
|
args: 6
|
||||||
|
- id: 2
|
||||||
|
type: IDF
|
||||||
|
function: mmu_hal_unmap_region
|
||||||
|
args: 3
|
||||||
|
- id: 3
|
||||||
|
type: IDF
|
||||||
|
function: mmu_hal_vaddr_to_paddr
|
||||||
|
args: 4
|
||||||
|
- id: 4
|
||||||
|
type: IDF
|
||||||
|
function: mmu_hal_paddr_to_vaddr
|
||||||
|
args: 5
|
||||||
|
- id: 5
|
||||||
|
type: IDF
|
||||||
|
function: Cache_Set_IDROM_MMU_Size
|
||||||
|
args: 2
|
||||||
|
# ID: 6-22 (17) - External memory (Flash) protection [SPI1]
|
||||||
|
- family: flash_protection_spi1
|
||||||
|
entries:
|
||||||
|
- id: 6
|
||||||
|
type: IDF
|
||||||
|
function: spi_flash_hal_check_status
|
||||||
|
args: 1
|
||||||
|
- id: 7
|
||||||
|
type: IDF
|
||||||
|
function: spi_flash_hal_common_command
|
||||||
|
args: 2
|
||||||
|
- id: 8
|
||||||
|
type: IDF
|
||||||
|
function: spi_flash_hal_device_config
|
||||||
|
args: 1
|
||||||
|
- id: 9
|
||||||
|
type: IDF
|
||||||
|
function: spi_flash_hal_erase_block
|
||||||
|
args: 2
|
||||||
|
- id: 10
|
||||||
|
type: IDF
|
||||||
|
function: spi_flash_hal_erase_chip
|
||||||
|
args: 1
|
||||||
|
- id: 11
|
||||||
|
type: IDF
|
||||||
|
function: spi_flash_hal_erase_sector
|
||||||
|
args: 2
|
||||||
|
- id: 12
|
||||||
|
type: IDF
|
||||||
|
function: spi_flash_hal_program_page
|
||||||
|
args: 4
|
||||||
|
- id: 13
|
||||||
|
type: IDF
|
||||||
|
function: spi_flash_hal_read
|
||||||
|
args: 4
|
||||||
|
- id: 14
|
||||||
|
type: IDF
|
||||||
|
function: spi_flash_hal_resume
|
||||||
|
args: 1
|
||||||
|
- id: 15
|
||||||
|
type: IDF
|
||||||
|
function: spi_flash_hal_set_write_protect
|
||||||
|
args: 2
|
||||||
|
- id: 16
|
||||||
|
type: IDF
|
||||||
|
function: spi_flash_hal_setup_read_suspend
|
||||||
|
args: 2
|
||||||
|
- id: 17
|
||||||
|
type: IDF
|
||||||
|
function: spi_flash_hal_supports_direct_read
|
||||||
|
args: 2
|
||||||
|
- id: 18
|
||||||
|
type: IDF
|
||||||
|
function: spi_flash_hal_supports_direct_write
|
||||||
|
args: 2
|
||||||
|
- id: 19
|
||||||
|
type: IDF
|
||||||
|
function: spi_flash_hal_suspend
|
||||||
|
args: 1
|
||||||
|
- id: 20
|
||||||
|
type: IDF
|
||||||
|
function: bootloader_flash_execute_command_common
|
||||||
|
args: 7
|
||||||
|
- id: 21
|
||||||
|
type: IDF
|
||||||
|
function: memspi_host_flush_cache
|
||||||
|
args: 3
|
||||||
|
- id: 22
|
||||||
|
type: IDF
|
||||||
|
function: spi_flash_chip_generic_config_host_io_mode
|
||||||
|
args: 2
|
||||||
|
# ID: 30-53 (24) - Interrupt Handling
|
||||||
|
- family: interrupt_handling
|
||||||
|
entries:
|
||||||
|
- id: 30
|
||||||
|
type: IDF
|
||||||
|
function: esp_rom_route_intr_matrix
|
||||||
|
args: 3
|
||||||
|
- id: 31
|
||||||
|
type: IDF
|
||||||
|
function: rv_utils_intr_enable
|
||||||
|
args: 1
|
||||||
|
- id: 32
|
||||||
|
type: IDF
|
||||||
|
function: rv_utils_intr_disable
|
||||||
|
args: 1
|
||||||
|
- id: 33
|
||||||
|
type: IDF
|
||||||
|
function: rv_utils_intr_set_priority
|
||||||
|
args: 2
|
||||||
|
- id: 34
|
||||||
|
type: IDF
|
||||||
|
function: rv_utils_intr_set_type
|
||||||
|
args: 2
|
||||||
|
- id: 35
|
||||||
|
type: IDF
|
||||||
|
function: rv_utils_intr_set_threshold
|
||||||
|
args: 1
|
||||||
|
- id: 36
|
||||||
|
type: IDF
|
||||||
|
function: rv_utils_intr_edge_ack
|
||||||
|
args: 1
|
||||||
|
- id: 37
|
||||||
|
type: IDF
|
||||||
|
function: rv_utils_intr_global_enable
|
||||||
|
args: 0
|
||||||
|
- id: 38
|
||||||
|
type: IDF
|
||||||
|
function: rv_utils_intr_get_enabled_mask
|
||||||
|
args: 0
|
||||||
|
- id: 39
|
||||||
|
type: IDF
|
||||||
|
function: rv_utils_set_cycle_count
|
||||||
|
args: 1
|
||||||
|
- id: 40
|
||||||
|
type: IDF
|
||||||
|
function: rv_utils_en_branch_predictor
|
||||||
|
args: 0
|
||||||
|
- id: 41
|
||||||
|
type: IDF
|
||||||
|
function: rv_utils_dis_branch_predictor
|
||||||
|
args: 0
|
||||||
|
- id: 42
|
||||||
|
type: IDF
|
||||||
|
function: rv_utils_wfe_mode_enable
|
||||||
|
args: 1
|
||||||
|
- id: 43
|
||||||
|
type: IDF
|
||||||
|
function: esprv_int_set_vectored
|
||||||
|
args: 2
|
||||||
|
# ID: 54-85 (32) - HAL
|
||||||
|
- family: hal
|
||||||
|
entries:
|
||||||
|
- id: 54
|
||||||
|
type: IDF
|
||||||
|
function: wdt_hal_init
|
||||||
|
args: 4
|
||||||
|
- id: 55
|
||||||
|
type: IDF
|
||||||
|
function: wdt_hal_deinit
|
||||||
|
args: 1
|
||||||
|
# ID: 86-133 (48) - Crypto
|
||||||
|
- family: crypto
|
||||||
|
entries:
|
||||||
|
- id: 86
|
||||||
|
type: IDF
|
||||||
|
function: esp_aes_intr_alloc
|
||||||
|
args: 0
|
||||||
|
- id: 87
|
||||||
|
type: IDF
|
||||||
|
function: esp_aes_crypt_cbc
|
||||||
|
args: 6
|
||||||
|
- id: 88
|
||||||
|
type: IDF
|
||||||
|
function: esp_aes_crypt_cfb8
|
||||||
|
args: 6
|
||||||
|
- id: 89
|
||||||
|
type: IDF
|
||||||
|
function: esp_aes_crypt_cfb128
|
||||||
|
args: 7
|
||||||
|
- id: 90
|
||||||
|
type: IDF
|
||||||
|
function: esp_aes_crypt_ctr
|
||||||
|
args: 7
|
||||||
|
- id: 91
|
||||||
|
type: IDF
|
||||||
|
function: esp_aes_crypt_ecb
|
||||||
|
args: 4
|
||||||
|
- id: 92
|
||||||
|
type: IDF
|
||||||
|
function: esp_aes_crypt_ofb
|
||||||
|
args: 6
|
||||||
|
- id: 93
|
||||||
|
type: IDF
|
||||||
|
function: esp_sha
|
||||||
|
args: 4
|
||||||
|
- id: 94
|
||||||
|
type: IDF
|
||||||
|
function: esp_sha_block
|
||||||
|
args: 3
|
||||||
|
- id: 95
|
||||||
|
type: IDF
|
||||||
|
function: esp_sha_dma
|
||||||
|
args: 6
|
||||||
|
- id: 96
|
||||||
|
type: IDF
|
||||||
|
function: esp_sha_read_digest_state
|
||||||
|
args: 2
|
||||||
|
- id: 97
|
||||||
|
type: IDF
|
||||||
|
function: esp_sha_write_digest_state
|
||||||
|
args: 2
|
||||||
|
- id: 98
|
||||||
|
type: IDF
|
||||||
|
function: esp_crypto_sha_enable_periph_clk
|
||||||
|
args: 1
|
||||||
|
- id: 99
|
||||||
|
type: IDF
|
||||||
|
function: esp_hmac_calculate
|
||||||
|
args: 4
|
||||||
|
- id: 100
|
||||||
|
type: IDF
|
||||||
|
function: esp_hmac_jtag_enable
|
||||||
|
args: 2
|
||||||
|
- id: 101
|
||||||
|
type: IDF
|
||||||
|
function: esp_hmac_jtag_disable
|
||||||
|
args: 0
|
||||||
|
- id: 102
|
||||||
|
type: IDF
|
||||||
|
function: esp_ds_sign
|
||||||
|
args: 4
|
||||||
|
- id: 103
|
||||||
|
type: IDF
|
||||||
|
function: esp_ds_start_sign
|
||||||
|
args: 4
|
||||||
|
- id: 104
|
||||||
|
type: IDF
|
||||||
|
function: esp_ds_is_busy
|
||||||
|
args: 0
|
||||||
|
- id: 105
|
||||||
|
type: IDF
|
||||||
|
function: esp_ds_finish_sign
|
||||||
|
args: 2
|
||||||
|
- id: 106
|
||||||
|
type: IDF
|
||||||
|
function: esp_ds_encrypt_params
|
||||||
|
args: 4
|
||||||
|
- id: 107
|
||||||
|
type: IDF
|
||||||
|
function: esp_crypto_mpi_enable_periph_clk
|
||||||
|
args: 1
|
||||||
|
- id: 108
|
||||||
|
type: IDF
|
||||||
|
function: esp_ecc_point_multiply
|
||||||
|
args: 4
|
||||||
|
- id: 109
|
||||||
|
type: IDF
|
||||||
|
function: esp_ecc_point_verify
|
||||||
|
args: 1
|
||||||
|
- id: 110
|
||||||
|
type: IDF
|
||||||
|
function: esp_crypto_ecc_enable_periph_clk
|
||||||
|
args: 1
|
||||||
|
- id: 111
|
||||||
|
type: IDF
|
||||||
|
function: esp_sha_set_mode
|
||||||
|
args: 1
|
||||||
|
- id: 112
|
||||||
|
type: IDF
|
||||||
|
function: esp_sha_512_t_init_hash
|
||||||
|
args: 1
|
||||||
|
# ID: 134-169 (36) - Reserved for future use
|
||||||
|
- family: attestation
|
||||||
|
entries:
|
||||||
|
- id: 170
|
||||||
|
type: custom
|
||||||
|
function: esp_tee_att_generate_token
|
||||||
|
args: 6
|
||||||
|
# ID: 175-194 (20) - Secure Storage
|
||||||
|
- family: secure_storage
|
||||||
|
entries:
|
||||||
|
- id: 175
|
||||||
|
type: custom
|
||||||
|
function: esp_tee_sec_storage_clear_key
|
||||||
|
args: 1
|
||||||
|
- id: 176
|
||||||
|
type: custom
|
||||||
|
function: esp_tee_sec_storage_gen_key
|
||||||
|
args: 1
|
||||||
|
- id: 177
|
||||||
|
type: custom
|
||||||
|
function: esp_tee_sec_storage_ecdsa_sign
|
||||||
|
args: 4
|
||||||
|
- id: 178
|
||||||
|
type: custom
|
||||||
|
function: esp_tee_sec_storage_ecdsa_get_pubkey
|
||||||
|
args: 2
|
||||||
|
- id: 179
|
||||||
|
type: custom
|
||||||
|
function: esp_tee_sec_storage_aead_encrypt
|
||||||
|
args: 4
|
||||||
|
- id: 180
|
||||||
|
type: custom
|
||||||
|
function: esp_tee_sec_storage_aead_decrypt
|
||||||
|
args: 4
|
||||||
|
# ID: 195-199 (5) - OTA
|
||||||
|
- family: ota
|
||||||
|
entries:
|
||||||
|
- id: 195
|
||||||
|
type: custom
|
||||||
|
function: esp_tee_ota_begin
|
||||||
|
args: 0
|
||||||
|
- id: 196
|
||||||
|
type: custom
|
||||||
|
function: esp_tee_ota_write
|
||||||
|
args: 3
|
||||||
|
- id: 197
|
||||||
|
type: custom
|
||||||
|
function: esp_tee_ota_end
|
||||||
|
args: 0
|
||||||
|
# ID: 200+ - User-defined
|
@@ -20,6 +20,7 @@
|
|||||||
#include "esp_flash.h"
|
#include "esp_flash.h"
|
||||||
|
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
#include "esp_tee.h"
|
#include "esp_tee.h"
|
||||||
#include "secure_service_num.h"
|
#include "secure_service_num.h"
|
||||||
@@ -31,6 +32,13 @@ void IRAM_ATTR __wrap_esp_rom_route_intr_matrix(int cpu_no, uint32_t model_num,
|
|||||||
esp_tee_service_call(4, SS_ESP_ROM_ROUTE_INTR_MATRIX, cpu_no, model_num, intr_num);
|
esp_tee_service_call(4, SS_ESP_ROM_ROUTE_INTR_MATRIX, cpu_no, model_num, intr_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOC_INT_CLIC_SUPPORTED
|
||||||
|
void IRAM_ATTR __wrap_esprv_int_set_vectored(int rv_int_num, bool vectored)
|
||||||
|
{
|
||||||
|
esp_tee_service_call(3, SS_ESPRV_INT_SET_VECTORED, rv_int_num, vectored);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------- RTC_WDT ------------------------------------------------- */
|
/* ---------------------------------------------- RTC_WDT ------------------------------------------------- */
|
||||||
|
|
||||||
void __wrap_wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescaler, bool enable_intr)
|
void __wrap_wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescaler, bool enable_intr)
|
||||||
@@ -222,6 +230,13 @@ void __wrap_esp_crypto_sha_enable_periph_clk(bool enable)
|
|||||||
esp_tee_service_call(2, SS_ESP_CRYPTO_SHA_ENABLE_PERIPH_CLK, enable);
|
esp_tee_service_call(2, SS_ESP_CRYPTO_SHA_ENABLE_PERIPH_CLK, enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOC_SHA_SUPPORT_SHA512_T
|
||||||
|
int __wrap_esp_sha_512_t_init_hash(uint16_t t)
|
||||||
|
{
|
||||||
|
return esp_tee_service_call(2, SS_ESP_SHA_512_T_INIT_HASH, t);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------- HMAC ------------------------------------------------- */
|
/* ---------------------------------------------- HMAC ------------------------------------------------- */
|
||||||
|
|
||||||
esp_err_t __wrap_esp_hmac_calculate(hmac_key_id_t key_id, const void *message, size_t message_len, uint8_t *hmac)
|
esp_err_t __wrap_esp_hmac_calculate(hmac_key_id_t key_id, const void *message, size_t message_len, uint8_t *hmac)
|
||||||
@@ -365,6 +380,25 @@ bool IRAM_ATTR __wrap_mmu_hal_paddr_to_vaddr(uint32_t mmu_id, uint32_t paddr, mm
|
|||||||
return esp_tee_service_call(6, SS_MMU_HAL_PADDR_TO_VADDR, mmu_id, paddr, target, type, out_vaddr);
|
return esp_tee_service_call(6, SS_MMU_HAL_PADDR_TO_VADDR, mmu_id, paddr, target, type, out_vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, we wrap this function to be routed as a TEE service call.
|
||||||
|
*/
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32C5
|
||||||
|
void IRAM_ATTR __wrap_Cache_Set_IDROM_MMU_Size(uint32_t irom_size, uint32_t drom_size)
|
||||||
|
{
|
||||||
|
esp_tee_service_call(3, SS_CACHE_SET_IDROM_MMU_SIZE, irom_size, drom_size);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||||
/* ---------------------------------------------- SPI Flash HAL ------------------------------------------------- */
|
/* ---------------------------------------------- SPI Flash HAL ------------------------------------------------- */
|
||||||
|
|
||||||
|
@@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@@ -100,7 +100,7 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t
|
|||||||
uint32_t mmap_len = MIN(len, partial_image_len);
|
uint32_t mmap_len = MIN(len, partial_image_len);
|
||||||
const void *image = esp_tee_flash_mmap(flash_offset, mmap_len);
|
const void *image = esp_tee_flash_mmap(flash_offset, mmap_len);
|
||||||
if (image == NULL) {
|
if (image == NULL) {
|
||||||
mbedtls_sha256_finish(&ctx, NULL);
|
mbedtls_sha256_free(&ctx);
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
mbedtls_sha256_update(&ctx, image, mmap_len);
|
mbedtls_sha256_update(&ctx, image, mmap_len);
|
||||||
|
@@ -14,8 +14,13 @@ set(srcs "core/esp_tee_init.c"
|
|||||||
"core/esp_secure_service_table.c")
|
"core/esp_secure_service_table.c")
|
||||||
|
|
||||||
# Arch specific implementation for TEE
|
# Arch specific implementation for TEE
|
||||||
list(APPEND srcs "arch/${arch}/esp_tee_vectors.S"
|
if(CONFIG_SOC_INT_PLIC_SUPPORTED)
|
||||||
"arch/${arch}/esp_tee_vector_table.S")
|
list(APPEND srcs "arch/${arch}/esp_tee_vectors_plic.S"
|
||||||
|
"arch/${arch}/esp_tee_vector_table_plic.S")
|
||||||
|
elseif(CONFIG_SOC_INT_CLIC_SUPPORTED)
|
||||||
|
list(APPEND srcs "arch/${arch}/esp_tee_vectors_clic.S"
|
||||||
|
"arch/${arch}/esp_tee_vector_table_clic.S")
|
||||||
|
endif()
|
||||||
|
|
||||||
# SoC specific implementation for TEE
|
# SoC specific implementation for TEE
|
||||||
list(APPEND srcs "soc/${target}/esp_tee_secure_sys_cfg.c"
|
list(APPEND srcs "soc/${target}/esp_tee_secure_sys_cfg.c"
|
||||||
|
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "soc/soc.h"
|
||||||
|
|
||||||
|
/* The system interrupts are not used for now, so trigger a panic every time one occurs. */
|
||||||
|
#define _system_int_handler _tee_panic_handler
|
||||||
|
|
||||||
|
/* Handlers defined in the `vector.S` file, common to all RISC-V targets */
|
||||||
|
.global _tee_ns_intr_handler
|
||||||
|
.global _tee_panic_handler
|
||||||
|
|
||||||
|
.section .exception_vectors_table.text
|
||||||
|
|
||||||
|
/* Prevent the compiler from generating 2-byte instruction in the vector tables */
|
||||||
|
.option push
|
||||||
|
.option norvc
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Non-hardware vectored interrupt entry. MTVEC CSR points here.
|
||||||
|
*
|
||||||
|
* On targets that use CLIC as their interrupt controller, when an exception occurs, the CPU
|
||||||
|
* jumps to the address stored in MTVEC[31:6] << 6. The CPU will also jump to this location
|
||||||
|
* if an interrupt is configured as non-vectored (CLIC_INT_ATTR.shv = 0).
|
||||||
|
*
|
||||||
|
* Because of the left-shift `<< 6`, this entry must be aligned on 64.
|
||||||
|
*/
|
||||||
|
.global _vector_table
|
||||||
|
.type _vector_table, @function
|
||||||
|
.balign 0x40
|
||||||
|
_vector_table:
|
||||||
|
j _tee_panic_handler
|
||||||
|
.size _vector_table, .-_vector_table
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vectored interrupt table. MTVT CSR points here.
|
||||||
|
*
|
||||||
|
* If an interrupt occurs and is configured as (hardware) vectored, the CPU will jump to
|
||||||
|
* MTVT[31:0] + 4 * interrupt_id
|
||||||
|
*
|
||||||
|
* In the case of the ESP32P4, the interrupt matrix, between the CPU interrupt lines
|
||||||
|
* and the peripherals, offers 32 lines. As such, the interrupt_id between 0 and 31.
|
||||||
|
*
|
||||||
|
* Since the interrupts are initialized as vectored on CPU start, we can manage the special
|
||||||
|
* interrupts ETS_T1_WDT_INUM, ETS_CACHEERR_INUM and ETS_MEMPROT_ERR_INUM here.
|
||||||
|
*/
|
||||||
|
.balign 0x40
|
||||||
|
.global _mtvt_table
|
||||||
|
.type _mtvt_table, @function
|
||||||
|
_mtvt_table:
|
||||||
|
.word _system_int_handler /* 0: System interrupt number. Exceptions are non-vectored, won't load this. */
|
||||||
|
.word _system_int_handler /* 1: System interrupt number */
|
||||||
|
.word _system_int_handler /* 2: System interrupt number */
|
||||||
|
.word _system_int_handler /* 3: System interrupt number */
|
||||||
|
.word _system_int_handler /* 4: System interrupt number */
|
||||||
|
.word _system_int_handler /* 5: System interrupt number */
|
||||||
|
.word _system_int_handler /* 6: System interrupt number */
|
||||||
|
.word _system_int_handler /* 7: System interrupt number */
|
||||||
|
.word _system_int_handler /* 8: System interrupt number */
|
||||||
|
.word _system_int_handler /* 9: System interrupt number */
|
||||||
|
.word _system_int_handler /* 10: System interrupt number */
|
||||||
|
.word _system_int_handler /* 11: System interrupt number */
|
||||||
|
.word _system_int_handler /* 12: System interrupt number */
|
||||||
|
.word _system_int_handler /* 13: System interrupt number */
|
||||||
|
.word _system_int_handler /* 14: System interrupt number */
|
||||||
|
.word _system_int_handler /* 15: System interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 16: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 17: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 18: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 19: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 20: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 21: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 22: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 23: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 24: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 25: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 26: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 27: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 28: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 29: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 30: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 31: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 32: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 33: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 34: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 35: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 36: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 37: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 38: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 39: Free interrupt number */
|
||||||
|
.word _tee_panic_handler /* 40: ETS_INT_WDT_INUM (+16) panic-interrupt (soc-level panic) */
|
||||||
|
.word _tee_panic_handler /* 41: ETS_CACHEERR_INUM (+16) panic-interrupt (soc-level panic) */
|
||||||
|
/* NOTE: Triggers panic irrespective of the Kconfig setting with ESP-TEE */
|
||||||
|
.word _tee_panic_handler /* 42: ETS_MEMPROT_ERR_INUM (+16) handler (soc-level panic) */
|
||||||
|
/* TODO: [IDF-10770] Not supported yet with ESP-TEE */
|
||||||
|
.word _tee_panic_handler /* 43: ETS_ASSIST_DEBUG_INUM (+16) handler (soc-level panic) */
|
||||||
|
.word _tee_ns_intr_handler /* 44: ETS_IPC_ISR_INUM (+16) handler*/
|
||||||
|
.word _tee_ns_intr_handler /* 45: Free interrupt number */
|
||||||
|
.word _tee_ns_intr_handler /* 46: ESP-TEE: U-mode interrupt delegation entry */
|
||||||
|
.word _tee_s_intr_handler /* 47: ESP-TEE: Secure interrupt handler entry */
|
||||||
|
|
||||||
|
.size _mtvt_table, .-_mtvt_table
|
||||||
|
.option pop
|
@@ -51,7 +51,7 @@ _vector_table:
|
|||||||
j _tee_ns_intr_handler /* 11: Free interrupt number */
|
j _tee_ns_intr_handler /* 11: Free interrupt number */
|
||||||
j _tee_ns_intr_handler /* 12: Free interrupt number */
|
j _tee_ns_intr_handler /* 12: Free interrupt number */
|
||||||
j _tee_ns_intr_handler /* 13: Free interrupt number */
|
j _tee_ns_intr_handler /* 13: Free interrupt number */
|
||||||
j _tee_s_intr_handler /* 14: ESP-TEE: Secure interrupt handler entry */
|
j _tee_ns_intr_handler /* 14: Free interrupt number */
|
||||||
j _tee_ns_intr_handler /* 15: Free interrupt number */
|
j _tee_ns_intr_handler /* 15: Free interrupt number */
|
||||||
j _tee_ns_intr_handler /* 16: Free interrupt number */
|
j _tee_ns_intr_handler /* 16: Free interrupt number */
|
||||||
j _tee_ns_intr_handler /* 17: Free interrupt number */
|
j _tee_ns_intr_handler /* 17: Free interrupt number */
|
||||||
@@ -70,7 +70,7 @@ _vector_table:
|
|||||||
j _tee_ns_intr_handler /* 28: Free interrupt number */
|
j _tee_ns_intr_handler /* 28: Free interrupt number */
|
||||||
j _tee_ns_intr_handler /* 29: Free interrupt number */
|
j _tee_ns_intr_handler /* 29: Free interrupt number */
|
||||||
j _tee_ns_intr_handler /* 30: Free interrupt number */
|
j _tee_ns_intr_handler /* 30: Free interrupt number */
|
||||||
j _tee_ns_intr_handler /* 31: Free interrupt number */
|
j _tee_s_intr_handler /* 31: ESP-TEE: Secure interrupt handler entry */
|
||||||
j _panic_handler /* exception handler, entry 0 */
|
j _panic_handler /* exception handler, entry 0 */
|
||||||
|
|
||||||
.size _vector_table, .-_vector_table
|
.size _vector_table, .-_vector_table
|
@@ -0,0 +1,628 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
#include "soc/clic_reg.h"
|
||||||
|
|
||||||
|
#include "riscv/encoding.h"
|
||||||
|
#include "riscv/rvruntime-frames.h"
|
||||||
|
#include "esp_private/vectors_const.h"
|
||||||
|
|
||||||
|
#include "esp_tee.h"
|
||||||
|
#include "esp_tee_intr_defs.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
.equ SAVE_REGS, 32
|
||||||
|
.equ CONTEXT_SIZE, (SAVE_REGS * 4)
|
||||||
|
.equ panic_from_exception, tee_panic_from_exc
|
||||||
|
.equ panic_from_isr, tee_panic_from_isr
|
||||||
|
.equ MAGIC, 0x1f
|
||||||
|
.equ RTNVAL, 0xc0de
|
||||||
|
.equ ECALL_U_MODE, 0x8
|
||||||
|
.equ ECALL_M_MODE, 0xb
|
||||||
|
.equ CSR_UINTTHRESH, 0x047
|
||||||
|
|
||||||
|
.global esp_tee_global_interrupt_handler
|
||||||
|
.global esp_tee_service_dispatcher
|
||||||
|
.global _tee_s_entry
|
||||||
|
|
||||||
|
.section .data
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
.global _ns_sp
|
||||||
|
_ns_sp:
|
||||||
|
.word 0
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
.global _s_sp
|
||||||
|
_s_sp:
|
||||||
|
.word 0
|
||||||
|
|
||||||
|
/* Macro which first allocates space on the stack to save general
|
||||||
|
* purpose registers, and then save them. GP register is excluded.
|
||||||
|
* The default size allocated on the stack is CONTEXT_SIZE, but it
|
||||||
|
* can be overridden. */
|
||||||
|
.macro save_general_regs cxt_size=CONTEXT_SIZE
|
||||||
|
addi sp, sp, -\cxt_size
|
||||||
|
sw ra, RV_STK_RA(sp)
|
||||||
|
sw tp, RV_STK_TP(sp)
|
||||||
|
sw t0, RV_STK_T0(sp)
|
||||||
|
sw t1, RV_STK_T1(sp)
|
||||||
|
sw t2, RV_STK_T2(sp)
|
||||||
|
sw s0, RV_STK_S0(sp)
|
||||||
|
sw s1, RV_STK_S1(sp)
|
||||||
|
sw a0, RV_STK_A0(sp)
|
||||||
|
sw a1, RV_STK_A1(sp)
|
||||||
|
sw a2, RV_STK_A2(sp)
|
||||||
|
sw a3, RV_STK_A3(sp)
|
||||||
|
sw a4, RV_STK_A4(sp)
|
||||||
|
sw a5, RV_STK_A5(sp)
|
||||||
|
sw a6, RV_STK_A6(sp)
|
||||||
|
sw a7, RV_STK_A7(sp)
|
||||||
|
sw s2, RV_STK_S2(sp)
|
||||||
|
sw s3, RV_STK_S3(sp)
|
||||||
|
sw s4, RV_STK_S4(sp)
|
||||||
|
sw s5, RV_STK_S5(sp)
|
||||||
|
sw s6, RV_STK_S6(sp)
|
||||||
|
sw s7, RV_STK_S7(sp)
|
||||||
|
sw s8, RV_STK_S8(sp)
|
||||||
|
sw s9, RV_STK_S9(sp)
|
||||||
|
sw s10, RV_STK_S10(sp)
|
||||||
|
sw s11, RV_STK_S11(sp)
|
||||||
|
sw t3, RV_STK_T3(sp)
|
||||||
|
sw t4, RV_STK_T4(sp)
|
||||||
|
sw t5, RV_STK_T5(sp)
|
||||||
|
sw t6, RV_STK_T6(sp)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro save_mepc
|
||||||
|
csrr t0, mepc
|
||||||
|
sw t0, RV_STK_MEPC(sp)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro save_mcsr
|
||||||
|
csrr t0, mstatus
|
||||||
|
sw t0, RV_STK_MSTATUS(sp)
|
||||||
|
csrr t0, mtvec
|
||||||
|
sw t0, RV_STK_MTVEC(sp)
|
||||||
|
csrr t0, mtval
|
||||||
|
sw t0, RV_STK_MTVAL(sp)
|
||||||
|
csrr t0, mhartid
|
||||||
|
sw t0, RV_STK_MHARTID(sp)
|
||||||
|
csrr t0, mcause
|
||||||
|
sw t0, RV_STK_MCAUSE(sp)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/* Restore the general purpose registers (excluding gp) from the context on
|
||||||
|
* the stack. The context is then deallocated. The default size is CONTEXT_SIZE
|
||||||
|
* but it can be overridden. */
|
||||||
|
.macro restore_general_regs cxt_size=CONTEXT_SIZE
|
||||||
|
lw ra, RV_STK_RA(sp)
|
||||||
|
lw tp, RV_STK_TP(sp)
|
||||||
|
lw t0, RV_STK_T0(sp)
|
||||||
|
lw t1, RV_STK_T1(sp)
|
||||||
|
lw t2, RV_STK_T2(sp)
|
||||||
|
lw s0, RV_STK_S0(sp)
|
||||||
|
lw s1, RV_STK_S1(sp)
|
||||||
|
lw a0, RV_STK_A0(sp)
|
||||||
|
lw a1, RV_STK_A1(sp)
|
||||||
|
lw a2, RV_STK_A2(sp)
|
||||||
|
lw a3, RV_STK_A3(sp)
|
||||||
|
lw a4, RV_STK_A4(sp)
|
||||||
|
lw a5, RV_STK_A5(sp)
|
||||||
|
lw a6, RV_STK_A6(sp)
|
||||||
|
lw a7, RV_STK_A7(sp)
|
||||||
|
lw s2, RV_STK_S2(sp)
|
||||||
|
lw s3, RV_STK_S3(sp)
|
||||||
|
lw s4, RV_STK_S4(sp)
|
||||||
|
lw s5, RV_STK_S5(sp)
|
||||||
|
lw s6, RV_STK_S6(sp)
|
||||||
|
lw s7, RV_STK_S7(sp)
|
||||||
|
lw s8, RV_STK_S8(sp)
|
||||||
|
lw s9, RV_STK_S9(sp)
|
||||||
|
lw s10, RV_STK_S10(sp)
|
||||||
|
lw s11, RV_STK_S11(sp)
|
||||||
|
lw t3, RV_STK_T3(sp)
|
||||||
|
lw t4, RV_STK_T4(sp)
|
||||||
|
lw t5, RV_STK_T5(sp)
|
||||||
|
lw t6, RV_STK_T6(sp)
|
||||||
|
addi sp,sp, \cxt_size
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro restore_mepc
|
||||||
|
lw t0, RV_STK_MEPC(sp)
|
||||||
|
csrw mepc, t0
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro store_magic_general_regs
|
||||||
|
lui ra, MAGIC
|
||||||
|
lui tp, MAGIC
|
||||||
|
lui t0, MAGIC
|
||||||
|
lui t1, MAGIC
|
||||||
|
lui t2, MAGIC
|
||||||
|
lui s0, MAGIC
|
||||||
|
lui s1, MAGIC
|
||||||
|
lui a0, MAGIC
|
||||||
|
lui a1, MAGIC
|
||||||
|
lui a2, MAGIC
|
||||||
|
lui a3, MAGIC
|
||||||
|
lui a4, MAGIC
|
||||||
|
lui a5, MAGIC
|
||||||
|
lui a6, MAGIC
|
||||||
|
lui a7, MAGIC
|
||||||
|
lui s2, MAGIC
|
||||||
|
lui s3, MAGIC
|
||||||
|
lui s4, MAGIC
|
||||||
|
lui s5, MAGIC
|
||||||
|
lui s6, MAGIC
|
||||||
|
lui s7, MAGIC
|
||||||
|
lui s8, MAGIC
|
||||||
|
lui s9, MAGIC
|
||||||
|
lui s10, MAGIC
|
||||||
|
lui s11, MAGIC
|
||||||
|
lui t3, MAGIC
|
||||||
|
lui t4, MAGIC
|
||||||
|
lui t5, MAGIC
|
||||||
|
lui t6, MAGIC
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.section .exception_vectors.text, "ax"
|
||||||
|
|
||||||
|
/* Exception handler. */
|
||||||
|
.global _tee_panic_handler
|
||||||
|
.type _tee_panic_handler, @function
|
||||||
|
_tee_panic_handler:
|
||||||
|
/* Exception handler. */
|
||||||
|
.global _panic_handler
|
||||||
|
.type _panic_handler, @function
|
||||||
|
_panic_handler:
|
||||||
|
/* Backup t0, t1 on the stack before using it */
|
||||||
|
addi sp, sp, -16
|
||||||
|
sw t0, 0(sp)
|
||||||
|
sw t1, 4(sp)
|
||||||
|
|
||||||
|
/* Read mcause */
|
||||||
|
csrr t0, mcause
|
||||||
|
li t1, VECTORS_MCAUSE_INTBIT_MASK | VECTORS_MCAUSE_REASON_MASK
|
||||||
|
and t0, t0, t1
|
||||||
|
|
||||||
|
/* Check whether the exception is an M-mode ecall */
|
||||||
|
li t1, ECALL_M_MODE
|
||||||
|
beq t0, t1, _machine_ecall
|
||||||
|
|
||||||
|
/* Check whether the exception is an U-mode ecall */
|
||||||
|
li t1, ECALL_U_MODE
|
||||||
|
beq t0, t1, _user_ecall
|
||||||
|
|
||||||
|
/* Restore t0, t1 from the stack */
|
||||||
|
lw t0, 0(sp)
|
||||||
|
lw t1, 4(sp)
|
||||||
|
addi sp, sp, 16
|
||||||
|
|
||||||
|
_actual_panic:
|
||||||
|
/* Not an ecall, proceed to the panic handler */
|
||||||
|
/* Allocate space on the stack and store general purpose registers */
|
||||||
|
save_general_regs RV_STK_FRMSZ
|
||||||
|
|
||||||
|
/* As gp register is not saved by the macro, save it here */
|
||||||
|
sw gp, RV_STK_GP(sp)
|
||||||
|
|
||||||
|
/* Same goes for the SP value before trapping */
|
||||||
|
addi t0, sp, RV_STK_FRMSZ /* restore sp with the value when trap happened */
|
||||||
|
|
||||||
|
/* Save CSRs */
|
||||||
|
sw t0, RV_STK_SP(sp)
|
||||||
|
save_mepc
|
||||||
|
save_mcsr
|
||||||
|
|
||||||
|
/* Keep mcause in s0, only the exception code and interrupt bit are relevant */
|
||||||
|
csrr s0, mcause
|
||||||
|
li t1, VECTORS_MCAUSE_INTBIT_MASK | VECTORS_MCAUSE_REASON_MASK
|
||||||
|
and s0, s0, t1
|
||||||
|
|
||||||
|
/* Call panic_from_exception(sp) or panic_from_isr(sp)
|
||||||
|
* depending on whether we have a pseudo excause or not.
|
||||||
|
* If mcause's highest bit is 1, then an interrupt called this routine,
|
||||||
|
* so we have a pseudo excause. Else, it is due to a exception, we don't
|
||||||
|
* have an pseudo excause */
|
||||||
|
mv a0, sp
|
||||||
|
mv a1, s0
|
||||||
|
/* Branches instructions don't accept immediates values, so use t1 to
|
||||||
|
* store our comparator */
|
||||||
|
li t0, 0x80000000
|
||||||
|
bgeu a1, t0, _call_panic_handler
|
||||||
|
sw a1, RV_STK_MCAUSE(sp)
|
||||||
|
/* exception_from_panic never returns */
|
||||||
|
jal panic_from_exception
|
||||||
|
/* We arrive here if the exception handler has returned. */
|
||||||
|
j _return_from_exception
|
||||||
|
|
||||||
|
_call_panic_handler:
|
||||||
|
/* Remove highest bit from mcause (a1) register and save it in the
|
||||||
|
* structure */
|
||||||
|
not t0, t0
|
||||||
|
and a1, a1, t0
|
||||||
|
#if CONFIG_SOC_INT_CLIC_SUPPORTED
|
||||||
|
/* When CLIC is supported, external interrupts are shifted by 16, deduct this difference from mcause */
|
||||||
|
add a1, a1, -16
|
||||||
|
#endif // CONFIG_SOC_INT_CLIC_SUPPORTED
|
||||||
|
sw a1, RV_STK_MCAUSE(sp)
|
||||||
|
jal panic_from_isr
|
||||||
|
|
||||||
|
/* We arrive here if the exception handler has returned. This means that
|
||||||
|
* the exception was handled, and the execution flow should resume.
|
||||||
|
* Restore the registers and return from the exception.
|
||||||
|
*/
|
||||||
|
_return_from_exception:
|
||||||
|
restore_mepc
|
||||||
|
/* MTVEC and SP are assumed to be unmodified.
|
||||||
|
* MSTATUS, MHARTID, MTVAL are read-only and not restored. */
|
||||||
|
lw gp, RV_STK_GP(sp)
|
||||||
|
restore_general_regs RV_STK_FRMSZ
|
||||||
|
mret
|
||||||
|
|
||||||
|
.size _panic_handler, .-_panic_handler
|
||||||
|
|
||||||
|
/* ECALL handler. */
|
||||||
|
.type _ecall_handler, @function
|
||||||
|
_ecall_handler:
|
||||||
|
/* M-mode ecall handler */
|
||||||
|
_machine_ecall:
|
||||||
|
/* Enable the U-mode delegation of all interrupts */
|
||||||
|
li t0, INTMTX_SIG_IDX_ASSERT_IN_SEC_REG
|
||||||
|
li t1, 0x00
|
||||||
|
sw t1, 0(t0)
|
||||||
|
fence
|
||||||
|
/* Verify the above */
|
||||||
|
_1:
|
||||||
|
lw t2, 0(t0)
|
||||||
|
bne t2, t1, _2
|
||||||
|
|
||||||
|
/* Set the privilege mode to transition to after mret to U-mode */
|
||||||
|
li t0, MSTATUS_MPP
|
||||||
|
csrc mstatus, t0
|
||||||
|
|
||||||
|
/* Check whether this is the first M-mode ecall (see esp_tee_init) and skip context restoration */
|
||||||
|
lui t0, ESP_TEE_M2U_SWITCH_MAGIC
|
||||||
|
beq a1, t0, _skip_ctx_restore
|
||||||
|
|
||||||
|
/* Switching back to the saved REE stack */
|
||||||
|
la t0, _ns_sp
|
||||||
|
lw sp, 0(t0)
|
||||||
|
fence
|
||||||
|
|
||||||
|
/* Backup the A0 register
|
||||||
|
* This point is reached after an ecall is triggered after executing the secure service.
|
||||||
|
* The A0 register contains the return value of the corresponding service.
|
||||||
|
* After restoring the entire register context, we assign A0 the value back to the return value. */
|
||||||
|
csrw mscratch, a0
|
||||||
|
restore_general_regs
|
||||||
|
csrrw a0, mscratch, zero
|
||||||
|
|
||||||
|
_skip_ctx_restore:
|
||||||
|
/* Copy the ra register to mepc which contains the user app entry point (i.e. call_start_cpu0) */
|
||||||
|
csrw mepc, ra
|
||||||
|
|
||||||
|
/* Jump to the REE */
|
||||||
|
mret
|
||||||
|
|
||||||
|
/* U-mode ecall handler */
|
||||||
|
_user_ecall:
|
||||||
|
/* Check whether we are returning after servicing an U-mode interrupt */
|
||||||
|
lui t0, RTNVAL
|
||||||
|
csrrw t1, mscratch, zero
|
||||||
|
beq t0, t1, _rtn_from_ns_int
|
||||||
|
|
||||||
|
/* Restore t0, t1 from the stack */
|
||||||
|
lw t0, 0(sp)
|
||||||
|
lw t1, 4(sp)
|
||||||
|
addi sp, sp, 16
|
||||||
|
|
||||||
|
/* This point is reached when a secure service call is issued from the REE */
|
||||||
|
/* Save register context and mepc */
|
||||||
|
save_general_regs
|
||||||
|
save_mepc
|
||||||
|
|
||||||
|
/* Save the U-mode (i.e. REE) stack pointer */
|
||||||
|
la t0, _ns_sp
|
||||||
|
sw sp, 0(t0)
|
||||||
|
|
||||||
|
/* Switch to the M-mode (i.e. TEE) stack */
|
||||||
|
la sp, _tee_stack
|
||||||
|
|
||||||
|
/* Load the TEE entry point (see _tee_s_entry) in the mepc */
|
||||||
|
la t0, _tee_s_entry
|
||||||
|
csrw mepc, t0
|
||||||
|
|
||||||
|
/* Disable the U-mode delegation of all interrupts */
|
||||||
|
li t0, INTMTX_SIG_IDX_ASSERT_IN_SEC_REG
|
||||||
|
li t1, TEE_PASS_INUM + CLIC_EXT_INTR_NUM_OFFSET
|
||||||
|
sw t1, 0(t0)
|
||||||
|
fence
|
||||||
|
/* Verify the above */
|
||||||
|
_2:
|
||||||
|
lw t2, 0(t0)
|
||||||
|
bne t2, t1, _2
|
||||||
|
|
||||||
|
/* Set the privilege mode to transition to after mret to M-mode */
|
||||||
|
li t0, MSTATUS_MPP
|
||||||
|
csrs mstatus, t0
|
||||||
|
|
||||||
|
mret
|
||||||
|
|
||||||
|
/* This point is reached after servicing a U-mode interrupt occurred
|
||||||
|
* while executing a secure service */
|
||||||
|
_rtn_from_ns_int:
|
||||||
|
/* Disable the U-mode interrupt delegation */
|
||||||
|
li t0, INTMTX_SIG_IDX_ASSERT_IN_SEC_REG
|
||||||
|
li t1, TEE_PASS_INUM + CLIC_EXT_INTR_NUM_OFFSET
|
||||||
|
sw t1, 0(t0)
|
||||||
|
fence
|
||||||
|
/* Verify the above */
|
||||||
|
_3:
|
||||||
|
lw t2, 0(t0)
|
||||||
|
bne t2, t1, _2
|
||||||
|
|
||||||
|
/* Restore the secure stack pointer */
|
||||||
|
la t0, _s_sp
|
||||||
|
lw sp, 0(t0)
|
||||||
|
|
||||||
|
/* Set the privilege mode to transition to after mret to M-mode */
|
||||||
|
li t0, MSTATUS_MPP
|
||||||
|
csrs mstatus, t0
|
||||||
|
|
||||||
|
/* Restore register context and resume the secure service */
|
||||||
|
restore_mepc
|
||||||
|
restore_general_regs
|
||||||
|
|
||||||
|
mret
|
||||||
|
|
||||||
|
.size _ecall_handler, .-_ecall_handler
|
||||||
|
|
||||||
|
/* This is the interrupt handler for the U-mode interrupts.
|
||||||
|
* It saves the registers on the stack, re-enables the interrupt delegation,
|
||||||
|
* then jumps to the U-mode global interrupt handler, */
|
||||||
|
.global _tee_ns_intr_handler
|
||||||
|
.type _tee_ns_intr_handler, @function
|
||||||
|
_tee_ns_intr_handler:
|
||||||
|
/* Start by saving the general purpose registers and the PC value before
|
||||||
|
* the interrupt happened. */
|
||||||
|
save_general_regs
|
||||||
|
save_mepc
|
||||||
|
|
||||||
|
/* Though it is not necessary we save GP and SP here.
|
||||||
|
* SP is necessary to help GDB to properly unwind
|
||||||
|
* the backtrace of threads preempted by interrupts (OS tick etc.).
|
||||||
|
* GP is saved just to have its proper value in GDB. */
|
||||||
|
/* As gp register is not saved by the macro, save it here */
|
||||||
|
sw gp, RV_STK_GP(sp)
|
||||||
|
/* Same goes for the SP value before trapping */
|
||||||
|
addi t0, sp, CONTEXT_SIZE /* restore sp with the value when interrupt happened */
|
||||||
|
/* Save SP */
|
||||||
|
sw t0, RV_STK_SP(sp)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: Since this is a delegated U-mode interrupt routed through M-mode, the U-mode CSRs
|
||||||
|
* (like ucause, uintstatus, and uintthresh) are not automatically populated by hardware.
|
||||||
|
*
|
||||||
|
* To correctly simulate the U-mode interrupt context, we must explicitly update:
|
||||||
|
* - ucause: to reflect the interrupt source (including EXCCODE, INTBIT, and PIE).
|
||||||
|
* - uintthresh: to the level of the interrupt being serviced.
|
||||||
|
*
|
||||||
|
* uintstatus is read-only and will be zero in this scenario.
|
||||||
|
* However, CLIC uses max(uintstatus.uil, uintthresh.th) to determine active interrupt level.
|
||||||
|
* So, setting uintthresh to the current interrupt level ensures that only higher-priority
|
||||||
|
* U-mode interrupts can preempt while this one is being handled.
|
||||||
|
*/
|
||||||
|
/* Pass the interrupt ID to be serviced to U-mode */
|
||||||
|
li t2, INTMTX_SEC_STATUS_REG
|
||||||
|
lw t0, 0(t2)
|
||||||
|
li t1, 0
|
||||||
|
|
||||||
|
_find_intr_loop:
|
||||||
|
and t2, t0, 1
|
||||||
|
bnez t2, _found_intr
|
||||||
|
srai t0, t0, 1
|
||||||
|
addi t1, t1, 1
|
||||||
|
bnez t0, _find_intr_loop
|
||||||
|
|
||||||
|
/* should not reach here */
|
||||||
|
li t1, -1
|
||||||
|
unimp
|
||||||
|
_found_intr:
|
||||||
|
addi t6, t1, CLIC_EXT_INTR_NUM_OFFSET
|
||||||
|
|
||||||
|
/* Update ucause */
|
||||||
|
csrr t0, ucause
|
||||||
|
li t1, VECTORS_MCAUSE_REASON_MASK
|
||||||
|
not t1, t1
|
||||||
|
and t0, t0, t1
|
||||||
|
or t0, t0, t6
|
||||||
|
li t1, VECTORS_MCAUSE_INTBIT_MASK
|
||||||
|
or t0, t0, t1
|
||||||
|
csrw ucause, t0
|
||||||
|
|
||||||
|
/* Update the new the U-mode interrupt threshold */
|
||||||
|
li t1, DR_REG_CLIC_CTRL_BASE
|
||||||
|
slli t2, t6, 2
|
||||||
|
add t1, t1, t2
|
||||||
|
lw t2, 0(t1)
|
||||||
|
fence
|
||||||
|
srli t2, t2, CLIC_INT_CTL_S
|
||||||
|
csrw CSR_UINTTHRESH, t2
|
||||||
|
|
||||||
|
/* Enable the U-mode interrupt delegation */
|
||||||
|
li t0, INTMTX_SIG_IDX_ASSERT_IN_SEC_REG
|
||||||
|
li t1, 0x00
|
||||||
|
sw t1, 0(t0)
|
||||||
|
fence
|
||||||
|
/* Verify the above */
|
||||||
|
_4:
|
||||||
|
lw t2, 0(t0)
|
||||||
|
bne t2, t1, _2
|
||||||
|
|
||||||
|
/* For U-mode interrupts, we use mret to switch to U-mode after executing the below steps - */
|
||||||
|
/* Disable the U-mode global interrupts */
|
||||||
|
csrci ustatus, USTATUS_UIE
|
||||||
|
|
||||||
|
/* Configure `uepc` with the U-mode ecall handler (see u2m_switch) so that we can
|
||||||
|
* return to M-mode after handling the interrupt */
|
||||||
|
la t0, esp_tee_app_config
|
||||||
|
lw t1, ESP_TEE_CFG_OFFS_NS_ENTRY_ADDR(t0)
|
||||||
|
csrw uepc, t1
|
||||||
|
|
||||||
|
/* Set the program counter to the U-mode global interrupt handler (see _interrupt_handler) */
|
||||||
|
lw t1, ESP_TEE_CFG_OFFS_NS_INTR_HANDLER(t0)
|
||||||
|
csrw mepc, t1
|
||||||
|
|
||||||
|
/* Set the privilege mode to transition to after mret to U-mode */
|
||||||
|
li t1, MSTATUS_MPP
|
||||||
|
csrc mstatus, t1
|
||||||
|
|
||||||
|
/* Save the current secure stack pointer and switch to the U-mode interrupt stack
|
||||||
|
* saved while entering the secure service call routine (see `sec_world_entry`) */
|
||||||
|
la t0, _s_sp
|
||||||
|
sw sp, 0(t0)
|
||||||
|
la t1, _ns_sp
|
||||||
|
lw sp, 0(t1)
|
||||||
|
|
||||||
|
/* Set a flag to identify the next U2M switch would be after handling a U-mode interrupt */
|
||||||
|
lui t0, RTNVAL
|
||||||
|
csrw mscratch, t0
|
||||||
|
|
||||||
|
/* Place magic bytes in all the general registers */
|
||||||
|
store_magic_general_regs
|
||||||
|
|
||||||
|
mret
|
||||||
|
|
||||||
|
.size _tee_ns_intr_handler, .-_tee_ns_intr_handler
|
||||||
|
|
||||||
|
/* This is the interrupt handler for the M-mode interrupts.
|
||||||
|
* It saves the registers on the stack, prepares for interrupt nesting,
|
||||||
|
* re-enables the interrupts, then jumps to the C dispatcher in esp_tee_intr.c. */
|
||||||
|
.global _tee_s_intr_handler
|
||||||
|
.type _tee_s_intr_handler, @function
|
||||||
|
_tee_s_intr_handler:
|
||||||
|
/* Start by saving the general purpose registers and the PC value before
|
||||||
|
* the interrupt happened. */
|
||||||
|
save_general_regs RV_STK_FRMSZ
|
||||||
|
save_mepc
|
||||||
|
|
||||||
|
/* Though it is not necessary we save GP and SP here.
|
||||||
|
* SP is necessary to help GDB to properly unwind
|
||||||
|
* the backtrace of threads preempted by interrupts (OS tick etc.).
|
||||||
|
* GP is saved just to have its proper value in GDB. */
|
||||||
|
/* As gp register is not saved by the macro, save it here */
|
||||||
|
sw gp, RV_STK_GP(sp)
|
||||||
|
/* Same goes for the SP value before trapping */
|
||||||
|
addi t0, sp, RV_STK_FRMSZ /* restore sp with the value when interrupt happened */
|
||||||
|
/* Save SP */
|
||||||
|
sw t0, RV_STK_SP(sp)
|
||||||
|
|
||||||
|
/* Check if the interrupt source is related to an APM exception */
|
||||||
|
/* Define the addresses of the registers */
|
||||||
|
li t0, INTMTX_STATUS_REG_0
|
||||||
|
/* Load the values from the registers */
|
||||||
|
lw t1, 0(t0)
|
||||||
|
/* Define the masks */
|
||||||
|
li t2, TEE_SECURE_INT_APM_MASK_0
|
||||||
|
/* Apply the masks */
|
||||||
|
and t1, t1, t2
|
||||||
|
/* Check if any of the masked bits are set */
|
||||||
|
bnez t1, _save_reg_ctx
|
||||||
|
|
||||||
|
/* Repeat for the other status register */
|
||||||
|
li t0, INTMTX_STATUS_REG_1
|
||||||
|
lw t1, 0(t0)
|
||||||
|
li t2, TEE_SECURE_INT_APM_MASK_1
|
||||||
|
and t1, t1, t2
|
||||||
|
bnez t1, _save_reg_ctx
|
||||||
|
|
||||||
|
/* Continue normal execution */
|
||||||
|
j _continue
|
||||||
|
|
||||||
|
_save_reg_ctx:
|
||||||
|
/* Save CSR context here */
|
||||||
|
save_mcsr
|
||||||
|
/* NOTE: With ESP-TEE, since APM violations trigger a panic, it's safe to use the mscratch
|
||||||
|
* register to pass on the stack pointer to the APM violation handler */
|
||||||
|
csrw mscratch, sp
|
||||||
|
j _intr_hdlr_exec
|
||||||
|
|
||||||
|
_continue:
|
||||||
|
/* Before doing anything preserve the stack pointer */
|
||||||
|
mv s11, sp
|
||||||
|
/* Switch to the TEE interrupt stack */
|
||||||
|
la sp, _tee_intr_stack
|
||||||
|
/* If this is a non-nested interrupt, SP now points to the interrupt stack */
|
||||||
|
|
||||||
|
/* Before dispatch c handler, restore interrupt to enable nested intr */
|
||||||
|
csrr s1, mcause
|
||||||
|
csrr s2, mstatus
|
||||||
|
|
||||||
|
/* TODO: [IDF-9972] Nested interrupts are not supported yet */
|
||||||
|
# csrsi mstatus, MSTATUS_MIE
|
||||||
|
# /* MIE set. Nested interrupts can now occur */
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_TRACE
|
||||||
|
li a0, 0 /* = ESP_PM_TRACE_IDLE */
|
||||||
|
#if SOC_CPU_CORES_NUM == 1
|
||||||
|
li a1, 0 /* No need to check core ID on single core hardware */
|
||||||
|
#else
|
||||||
|
csrr a1, mhartid
|
||||||
|
#endif
|
||||||
|
la t0, esp_pm_trace_exit
|
||||||
|
jalr t0 /* absolute jump, avoid the 1 MiB range constraint */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_ENABLE
|
||||||
|
la t0, esp_pm_impl_isr_hook
|
||||||
|
jalr t0 /* absolute jump, avoid the 1 MiB range constraint */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_intr_hdlr_exec:
|
||||||
|
/* call the C dispatcher */
|
||||||
|
mv a0, sp /* argument 1, stack pointer */
|
||||||
|
mv a1, s1 /* argument 2, interrupt number (mcause) */
|
||||||
|
/* mask off the interrupt flag of mcause */
|
||||||
|
li t0, VECTORS_MCAUSE_INTBIT_MASK | VECTORS_MCAUSE_REASON_MASK
|
||||||
|
and a1, a1, t0
|
||||||
|
|
||||||
|
jal esp_tee_global_interrupt_handler
|
||||||
|
|
||||||
|
/* TODO: [IDF-9972] Nested interrupts are not supported yet */
|
||||||
|
# csrci mstatus, MSTATUS_MIE
|
||||||
|
# /* MIE cleared. Nested interrupts are disabled */
|
||||||
|
|
||||||
|
/* restore the rest of the registers */
|
||||||
|
csrw mcause, s1
|
||||||
|
csrw mstatus, s2
|
||||||
|
|
||||||
|
/* Restoring the stack pointer */
|
||||||
|
mv sp, s11
|
||||||
|
|
||||||
|
restore_mepc
|
||||||
|
restore_general_regs RV_STK_FRMSZ
|
||||||
|
/* exit, this will also re-enable the interrupts */
|
||||||
|
mret
|
||||||
|
|
||||||
|
.size _tee_s_intr_handler, .-_tee_s_intr_handler
|
||||||
|
|
||||||
|
.section .text, "ax"
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
.type _tee_s_entry, @function
|
||||||
|
_tee_s_entry:
|
||||||
|
/* Jump to the secure service dispatcher */
|
||||||
|
jal esp_tee_service_dispatcher
|
||||||
|
|
||||||
|
/* Fire an M-ecall */
|
||||||
|
mv a1, zero
|
||||||
|
ecall
|
||||||
|
fence
|
||||||
|
|
||||||
|
.size _tee_s_entry, .-_tee_s_entry
|
@@ -23,7 +23,7 @@
|
|||||||
.equ RTNVAL, 0xc0de
|
.equ RTNVAL, 0xc0de
|
||||||
.equ ECALL_U_MODE, 0x8
|
.equ ECALL_U_MODE, 0x8
|
||||||
.equ ECALL_M_MODE, 0xb
|
.equ ECALL_M_MODE, 0xb
|
||||||
.equ TEE_INTR_DELEG_MASK, 0xffffbfff
|
.equ TEE_INTR_DELEG_MASK, ~(1U << TEE_SECURE_INUM)
|
||||||
|
|
||||||
.global esp_tee_global_interrupt_handler
|
.global esp_tee_global_interrupt_handler
|
||||||
.global esp_tee_service_dispatcher
|
.global esp_tee_service_dispatcher
|
@@ -39,22 +39,37 @@ static void assert_valid_block(const heap_t *heap, const block_header_t *block)
|
|||||||
esp_err_t esp_tee_heap_init(void *start_ptr, size_t size)
|
esp_err_t esp_tee_heap_init(void *start_ptr, size_t size)
|
||||||
{
|
{
|
||||||
assert(start_ptr);
|
assert(start_ptr);
|
||||||
if (size < (tlsf_size() + tlsf_block_size_min() + sizeof(heap_t))) {
|
|
||||||
// Region too small to be a heap.
|
heap_t *result = (heap_t *)start_ptr;
|
||||||
|
size_t usable_size = size - sizeof(heap_t);
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
bool too_small = (usable_size < tlsf_size() + tlsf_block_size_min());
|
||||||
|
#else
|
||||||
|
bool too_small = (size < sizeof(heap_t));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (too_small) {
|
||||||
return ESP_ERR_INVALID_SIZE;
|
return ESP_ERR_INVALID_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
heap_t *result = (heap_t *)start_ptr;
|
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
|
||||||
size -= sizeof(heap_t);
|
void *heap = tlsf_create_with_pool(start_ptr + sizeof(heap_t), usable_size);
|
||||||
|
size_t overhead = tlsf_size();
|
||||||
|
#else
|
||||||
|
size_t max_bytes = 0;
|
||||||
|
void *heap = tlsf_create_with_pool(start_ptr + sizeof(heap_t), usable_size, max_bytes);
|
||||||
|
size_t overhead = tlsf_size(heap);
|
||||||
|
#endif
|
||||||
|
|
||||||
result->heap_data = tlsf_create_with_pool(start_ptr + sizeof(heap_t), size);
|
if (heap == NULL) {
|
||||||
if (result->heap_data == NULL) {
|
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result->heap_data = heap;
|
||||||
result->lock = NULL;
|
result->lock = NULL;
|
||||||
result->free_bytes = size - tlsf_size();
|
result->free_bytes = usable_size - overhead;
|
||||||
result->pool_size = size;
|
result->pool_size = usable_size;
|
||||||
result->minimum_free_bytes = result->free_bytes;
|
result->minimum_free_bytes = result->free_bytes;
|
||||||
|
|
||||||
tee_heap = (multi_heap_handle_t)result;
|
tee_heap = (multi_heap_handle_t)result;
|
||||||
|
@@ -10,13 +10,21 @@
|
|||||||
#include "esp_macros.h"
|
#include "esp_macros.h"
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
#include "esp_rom_serial_output.h"
|
#include "esp_rom_serial_output.h"
|
||||||
#include "rom/cache.h"
|
|
||||||
|
|
||||||
#include "riscv/rv_utils.h"
|
#include "riscv/rv_utils.h"
|
||||||
#include "riscv/rvruntime-frames.h"
|
#include "riscv/rvruntime-frames.h"
|
||||||
|
|
||||||
|
#include "hal/cache_types.h"
|
||||||
|
#include "hal/cache_ll.h"
|
||||||
|
#include "hal/cache_hal.h"
|
||||||
#include "hal/apm_hal.h"
|
#include "hal/apm_hal.h"
|
||||||
|
|
||||||
|
#if SOC_INT_PLIC_SUPPORTED
|
||||||
|
#include "soc/plic_reg.h"
|
||||||
|
#elif SOC_INT_CLIC_SUPPORTED
|
||||||
|
#include "soc/clic_reg.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "esp_tee.h"
|
#include "esp_tee.h"
|
||||||
#include "esp_tee_apm_intr.h"
|
#include "esp_tee_apm_intr.h"
|
||||||
#include "esp_tee_rv_utils.h"
|
#include "esp_tee_rv_utils.h"
|
||||||
@@ -32,11 +40,16 @@ static void tee_panic_end(void)
|
|||||||
rv_utils_tee_intr_global_disable();
|
rv_utils_tee_intr_global_disable();
|
||||||
|
|
||||||
// Disable the cache
|
// Disable the cache
|
||||||
Cache_Disable_ICache();
|
cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL);
|
||||||
|
|
||||||
// Clear the interrupt controller configurations
|
// Clear the interrupt controller configurations
|
||||||
|
#if SOC_INT_PLIC_SUPPORTED
|
||||||
memset((void *)DR_REG_PLIC_MX_BASE, 0x00, (PLIC_MXINT_CLAIM_REG + 4 - DR_REG_PLIC_MX_BASE));
|
memset((void *)DR_REG_PLIC_MX_BASE, 0x00, (PLIC_MXINT_CLAIM_REG + 4 - DR_REG_PLIC_MX_BASE));
|
||||||
memset((void *)DR_REG_PLIC_UX_BASE, 0x00, (PLIC_UXINT_CLAIM_REG + 4 - DR_REG_PLIC_UX_BASE));
|
memset((void *)DR_REG_PLIC_UX_BASE, 0x00, (PLIC_UXINT_CLAIM_REG + 4 - DR_REG_PLIC_UX_BASE));
|
||||||
|
#elif SOC_INT_CLIC_SUPPORTED
|
||||||
|
memset((void *)DR_REG_CLIC_CTRL_BASE, 0x00, (REG_GET_FIELD(CLIC_INT_INFO_REG, CLIC_INT_INFO_NUM_INT)) * 4);
|
||||||
|
REG_WRITE(CLIC_INT_THRESH_REG, 0x00);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Make sure all the panic handler output is sent from UART FIFO
|
// Make sure all the panic handler output is sent from UART FIFO
|
||||||
if (CONFIG_ESP_CONSOLE_UART_NUM >= 0) {
|
if (CONFIG_ESP_CONSOLE_UART_NUM >= 0) {
|
||||||
|
@@ -7,11 +7,12 @@
|
|||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
#include "esp_private/panic_reason.h"
|
#include "esp_private/panic_reason.h"
|
||||||
|
#include "esp_private/vectors_const.h"
|
||||||
|
|
||||||
#include "riscv/csr.h"
|
#include "riscv/csr.h"
|
||||||
#include "riscv/encoding.h"
|
#include "riscv/encoding.h"
|
||||||
#include "riscv/rvruntime-frames.h"
|
#include "riscv/rvruntime-frames.h"
|
||||||
|
#include "soc/tee_reg.h"
|
||||||
#include "esp_tee.h"
|
#include "esp_tee.h"
|
||||||
#include "panic_helper.h"
|
#include "panic_helper.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
@@ -60,16 +61,26 @@ void panic_print_registers(const void *f, int core)
|
|||||||
const char *name;
|
const char *name;
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
} csr_regs[] = {
|
} csr_regs[] = {
|
||||||
{ "MIE ", RV_READ_CSR(mie) },
|
{ "MSCRATCH ", RV_READ_CSR(mscratch) },
|
||||||
{ "MIP ", RV_READ_CSR(mip) },
|
|
||||||
{ "MSCRATCH", RV_READ_CSR(mscratch) },
|
|
||||||
{ "UEPC ", RV_READ_CSR(uepc) },
|
{ "UEPC ", RV_READ_CSR(uepc) },
|
||||||
{ "USTATUS ", RV_READ_CSR(ustatus) },
|
{ "USTATUS ", RV_READ_CSR(ustatus) },
|
||||||
{ "UTVEC ", RV_READ_CSR(utvec) },
|
{ "UTVEC ", RV_READ_CSR(utvec) },
|
||||||
{ "UCAUSE ", RV_READ_CSR(ucause) },
|
{ "UCAUSE ", RV_READ_CSR(ucause) },
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32C6
|
||||||
|
{ "MIE ", RV_READ_CSR(mie) },
|
||||||
|
{ "MIP ", RV_READ_CSR(mip) },
|
||||||
{ "UTVAL ", RV_READ_CSR(utval) },
|
{ "UTVAL ", RV_READ_CSR(utval) },
|
||||||
{ "UIE ", RV_READ_CSR(uie) },
|
{ "UIE ", RV_READ_CSR(uie) },
|
||||||
{ "UIP ", RV_READ_CSR(uip) },
|
{ "UIP ", RV_READ_CSR(uip) },
|
||||||
|
#endif
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32C5
|
||||||
|
{ "USCRATCH ", RV_READ_CSR(0x040) },
|
||||||
|
{ "MEXSTATUS ", RV_READ_CSR(0x7E1) },
|
||||||
|
{ "MINTSTATUS", RV_READ_CSR(0xFB1) },
|
||||||
|
{ "MINTTHRESH", RV_READ_CSR(0x347) },
|
||||||
|
{ "UINTSTATUS", RV_READ_CSR(0xCB1) },
|
||||||
|
{ "UINTTHRESH", RV_READ_CSR(0x047) },
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
tee_panic_print("\n\n");
|
tee_panic_print("\n\n");
|
||||||
@@ -116,9 +127,10 @@ void panic_print_exccause(const void *f, int core)
|
|||||||
};
|
};
|
||||||
|
|
||||||
const char *rsn = NULL;
|
const char *rsn = NULL;
|
||||||
if (regs->mcause < (sizeof(reason) / sizeof(reason[0]))) {
|
uint32_t mcause = regs->mcause & (VECTORS_MCAUSE_INTBIT_MASK | VECTORS_MCAUSE_REASON_MASK);
|
||||||
if (reason[regs->mcause] != NULL) {
|
if (mcause < (sizeof(reason) / sizeof(reason[0]))) {
|
||||||
rsn = (reason[regs->mcause]);
|
if (reason[mcause] != NULL) {
|
||||||
|
rsn = (reason[mcause]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -203,6 +203,13 @@ void _ss_esp_crypto_sha_enable_periph_clk(bool enable)
|
|||||||
esp_crypto_sha_enable_periph_clk(enable);
|
esp_crypto_sha_enable_periph_clk(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOC_SHA_SUPPORT_SHA512_T
|
||||||
|
int _ss_esp_sha_512_t_init_hash(uint16_t t)
|
||||||
|
{
|
||||||
|
return esp_sha_512_t_init_hash(t);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------- HMAC ------------------------------------------------- */
|
/* ---------------------------------------------- HMAC ------------------------------------------------- */
|
||||||
|
|
||||||
esp_err_t _ss_esp_hmac_calculate(hmac_key_id_t key_id, const void *message, size_t message_len, uint8_t *hmac)
|
esp_err_t _ss_esp_hmac_calculate(hmac_key_id_t key_id, const void *message, size_t message_len, uint8_t *hmac)
|
||||||
|
@@ -12,12 +12,14 @@
|
|||||||
#include "hal/mmu_types.h"
|
#include "hal/mmu_types.h"
|
||||||
#include "hal/mmu_hal.h"
|
#include "hal/mmu_hal.h"
|
||||||
#include "hal/wdt_hal.h"
|
#include "hal/wdt_hal.h"
|
||||||
|
#include "rom/cache.h"
|
||||||
|
|
||||||
#include "hal/spi_flash_hal.h"
|
#include "hal/spi_flash_hal.h"
|
||||||
#include "hal/spi_flash_types.h"
|
#include "hal/spi_flash_types.h"
|
||||||
#include "spi_flash_chip_generic.h"
|
#include "spi_flash_chip_generic.h"
|
||||||
#include "memspi_host_driver.h"
|
#include "memspi_host_driver.h"
|
||||||
#include "esp_flash.h"
|
#include "esp_flash.h"
|
||||||
|
#include "riscv/rv_utils.h"
|
||||||
|
|
||||||
#include "esp_tee.h"
|
#include "esp_tee.h"
|
||||||
#include "esp_tee_memory_utils.h"
|
#include "esp_tee_memory_utils.h"
|
||||||
@@ -63,7 +65,7 @@ void _ss_rv_utils_intr_set_threshold(int priority_threshold)
|
|||||||
|
|
||||||
void _ss_rv_utils_intr_edge_ack(uint32_t intr_num)
|
void _ss_rv_utils_intr_edge_ack(uint32_t intr_num)
|
||||||
{
|
{
|
||||||
rv_utils_tee_intr_edge_ack(intr_num);
|
rv_utils_intr_edge_ack(intr_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _ss_rv_utils_intr_global_enable(void)
|
void _ss_rv_utils_intr_global_enable(void)
|
||||||
@@ -71,6 +73,42 @@ void _ss_rv_utils_intr_global_enable(void)
|
|||||||
rv_utils_tee_intr_global_enable();
|
rv_utils_tee_intr_global_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t _ss_rv_utils_intr_get_enabled_mask(void)
|
||||||
|
{
|
||||||
|
return rv_utils_intr_get_enabled_mask();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _ss_rv_utils_set_cycle_count(uint32_t ccount)
|
||||||
|
{
|
||||||
|
rv_utils_set_cycle_count(ccount);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SOC_BRANCH_PREDICTOR_SUPPORTED
|
||||||
|
void _ss_rv_utils_en_branch_predictor(void)
|
||||||
|
{
|
||||||
|
rv_utils_en_branch_predictor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _ss_rv_utils_dis_branch_predictor(void)
|
||||||
|
{
|
||||||
|
rv_utils_dis_branch_predictor();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SOC_CPU_SUPPORT_WFE
|
||||||
|
void _ss_rv_utils_wfe_mode_enable(bool en)
|
||||||
|
{
|
||||||
|
rv_utils_wfe_mode_enable(en);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SOC_INT_CLIC_SUPPORTED
|
||||||
|
void _ss_esprv_int_set_vectored(int rv_int_num, bool vectored)
|
||||||
|
{
|
||||||
|
esprv_int_set_vectored(rv_int_num, vectored);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------- RTC_WDT ------------------------------------------------- */
|
/* ---------------------------------------------- RTC_WDT ------------------------------------------------- */
|
||||||
|
|
||||||
void _ss_wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescaler, bool enable_intr)
|
void _ss_wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescaler, bool enable_intr)
|
||||||
@@ -164,6 +202,7 @@ void _ss_mmu_hal_map_region(uint32_t mmu_id, mmu_target_t mem_type, uint32_t vad
|
|||||||
bool vaddr_chk = esp_tee_flash_check_vaddr_in_tee_region(vaddr);
|
bool vaddr_chk = esp_tee_flash_check_vaddr_in_tee_region(vaddr);
|
||||||
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(paddr);
|
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(paddr);
|
||||||
if (vaddr_chk || paddr_chk) {
|
if (vaddr_chk || paddr_chk) {
|
||||||
|
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x | 0x%08x", __func__, vaddr, paddr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ESP_FAULT_ASSERT(!vaddr_chk && !paddr_chk);
|
ESP_FAULT_ASSERT(!vaddr_chk && !paddr_chk);
|
||||||
@@ -175,6 +214,7 @@ void _ss_mmu_hal_unmap_region(uint32_t mmu_id, uint32_t vaddr, uint32_t len)
|
|||||||
{
|
{
|
||||||
bool vaddr_chk = esp_tee_flash_check_vaddr_in_tee_region(vaddr);
|
bool vaddr_chk = esp_tee_flash_check_vaddr_in_tee_region(vaddr);
|
||||||
if (vaddr_chk) {
|
if (vaddr_chk) {
|
||||||
|
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, vaddr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ESP_FAULT_ASSERT(!vaddr_chk);
|
ESP_FAULT_ASSERT(!vaddr_chk);
|
||||||
@@ -202,6 +242,13 @@ bool _ss_mmu_hal_paddr_to_vaddr(uint32_t mmu_id, uint32_t paddr, mmu_target_t ta
|
|||||||
return mmu_hal_paddr_to_vaddr(mmu_id, paddr, target, type, out_vaddr);
|
return mmu_hal_paddr_to_vaddr(mmu_id, paddr, target, type, out_vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32C5
|
||||||
|
void _ss_Cache_Set_IDROM_MMU_Size(uint32_t irom_size, uint32_t drom_size)
|
||||||
|
{
|
||||||
|
Cache_Set_IDROM_MMU_Size(irom_size, drom_size);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||||
/* ---------------------------------------------- SPI Flash HAL ------------------------------------------------- */
|
/* ---------------------------------------------- SPI Flash HAL ------------------------------------------------- */
|
||||||
|
|
||||||
|
@@ -60,8 +60,23 @@ void esp_tee_route_intr_matrix(int cpu_no, uint32_t model_num, uint32_t intr_num
|
|||||||
if (esp_tee_is_intr_src_protected(model_num) || intr_num == TEE_SECURE_INUM) {
|
if (esp_tee_is_intr_src_protected(model_num) || intr_num == TEE_SECURE_INUM) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#if SOC_INT_CLIC_SUPPORTED
|
||||||
|
if (intr_num == TEE_PASS_INUM) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
esp_rom_route_intr_matrix(cpu_no, model_num, intr_num);
|
esp_rom_route_intr_matrix(cpu_no, model_num, intr_num);
|
||||||
|
ESP_LOGV(TAG, "Connected src %d to int %d (cpu %d)", model_num, intr_num, cpu_no);
|
||||||
|
|
||||||
|
#if SOC_INT_CLIC_SUPPORTED
|
||||||
|
if (intr_num != ETS_T1_WDT_INUM && intr_num != ETS_CACHEERR_INUM) {
|
||||||
|
/* Configure interrupts to be visible in the TEE (M-mode) */
|
||||||
|
REG_SET_BIT(DR_REG_INTMTX_BASE + 4 * model_num, BIT(8));
|
||||||
|
/* Configure interrupts to be serviced in the REE (U-mode) */
|
||||||
|
rv_utils_tee_intr_set_mode(intr_num, PRV_U);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -119,7 +134,7 @@ int esp_tee_intr_deregister(void *arg)
|
|||||||
tee_set_interrupt_handler(vd);
|
tee_set_interrupt_handler(vd);
|
||||||
|
|
||||||
// Setting back the default value for interrupt pin.
|
// Setting back the default value for interrupt pin.
|
||||||
esp_rom_route_intr_matrix(cpu, vd->source, 0);
|
esp_rom_route_intr_matrix(cpu, vd->source, ETS_INVALID_INUM);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -3,4 +3,4 @@ dependencies:
|
|||||||
espressif/json_generator:
|
espressif/json_generator:
|
||||||
version: "^1.1.2"
|
version: "^1.1.2"
|
||||||
rules:
|
rules:
|
||||||
- if: "target in [esp32c6, esp32h2]"
|
- if: "target in [esp32c6, esp32h2, esp32c5]"
|
||||||
|
302
components/esp_tee/subproject/main/ld/esp32c5/esp_tee.ld.in
Normal file
302
components/esp_tee/subproject/main/ld/esp32c5/esp_tee.ld.in
Normal file
@@ -0,0 +1,302 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#define SRAM_IRAM_START (0x40800000)
|
||||||
|
#define SRAM_IRAM_TEE_ORG (SRAM_IRAM_START)
|
||||||
|
#define SRAM_DRAM_TEE_ORG (SRAM_IRAM_START)
|
||||||
|
|
||||||
|
#define SRAM_IRAM_ORG (SRAM_IRAM_TEE_ORG + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE)
|
||||||
|
|
||||||
|
#define SRAM_DRAM_TEE_SIZE (CONFIG_SECURE_TEE_DRAM_SIZE - CONFIG_SECURE_TEE_STACK_SIZE - CONFIG_SECURE_TEE_INTR_STACK_SIZE)
|
||||||
|
#define SRAM_DRAM_TEE_END (SRAM_DRAM_TEE_ORG + CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_DRAM_TEE_SIZE)
|
||||||
|
|
||||||
|
#define I_D_SRAM_TEE_SIZE (CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_DRAM_TEE_SIZE)
|
||||||
|
|
||||||
|
/* TEE interrupt stack is placed at the end of the TEE DRAM segment.
|
||||||
|
* The top of the TEE stack is before the end of interrupt stack
|
||||||
|
* and the bottom of the stack is at _heap_end.
|
||||||
|
*/
|
||||||
|
#define SRAM_STACK_TEE_ORG (SRAM_DRAM_TEE_END)
|
||||||
|
#define SRAM_INTR_STACK_TEE_ORG (SRAM_DRAM_TEE_END + CONFIG_SECURE_TEE_STACK_SIZE)
|
||||||
|
|
||||||
|
#define FLASH_IROM_TEE_ORG (0x42000000)
|
||||||
|
#define FLASH_DROM_TEE_ORG (0x42000000)
|
||||||
|
#define I_D_FLASH_TEE_SIZE (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These values are the same in every app binary for the same chip target.
|
||||||
|
*
|
||||||
|
* Values that may change when the app is rebuilt, or in a new ESP-IDF version,
|
||||||
|
* should be stored via esp_app_tee_config structure
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if CONFIG_ESP_DEBUG_INCLUDE_OCD_STUB_BINS
|
||||||
|
PROVIDE ( esp_tee_app_config = SRAM_IRAM_ORG + 0x22b0 );
|
||||||
|
#else
|
||||||
|
PROVIDE ( esp_tee_app_config = SRAM_IRAM_ORG + 0x2b0 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PROVIDE ( GDMA = 0x60080000 );
|
||||||
|
|
||||||
|
/* Default entry point: */
|
||||||
|
ENTRY(esp_tee_init);
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
/* IRAM Configuration */
|
||||||
|
iram_tee_seg (RX) : org = SRAM_IRAM_TEE_ORG, len = I_D_SRAM_TEE_SIZE
|
||||||
|
|
||||||
|
/* DRAM Configuration */
|
||||||
|
dram_tee_seg (RW) : org = SRAM_DRAM_TEE_ORG, len = I_D_SRAM_TEE_SIZE
|
||||||
|
|
||||||
|
/* TEE Stack Configuration */
|
||||||
|
stack_tee_seg (RW) : org = SRAM_STACK_TEE_ORG, len = CONFIG_SECURE_TEE_STACK_SIZE
|
||||||
|
|
||||||
|
/* TEE Interrupt Stack Configuration */
|
||||||
|
intr_stack_tee_seg (RW) : org = SRAM_INTR_STACK_TEE_ORG, len = CONFIG_SECURE_TEE_INTR_STACK_SIZE
|
||||||
|
|
||||||
|
/* TEE flash data section */
|
||||||
|
flash_data_seg (R) : org = FLASH_DROM_TEE_ORG + 0x20, len = I_D_FLASH_TEE_SIZE - 0x20
|
||||||
|
|
||||||
|
/* TEE flash text section */
|
||||||
|
flash_text_seg (RX): org = FLASH_IROM_TEE_ORG + 0x20, len = I_D_FLASH_TEE_SIZE - 0x20
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This section is required to skip .iram.tee_text area because iram_tee_seg and
|
||||||
|
* dram_tee_seg reflect the same address space on different buses.
|
||||||
|
*/
|
||||||
|
.dram.tee_dummy (NOLOAD):
|
||||||
|
{
|
||||||
|
. = ORIGIN(dram_tee_seg) + CONFIG_SECURE_TEE_IRAM_SIZE;
|
||||||
|
} > dram_tee_seg
|
||||||
|
|
||||||
|
.dram.tee.bss (NOLOAD) :
|
||||||
|
{
|
||||||
|
. = ALIGN (8);
|
||||||
|
_tee_dram_start = ABSOLUTE(.);
|
||||||
|
_tee_bss_start = ABSOLUTE(.);
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(.sbss .sbss.*)
|
||||||
|
. = ALIGN (8);
|
||||||
|
_tee_bss_end = ABSOLUTE(.);
|
||||||
|
} > dram_tee_seg
|
||||||
|
|
||||||
|
.dram.tee.data :
|
||||||
|
{
|
||||||
|
_data_start = ABSOLUTE(.);
|
||||||
|
*(.data .data.*)
|
||||||
|
*(.sdata .sdata.*)
|
||||||
|
*(.dram1 .dram1.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_data_end = ABSOLUTE(.);
|
||||||
|
} > dram_tee_seg
|
||||||
|
|
||||||
|
.dram.tee.rodata :
|
||||||
|
{
|
||||||
|
_rodata_start = ABSOLUTE(.);
|
||||||
|
/* TEE flash manager */
|
||||||
|
*libtee_flash_mgr.a:*(.rodata .srodata .rodata.* .srodata.*)
|
||||||
|
*libbootloader_support.a:bootloader_flash.*(.rodata .srodata .rodata.* .srodata.*)
|
||||||
|
/* Secure services */
|
||||||
|
*libmain.a:esp_secure_services_iram.c.*(.rodata .srodata .rodata.* .srodata.*)
|
||||||
|
*libmain.a:esp_secure_dispatcher.c.*(.rodata .srodata .rodata.* .srodata.*)
|
||||||
|
/* Panic handler */
|
||||||
|
*libmain.a:panic_helper_riscv.*(.rodata .srodata .rodata.* .srodata.*)
|
||||||
|
*libmain.a:esp_tee_apm_intr.c.*(.rodata .srodata .rodata.* .srodata.*)
|
||||||
|
/* HAL (noflash) */
|
||||||
|
*libhal.a:mmu_hal.c*(.rodata .srodata .rodata.* .srodata.*)
|
||||||
|
*libhal.a:cache_hal.c*(.rodata .srodata .rodata.* .srodata.*)
|
||||||
|
_rodata_end = ABSOLUTE(.);
|
||||||
|
_tee_dram_end = ABSOLUTE(.);
|
||||||
|
} > dram_tee_seg
|
||||||
|
|
||||||
|
.dram.tee.heap :
|
||||||
|
{
|
||||||
|
. = ALIGN (16);
|
||||||
|
_tee_heap_start = ABSOLUTE(.);
|
||||||
|
. = ORIGIN(dram_tee_seg) + LENGTH(dram_tee_seg);
|
||||||
|
_tee_heap_end = ABSOLUTE(.);
|
||||||
|
} > dram_tee_seg
|
||||||
|
|
||||||
|
.dram.tee.stack :
|
||||||
|
{
|
||||||
|
. = ALIGN (16);
|
||||||
|
_tee_stack_bottom = ABSOLUTE(.);
|
||||||
|
. = ORIGIN(stack_tee_seg) + LENGTH(stack_tee_seg);
|
||||||
|
_tee_stack = ABSOLUTE(.);
|
||||||
|
} > stack_tee_seg
|
||||||
|
|
||||||
|
.dram.tee.intr_stack :
|
||||||
|
{
|
||||||
|
. = ALIGN (16);
|
||||||
|
_tee_intr_stack_bottom = ABSOLUTE(.);
|
||||||
|
. = ORIGIN(intr_stack_tee_seg) + LENGTH(intr_stack_tee_seg);
|
||||||
|
_tee_intr_stack = ABSOLUTE(.);
|
||||||
|
} > intr_stack_tee_seg
|
||||||
|
|
||||||
|
.flash.rodata :
|
||||||
|
{
|
||||||
|
_tee_xip_data_start = ABSOLUTE(.);
|
||||||
|
*(.rodata_desc .rodata_desc.*) /* Should be the first. TEE App version info. DO NOT PUT ANYTHING BEFORE IT! */
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.srodata .srodata.*)
|
||||||
|
*(.gcc_except_table .gcc_except_table.*)
|
||||||
|
_tee_xip_data_end = ABSOLUTE(.);
|
||||||
|
} > flash_data_seg
|
||||||
|
|
||||||
|
.flash.text_dummy (NOLOAD):
|
||||||
|
{
|
||||||
|
. = ALIGN(ALIGNOF(.flash.rodata));
|
||||||
|
/* Create an empty gap as big as .flash.rodata section */
|
||||||
|
. = . + SIZEOF(.flash.rodata);
|
||||||
|
/* Prepare the alignment of the section above. Few bytes (0x20) must be
|
||||||
|
* added for the mapping header. */
|
||||||
|
. = ALIGN(CONFIG_MMU_PAGE_SIZE) + 0x20;
|
||||||
|
} > flash_text_seg
|
||||||
|
|
||||||
|
|
||||||
|
/* HAL modules and their memory placement:
|
||||||
|
*
|
||||||
|
* +-----------+---------------+--------+
|
||||||
|
* | Module | Section | Memory |
|
||||||
|
* +-----------+---------------+--------+
|
||||||
|
* | MMU | text+rodata | SRAM |
|
||||||
|
* | CACHE | text+rodata | SRAM |
|
||||||
|
* | WDT | text | SRAM |
|
||||||
|
* | APM | text | Flash* |
|
||||||
|
* | AES | text | Flash |
|
||||||
|
* | SHA | text | Flash |
|
||||||
|
* | HMAC | text | Flash |
|
||||||
|
* | DS | text | Flash |
|
||||||
|
* | ECC | text | Flash |
|
||||||
|
* | BROWNOUT | text | Flash |
|
||||||
|
* | EFUSE | text | Flash |
|
||||||
|
* | LPTIMER | text | Flash |
|
||||||
|
* | SPI_FLASH | text | Flash |
|
||||||
|
* +-----------+---------------+--------+
|
||||||
|
*
|
||||||
|
* By default, for ESP-TEE, text sections are placed in SRAM while rodata sections go to the flash.
|
||||||
|
* Therefore, only HAL modules that require SRAM placement for proper functionality are located there,
|
||||||
|
* while the remaining modules are placed in flash memory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.flash.text :
|
||||||
|
{
|
||||||
|
_tee_xip_text_start = ABSOLUTE(.);
|
||||||
|
/* Secure Services */
|
||||||
|
*libmain.a:esp_secure_services.c*(.literal .text .literal.* .text.*)
|
||||||
|
/* HAL */
|
||||||
|
*libhal.a:aes_hal.c*(.literal .text .literal.* .text.*)
|
||||||
|
*libhal.a:sha_hal.c*(.literal .text .literal.* .text.*)
|
||||||
|
*libhal.a:hmac_hal.c*(.literal .text .literal.* .text.*)
|
||||||
|
*libhal.a:ds_hal.c*(.literal .text .literal.* .text.*)
|
||||||
|
*libhal.a:ecc_hal.c*(.literal .text .literal.* .text.*)
|
||||||
|
/* NOTE: There is a possibility of APM violations (SPI1 flash protection)
|
||||||
|
* being triggered with the flash cache disabled */
|
||||||
|
#if !CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||||
|
*libhal.a:apm_hal.c*(.literal .text .literal.* .text.*)
|
||||||
|
#endif
|
||||||
|
*libhal.a:brownout_hal.c*(.literal .text .literal.* .text.*)
|
||||||
|
*libhal.a:spi_flash_hal.c*(.literal .text .literal.* .text.*)
|
||||||
|
/* These HAL modules have functions marked with the IRAM_ATTR attribute which get placed in the SRAM */
|
||||||
|
*libhal.a:efuse_hal.c*(.literal .text .literal.* .text.*)
|
||||||
|
*libhal.a:lp_timer_hal.c*(.literal .text .literal.* .text.*)
|
||||||
|
/* Mbedtls for TEE */
|
||||||
|
*libmbedtls.a:*(.literal .text .literal.* .text.*)
|
||||||
|
*libmbedcrypto.a:*(.literal .text .literal.* .text.*)
|
||||||
|
/* HMAC-DS layer */
|
||||||
|
*libesp_security.a:*(.literal .text .literal.* .text.*)
|
||||||
|
/* NVS flash and related modules */
|
||||||
|
*libnvs_flash.a:*(.literal .text .literal.* .text.*)
|
||||||
|
*libstdc++.a:*(.literal .text .literal.* .text.*)
|
||||||
|
*libgcc.a:*(.literal .text .literal.* .text.*)
|
||||||
|
/* esp_partition API */
|
||||||
|
*libesp_partition.a:*(.literal .text .literal.* .text.*)
|
||||||
|
/* TEE attestation module */
|
||||||
|
*libattestation.a:*(.literal .text .literal.* .text.*)
|
||||||
|
*json_generator.a:*(.literal .text .literal.* .text.*)
|
||||||
|
/* TEE test module */
|
||||||
|
*libtest_sec_srv.a:*(.literal .text .literal.* .text.*)
|
||||||
|
_tee_xip_text_end = ABSOLUTE(.);
|
||||||
|
_tee_xip_end = ABSOLUTE(.);
|
||||||
|
} > flash_text_seg
|
||||||
|
|
||||||
|
.iram.tee.text :
|
||||||
|
{
|
||||||
|
/* Vectors go to start of IRAM */
|
||||||
|
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
|
||||||
|
_tee_vec_start = ABSOLUTE(.);
|
||||||
|
KEEP(*(.exception_vectors_table.text));
|
||||||
|
KEEP(*(.exception_vectors.text));
|
||||||
|
. = ALIGN(4);
|
||||||
|
_invalid_pc_placeholder = ABSOLUTE(.);
|
||||||
|
_tee_vec_end = ABSOLUTE(.);
|
||||||
|
|
||||||
|
_tee_iram_start = ABSOLUTE(.);
|
||||||
|
*(.literal .text .iram1 .literal.* .text.* .iram1.*)
|
||||||
|
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||||
|
_tee_iram_end = ABSOLUTE(.);
|
||||||
|
} > iram_tee_seg
|
||||||
|
|
||||||
|
.riscv.attributes 0: { *(.riscv.attributes) }
|
||||||
|
|
||||||
|
/* DWARF 1 */
|
||||||
|
.debug 0 : { *(.debug) }
|
||||||
|
.line 0 : { *(.line) }
|
||||||
|
/* GNU DWARF 1 extensions */
|
||||||
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||||
|
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||||
|
/* DWARF 1.1 and DWARF 2 */
|
||||||
|
.debug_aranges 0 : { *(.debug_aranges) }
|
||||||
|
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||||
|
/* DWARF 2 */
|
||||||
|
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||||
|
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||||
|
.debug_line 0 : { *(.debug_line) }
|
||||||
|
.debug_frame 0 : { *(.debug_frame) }
|
||||||
|
.debug_str 0 : { *(.debug_str) }
|
||||||
|
.debug_loc 0 : { *(.debug_loc) }
|
||||||
|
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||||
|
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||||
|
/* DWARF 3 */
|
||||||
|
.debug_ranges 0 : { *(.debug_ranges) }
|
||||||
|
/* SGI/MIPS DWARF 2 extensions */
|
||||||
|
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||||
|
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||||
|
.debug_typenames 0 : { *(.debug_typenames) }
|
||||||
|
.debug_varnames 0 : { *(.debug_varnames) }
|
||||||
|
/* GNU DWARF 2 extensions */
|
||||||
|
.debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) }
|
||||||
|
.debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) }
|
||||||
|
/* DWARF 4 */
|
||||||
|
.debug_types 0 : { *(.debug_types) }
|
||||||
|
/* DWARF 5 */
|
||||||
|
.debug_addr 0 : { *(.debug_addr) }
|
||||||
|
.debug_line_str 0 : { *(.debug_line_str) }
|
||||||
|
.debug_loclists 0 : { *(.debug_loclists) }
|
||||||
|
.debug_macro 0 : { *(.debug_macro) }
|
||||||
|
.debug_names 0 : { *(.debug_names) }
|
||||||
|
.debug_rnglists 0 : { *(.debug_rnglists) }
|
||||||
|
.debug_str_offsets 0 : { *(.debug_str_offsets) }
|
||||||
|
|
||||||
|
.comment 0 : { *(.comment) }
|
||||||
|
.note.GNU-stack 0: { *(.note.GNU-stack) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discarding .rela.* sections results in the following mapping:
|
||||||
|
* .rela.text.* -> .text.*
|
||||||
|
* .rela.data.* -> .data.*
|
||||||
|
* And so forth...
|
||||||
|
*/
|
||||||
|
/DISCARD/ : { *(.rela.*) }
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT ((_tee_iram_end < _tee_dram_start), "Error: TEE IRAM segment overflowed into the DRAM segment!");
|
@@ -0,0 +1,266 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
#include "soc/spi_mem_c_reg.h"
|
||||||
|
#include "soc/efuse_reg.h"
|
||||||
|
#include "soc/pcr_reg.h"
|
||||||
|
#include "soc/lp_analog_peri_reg.h"
|
||||||
|
#include "soc/lp_wdt_reg.h"
|
||||||
|
|
||||||
|
#include "soc/apm_defs.h"
|
||||||
|
#include "hal/apm_types.h"
|
||||||
|
#include "hal/apm_hal.h"
|
||||||
|
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_bit_defs.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";
|
||||||
|
|
||||||
|
/* NOTE: Figuring out the eFuse protection range based on where the TEE secure storage key is stored */
|
||||||
|
#if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE
|
||||||
|
#if CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID < 0
|
||||||
|
#error "TEE: eFuse protection region for APM out of range! (see CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID)"
|
||||||
|
#endif
|
||||||
|
#define LP_APM_EFUSE_REG_START \
|
||||||
|
(EFUSE_RD_KEY0_DATA0_REG + (CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID * 0x20))
|
||||||
|
|
||||||
|
#define LP_APM_EFUSE_REG_END \
|
||||||
|
(EFUSE_RD_KEY1_DATA0_REG + (CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID * 0x20))
|
||||||
|
#elif CONFIG_SECURE_TEE_SEC_STG_MODE_DEVELOPMENT
|
||||||
|
#define LP_APM_EFUSE_REG_START EFUSE_RD_KEY5_DATA0_REG
|
||||||
|
#if CONFIG_SECURE_TEE_TEST_MODE
|
||||||
|
#define LP_APM_EFUSE_REG_END EFUSE_RD_SYS_PART2_DATA0_REG
|
||||||
|
#else
|
||||||
|
#define LP_APM_EFUSE_REG_END LP_APM_EFUSE_REG_START
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* NOTE: Flash protection over the SPI1 controller */
|
||||||
|
#define HP_APM_SPI1_REG_START DR_REG_SPIMEM1_BASE
|
||||||
|
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||||
|
#define HP_APM_SPI1_REG_END DR_REG_I2C_BASE
|
||||||
|
#else
|
||||||
|
#define HP_APM_SPI1_REG_END HP_APM_SPI1_REG_START
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* NOTE: Super-Watchdog and Brownout Detector protection */
|
||||||
|
#define LP_APM_SWD_REG_START (LP_WDT_SWD_CONFIG_REG)
|
||||||
|
#define LP_APM_SWD_REG_END (LP_WDT_INT_CLR_REG + 4U)
|
||||||
|
#define LP_APM_BOD_REG_START (LP_ANA_BOD_MODE0_CNTL_REG)
|
||||||
|
#define LP_APM_BOD_REG_END (LP_ANA_LP_INT_CLR_REG + 4U)
|
||||||
|
|
||||||
|
/* NOTE: Following are the master IDs for setting the security mode and access through APM:
|
||||||
|
* +---------+-------------+
|
||||||
|
* | Bit | Source |
|
||||||
|
* +---------+-------------+
|
||||||
|
* | 0 | HP CPU |
|
||||||
|
* | 1 | LP CPU |
|
||||||
|
* | 2 | reserved |
|
||||||
|
* | 3 | SDIO_SLV |
|
||||||
|
* | 4 | reserved |
|
||||||
|
* | 5 | MEM_MONITOR |
|
||||||
|
* | 6 | TRACE |
|
||||||
|
* | 7~15 | reserved |
|
||||||
|
* | 16 | SPI2 |
|
||||||
|
* | 17 | Dummy-1 |
|
||||||
|
* | 18 | UHCI |
|
||||||
|
* | 19 | I2S |
|
||||||
|
* | 20 | Dummy-4 |
|
||||||
|
* | 21 | Dummy-5 |
|
||||||
|
* | 22 | AES |
|
||||||
|
* | 23 | SHA |
|
||||||
|
* | 24 | ADC |
|
||||||
|
* | 25 | PARLIO |
|
||||||
|
* | 26~31 | Dummy-10~15 |
|
||||||
|
* +---------+-------------+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define APM_MASTERS_ALL (UINT32_MAX)
|
||||||
|
#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))
|
||||||
|
|
||||||
|
#define APM_PERIPH_ALL (UINT64_MAX)
|
||||||
|
#define APM_PERIPH_HP_PMS (BIT64(APM_TEE_HP_PERIPH_HP_APM) | BIT64(APM_TEE_HP_PERIPH_CPU_APM) | BIT64(APM_TEE_HP_PERIPH_TEE))
|
||||||
|
#define APM_PERIPH_LP_PMS (BIT64(APM_TEE_LP_PERIPH_LP_TEE) | BIT64(APM_TEE_LP_PERIPH_LP_APM))
|
||||||
|
#define APM_PERIPH_HP_REE (APM_PERIPH_ALL & ~(APM_PERIPH_HP_PMS))
|
||||||
|
#define APM_PERIPH_LP_REE (APM_PERIPH_ALL & ~(APM_PERIPH_LP_PMS))
|
||||||
|
|
||||||
|
/*----------------------- 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 0: CPU peripherals (RW) */
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M0, 0, DR_REG_TRACE_BASE, 0x600D0000, APM_PERM_R | APM_PERM_W, true),
|
||||||
|
|
||||||
|
/* NOTE: Without this entry, the REE D/IRAM region becomes inaccessible to
|
||||||
|
* the MODEM master, resulting in an APM violation during Wi-Fi initialization.
|
||||||
|
*/
|
||||||
|
/* Region 1: REE SRAM region (RW) - for all other masters except LP_CORE */
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M1, 1, SOC_NS_IRAM_START, SOC_IRAM_HIGH, APM_PERM_R | APM_PERM_W, true),
|
||||||
|
/* Region 1: REE SRAM region (RW) - for all LP_CORE */
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M2, 1, SOC_NS_IRAM_START, SOC_IRAM_HIGH, APM_PERM_R | APM_PERM_W, true),
|
||||||
|
|
||||||
|
/* Region 2: Peripherals [Start - MMU] (RW) */
|
||||||
|
/* Protected: MMU */
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 2, SOC_PERIPHERAL_LOW, SPI_MEM_MMU_ITEM_CONTENT_REG(0), APM_PERM_R | APM_PERM_W, true),
|
||||||
|
|
||||||
|
/* Region 3: Peripherals [MMU - SPI1] (RW) */
|
||||||
|
/* Protected: SPI1 */
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 3, SPI_MEM_MMU_POWER_CTRL_REG(0), HP_APM_SPI1_REG_START, APM_PERM_R | APM_PERM_W, true),
|
||||||
|
|
||||||
|
/* Region 4: Peripherals [SPI1 - Interrupt Matrix] (RW) */
|
||||||
|
/* Protected: Interrupt Matrix */
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 4, HP_APM_SPI1_REG_END, DR_REG_INTMTX_BASE, APM_PERM_R | APM_PERM_W, true),
|
||||||
|
|
||||||
|
/* Region 5/6: Peripherals [H/W Lock - HMAC] (RW) */
|
||||||
|
/* Protected: AES, SHA, ECC, DS, HMAC */
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 5, DR_REG_PCNT_BASE, DR_REG_AES_BASE, APM_PERM_R | APM_PERM_W, true),
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 6, DR_REG_RSA_BASE, DR_REG_ECC_MULT_BASE, APM_PERM_R | APM_PERM_W, true),
|
||||||
|
|
||||||
|
/* Region 7/8/9: Peripherals [ECDSA - PMU] (RW) */
|
||||||
|
/* Protected: AES, SHA, ECC, DS and HMAC PCRs */
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 7, DR_REG_ECDSA_BASE, PCR_AES_CONF_REG, APM_PERM_R | APM_PERM_W, true),
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 8, PCR_RSA_CONF_REG, PCR_ECC_CONF_REG, APM_PERM_R | APM_PERM_W, true),
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M3, 9, PCR_ECDSA_CONF_REG, DR_REG_PMU_BASE, APM_PERM_R | APM_PERM_W, true),
|
||||||
|
|
||||||
|
/* Region 10: EXT_MEM region (RW) */
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M4, 10, SOC_S_DROM_HIGH, SOC_EXTRAM_DATA_HIGH, APM_PERM_R | APM_PERM_W, true),
|
||||||
|
};
|
||||||
|
|
||||||
|
/* HP_APM: REE0 mode masters' configuration */
|
||||||
|
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 configuration -----------------------*/
|
||||||
|
|
||||||
|
static apm_hal_ctrl_region_cfg_t lp_apm_regn_cfg_ree0[] = {
|
||||||
|
/* Region 0: RTC memory (RWX) */
|
||||||
|
/* 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, 0, SOC_RTC_IRAM_LOW + 0x20000000, SOC_RTC_IRAM_HIGH + 0x20000000, APM_PERM_ALL, true),
|
||||||
|
|
||||||
|
/* Region 1: LP Peripherals [PMU - SWDT] (RW) */
|
||||||
|
/* Protected: SWDT */
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M1, 1, DR_REG_PMU_BASE, LP_APM_SWD_REG_START, APM_PERM_R | APM_PERM_W, true),
|
||||||
|
|
||||||
|
/* Region 2: LP Peripherals [SWDT - BOD] (RW) */
|
||||||
|
/* Protected: BOD */
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M1, 2, LP_APM_SWD_REG_END, LP_APM_BOD_REG_START, APM_PERM_R | APM_PERM_W, true),
|
||||||
|
|
||||||
|
/* Region 3: LP Peripherals [BOD - eFuse BLK x] (RW) */
|
||||||
|
/* Protected: eFuse BLK x */
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M1, 3, LP_APM_BOD_REG_END, LP_APM_EFUSE_REG_START, APM_PERM_R | APM_PERM_W, true),
|
||||||
|
|
||||||
|
/* Region 4: LP Peripherals [eFuse - END] (RW) */
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M1, 4, LP_APM_EFUSE_REG_END, DR_REG_TRACE_BASE, APM_PERM_R | APM_PERM_W, true),
|
||||||
|
};
|
||||||
|
|
||||||
|
/* LP_APM: REE0 mode masters' configuration */
|
||||||
|
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, 0, SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH, APM_PERM_ALL, true),
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/*----------------------- CPU_APM configuration -----------------------*/
|
||||||
|
|
||||||
|
/* CPU_APM: REE0 mode accessible regions */
|
||||||
|
static apm_hal_ctrl_region_cfg_t cpu_apm_regn_cfg_ree0[] = {
|
||||||
|
/* Region 0: All SRAM access (RWX) */
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M0, 0, SOC_IRAM_LOW, SOC_DRAM_HIGH, APM_PERM_ALL, true),
|
||||||
|
APM_HAL_REGION_ENTRY(APM_CTRL_ACCESS_PATH_M1, 0, SOC_IRAM_LOW, SOC_DRAM_HIGH, APM_PERM_ALL, true),
|
||||||
|
};
|
||||||
|
|
||||||
|
/* CPU_APM: REE0 mode masters' configuration */
|
||||||
|
static apm_hal_ctrl_sec_mode_cfg_t cpu_apm_ctrl_sec_mode_cfg_ree0 =
|
||||||
|
APM_HAL_SEC_MODE_CFG(APM_CTRL_CPU_APM, APM_SEC_MODE_REE0, cpu_apm_regn_cfg_ree0);
|
||||||
|
|
||||||
|
/*---------------- TEE APM Setup -----------------------*/
|
||||||
|
|
||||||
|
static void enable_apm_intr(apm_ctrl_module_t ctrl_mod, uint32_t path_count)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
ctrl_info->ctrl_mod = ctrl_mod;
|
||||||
|
ctrl_info->path = i;
|
||||||
|
|
||||||
|
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 *)ctrl_info;
|
||||||
|
|
||||||
|
/* Register interrupt handler with TEE. */
|
||||||
|
esp_tee_intr_register((void *)&apm_vd);
|
||||||
|
|
||||||
|
/* 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_enable_ctrl_filter_all(false);
|
||||||
|
|
||||||
|
/* 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_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_APM0 REE0 configuration. */
|
||||||
|
apm_hal_set_ctrl_sec_mode_cfg(&lp_apm0_ctrl_sec_mode_cfg_ree0);
|
||||||
|
/* LP_APM0 interrupt configuration. */
|
||||||
|
enable_apm_intr(APM_CTRL_LP_APM0, APM_CTRL_LP_APM0_PATH_NUM);
|
||||||
|
ESP_LOGD(TAG, "[LP_APM0] Configured for REE0");
|
||||||
|
|
||||||
|
/* CPU_APM REE0 configuration. */
|
||||||
|
apm_hal_set_ctrl_sec_mode_cfg(&cpu_apm_ctrl_sec_mode_cfg_ree0);
|
||||||
|
/* CPU_APM interrupt configuration. */
|
||||||
|
enable_apm_intr(APM_CTRL_CPU_APM, APM_CTRL_CPU_APM_PATH_NUM);
|
||||||
|
ESP_LOGD(TAG, "[CPU_APM] Configured for REE0");
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
apm_hal_lock_master_sec_mode(APM_MASTERS_ALL);
|
||||||
|
|
||||||
|
/* Open up all peripherals to REE0 mode*/
|
||||||
|
apm_hal_tee_set_peri_access(APM_TEE_CTRL_HP, APM_PERIPH_HP_REE, APM_SEC_MODE_REE0, APM_PERM_R | APM_PERM_W);
|
||||||
|
apm_hal_tee_set_peri_access(APM_TEE_CTRL_LP, APM_PERIPH_LP_REE, APM_SEC_MODE_REE0, APM_PERM_R | APM_PERM_W);
|
||||||
|
}
|
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "soc/ext_mem_defs.h"
|
||||||
|
#include "esp_cpu.h"
|
||||||
|
#include "esp_fault.h"
|
||||||
|
#include "esp32c5/rom/rom_layout.h"
|
||||||
|
#include "esp_tee.h"
|
||||||
|
|
||||||
|
void esp_tee_configure_region_protection(void)
|
||||||
|
{
|
||||||
|
/* Notes on implementation:
|
||||||
|
*
|
||||||
|
* 1) Note: ESP32-C5 CPU support overlapping PMP regions
|
||||||
|
*
|
||||||
|
* 2) ESP32-C5 supports 16 PMA regions so we use this feature to block all the invalid address ranges
|
||||||
|
*
|
||||||
|
* 3) We use combination of NAPOT (Naturally Aligned Power Of Two) and TOR (top of range)
|
||||||
|
* entries to map all the valid address space, bottom to top. This leaves us with some extra PMP entries
|
||||||
|
* which can be used to provide more granular access
|
||||||
|
*
|
||||||
|
* 4) Entries are grouped in order with some static asserts to try and verify everything is
|
||||||
|
* correct.
|
||||||
|
*/
|
||||||
|
const unsigned NONE = PMP_L;
|
||||||
|
const unsigned R = PMP_L | PMP_R;
|
||||||
|
const unsigned RW = PMP_L | PMP_R | PMP_W;
|
||||||
|
const unsigned RX = PMP_L | PMP_R | PMP_X;
|
||||||
|
const unsigned RWX = PMP_L | PMP_R | PMP_W | PMP_X;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure all the valid address regions using PMP
|
||||||
|
//
|
||||||
|
|
||||||
|
// 1. CPU Subsystem region - contains interrupt config registers
|
||||||
|
PMP_ENTRY_CFG_RESET(0);
|
||||||
|
const uint32_t pmpaddr0 = PMPADDR_NAPOT(SOC_CPU_SUBSYSTEM_LOW, SOC_CPU_SUBSYSTEM_HIGH);
|
||||||
|
PMP_ENTRY_SET(0, pmpaddr0, PMP_NAPOT | RWX);
|
||||||
|
_Static_assert(SOC_CPU_SUBSYSTEM_LOW < SOC_CPU_SUBSYSTEM_HIGH, "Invalid CPU subsystem region");
|
||||||
|
|
||||||
|
// 2. I/D-ROM
|
||||||
|
PMP_ENTRY_CFG_RESET(1);
|
||||||
|
PMP_ENTRY_CFG_RESET(2);
|
||||||
|
PMP_ENTRY_CFG_RESET(3);
|
||||||
|
const uint32_t drom_start = (uint32_t)(ets_rom_layout_p->drom_start);
|
||||||
|
if ((drom_start & (SOC_CPU_PMP_REGION_GRANULARITY - 1)) == 0) {
|
||||||
|
PMP_ENTRY_SET(1, SOC_IROM_MASK_LOW, NONE);
|
||||||
|
PMP_ENTRY_SET(2, drom_start, PMP_TOR | RX);
|
||||||
|
PMP_ENTRY_SET(3, SOC_DROM_MASK_HIGH, PMP_TOR | R);
|
||||||
|
} else {
|
||||||
|
PMP_ENTRY_SET(1, SOC_IROM_MASK_LOW, NONE);
|
||||||
|
PMP_ENTRY_SET(2, SOC_IROM_MASK_HIGH, PMP_TOR | RX);
|
||||||
|
_Static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH, "Invalid I/D-ROM region");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. IRAM and DRAM
|
||||||
|
PMP_ENTRY_CFG_RESET(4);
|
||||||
|
PMP_ENTRY_CFG_RESET(5);
|
||||||
|
PMP_ENTRY_CFG_RESET(6);
|
||||||
|
if (esp_cpu_dbgr_is_attached()) {
|
||||||
|
// Anti-FI check that cpu is really in ocd mode
|
||||||
|
ESP_FAULT_ASSERT(esp_cpu_dbgr_is_attached());
|
||||||
|
PMP_ENTRY_SET(4, SOC_IRAM_LOW, NONE);
|
||||||
|
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);
|
||||||
|
PMP_ENTRY_SET(6, SOC_DRAM_HIGH, PMP_TOR | RW);
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t s_irom_resv_end = SOC_IROM_LOW + CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE;
|
||||||
|
const uint32_t ns_irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_irom_end);
|
||||||
|
const uint32_t ns_drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_drom_end);
|
||||||
|
const uint32_t ns_drom_mmap_end = (uint32_t)(SOC_S_MMU_MMAP_RESV_START_VADDR);
|
||||||
|
|
||||||
|
// 4. I_Cache / D_Cache (flash) - REE
|
||||||
|
PMP_ENTRY_CFG_RESET(7);
|
||||||
|
PMP_ENTRY_CFG_RESET(8);
|
||||||
|
PMP_ENTRY_CFG_RESET(9);
|
||||||
|
PMP_ENTRY_CFG_RESET(10);
|
||||||
|
PMP_ENTRY_SET(7, s_irom_resv_end, NONE);
|
||||||
|
PMP_ENTRY_SET(8, ns_irom_resv_end, PMP_TOR | RX);
|
||||||
|
PMP_ENTRY_SET(9, ns_drom_resv_end, PMP_TOR | R);
|
||||||
|
PMP_ENTRY_SET(10, ns_drom_mmap_end, PMP_TOR | RX);
|
||||||
|
|
||||||
|
// 5. LP memory
|
||||||
|
// TODO: LP memory to be further partitioned into text and data regions using APM
|
||||||
|
PMP_ENTRY_CFG_RESET(11);
|
||||||
|
const uint32_t pmpaddr11 = PMPADDR_NAPOT(SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH);
|
||||||
|
PMP_ENTRY_SET(11, pmpaddr11, PMP_NAPOT | RWX);
|
||||||
|
_Static_assert(SOC_RTC_IRAM_LOW < SOC_RTC_IRAM_HIGH, "Invalid RTC IRAM region");
|
||||||
|
|
||||||
|
// 6. Peripheral addresses
|
||||||
|
PMP_ENTRY_CFG_RESET(12);
|
||||||
|
const uint32_t pmpaddr12 = PMPADDR_NAPOT(SOC_PERIPHERAL_LOW, SOC_PERIPHERAL_HIGH);
|
||||||
|
PMP_ENTRY_SET(12, pmpaddr12, PMP_NAPOT | RW);
|
||||||
|
_Static_assert(SOC_PERIPHERAL_LOW < SOC_PERIPHERAL_HIGH, "Invalid peripheral region");
|
||||||
|
|
||||||
|
//TODO: Add protection for SPIRAM
|
||||||
|
}
|
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "riscv/rv_utils.h"
|
||||||
|
#include "riscv/encoding.h"
|
||||||
|
|
||||||
|
#include "hal/apm_hal.h"
|
||||||
|
#include "hal/aes_ll.h"
|
||||||
|
#include "hal/sha_ll.h"
|
||||||
|
#include "hal/hmac_ll.h"
|
||||||
|
#include "hal/ds_ll.h"
|
||||||
|
#include "hal/ecc_ll.h"
|
||||||
|
|
||||||
|
#include "soc/clic_reg.h"
|
||||||
|
#include "soc/interrupts.h"
|
||||||
|
|
||||||
|
#include "esp_tee.h"
|
||||||
|
#include "esp_tee_intr.h"
|
||||||
|
#include "esp_tee_rv_utils.h"
|
||||||
|
|
||||||
|
#include "esp_cpu.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#define CSR_MCOUNTEREN 0x306
|
||||||
|
|
||||||
|
#define _m2u_switch(arg0, arg1) \
|
||||||
|
({ \
|
||||||
|
register uintptr_t ra asm("ra") = (uintptr_t)(arg0); \
|
||||||
|
register uintptr_t a1 asm("a1") = (uintptr_t)(arg1); \
|
||||||
|
asm volatile("ecall" : :"r"(ra), "r"(a1) : ); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define SET_BIT(t, n) (t |= (1UL << (n)))
|
||||||
|
#define CLR_BIT(t, n) (t &= ~(1UL << (n)))
|
||||||
|
|
||||||
|
static const char *TAG = "esp_tee_secure_sys_cfg";
|
||||||
|
|
||||||
|
extern uint32_t _vector_table;
|
||||||
|
extern uint32_t _mtvt_table;
|
||||||
|
|
||||||
|
void esp_tee_soc_secure_sys_init(void)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Current privilege level - 0x%x", esp_cpu_get_curr_privilege_level());
|
||||||
|
|
||||||
|
/* Setting the M-mode vector table */
|
||||||
|
rv_utils_set_mtvec((uint32_t)&_vector_table);
|
||||||
|
rv_utils_set_mtvt((uint32_t)&_mtvt_table);
|
||||||
|
|
||||||
|
/* Disable global interrupts */
|
||||||
|
RV_CLEAR_CSR(mstatus, MSTATUS_UIE);
|
||||||
|
RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||||
|
|
||||||
|
/* Enabled support for U-mode interrupts */
|
||||||
|
REG_SET_FIELD(CLIC_INT_CONFIG_REG, CLIC_INT_CONFIG_NMBITS, 0x01);
|
||||||
|
REG_SET_FIELD(CLIC_INT_CONFIG_REG, CLIC_INT_CONFIG_UNLBITS, NLBITS);
|
||||||
|
REG_SET_FIELD(CLIC_INT_CONFIG_REG, CLIC_INT_CONFIG_MNLBITS, NLBITS);
|
||||||
|
|
||||||
|
/* Allow reading the cycle counter CSRs from U-mode */
|
||||||
|
RV_WRITE_CSR(CSR_MCOUNTEREN, 0x07);
|
||||||
|
|
||||||
|
/* Clearing all interrupt configurations */
|
||||||
|
uint32_t core_id = esp_cpu_get_core_id();
|
||||||
|
for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) {
|
||||||
|
interrupt_clic_ll_route(core_id, i, ETS_INVALID_INUM);
|
||||||
|
REG_CLR_BIT(DR_REG_INTMTX_BASE + 4 * i, BIT(8));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: IDF-8958
|
||||||
|
* The values for the secure interrupt number and priority and
|
||||||
|
* the interrupt priority threshold (for both M and U mode) need
|
||||||
|
* to be investigated further
|
||||||
|
*/
|
||||||
|
esprv_int_set_threshold(0);
|
||||||
|
|
||||||
|
esprv_int_set_priority(TEE_SECURE_INUM, 7);
|
||||||
|
esprv_int_set_type(TEE_SECURE_INUM, ESP_CPU_INTR_TYPE_LEVEL);
|
||||||
|
esprv_int_enable(BIT(TEE_SECURE_INUM));
|
||||||
|
esprv_int_set_vectored(TEE_SECURE_INUM, true);
|
||||||
|
rv_utils_tee_intr_set_mode(TEE_SECURE_INUM, PRV_M);
|
||||||
|
|
||||||
|
esprv_int_set_priority(TEE_PASS_INUM, 1);
|
||||||
|
esprv_int_set_type(TEE_PASS_INUM, ESP_CPU_INTR_TYPE_LEVEL);
|
||||||
|
esprv_int_enable(BIT(TEE_PASS_INUM));
|
||||||
|
esprv_int_set_vectored(TEE_PASS_INUM, true);
|
||||||
|
rv_utils_tee_intr_set_mode(TEE_PASS_INUM, PRV_M);
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Initial interrupt config -");
|
||||||
|
ESP_LOGD(TAG, "mtvec: 0x%08x", RV_READ_CSR(mtvec));
|
||||||
|
ESP_LOGD(TAG, "mtvt: 0x%08x", RV_READ_CSR(MTVT_CSR));
|
||||||
|
ESP_LOGD(TAG, "mstatus: 0x%08x", RV_READ_CSR(mstatus));
|
||||||
|
ESP_LOGD(TAG, "mcounteren: 0x%08x", RV_READ_CSR(CSR_MCOUNTEREN));
|
||||||
|
|
||||||
|
/* PMP, PMA and APM configuration to isolate the resources between TEE and REE. */
|
||||||
|
esp_tee_configure_region_protection();
|
||||||
|
esp_tee_configure_apm_protection();
|
||||||
|
|
||||||
|
/* Protect secure interrupt sources */
|
||||||
|
esp_tee_protect_intr_src(ETS_LP_APM_M0_INTR_SOURCE); // LP_APM_M0
|
||||||
|
esp_tee_protect_intr_src(ETS_LP_APM_M1_INTR_SOURCE); // LP_APM_M1
|
||||||
|
esp_tee_protect_intr_src(ETS_HP_APM_M0_INTR_SOURCE); // HP_APM_M0
|
||||||
|
esp_tee_protect_intr_src(ETS_HP_APM_M1_INTR_SOURCE); // HP_APM_M1
|
||||||
|
esp_tee_protect_intr_src(ETS_HP_APM_M2_INTR_SOURCE); // HP_APM_M2
|
||||||
|
esp_tee_protect_intr_src(ETS_HP_APM_M3_INTR_SOURCE); // HP_APM_M3
|
||||||
|
esp_tee_protect_intr_src(ETS_HP_APM_M4_INTR_SOURCE); // HP_APM_M4
|
||||||
|
esp_tee_protect_intr_src(ETS_LP_APM0_INTR_SOURCE); // LP_APM0
|
||||||
|
esp_tee_protect_intr_src(ETS_CPU_APM_M0_INTR_SOURCE); // CPU_APM_M0
|
||||||
|
esp_tee_protect_intr_src(ETS_CPU_APM_M1_INTR_SOURCE); // CPU_APM_M1
|
||||||
|
esp_tee_protect_intr_src(ETS_AES_INTR_SOURCE); // AES
|
||||||
|
esp_tee_protect_intr_src(ETS_SHA_INTR_SOURCE); // SHA
|
||||||
|
esp_tee_protect_intr_src(ETS_ECC_INTR_SOURCE); // ECC
|
||||||
|
|
||||||
|
/* Disable protected crypto peripheral clocks; they will be toggled as needed when the peripheral is in use */
|
||||||
|
aes_ll_enable_bus_clock(false);
|
||||||
|
sha_ll_enable_bus_clock(false);
|
||||||
|
hmac_ll_enable_bus_clock(false);
|
||||||
|
ds_ll_enable_bus_clock(false);
|
||||||
|
ecc_ll_enable_bus_clock(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
IRAM_ATTR inline void esp_tee_switch_to_ree(uint32_t ns_entry_addr)
|
||||||
|
{
|
||||||
|
/* 2nd argument is used as magic value to detect very first M2U switch */
|
||||||
|
/* TBD: clean this up and use proper temporary register instead of a1 */
|
||||||
|
/* Switch to non-secure world and launch App. */
|
||||||
|
_m2u_switch(ns_entry_addr, ESP_TEE_M2U_SWITCH_MAGIC << 12);
|
||||||
|
}
|
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "soc/interrupt_matrix_reg.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// LP_APM_M0_INTR, LP_APM_M1_INTR
|
||||||
|
#define TEE_SECURE_INT_APM_MASK_0 (0x00300000)
|
||||||
|
// HP_APM_M0_INTR, HP_APM_M1_INTR, HP_APM_M2_INTR, HP_APM_M3_INTR,
|
||||||
|
// HP_APM_M4_INTR, LP_APM0_INTR, CPU_APM_M0_INTR, CPU_APM_M1_INTR
|
||||||
|
#define TEE_SECURE_INT_APM_MASK_1 (0x00000FF0)
|
||||||
|
|
||||||
|
// LP_RTC_TIMER_INTR
|
||||||
|
#define TEE_SECURE_INT_MASK_0 (TEE_SECURE_INT_APM_MASK_0 | 0x00008000)
|
||||||
|
#if !CONFIG_SECURE_TEE_TEST_MODE
|
||||||
|
#define TEE_SECURE_INT_MASK_1 (TEE_SECURE_INT_APM_MASK_1)
|
||||||
|
#else
|
||||||
|
// + TG0_T0_INTR (only for test mode)
|
||||||
|
#define TEE_SECURE_INT_MASK_1 (TEE_SECURE_INT_APM_MASK_1 | 0x02000000)
|
||||||
|
#endif
|
||||||
|
// AES_INTR, SHA_INTR, ECC_INTR
|
||||||
|
#define TEE_SECURE_INT_MASK_2 (0x0002C000)
|
||||||
|
|
||||||
|
#define INTMTX_STATUS_REG_0 (INTERRUPT_CORE0_INT_STATUS_REG_0_REG)
|
||||||
|
#define INTMTX_STATUS_REG_1 (INTERRUPT_CORE0_INT_STATUS_REG_1_REG)
|
||||||
|
#define INTMTX_STATUS_REG_2 (INTERRUPT_CORE0_INT_STATUS_REG_2_REG)
|
||||||
|
|
||||||
|
#define INTMTX_SEC_STATUS_REG (INTERRUPT_CORE0_SECURE_STATUS_REG)
|
||||||
|
#define INTMTX_SIG_IDX_ASSERT_IN_SEC_REG (INTERRUPT_CORE0_SIG_IDX_ASSERT_IN_SEC_REG)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "riscv/csr.h"
|
||||||
|
#include "riscv/interrupt.h"
|
||||||
|
|
||||||
|
#include "hal/interrupt_clic_ll.h"
|
||||||
|
#include "soc/interrupt_reg.h"
|
||||||
|
#include "soc/clic_reg.h"
|
||||||
|
|
||||||
|
#include "esp_attr.h"
|
||||||
|
#include "esp_tee.h"
|
||||||
|
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MCOUNTEREN_CSR 0x306
|
||||||
|
#define MTVT_CSR 0x307
|
||||||
|
#define MINTSTATUS_CSR 0xFB1
|
||||||
|
#define MINTTHRESH_CSR 0x347
|
||||||
|
#define UINTTHRESH_CSR 0x047
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void rv_utils_tee_intr_global_enable(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Set the the U-mode previous enable global interrupts state
|
||||||
|
*
|
||||||
|
* NOTE: The TICK interrupt is setup before this service call and thus,
|
||||||
|
* it occurs in the return path of this call.
|
||||||
|
*
|
||||||
|
* Before entering the U-mode interrupt handler routine, USTATUS:UIE is
|
||||||
|
* cleared to disable U-mode interrupts temporarily.
|
||||||
|
*
|
||||||
|
* While exiting the above routine, URET is executed, setting USTATUS:UIE
|
||||||
|
* to the value of USTATUS:UPIE. However, since no interrupts were enabled
|
||||||
|
* previously, USTATUS:UPIE and thus, USTATUS:UIE is cleared.
|
||||||
|
*
|
||||||
|
* The service call completes and returns to U-mode with USTATUS:UIE disabled,
|
||||||
|
* preventing any further interrupts in U-mode.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
RV_SET_CSR(ustatus, USTATUS_UPIE);
|
||||||
|
/* Enabling the global M-mode and U-mode interrupts */
|
||||||
|
RV_SET_CSR(ustatus, USTATUS_UIE);
|
||||||
|
RV_SET_CSR(mstatus, MSTATUS_UIE);
|
||||||
|
RV_SET_CSR(mstatus, MSTATUS_MIE);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void rv_utils_tee_intr_global_disable(void)
|
||||||
|
{
|
||||||
|
RV_CLEAR_CSR(ustatus, USTATUS_UIE);
|
||||||
|
RV_CLEAR_CSR(mstatus, MSTATUS_UIE);
|
||||||
|
RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void rv_utils_tee_intr_enable(uint32_t intr_mask)
|
||||||
|
{
|
||||||
|
// Machine mode
|
||||||
|
// Disable all interrupts to make updating of the interrupt mask atomic.
|
||||||
|
unsigned old_xstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||||
|
while (intr_mask != 0) {
|
||||||
|
// __builtin_ffs returns one plus the index of the lsb 1-bit of x. If x is zero, returns zero
|
||||||
|
uint32_t intr_num = __builtin_ffs(intr_mask) - 1;
|
||||||
|
*(uint8_t volatile *)(BYTE_CLIC_INT_IE_REG(intr_num + CLIC_EXT_INTR_NUM_OFFSET)) = BYTE_CLIC_INT_IE;
|
||||||
|
intr_mask &= (intr_mask - 1);
|
||||||
|
}
|
||||||
|
RV_SET_CSR(mstatus, old_xstatus & MSTATUS_MIE);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void rv_utils_tee_intr_disable(uint32_t intr_mask)
|
||||||
|
{
|
||||||
|
// Machine mode
|
||||||
|
// Disable all interrupts to make updating of the interrupt mask atomic.
|
||||||
|
unsigned old_xstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||||
|
while (intr_mask != 0) {
|
||||||
|
// __builtin_ffs returns one plus the index of the lsb 1-bit of x. If x is zero, returns zero
|
||||||
|
uint32_t intr_num = __builtin_ffs(intr_mask) - 1;
|
||||||
|
*(uint8_t volatile *)(BYTE_CLIC_INT_IE_REG(intr_num + CLIC_EXT_INTR_NUM_OFFSET)) = 0;
|
||||||
|
intr_mask &= (intr_mask - 1);
|
||||||
|
}
|
||||||
|
RV_SET_CSR(mstatus, old_xstatus & MSTATUS_MIE);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void rv_utils_tee_intr_set_type(int intr_num, enum intr_type type)
|
||||||
|
{
|
||||||
|
assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM);
|
||||||
|
/* TODO: CLIC supports both rising and falling edge triggered interrupts.
|
||||||
|
* Currently only rising edge is implemented.
|
||||||
|
*/
|
||||||
|
volatile uint8_t *attr_reg = (volatile uint8_t *)BYTE_CLIC_INT_ATTR_REG(intr_num + CLIC_EXT_INTR_NUM_OFFSET);
|
||||||
|
uint8_t attr = *attr_reg;
|
||||||
|
attr &= ~BYTE_CLIC_INT_ATTR_TRIG_M;
|
||||||
|
if (type == INTR_TYPE_EDGE) {
|
||||||
|
attr |= (INTR_TYPE_EDGE << BYTE_CLIC_INT_ATTR_TRIG_S);
|
||||||
|
}
|
||||||
|
*attr_reg = attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void rv_utils_tee_intr_set_priority(int rv_int_num, int priority)
|
||||||
|
{
|
||||||
|
assert(rv_int_num >= 0 && rv_int_num < SOC_CPU_INTR_NUM);
|
||||||
|
*(uint8_t volatile *)(BYTE_CLIC_INT_CTL_REG(rv_int_num + CLIC_EXT_INTR_NUM_OFFSET)) = (priority << BYTE_CLIC_INT_CTL_S);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void rv_utils_tee_intr_set_threshold(int priority_threshold)
|
||||||
|
{
|
||||||
|
uint32_t adj_threshold = ((priority_threshold << (8 - NLBITS)) | 0x1f);
|
||||||
|
REG_SET_FIELD(CLIC_INT_THRESH_REG, CLIC_CPU_INT_THRESH, adj_threshold);
|
||||||
|
RV_WRITE_CSR(MINTTHRESH_CSR, adj_threshold);
|
||||||
|
RV_WRITE_CSR(UINTTHRESH_CSR, adj_threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void rv_utils_tee_intr_set_mode(int rv_int_num, int mode)
|
||||||
|
{
|
||||||
|
assert(rv_int_num >= 0 && rv_int_num < SOC_CPU_INTR_NUM);
|
||||||
|
REG_SET_FIELD(CLIC_INT_CTRL_REG(rv_int_num + CLIC_EXT_INTR_NUM_OFFSET), CLIC_INT_ATTR_MODE, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@@ -10,6 +10,9 @@
|
|||||||
#include "riscv/encoding.h"
|
#include "riscv/encoding.h"
|
||||||
#include "esp_private/interrupt_plic.h"
|
#include "esp_private/interrupt_plic.h"
|
||||||
|
|
||||||
|
#include "soc/plic_reg.h"
|
||||||
|
#include "soc/interrupts.h"
|
||||||
|
|
||||||
#include "esp_cpu.h"
|
#include "esp_cpu.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "hal/apm_hal.h"
|
#include "hal/apm_hal.h"
|
||||||
@@ -57,20 +60,24 @@ void esp_tee_soc_secure_sys_init(void)
|
|||||||
|
|
||||||
/* All interrupts except the TEE secure interrupt are delegated to the U-mode */
|
/* All interrupts except the TEE secure interrupt are delegated to the U-mode */
|
||||||
RV_WRITE_CSR(mideleg, UINT32_MAX);
|
RV_WRITE_CSR(mideleg, UINT32_MAX);
|
||||||
RV_CLEAR_CSR(mideleg, TEE_SECURE_INUM);
|
RV_CLEAR_CSR(mideleg, BIT(TEE_SECURE_INUM));
|
||||||
|
|
||||||
|
/* Clearing all interrupt configurations */
|
||||||
|
uint32_t core_id = esp_cpu_get_core_id();
|
||||||
|
for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) {
|
||||||
|
esp_rom_route_intr_matrix(core_id, i, ETS_INVALID_INUM);
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: IDF-8958
|
/* TODO: IDF-8958
|
||||||
* The values for the secure interrupt number and priority and
|
* The values for the secure interrupt number and priority and
|
||||||
* the interrupt priority threshold (for both M and U mode) need
|
* the interrupt priority threshold (for both M and U mode) need
|
||||||
* to be investigated further
|
* to be investigated further
|
||||||
*/
|
*/
|
||||||
#ifdef SOC_CPU_HAS_FLEXIBLE_INTC
|
|
||||||
/* TODO: Currently, we do not allow interrupts to be set up with a priority greater than 7, see intr_alloc.c */
|
/* TODO: Currently, we do not allow interrupts to be set up with a priority greater than 7, see intr_alloc.c */
|
||||||
esprv_int_set_priority(TEE_SECURE_INUM, 7);
|
esprv_int_set_priority(TEE_SECURE_INUM, 7);
|
||||||
esprv_int_set_type(TEE_SECURE_INUM, ESP_CPU_INTR_TYPE_LEVEL);
|
esprv_int_set_type(TEE_SECURE_INUM, ESP_CPU_INTR_TYPE_LEVEL);
|
||||||
esprv_int_set_threshold(RVHAL_INTR_ENABLE_THRESH);
|
esprv_int_set_threshold(RVHAL_INTR_ENABLE_THRESH);
|
||||||
esprv_int_enable(BIT(TEE_SECURE_INUM));
|
esprv_int_enable(BIT(TEE_SECURE_INUM));
|
||||||
#endif
|
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Initial interrupt config -");
|
ESP_LOGD(TAG, "Initial interrupt config -");
|
||||||
ESP_LOGD(TAG, "mideleg: 0x%08x", RV_READ_CSR(mideleg));
|
ESP_LOGD(TAG, "mideleg: 0x%08x", RV_READ_CSR(mideleg));
|
||||||
|
@@ -10,6 +10,9 @@
|
|||||||
#include "riscv/encoding.h"
|
#include "riscv/encoding.h"
|
||||||
#include "esp_private/interrupt_plic.h"
|
#include "esp_private/interrupt_plic.h"
|
||||||
|
|
||||||
|
#include "soc/plic_reg.h"
|
||||||
|
#include "soc/interrupts.h"
|
||||||
|
|
||||||
#include "esp_cpu.h"
|
#include "esp_cpu.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "hal/apm_hal.h"
|
#include "hal/apm_hal.h"
|
||||||
@@ -57,7 +60,13 @@ void esp_tee_soc_secure_sys_init(void)
|
|||||||
|
|
||||||
/* All interrupts except the TEE secure interrupt are delegated to the U-mode */
|
/* All interrupts except the TEE secure interrupt are delegated to the U-mode */
|
||||||
RV_WRITE_CSR(mideleg, UINT32_MAX);
|
RV_WRITE_CSR(mideleg, UINT32_MAX);
|
||||||
RV_CLEAR_CSR(mideleg, TEE_SECURE_INUM);
|
RV_CLEAR_CSR(mideleg, BIT(TEE_SECURE_INUM));
|
||||||
|
|
||||||
|
/* Clearing all interrupt configurations */
|
||||||
|
uint32_t core_id = esp_cpu_get_core_id();
|
||||||
|
for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) {
|
||||||
|
esp_rom_route_intr_matrix(core_id, i, ETS_INVALID_INUM);
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: IDF-8958
|
/* TODO: IDF-8958
|
||||||
* The values for the secure interrupt number and priority and
|
* The values for the secure interrupt number and priority and
|
||||||
|
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
components/esp_tee/test_apps/tee_cli_app:
|
components/esp_tee/test_apps/tee_cli_app:
|
||||||
disable:
|
disable:
|
||||||
- if: IDF_TARGET not in ["esp32c6"]
|
- if: IDF_TARGET not in ["esp32c6", "esp32c5"]
|
||||||
reason: only supported with esp32c6 for now
|
reason: only supported with c6 and c5
|
||||||
|
|
||||||
components/esp_tee/test_apps/tee_test_fw:
|
components/esp_tee/test_apps/tee_test_fw:
|
||||||
disable:
|
disable:
|
||||||
- if: IDF_TARGET not in ["esp32c6", "esp32h2"]
|
- if: IDF_TARGET not in ["esp32c6", "esp32h2", "esp32c5"]
|
||||||
reason: only supported with esp32c6 and esp32h2 for now
|
reason: only supported with c6, h2 and c5
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
| Supported Targets | ESP32-C6 |
|
| Supported Targets | ESP32-C5 | ESP32-C6 |
|
||||||
| ----------------- | -------- |
|
| ----------------- | -------- | -------- |
|
||||||
|
|
||||||
# TEE CLI Application: Secure Services Demonstration
|
# TEE CLI Application: Secure Services Demonstration
|
||||||
|
|
||||||
|
@@ -111,7 +111,6 @@ static void tee_ota_task(void *pvParameter)
|
|||||||
task_fatal_error();
|
task_fatal_error();
|
||||||
} else if (data_read > 0) {
|
} else if (data_read > 0) {
|
||||||
if (image_header_was_checked == false) {
|
if (image_header_was_checked == false) {
|
||||||
/* TODO: TEE image header is missing the `esp_app_desc_t` configuration structure */
|
|
||||||
if (data_read > sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)) {
|
if (data_read > sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)) {
|
||||||
esp_image_header_t img_hdr;
|
esp_image_header_t img_hdr;
|
||||||
memcpy(&img_hdr, ota_write_data, sizeof(esp_image_header_t));
|
memcpy(&img_hdr, ota_write_data, sizeof(esp_image_header_t));
|
||||||
|
@@ -6,11 +6,9 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import os
|
import os
|
||||||
import socket
|
|
||||||
import ssl
|
import ssl
|
||||||
import time
|
import time
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Callable
|
|
||||||
|
|
||||||
import pexpect
|
import pexpect
|
||||||
import pytest
|
import pytest
|
||||||
@@ -22,7 +20,6 @@ from ecdsa.keys import VerifyingKey
|
|||||||
from ecdsa.util import sigdecode_der
|
from ecdsa.util import sigdecode_der
|
||||||
from pytest_embedded import Dut
|
from pytest_embedded import Dut
|
||||||
from pytest_embedded_idf.utils import idf_parametrize
|
from pytest_embedded_idf.utils import idf_parametrize
|
||||||
from RangeHTTPServer import RangeRequestHandler
|
|
||||||
|
|
||||||
TEST_MSG = 'hello world'
|
TEST_MSG = 'hello world'
|
||||||
|
|
||||||
@@ -36,12 +33,12 @@ key_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_certs/
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
@idf_parametrize('target', ['supported_targets'], indirect=['target'])
|
||||||
def test_tee_cli_secure_storage(dut: Dut) -> None:
|
def test_tee_cli_secure_storage(dut: Dut) -> None:
|
||||||
# Dumping the REE binary size
|
# Dumping the REE binary size
|
||||||
binary_file = os.path.join(dut.app.binary_path, 'tee_cli.bin')
|
binary_file = os.path.join(dut.app.binary_path, 'tee_cli.bin')
|
||||||
bin_size = os.path.getsize(binary_file)
|
bin_size = os.path.getsize(binary_file)
|
||||||
logging.info('tee_cli_bin_size : {}KB'.format(bin_size // 1024))
|
logging.info(f'tee_cli_bin_size : {bin_size // 1024}KB')
|
||||||
|
|
||||||
# Starting the test
|
# Starting the test
|
||||||
dut.expect('ESP-TEE: Secure services demonstration', timeout=30)
|
dut.expect('ESP-TEE: Secure services demonstration', timeout=30)
|
||||||
@@ -122,12 +119,12 @@ def verify_att_token_signature(att_tk: str) -> Any:
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
@idf_parametrize('target', ['supported_targets'], indirect=['target'])
|
||||||
def test_tee_cli_attestation(dut: Dut) -> None:
|
def test_tee_cli_attestation(dut: Dut) -> None:
|
||||||
# Dumping the REE binary size
|
# Dumping the REE binary size
|
||||||
binary_file = os.path.join(dut.app.binary_path, 'tee_cli.bin')
|
binary_file = os.path.join(dut.app.binary_path, 'tee_cli.bin')
|
||||||
bin_size = os.path.getsize(binary_file)
|
bin_size = os.path.getsize(binary_file)
|
||||||
logging.info('tee_cli_bin_size : {}KB'.format(bin_size // 1024))
|
logging.info(f'tee_cli_bin_size : {bin_size // 1024}KB')
|
||||||
|
|
||||||
# Starting the test
|
# Starting the test
|
||||||
dut.expect('ESP-TEE: Secure services demonstration', timeout=30)
|
dut.expect('ESP-TEE: Secure services demonstration', timeout=30)
|
||||||
@@ -149,41 +146,22 @@ def test_tee_cli_attestation(dut: Dut) -> None:
|
|||||||
#######################################
|
#######################################
|
||||||
|
|
||||||
|
|
||||||
def https_request_handler() -> Callable[..., http.server.BaseHTTPRequestHandler]:
|
|
||||||
"""
|
|
||||||
Returns a request handler class that handles broken pipe exception
|
|
||||||
"""
|
|
||||||
|
|
||||||
class RequestHandler(RangeRequestHandler):
|
|
||||||
def finish(self) -> None:
|
|
||||||
try:
|
|
||||||
if not self.wfile.closed:
|
|
||||||
self.wfile.flush()
|
|
||||||
self.wfile.close()
|
|
||||||
except socket.error:
|
|
||||||
pass
|
|
||||||
self.rfile.close()
|
|
||||||
|
|
||||||
def handle(self) -> None:
|
|
||||||
try:
|
|
||||||
RangeRequestHandler.handle(self)
|
|
||||||
except socket.error:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return RequestHandler
|
|
||||||
|
|
||||||
|
|
||||||
def start_https_server(ota_image_dir: str, server_ip: str, server_port: int) -> None:
|
def start_https_server(ota_image_dir: str, server_ip: str, server_port: int) -> None:
|
||||||
os.chdir(ota_image_dir)
|
os.chdir(ota_image_dir)
|
||||||
requestHandler = https_request_handler()
|
server_address = (server_ip, server_port)
|
||||||
httpd = http.server.HTTPServer((server_ip, server_port), requestHandler)
|
|
||||||
|
|
||||||
httpd.socket = ssl.wrap_socket(httpd.socket, keyfile=key_file, certfile=server_file, server_side=True)
|
Handler = http.server.SimpleHTTPRequestHandler
|
||||||
|
httpd = http.server.HTTPServer(server_address, Handler)
|
||||||
|
|
||||||
|
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
||||||
|
context.load_cert_chain(certfile=server_file, keyfile=key_file)
|
||||||
|
|
||||||
|
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
|
||||||
httpd.serve_forever()
|
httpd.serve_forever()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.wifi_high_traffic
|
@pytest.mark.wifi_high_traffic
|
||||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
@idf_parametrize('target', ['supported_targets'], indirect=['target'])
|
||||||
def test_tee_cli_secure_ota_wifi(dut: Dut) -> None:
|
def test_tee_cli_secure_ota_wifi(dut: Dut) -> None:
|
||||||
"""
|
"""
|
||||||
This is a positive test case, which downloads complete binary file multiple number of times.
|
This is a positive test case, which downloads complete binary file multiple number of times.
|
||||||
@@ -214,7 +192,7 @@ def test_tee_cli_secure_ota_wifi(dut: Dut) -> None:
|
|||||||
|
|
||||||
# Starting the test
|
# Starting the test
|
||||||
dut.expect('ESP-TEE: Secure services demonstration', timeout=30)
|
dut.expect('ESP-TEE: Secure services demonstration', timeout=30)
|
||||||
time.sleep(1)
|
time.sleep(2)
|
||||||
|
|
||||||
# Connecting to Wi-Fi
|
# Connecting to Wi-Fi
|
||||||
env_name = 'wifi_high_traffic'
|
env_name = 'wifi_high_traffic'
|
||||||
@@ -225,7 +203,7 @@ def test_tee_cli_secure_ota_wifi(dut: Dut) -> None:
|
|||||||
# Fetch the DUT IP address
|
# Fetch the DUT IP address
|
||||||
try:
|
try:
|
||||||
ip_address = dut.expect(r'got ip:(\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode()
|
ip_address = dut.expect(r'got ip:(\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode()
|
||||||
print('Connected to AP/Ethernet with IP: {}'.format(ip_address))
|
print(f'Connected to AP/Ethernet with IP: {ip_address}')
|
||||||
except pexpect.exceptions.TIMEOUT:
|
except pexpect.exceptions.TIMEOUT:
|
||||||
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP')
|
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP')
|
||||||
|
|
||||||
|
@@ -14,7 +14,7 @@ CONFIG_FREERTOS_UNICORE=y
|
|||||||
# TEE: OTA-related
|
# TEE: OTA-related
|
||||||
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y
|
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y
|
||||||
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||||
CONFIG_EXAMPLE_OTA_RECV_TIMEOUT=45000
|
CONFIG_EXAMPLE_OTA_RECV_TIMEOUT=30000
|
||||||
|
|
||||||
# Custom certificates for testing
|
# Custom certificates for testing
|
||||||
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN=y
|
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN=y
|
||||||
|
@@ -1,20 +1,27 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIIDWDCCAkACCQCbF4+gVh/MLjANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJJ
|
MIIEmzCCAwOgAwIBAgIUCjRtb8JpjaUnUr1g2JJK8WxzXAkwDQYJKoZIhvcNAQEL
|
||||||
TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD
|
BQAwTDELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAk1IMQswCQYDVQQHDAJQTjEMMAoG
|
||||||
VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j
|
A1UECgwDZXNwMRUwEwYDVQQDDAwxOTIuMTY4LjEuMzYwHhcNMjUwNzI0MTI0OTQw
|
||||||
b20wHhcNMjEwNzEyMTIzNjI3WhcNNDEwNzA3MTIzNjI3WjBuMQswCQYDVQQGEwJJ
|
WhcNMzUwNzIyMTI0OTQwWjBMMQswCQYDVQQGEwJJTjELMAkGA1UECAwCTUgxCzAJ
|
||||||
TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD
|
BgNVBAcMAlBOMQwwCgYDVQQKDANlc3AxFTATBgNVBAMMDDE5Mi4xNjguMS4zNjCC
|
||||||
VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j
|
AaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAK4nnofpHHPvvF4IuF1OhZvp
|
||||||
b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhxF/y7bygndxPwiWL
|
cTtScOV/h0eTFCpm+eq9NcsIUpEad1DMmKPGN9y1dp//qNZUJomZBnhG+NoHBLPX
|
||||||
SwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQuc32W
|
Xu62fQ+n1EsJ8QtmEaNo+3fElM2joN6Vfi5/Pz6JyrYq5FYkZnI5agMlLPbrldZa
|
||||||
ukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2mKRbQ
|
G3ZHh1vCAhbVrD6S0hLKNrTRt/PbKWfohz8swkl4DqOk0DQDKdkIB/WVLmFo3sMZ
|
||||||
S5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO2fEz
|
wfTm04lfH9VMJXUrmxFI+WUycTqlpdupMPHdVAr4v85RsC8kRcIneJnc1lKDDHlX
|
||||||
YaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnvL6Oz
|
ou0Loxjz3oLCtFNfiqARx7UQ0voAdLJlk7+NHM8D/ArcfMcKWE+aj/e8S6USf/9F
|
||||||
3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdOAoap
|
fkvqKJzdCQieEnI4uISAeHgj1Cy52nafD+eQRXcjjPCe3WZxYyD9kpeindoy0suM
|
||||||
rFTRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAItw24y565k3C/zENZlxyzto44ud
|
EPgIMCTXKY/0iQxYNO9CxGqw5O3ROVPq/vWbRr/yOfJ8SRGnklztxrQiLB0kRtpO
|
||||||
IYPQXN8Fa2pBlLe1zlSIyuaA/rWQ+i1daS8nPotkCbWZyf5N8DYaTE4B0OfvoUPk
|
hVCYmfk84l+98c9CPu1CY9VjlYqUOREjKc4edBeR9QIDAQABo3UwczAdBgNVHQ4E
|
||||||
B5uGDmbuk6akvlB5BGiYLfQjWHRsK9/4xjtIqN1H58yf3QNROuKsPAeywWS3Fn32
|
FgQUAL1glrdORLboiLujugzLmArsLXowHwYDVR0jBBgwFoAUAL1glrdORLboiLuj
|
||||||
3//OpbWaClQePx6udRYMqAitKR+QxL7/BKZQsX+UyShuq8hjphvXvk0BW8ONzuw9
|
ugzLmArsLXowDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCBaAwEwYDVR0lBAww
|
||||||
RcoORxM0FzySYjeQvm4LhzC/P3ZBhEq0xs55aL2a76SJhq5hJy7T/Xz6NFByvlrN
|
CgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggGBAFiQgcPxNLK2Tan6Kw4Xyb2q
|
||||||
lFJJey33KFrAf5vnV9qcyWFIo7PYy2VsaaEjFeefr7q3sTFSMlJeadexW2Y=
|
LdpEQXvxiF0f+tLAFJx1mc8aExaM0WinNehGZSwZl1DnH6sJlOiuitAewSjiaFVF
|
||||||
|
QXxS+8nkBGn0C0tAV4kc3/TxOpbNpTPZUDb3PNMhlGH1LJqZBpWrzbzHL8YSwXmT
|
||||||
|
aoiXV6/ubWk1yYjTLPChmavWaOAVhYK3GqRbDGDERXC8uXe7de5UuD8R+oaFS1oh
|
||||||
|
nC6x1wspGQbILjDwmqRE5GvPlTWSBAHw4bbWD4GnXMXAAkDj5Fjom+CzC5D7Q3wQ
|
||||||
|
C/JlVN1cHNLF6VlOlLDZyLDeWPOVkpm3OB5+IxPEW+8XtNfGrpB5cI/zf2Ba7kZU
|
||||||
|
jmZNrMqXXd3r7fYLTGjWfMMQb/XLTT2/qE/iOc/tCVLVkDu2hd5gtsIasnlwaBZ7
|
||||||
|
dn1nRwrKaXwZnPql+Fx3KjuY6nA2+SDz9t57bIxkWhjE+Nn/zFZk7l84foyo3RhO
|
||||||
|
TAlCEC81uG9vZqL2fShbrTqpXs59KP3wlPVKuWro5Q==
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
@@ -1,28 +1,40 @@
|
|||||||
-----BEGIN PRIVATE KEY-----
|
-----BEGIN PRIVATE KEY-----
|
||||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDhxF/y7bygndxP
|
MIIG/gIBADANBgkqhkiG9w0BAQEFAASCBugwggbkAgEAAoIBgQCuJ56H6Rxz77xe
|
||||||
wiWLSwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQu
|
CLhdToWb6XE7UnDlf4dHkxQqZvnqvTXLCFKRGndQzJijxjfctXaf/6jWVCaJmQZ4
|
||||||
c32WukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2m
|
RvjaBwSz117utn0Pp9RLCfELZhGjaPt3xJTNo6DelX4ufz8+icq2KuRWJGZyOWoD
|
||||||
KRbQS5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO
|
JSz265XWWht2R4dbwgIW1aw+ktISyja00bfz2yln6Ic/LMJJeA6jpNA0AynZCAf1
|
||||||
2fEzYaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnv
|
lS5haN7DGcH05tOJXx/VTCV1K5sRSPllMnE6paXbqTDx3VQK+L/OUbAvJEXCJ3iZ
|
||||||
L6Oz3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdO
|
3NZSgwx5V6LtC6MY896CwrRTX4qgEce1ENL6AHSyZZO/jRzPA/wK3HzHClhPmo/3
|
||||||
AoaprFTRAgMBAAECggEAE0HCxV/N1Q1h+1OeDDGL5+74yjKSFKyb/vTVcaPCrmaH
|
vEulEn//RX5L6iic3QkInhJyOLiEgHh4I9Qsudp2nw/nkEV3I4zwnt1mcWMg/ZKX
|
||||||
fPvp0ddOvMZJ4FDMAsiQS6/n4gQ7EKKEnYmwTqj4eUYW8yxGUn3f0YbPHbZT+Mkj
|
op3aMtLLjBD4CDAk1ymP9IkMWDTvQsRqsOTt0TlT6v71m0a/8jnyfEkRp5Jc7ca0
|
||||||
z5woi3nMKi/MxCGDQZX4Ow3xUQlITUqibsfWcFHis8c4mTqdh4qj7xJzehD2PVYF
|
IiwdJEbaToVQmJn5POJfvfHPQj7tQmPVY5WKlDkRIynOHnQXkfUCAwEAAQKCAYA4
|
||||||
gNHZsvVj6MltjBDAVwV1IlGoHjuElm6vuzkfX7phxcA1B4ZqdYY17yCXUnvui46z
|
VJxUfbQ0U+Dr0YpAs/tHePSlKX9W3C8XmZ02MeS4ZscVivWZ9aOOQP9GSgEbpJ5g
|
||||||
Xn2kUTOOUCEgfgvGa9E+l4OtdXi5IxjaSraU+dlg2KsE4TpCuN2MEVkeR5Ms3Y7Q
|
FkO4P7PPYe3TzbEEZKzCtvD/6Yr+G1zxgJ+0/ijKYFSmYrF26mxIUrZjt8jvI4ar
|
||||||
jgJl8vlNFJDQpbFukLcYwG7rO5N5dQ6WWfVia/5XgQKBgQD74at/bXAPrh9NxPmz
|
8ae1rURtweBmcAnhPEZU9QRY973ykgg29pomCztj1IBpcEQ93i/AalgEuSeGuAyU
|
||||||
i1oqCHMDoM9sz8xIMZLF9YVu3Jf8ux4xVpRSnNy5RU1gl7ZXbpdgeIQ4v04zy5aw
|
JeUqTbOlfZGFf+FmpJMZLCWuX1Mg5eHYDi83fQlFSANTFkPFonrJWCp6sQpUGiz2
|
||||||
8T4tu9K3XnR3UXOy25AK0q+cnnxZg3kFQm+PhtOCKEFjPHrgo2MUfnj+EDddod7N
|
hFgGkH3jqLbA1KE5x/SwuQmWMbBHRPYhET2Py5mhkS5zddJS5YG3WSO/dv6o7tGP
|
||||||
JQr9q5rEFbqHupFPpWlqCa3QmQKBgQDldWUGokNaEpmgHDMnHxiibXV5LQhzf8Rq
|
Ek0G0RQzfKqraJRBM0ePb4texi5umIE+G3XpQApE8ZELJjVpEAQkKCH189np7oxv
|
||||||
gJIQXb7R9EsTSXEvsDyqTBb7PHp2Ko7rZ5YQfyf8OogGGjGElnPoU/a+Jij1gVFv
|
tcWCQwPq5addMTPqVzaNjhC4JADhUeSiXYGlTmvSuSV/ZIXI7fffI1qDwrBVIX7N
|
||||||
kZ064uXAAISBkwHdcuobqc5EbG3ceyH46F+FBFhqM8KcbxJxx08objmh58+83InN
|
T6ie4JQU+lc+hv8gPZqNdglHYUMj6i3bPPzQ8p/Tu5MdNcAoh455aXUilflJjukC
|
||||||
P9Qr25Xw+QKBgEGXMHuMWgQbSZeM1aFFhoMvlBO7yogBTKb4Ecpu9wI5e3Kan3Al
|
gcEA8EtvDE9k1zHgZFmcXkl+c+PgpGcp0nwoJ+uH2BCd5PI962IcDhQcKxCPNPa2
|
||||||
pZYltuyf+VhP6XG3IMBEYdoNJyYhu+nzyEdMg8CwXg+8LC7FMis/Ve+o7aS5scgG
|
GxV/6J/y6cLk99v3novIlZmEnIvMf/g2gYdW0XNKEljwtB6ms/Oq/OMMuGMP+Ix4
|
||||||
1to/N9DK/swCsdTRdzmc/ZDbVC+TuVsebFBGYZTyO5KgqLpezqaIQrTxAoGALFCU
|
0H9uW6LpYzYBuyKOt6RfYrgWsNsL2caojcu92aX4ug4kkf97OnsslrAqkp1hGJiN
|
||||||
10glO9MVyl9H3clap5v+MQ3qcOv/EhaMnw6L2N6WVT481tnxjW4ujgzrFcE4YuxZ
|
okuiss63UVROalcNSWFLqkz7zcKy67eItuIBOEY+tKkdUt1b3/DURHFL4e5ZCdWo
|
||||||
hgwYu9TOCmeqopGwBvGYWLbj+C4mfSahOAs0FfXDoYazuIIGBpuv03UhbpB1Si4O
|
UnjrAoHBALmJi3f9VGqsn2mFnetSeablRnvOyNMMblRgBLBVsc6hEl3Vxd0ejY8N
|
||||||
rJDfRnuCnVWyOTkl54gKJ2OusinhjztBjcrV1XkCgYEA3qNi4uBsPdyz9BZGb/3G
|
APWZ+W8/AXwpHj+Oqoap6wYiuXr1xcHBRNZu2gRB0evZUEzdu7m6dj28dc9ICymj
|
||||||
rOMSw0CaT4pEMTLZqURmDP/0hxvTk1polP7O/FYwxVuJnBb6mzDa0xpLFPTpIAnJ
|
9CuFW+HVxidmBPfAum1+PU0WHkB4CwDpm5DtPymlNHJKKvDILawo4j2jh9K5YeCK
|
||||||
YXB8xpXU69QVh+EBbemdJWOd+zp5UCfXvb2shAeG3Tn/Dz4cBBMEUutbzP+or0nG
|
6/YdjmQVaBeHoB2v59UkEPZCcFarZa1Z6ZBlkNKCeCrKYB081RsEjYpwZUVd8eHw
|
||||||
vSXnRLaxQhooWm+IuX9SuBQ=
|
49jl131onwKBwFHFec64ndpVUMUVcY7sd6m8XE/WA3drZMbg8eNnFDQ68zNMubtY
|
||||||
|
wJUvF2ywoBvrXxGsjJ9cAUsPgd5kNyghi+0x7a+GqhW+Fp9EGmrP9Wl2HMiUHRXd
|
||||||
|
thBxNZghRWO+WbG5aK6oTEKAagy4VPVlK+OXRxse7XEDamHMhy3Zbjx4slieXfgR
|
||||||
|
jwtBny8diuU10/IBQoTcqaqqYQ0dnQAhHndQ0E5CsLV7h2q9DM2x1xbB2WgFrlZ0
|
||||||
|
L5x83bPpD1SxbQKBwQCjuKr4o/Qk+dTlwcGbkTjGPFWZFN0D11lYXS5mCAiSBHJ3
|
||||||
|
mRczyy0xSVFKaKfCMf/2dzY48YSqtjAtRuETjuMF2a0L59+8l/RMwYPpgFSSTObg
|
||||||
|
DXiMA8/N296vtMtimkh0JcNGeKxJyHcBmf3x97wF/x6GocP11NFV9Pq1ZH9hBua1
|
||||||
|
a6OEIJAtG4misWwgBv/Gm6h/6eSSoXPSSshkwnRDpy7Ce81y5Sxy3gg4ZKDMaZUY
|
||||||
|
z5udvYufS/lTQWaJRJMCgcEAzxLRrGW3Gz4ch1V+ZCNTNQJqUwHeIQF4mVNkeEk5
|
||||||
|
wXE2NsW/DqStQiNkNDSMHiTXPfVoHDGhxxKhSYPe2O7JXkJL8EyzwMwEZJ4ypjuV
|
||||||
|
5/DadZh6cGu6UWVNAzzvcOMnEH8rHFfQlAd7MnFdJafXnEAX9UCfNFHOoNJhBbUj
|
||||||
|
kQPYVUEkEws0Feu0yUgyDRfDZcxeEC+ubvO0mGZEdGAuvu29AHnnGLhBTTdFb05H
|
||||||
|
Q4QjfIE8PkLbVa1oC3niOWdo
|
||||||
-----END PRIVATE KEY-----
|
-----END PRIVATE KEY-----
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
| Supported Targets | ESP32-C6 | ESP32-H2 |
|
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-H2 |
|
||||||
| ----------------- | -------- | -------- |
|
| ----------------- | -------- | -------- | -------- |
|
||||||
|
|
||||||
## ESP-TEE: Test Suite
|
## ESP-TEE: Test Suite
|
||||||
|
|
||||||
|
@@ -9,36 +9,11 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
|
|
||||||
#define TEE_TEST_INT_COUNT 3
|
#define ESP_TEE_TEST_INTR_ITER (4)
|
||||||
|
|
||||||
uint32_t NOINLINE_ATTR esp_tee_service_add(uint32_t a, uint32_t b);
|
void NOINLINE_ATTR esp_tee_test_dummy_sec_srv(int a, int b, int c, int d, int e, int f, int g, int h, int *i);
|
||||||
|
|
||||||
uint32_t NOINLINE_ATTR esp_tee_service_sub(uint32_t a, uint32_t b);
|
|
||||||
|
|
||||||
uint32_t NOINLINE_ATTR esp_tee_service_mul(uint32_t a, uint32_t b);
|
|
||||||
|
|
||||||
uint32_t NOINLINE_ATTR esp_tee_service_div(uint32_t a, uint32_t b);
|
|
||||||
|
|
||||||
int esp_tee_secure_int_test(void);
|
|
||||||
|
|
||||||
int esp_tee_non_secure_int_test(volatile uint32_t* volatile ns_int_count);
|
|
||||||
|
|
||||||
int esp_tee_test_int_count(uint32_t *secure_int_count);
|
|
||||||
|
|
||||||
int esp_tee_test_store_prohibited(uint32_t type);
|
|
||||||
|
|
||||||
int esp_tee_test_illegal_instr(void);
|
|
||||||
|
|
||||||
int esp_tee_test_instr_fetch_prohibited(uint32_t type);
|
|
||||||
|
|
||||||
void NOINLINE_ATTR dummy_secure_service(int a, int b, int c, int d, int e, int f, int g, int h, int *i);
|
|
||||||
|
|
||||||
uint32_t add_in_loop(uint32_t a, uint32_t b, uint32_t iter);
|
|
||||||
|
|
||||||
int _ss_esp_tee_test_heap_malloc_write_free(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@@ -3,73 +3,69 @@ secure_services:
|
|||||||
entries:
|
entries:
|
||||||
- id: 200
|
- id: 200
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_service_add
|
function: esp_tee_test_service_add
|
||||||
args: 2
|
args: 2
|
||||||
- id: 201
|
- id: 201
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_service_sub
|
function: esp_tee_test_service_sub
|
||||||
args: 2
|
args: 2
|
||||||
- id: 202
|
- id: 202
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_service_mul
|
function: esp_tee_test_service_mul
|
||||||
args: 2
|
args: 2
|
||||||
- id: 203
|
- id: 203
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_service_div
|
function: esp_tee_test_service_div
|
||||||
args: 2
|
args: 2
|
||||||
- id: 204
|
- id: 204
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_test_timer_init
|
function: esp_tee_test_tee_intr_in_tee
|
||||||
args: 1
|
args: 0
|
||||||
- id: 205
|
- id: 205
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_secure_int_test
|
function: esp_tee_test_ree_intr_in_tee
|
||||||
args: 0
|
args: 1
|
||||||
- id: 206
|
- id: 206
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_non_secure_int_test
|
function: esp_tee_test_tee_intr_in_ree
|
||||||
args: 1
|
args: 2
|
||||||
- id: 207
|
- id: 207
|
||||||
type: custom
|
|
||||||
function: esp_tee_test_int_count
|
|
||||||
args: 1
|
|
||||||
- id: 208
|
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_test_resv_reg1_write_violation
|
function: esp_tee_test_resv_reg1_write_violation
|
||||||
args: 0
|
args: 0
|
||||||
- id: 209
|
- id: 208
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_test_resv_reg1_exec_violation
|
function: esp_tee_test_resv_reg1_exec_violation
|
||||||
args: 0
|
args: 0
|
||||||
- id: 210
|
- id: 209
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_test_iram_reg1_write_violation
|
function: esp_tee_test_iram_reg1_write_violation
|
||||||
args: 0
|
args: 0
|
||||||
- id: 211
|
- id: 210
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_test_iram_reg2_write_violation
|
function: esp_tee_test_iram_reg2_write_violation
|
||||||
args: 0
|
args: 0
|
||||||
- id: 212
|
- id: 211
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_test_dram_reg1_exec_violation
|
function: esp_tee_test_dram_reg1_exec_violation
|
||||||
args: 0
|
args: 0
|
||||||
- id: 213
|
- id: 212
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_test_dram_reg2_exec_violation
|
function: esp_tee_test_dram_reg2_exec_violation
|
||||||
args: 0
|
args: 0
|
||||||
- id: 214
|
- id: 213
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_test_illegal_instruction
|
function: esp_tee_test_illegal_instruction
|
||||||
args: 0
|
args: 0
|
||||||
|
- id: 214
|
||||||
|
type: custom
|
||||||
|
function: esp_tee_test_dummy_sec_srv
|
||||||
|
args: 9
|
||||||
- id: 215
|
- id: 215
|
||||||
type: custom
|
type: custom
|
||||||
function: dummy_secure_service
|
function: esp_tee_test_priv_mode_switch
|
||||||
args: 9
|
args: 2
|
||||||
- id: 216
|
- id: 216
|
||||||
type: custom
|
|
||||||
function: add_in_loop
|
|
||||||
args: 3
|
|
||||||
- id: 217
|
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_test_heap_malloc_write_free
|
function: esp_tee_test_heap_malloc_write_free
|
||||||
args: 0
|
args: 0
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#include "multi_heap.h"
|
#include "multi_heap.h"
|
||||||
|
|
||||||
void NOINLINE_ATTR _ss_dummy_secure_service(int a, int b, int c, int d, int e, int f, int g, int h, int *i)
|
void NOINLINE_ATTR _ss_esp_tee_test_dummy_sec_srv(int a, int b, int c, int d, int e, int f, int g, int h, int *i)
|
||||||
{
|
{
|
||||||
esp_rom_printf("Dummy secure service\n");
|
esp_rom_printf("Dummy secure service\n");
|
||||||
*i = a + b + c + d + e + f + g + h;
|
*i = a + b + c + d + e + f + g + h;
|
||||||
|
@@ -1,14 +1,14 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "secure_service_num.h"
|
#include "secure_service_num.h"
|
||||||
#include "esp_tee.h"
|
#include "esp_tee.h"
|
||||||
#include "esp_err.h"
|
#include "esp_attr.h"
|
||||||
|
|
||||||
void dummy_secure_service(int a, int b, int c, int d, int e, int f, int g, int h, int *i)
|
void NOINLINE_ATTR esp_tee_test_dummy_sec_srv(int a, int b, int c, int d, int e, int f, int g, int h, int *i)
|
||||||
{
|
{
|
||||||
esp_tee_service_call(10, SS_DUMMY_SECURE_SERVICE, a, b, c, d, e, f, g, h, i);
|
esp_tee_service_call(10, SS_ESP_TEE_TEST_DUMMY_SEC_SRV, a, b, c, d, e, f, g, h, i);
|
||||||
}
|
}
|
||||||
|
@@ -4,174 +4,168 @@
|
|||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "esp_cpu.h"
|
#include "esp_cpu.h"
|
||||||
#include "esp_log.h"
|
#include "esp_rom_sys.h"
|
||||||
#include "riscv/csr.h"
|
|
||||||
|
|
||||||
#include "hal/timer_ll.h"
|
#include "soc/soc.h"
|
||||||
#include "hal/clk_gate_ll.h"
|
#include "soc/interrupts.h"
|
||||||
|
|
||||||
#include "soc/timer_group_reg.h"
|
|
||||||
#include "soc/interrupt_matrix_reg.h"
|
#include "soc/interrupt_matrix_reg.h"
|
||||||
|
#include "soc/pcr_reg.h"
|
||||||
|
#include "hal/timer_ll.h"
|
||||||
|
|
||||||
#include "esp_tee.h"
|
#include "esp_tee.h"
|
||||||
#include "esp_tee_intr.h"
|
#include "esp_tee_intr.h"
|
||||||
#include "esp_tee_test.h"
|
#include "esp_tee_test.h"
|
||||||
|
|
||||||
#define TIMER_DIVIDER 80 // Hardware timer clock divider
|
static const char *TAG __attribute__((unused)) = "esp_tee_intr_test";
|
||||||
#define TIMER_RESOLUTION_HZ 1000000 // 1MHz resolution
|
|
||||||
#define TIMER_ALARM_PERIOD_S 0.10 // sample test interval for the first timer
|
|
||||||
|
|
||||||
/* TEE uses Group0 Timer0 */
|
/* ---------------------------------------------------- Utility functions ---------------------------------------------------- */
|
||||||
#define TEE_SECURE_GROUP 0
|
|
||||||
#define TEE_SECURE_TIMER 0
|
|
||||||
|
|
||||||
static const char *TAG = "esp_tee_intr_test";
|
#define TEST_TIMER_GROUP (0)
|
||||||
|
#define TEST_TIMER_ID (0)
|
||||||
|
#define TEST_TIMER_DIVIDER (80)
|
||||||
|
|
||||||
static timg_dev_t *timg_hw = (&TIMERG0);
|
#define TEST_TIMER_RESOLUTION_HZ (1000000ULL) // 1MHz, 1 tick = 1us
|
||||||
|
#define TIMER_ALARM_PERIOD_S (0.25f) // 250ms @ resolution 1MHz
|
||||||
|
|
||||||
uint32_t *psecure_int_count = NULL;
|
static timg_dev_t *timg_dev = TIMER_LL_GET_HW(TEST_TIMER_GROUP);
|
||||||
|
|
||||||
static void IRAM_ATTR timer_group0_isr(void *arg)
|
static void IRAM_ATTR test_timer_isr(void *arg)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "Timer ISR Handler from World %d!", esp_cpu_get_curr_privilege_level());
|
uint32_t *intr_count = (uint32_t *)arg;
|
||||||
|
*intr_count = *intr_count + 1;
|
||||||
|
esp_rom_printf("[mode: %d] Interrupt triggered (%d)\n", esp_cpu_get_curr_privilege_level(), *intr_count);
|
||||||
|
|
||||||
/* For interrupt test. */
|
/* Clear interrupt and re-enable the alarm */
|
||||||
*psecure_int_count = *psecure_int_count + 1;
|
timer_ll_clear_intr_status(timg_dev, TIMER_LL_EVENT_ALARM(TEST_TIMER_ID));
|
||||||
|
timer_ll_enable_alarm(timg_dev, TEST_TIMER_ID, true);
|
||||||
/* Clear interrupt */
|
|
||||||
timer_ll_clear_intr_status(timg_hw, TIMER_LL_EVENT_ALARM(TEE_SECURE_TIMER));
|
|
||||||
|
|
||||||
/* Re-enable the alarm. */
|
|
||||||
timer_ll_enable_alarm(timg_hw, TEE_SECURE_TIMER, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tee_timer_enable(void)
|
static void test_timer_deinit(void)
|
||||||
{
|
{
|
||||||
struct vector_desc_t timer_vd = { 0, NULL, NULL, NULL };
|
const uint32_t timer_id = TEST_TIMER_ID;
|
||||||
|
|
||||||
// init timer_vc
|
// Disable and clear timer state
|
||||||
timer_vd.source = ETS_TG0_T0_LEVEL_INTR_SOURCE;
|
timer_ll_enable_counter(timg_dev, timer_id, false);
|
||||||
timer_vd.isr = timer_group0_isr;
|
timer_ll_enable_auto_reload(timg_dev, timer_id, false);
|
||||||
|
timer_ll_enable_alarm(timg_dev, timer_id, false);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Enabling test timer from secure world");
|
timer_ll_enable_intr(timg_dev, TIMER_LL_EVENT_ALARM(timer_id), false);
|
||||||
|
timer_ll_clear_intr_status(timg_dev, TIMER_LL_EVENT_ALARM(timer_id));
|
||||||
|
|
||||||
/* Enable TG0 peripheral module */
|
// Reset the counter
|
||||||
_timer_ll_enable_bus_clock(TEE_SECURE_GROUP, true);
|
uint64_t prev_val = timer_ll_get_reload_value(timg_dev, timer_id);
|
||||||
_timer_ll_reset_register(TEE_SECURE_GROUP);
|
timer_ll_set_reload_value(timg_dev, timer_id, 0);
|
||||||
|
timer_ll_trigger_soft_reload(timg_dev, timer_id);
|
||||||
/* Stop counter, alarm, auto-reload at first place */
|
timer_ll_set_reload_value(timg_dev, timer_id, prev_val);
|
||||||
timer_ll_enable_clock(TEE_SECURE_GROUP, TEE_SECURE_TIMER, true);
|
|
||||||
timer_ll_enable_counter(timg_hw, TEE_SECURE_TIMER, false);
|
|
||||||
timer_ll_enable_auto_reload(timg_hw, TEE_SECURE_TIMER, false);
|
|
||||||
timer_ll_enable_alarm(timg_hw, TEE_SECURE_TIMER, false);
|
|
||||||
|
|
||||||
// Set clock source
|
|
||||||
timer_ll_set_clock_source(TEE_SECURE_GROUP, TEE_SECURE_TIMER, GPTIMER_CLK_SRC_DEFAULT);
|
|
||||||
timer_ll_set_clock_prescale(timg_hw, TEE_SECURE_TIMER, TIMER_DIVIDER);
|
|
||||||
|
|
||||||
// Initialize counter value to zero
|
|
||||||
timer_ll_set_reload_value(timg_hw, TEE_SECURE_TIMER, 0);
|
|
||||||
timer_ll_trigger_soft_reload(timg_hw, TEE_SECURE_TIMER);
|
|
||||||
|
|
||||||
// set counting direction
|
|
||||||
timer_ll_set_count_direction(timg_hw, TEE_SECURE_TIMER, GPTIMER_COUNT_UP);
|
|
||||||
|
|
||||||
// disable interrupt
|
|
||||||
timer_ll_enable_intr(timg_hw, TIMER_LL_EVENT_ALARM(TEE_SECURE_TIMER), false);
|
|
||||||
// clear pending interrupt event
|
|
||||||
timer_ll_clear_intr_status(timg_hw, TIMER_LL_EVENT_ALARM(TEE_SECURE_TIMER));
|
|
||||||
|
|
||||||
esp_tee_intr_register((void *)&timer_vd);
|
|
||||||
timer_ll_enable_intr(timg_hw, TIMER_LL_EVENT_ALARM(TEE_SECURE_TIMER), true);
|
|
||||||
|
|
||||||
timer_ll_set_reload_value(timg_hw, TEE_SECURE_TIMER, 0);
|
|
||||||
|
|
||||||
// enable timer interrupt
|
|
||||||
timer_ll_enable_intr(timg_hw, TIMER_LL_EVENT_ALARM(TEE_SECURE_TIMER), true);
|
|
||||||
|
|
||||||
// set timer alarm
|
|
||||||
uint64_t alarm_value = (TIMER_ALARM_PERIOD_S * TIMER_RESOLUTION_HZ);
|
|
||||||
timer_ll_set_alarm_value(timg_hw, TEE_SECURE_TIMER, alarm_value);
|
|
||||||
|
|
||||||
timer_ll_enable_auto_reload(timg_hw, TEE_SECURE_TIMER, true);
|
|
||||||
timer_ll_enable_alarm(timg_hw, TEE_SECURE_TIMER, true);
|
|
||||||
timer_ll_enable_counter(timg_hw, TEE_SECURE_TIMER, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tee_timer_disable(void)
|
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "Disabling test timer from secure world");
|
|
||||||
|
|
||||||
/* Init timer interrupt vector descriptor */
|
|
||||||
struct vector_desc_t timer_vd = { 0, NULL, NULL, NULL };
|
|
||||||
timer_vd.source = ETS_TG0_T0_LEVEL_INTR_SOURCE;
|
|
||||||
timer_vd.isr = timer_group0_isr;
|
|
||||||
|
|
||||||
|
// Deregister ISR
|
||||||
|
struct vector_desc_t timer_vd = {
|
||||||
|
.source = ETS_TG0_T0_LEVEL_INTR_SOURCE,
|
||||||
|
};
|
||||||
esp_tee_intr_deregister((void *)&timer_vd);
|
esp_tee_intr_deregister((void *)&timer_vd);
|
||||||
|
timer_ll_enable_clock(TEST_TIMER_GROUP, timer_id, false);
|
||||||
/* Disable timer */
|
|
||||||
timer_ll_enable_counter(timg_hw, TEE_SECURE_TIMER, false);
|
|
||||||
timer_ll_enable_auto_reload(timg_hw, TEE_SECURE_TIMER, false);
|
|
||||||
timer_ll_enable_alarm(timg_hw, TEE_SECURE_TIMER, false);
|
|
||||||
|
|
||||||
/* Disable and clear interrupt */
|
|
||||||
timer_ll_enable_intr(timg_hw, TIMER_LL_EVENT_ALARM(TEE_SECURE_TIMER), false);
|
|
||||||
timer_ll_clear_intr_status(timg_hw, TIMER_LL_EVENT_ALARM(TEE_SECURE_TIMER));
|
|
||||||
|
|
||||||
/* Disable TG0 peripheral module */
|
|
||||||
// periph_ll_disable_clk_set_rst(PERIPH_TIMG0_MODULE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _ss_esp_tee_test_timer_init(bool enable)
|
static void test_timer_init(volatile uint32_t *arg)
|
||||||
{
|
{
|
||||||
if (enable) {
|
const uint32_t group_id = TEST_TIMER_GROUP;
|
||||||
tee_timer_enable();
|
const uint32_t timer_id = TEST_TIMER_ID;
|
||||||
} else {
|
|
||||||
tee_timer_disable();
|
test_timer_deinit();
|
||||||
}
|
|
||||||
|
// Enable peripheral clock and reset hardware
|
||||||
|
_timer_ll_enable_bus_clock(group_id, true);
|
||||||
|
_timer_ll_reset_register(group_id);
|
||||||
|
|
||||||
|
// Select clock source and enable module clock
|
||||||
|
// Enable the default clock source PLL_F80M
|
||||||
|
REG_SET_BIT(PCR_PLL_DIV_CLK_EN_REG, PCR_PLL_80M_CLK_EN);
|
||||||
|
timer_ll_set_clock_source(group_id, timer_id, GPTIMER_CLK_SRC_DEFAULT);
|
||||||
|
timer_ll_enable_clock(group_id, timer_id, true);
|
||||||
|
timer_ll_set_clock_prescale(timg_dev, timer_id, TEST_TIMER_DIVIDER);
|
||||||
|
timer_ll_set_count_direction(timg_dev, timer_id, GPTIMER_COUNT_UP);
|
||||||
|
|
||||||
|
// Register ISR
|
||||||
|
struct vector_desc_t timer_vd = {
|
||||||
|
.source = ETS_TG0_T0_LEVEL_INTR_SOURCE,
|
||||||
|
.isr = test_timer_isr,
|
||||||
|
.arg = (void *)arg,
|
||||||
|
};
|
||||||
|
esp_tee_intr_register((void *)&timer_vd);
|
||||||
|
timer_ll_enable_intr(timg_dev, TIMER_LL_EVENT_ALARM(timer_id), true);
|
||||||
|
|
||||||
|
// Configure and enable timer alarm
|
||||||
|
timer_ll_set_alarm_value(timg_dev, timer_id, TIMER_ALARM_PERIOD_S * TEST_TIMER_RESOLUTION_HZ);
|
||||||
|
timer_ll_enable_auto_reload(timg_dev, timer_id, true);
|
||||||
|
timer_ll_enable_alarm(timg_dev, timer_id, true);
|
||||||
|
timer_ll_enable_counter(timg_dev, timer_id, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* ---------------------------------------------------- Test cases ---------------------------------------------------- */
|
||||||
* Secure interrupt in secure world test.
|
|
||||||
*/
|
uint32_t _ss_esp_tee_test_tee_intr_in_tee(void)
|
||||||
int _ss_esp_tee_secure_int_test(void)
|
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "In WORLD %d", esp_cpu_get_curr_privilege_level());
|
esp_cpu_priv_mode_t mode = esp_cpu_get_curr_privilege_level();
|
||||||
volatile uint32_t secure_int_count = 0;
|
assert((mode == ESP_CPU_S_MODE) && "Incorrect privilege mode!");
|
||||||
psecure_int_count = (uint32_t *)&secure_int_count;
|
|
||||||
|
|
||||||
_ss_esp_tee_test_timer_init(true);
|
volatile uint32_t tee_intr_count = 0;
|
||||||
while (secure_int_count < TEE_TEST_INT_COUNT);
|
test_timer_init(&tee_intr_count);
|
||||||
_ss_esp_tee_test_timer_init(false);
|
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Exiting WORLD %d", esp_cpu_get_curr_privilege_level());
|
while (tee_intr_count < ESP_TEE_TEST_INTR_ITER) {
|
||||||
return secure_int_count;
|
esp_rom_delay_us(10 * 1000U);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_timer_deinit();
|
||||||
|
|
||||||
|
mode = esp_cpu_get_curr_privilege_level();
|
||||||
|
assert((mode == ESP_CPU_S_MODE) && "Incorrect privilege mode!");
|
||||||
|
return tee_intr_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
uint32_t _ss_esp_tee_test_tee_intr_in_ree(int stage, volatile uint32_t *volatile intr_count)
|
||||||
* Non-Secure interrupt in secure world test.
|
|
||||||
*/
|
|
||||||
int _ss_esp_tee_non_secure_int_test(volatile uint32_t *volatile ns_int_count)
|
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "In WORLD %d", esp_cpu_get_curr_privilege_level());
|
esp_cpu_priv_mode_t mode = esp_cpu_get_curr_privilege_level();
|
||||||
|
assert((mode == ESP_CPU_S_MODE) && "Incorrect privilege mode!");
|
||||||
|
|
||||||
uint32_t count = 0;
|
switch (stage) {
|
||||||
count = *ns_int_count;
|
case 0:
|
||||||
|
test_timer_init(intr_count);
|
||||||
while ((*ns_int_count < TEE_TEST_INT_COUNT)) {
|
break;
|
||||||
if (*ns_int_count > count) {
|
case 1:
|
||||||
count = *ns_int_count;
|
test_timer_deinit();
|
||||||
ESP_LOGI(TAG, "Interrupt count %d", count);
|
break;
|
||||||
}
|
default:
|
||||||
|
assert(false && "Invalid stage!");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Exiting WORLD %d", esp_cpu_get_curr_privilege_level());
|
mode = esp_cpu_get_curr_privilege_level();
|
||||||
|
assert((mode == ESP_CPU_S_MODE) && "Incorrect privilege mode!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _ss_esp_tee_test_int_count(uint32_t *secure_int_count)
|
uint32_t _ss_esp_tee_test_ree_intr_in_tee(volatile uint32_t *volatile intr_count)
|
||||||
{
|
{
|
||||||
psecure_int_count = secure_int_count;
|
esp_cpu_priv_mode_t mode = esp_cpu_get_curr_privilege_level();
|
||||||
return (*psecure_int_count);
|
assert((mode == ESP_CPU_S_MODE) && "Incorrect privilege mode!");
|
||||||
|
|
||||||
|
uint32_t prev_count = 0;
|
||||||
|
while (true) {
|
||||||
|
uint32_t curr_count = *intr_count;
|
||||||
|
if (curr_count > prev_count) {
|
||||||
|
prev_count = curr_count;
|
||||||
|
esp_rom_printf("[mode: %d] Interrupt received (%d)\n", esp_cpu_get_curr_privilege_level(), curr_count);
|
||||||
|
}
|
||||||
|
if (curr_count >= ESP_TEE_TEST_INTR_ITER) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
esp_rom_delay_us(1000U);
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = esp_cpu_get_curr_privilege_level();
|
||||||
|
assert((mode == ESP_CPU_S_MODE) && "Incorrect privilege mode!");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -12,37 +12,45 @@ static const char *TAG = "test_sec_srv";
|
|||||||
|
|
||||||
/* Sample Trusted App */
|
/* Sample Trusted App */
|
||||||
|
|
||||||
uint32_t NOINLINE_ATTR _ss_esp_tee_service_add(uint32_t a, uint32_t b)
|
uint32_t NOINLINE_ATTR _ss_esp_tee_test_service_add(uint32_t a, uint32_t b)
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "SS: %s", __func__);
|
ESP_LOGD(TAG, "SS: %s", __func__);
|
||||||
return (a + b);
|
return (a + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t NOINLINE_ATTR _ss_esp_tee_service_sub(uint32_t a, uint32_t b)
|
uint32_t NOINLINE_ATTR _ss_esp_tee_test_service_sub(uint32_t a, uint32_t b)
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "SS: %s", __func__);
|
ESP_LOGD(TAG, "SS: %s", __func__);
|
||||||
return (a - b);
|
return (a - b);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t NOINLINE_ATTR _ss_esp_tee_service_mul(uint32_t a, uint32_t b)
|
uint32_t NOINLINE_ATTR _ss_esp_tee_test_service_mul(uint32_t a, uint32_t b)
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "SS: %s", __func__);
|
ESP_LOGD(TAG, "SS: %s", __func__);
|
||||||
return (a * b);
|
return (a * b);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t NOINLINE_ATTR _ss_esp_tee_service_div(uint32_t a, uint32_t b)
|
uint32_t NOINLINE_ATTR _ss_esp_tee_test_service_div(uint32_t a, uint32_t b)
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "SS: %s", __func__);
|
ESP_LOGD(TAG, "SS: %s", __func__);
|
||||||
return (a / b);
|
return (a / b);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t _ss_add_in_loop(uint32_t a, uint32_t b, uint32_t iter)
|
uint32_t _ss_esp_tee_test_priv_mode_switch(uint32_t *a, uint32_t *b)
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "SS: %s", __func__);
|
ESP_LOGD(TAG, "SS: %s", __func__);
|
||||||
for (int i = 0; i < iter; i++) {
|
|
||||||
a += b;
|
*a = 1;
|
||||||
esp_rom_delay_us(1000000);
|
*b = 1;
|
||||||
esp_rom_printf("[mode: %d] val: %d\n", esp_cpu_get_curr_privilege_level(), a);
|
|
||||||
|
uint32_t c = 0;
|
||||||
|
while (c < ESP_TEE_TEST_INTR_ITER * 2) {
|
||||||
|
c = *a + *b;
|
||||||
|
esp_rom_delay_us(500 * 1000U);
|
||||||
|
esp_rom_printf("[mode: %d] val: %d\n", esp_cpu_get_curr_privilege_level(), c);
|
||||||
|
*a += 1;
|
||||||
|
*b += 1;
|
||||||
}
|
}
|
||||||
return a;
|
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
@@ -10,8 +10,6 @@ import sys
|
|||||||
import tempfile
|
import tempfile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Dict
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
import espsecure
|
import espsecure
|
||||||
import esptool
|
import esptool
|
||||||
@@ -104,7 +102,48 @@ esp_tee_empty_bin = {
|
|||||||
0xDC, 0x60, 0x86, 0x6C, 0x37, 0x76, 0xAA, 0x30, 0x1F, 0x61, 0x48, 0x23,
|
0xDC, 0x60, 0x86, 0x6C, 0x37, 0x76, 0xAA, 0x30, 0x1F, 0x61, 0x48, 0x23,
|
||||||
0xEA, 0x34, 0xAA, 0x19, 0xE8, 0xDE, 0x04, 0x7D, 0x2A, 0x30, 0xC1, 0xDD,
|
0xEA, 0x34, 0xAA, 0x19, 0xE8, 0xDE, 0x04, 0x7D, 0x2A, 0x30, 0xC1, 0xDD,
|
||||||
0x61, 0x38, 0x9D, 0xB5, 0xCA, 0x13, 0x5A, 0x79
|
0x61, 0x38, 0x9D, 0xB5, 0xCA, 0x13, 0x5A, 0x79
|
||||||
]
|
],
|
||||||
|
'esp32c5': [
|
||||||
|
0xE9, 0x04, 0x02, 0x1F, 0x00, 0x00, 0x80, 0x40, 0xEE, 0x00, 0x00, 0x00,
|
||||||
|
0x17, 0x00, 0x00, 0x64, 0x00, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||||
|
# DROM segment
|
||||||
|
0x20, 0x00, 0x00, 0x42, 0x00, 0x02, 0x00, 0x00,
|
||||||
|
# esp_app_desc structure
|
||||||
|
0x32, 0x54, 0xCD, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x76, 0x35, 0x2E, 0x35, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x65, 0x73, 0x70, 0x5F, 0x74, 0x65, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x30, 0x30, 0x3A, 0x30, 0x30, 0x3A, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x4E, 0x6F, 0x76, 0x20, 0x31, 0x31, 0x20, 0x32,
|
||||||
|
0x30, 0x32, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x35, 0x2E, 0x35,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x2D, 0x63, 0x66, 0x8B, 0x75, 0xFA, 0x59, 0x05,
|
||||||
|
0x53, 0x34, 0x91, 0x71, 0x51, 0x33, 0x91, 0xDD, 0xF8, 0xB1, 0xFE, 0x83,
|
||||||
|
0x06, 0xEB, 0x03, 0x80, 0x45, 0xC9, 0x18, 0x20, 0x83, 0x7E, 0x2E, 0x43,
|
||||||
|
*([0x00] * 0x58),
|
||||||
|
# Padding
|
||||||
|
*([0x00] * 0x100),
|
||||||
|
# IRAM segment
|
||||||
|
0x00, 0x00, 0x80, 0x40, 0x20, 0x00, 0x00, 0x00,
|
||||||
|
*([0x00] * 0x20),
|
||||||
|
# PADDING segment
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xC8, 0x7D, 0x00, 0x00,
|
||||||
|
*([0x00] * 0x7DC8),
|
||||||
|
# IROM segment
|
||||||
|
0x20, 0x80, 0x00, 0x42, 0x00, 0x01, 0x00, 0x00,
|
||||||
|
*([0x00] * 0x100),
|
||||||
|
# Padding
|
||||||
|
*([0x00] * 0x0F),
|
||||||
|
# CRC8 checksum
|
||||||
|
0x56,
|
||||||
|
# Image SHA256
|
||||||
|
0xCD, 0xCC, 0xF2, 0xE3, 0x52, 0x76, 0xE5, 0x6D, 0xF6, 0x32, 0x95, 0x27,
|
||||||
|
0x5F, 0xF3, 0xD8, 0x90, 0xD7, 0x95, 0xA0, 0x95, 0xD5, 0xDA, 0xE7, 0xA4,
|
||||||
|
0x58, 0x08, 0x84, 0xBB, 0x8F, 0x29, 0xAB, 0xE4
|
||||||
|
],
|
||||||
}
|
}
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
@@ -233,7 +272,7 @@ class TEESerial(IdfSerial):
|
|||||||
self.flash()
|
self.flash()
|
||||||
self.custom_erase_partition('secure_storage')
|
self.custom_erase_partition('secure_storage')
|
||||||
|
|
||||||
KEY_DEFS: List[Dict[str, Any]] = [
|
KEY_DEFS: list[dict[str, Any]] = [
|
||||||
{'key': 'aes256_key0', 'type': 'aes256', 'input': None, 'write_once': True},
|
{'key': 'aes256_key0', 'type': 'aes256', 'input': None, 'write_once': True},
|
||||||
{
|
{
|
||||||
'key': 'aes256_key1',
|
'key': 'aes256_key1',
|
||||||
@@ -264,7 +303,7 @@ class TEESerial(IdfSerial):
|
|||||||
NVS_CSV_PATH = TMP_DIR / 'tee_sec_stg_val.csv'
|
NVS_CSV_PATH = TMP_DIR / 'tee_sec_stg_val.csv'
|
||||||
NVS_BIN_PATH = TMP_DIR / 'tee_sec_stg_nvs.bin'
|
NVS_BIN_PATH = TMP_DIR / 'tee_sec_stg_nvs.bin'
|
||||||
|
|
||||||
def run_command(self, command: List[str]) -> None:
|
def run_command(self, command: list[str]) -> None:
|
||||||
try:
|
try:
|
||||||
subprocess.check_call(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
subprocess.check_call(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
@@ -276,7 +315,7 @@ class TEESerial(IdfSerial):
|
|||||||
|
|
||||||
def create_tee_sec_stg_csv(self, tmp_dir: Path) -> Path:
|
def create_tee_sec_stg_csv(self, tmp_dir: Path) -> Path:
|
||||||
csv_path = self.NVS_CSV_PATH
|
csv_path = self.NVS_CSV_PATH
|
||||||
rows: List[List[str]] = [
|
rows: list[list[str]] = [
|
||||||
['key', 'type', 'encoding', 'value'],
|
['key', 'type', 'encoding', 'value'],
|
||||||
['tee_sec_stg_ns', 'namespace', '', ''],
|
['tee_sec_stg_ns', 'namespace', '', ''],
|
||||||
]
|
]
|
||||||
|
@@ -4,32 +4,46 @@
|
|||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "unity.h"
|
|
||||||
#include "esp_tee.h"
|
|
||||||
#include "secure_service_num.h"
|
|
||||||
#include "esp_tee_test.h"
|
|
||||||
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/event_groups.h"
|
||||||
|
|
||||||
|
#include "esp_cpu.h"
|
||||||
|
#include "esp_tee.h"
|
||||||
|
#include "esp_tee_test.h"
|
||||||
|
#include "secure_service_num.h"
|
||||||
|
|
||||||
|
#include "unity.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#define TEST_TASK_1_DONE_BIT (BIT0)
|
||||||
|
#define TEST_TASK_2_DONE_BIT (BIT1)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t *val;
|
||||||
|
EventBits_t done_bit;
|
||||||
|
} test_task_args_t;
|
||||||
|
|
||||||
|
static EventGroupHandle_t test_task_eg;
|
||||||
|
|
||||||
static void test_op(int sec_srv_num, uint32_t a, uint32_t b)
|
static void test_op(int sec_srv_num, uint32_t a, uint32_t b)
|
||||||
{
|
{
|
||||||
esp_cpu_priv_mode_t world = esp_cpu_get_curr_privilege_level();
|
esp_cpu_priv_mode_t mode = esp_cpu_get_curr_privilege_level();
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "Current world is not NS");
|
TEST_ASSERT_MESSAGE((mode == ESP_CPU_NS_MODE), "Incorrect privilege mode!");
|
||||||
|
|
||||||
uint32_t lval = 0;
|
uint32_t lval = 0;
|
||||||
switch (sec_srv_num) {
|
switch (sec_srv_num) {
|
||||||
case SS_ESP_TEE_SERVICE_ADD:
|
case SS_ESP_TEE_TEST_SERVICE_ADD:
|
||||||
lval = (a + b);
|
lval = (a + b);
|
||||||
break;
|
break;
|
||||||
case SS_ESP_TEE_SERVICE_SUB:
|
case SS_ESP_TEE_TEST_SERVICE_SUB:
|
||||||
lval = (a - b);
|
lval = (a - b);
|
||||||
break;
|
break;
|
||||||
case SS_ESP_TEE_SERVICE_MUL:
|
case SS_ESP_TEE_TEST_SERVICE_MUL:
|
||||||
lval = (a * b);
|
lval = (a * b);
|
||||||
break;
|
break;
|
||||||
case SS_ESP_TEE_SERVICE_DIV:
|
case SS_ESP_TEE_TEST_SERVICE_DIV:
|
||||||
lval = (a / b);
|
lval = (a / b);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -40,60 +54,94 @@ static void test_op(int sec_srv_num, uint32_t a, uint32_t b)
|
|||||||
uint32_t val = esp_tee_service_call(3, sec_srv_num, a, b);
|
uint32_t val = esp_tee_service_call(3, sec_srv_num, a, b);
|
||||||
TEST_ASSERT_EQUAL_UINT32(lval, val);
|
TEST_ASSERT_EQUAL_UINT32(lval, val);
|
||||||
|
|
||||||
world = esp_cpu_get_curr_privilege_level();
|
mode = esp_cpu_get_curr_privilege_level();
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "Sample app world switch failed");
|
TEST_ASSERT_MESSAGE((mode == ESP_CPU_NS_MODE), "Incorrect privilege mode!");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Test single calls to sample app (basic services)", "[basic]")
|
TEST_CASE("Test single calls to sample app (basic services)", "[basic]")
|
||||||
{
|
{
|
||||||
const uint32_t a = 200, b = 100;
|
const uint32_t a = 200, b = 100;
|
||||||
test_op(SS_ESP_TEE_SERVICE_ADD, a, b);
|
test_op(SS_ESP_TEE_TEST_SERVICE_ADD, a, b);
|
||||||
test_op(SS_ESP_TEE_SERVICE_SUB, a, b);
|
test_op(SS_ESP_TEE_TEST_SERVICE_SUB, a, b);
|
||||||
test_op(SS_ESP_TEE_SERVICE_MUL, a, b);
|
test_op(SS_ESP_TEE_TEST_SERVICE_MUL, a, b);
|
||||||
test_op(SS_ESP_TEE_SERVICE_DIV, a, b);
|
test_op(SS_ESP_TEE_TEST_SERVICE_DIV, a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Test multiple calls to sample app (basic services)", "[basic]")
|
TEST_CASE("Test multiple calls to sample app (basic services)", "[basic]")
|
||||||
{
|
{
|
||||||
esp_cpu_priv_mode_t world = esp_cpu_get_curr_privilege_level();
|
esp_cpu_priv_mode_t mode = esp_cpu_get_curr_privilege_level();
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "Current world is not NS");
|
TEST_ASSERT_MESSAGE((mode == ESP_CPU_NS_MODE), "Incorrect privilege mode!");
|
||||||
|
|
||||||
for (int i = 0; i < 1024; i++) {
|
for (int i = 0; i < 1024; i++) {
|
||||||
uint32_t val = esp_tee_service_call(3, SS_ESP_TEE_SERVICE_ADD, i, i + 1);
|
uint32_t val = esp_tee_service_call(3, SS_ESP_TEE_TEST_SERVICE_ADD, i, i + 1);
|
||||||
TEST_ASSERT_EQUAL_UINT32((2 * i + 1), val);
|
TEST_ASSERT_EQUAL_UINT32((2 * i + 1), val);
|
||||||
world = esp_cpu_get_curr_privilege_level();
|
mode = esp_cpu_get_curr_privilege_level();
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "Sample app world switch failed");
|
TEST_ASSERT_MESSAGE((mode == ESP_CPU_NS_MODE), "Incorrect privilege mode!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Custom secure service call", "[basic]")
|
TEST_CASE("Test custom secure service call", "[basic]")
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
dummy_secure_service(1, 2, 3, 4, 5, 6, 7, 8, &res);
|
esp_tee_test_dummy_sec_srv(1, 2, 3, 4, 5, 6, 7, 8, &res);
|
||||||
TEST_ASSERT_EQUAL_UINT32(36, res);
|
TEST_ASSERT_EQUAL_UINT32(36, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_task(void *pvParameters)
|
static void test_task(void *pvParameters)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 8; i++) {
|
test_task_args_t *args = (test_task_args_t *)pvParameters;
|
||||||
esp_rom_printf("[mode: %d] test_task - %d\n", esp_cpu_get_curr_privilege_level(), i);
|
uint32_t *val = args->val;
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
uint32_t id = args->id;
|
||||||
|
|
||||||
|
uint32_t prev_val = *val;
|
||||||
|
while (*val <= ESP_TEE_TEST_INTR_ITER) {
|
||||||
|
uint32_t curr_val = *val;
|
||||||
|
if (curr_val != prev_val) {
|
||||||
|
esp_rom_printf("[mode: %d] test_task - %d | val - %d\n", esp_cpu_get_curr_privilege_level(), id, curr_val);
|
||||||
|
prev_val = curr_val;
|
||||||
}
|
}
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
xEventGroupSetBits(test_task_eg, args->done_bit);
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Task switching during secure service calls", "[basic]")
|
TEST_CASE("Test task switching during secure service calls", "[basic]")
|
||||||
{
|
{
|
||||||
esp_cpu_priv_mode_t world = esp_cpu_get_curr_privilege_level();
|
esp_cpu_priv_mode_t mode = esp_cpu_get_curr_privilege_level();
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "Current world is not NS");
|
TEST_ASSERT_MESSAGE((mode == ESP_CPU_NS_MODE), "Incorrect privilege mode!");
|
||||||
|
|
||||||
xTaskCreate(test_task, "test_task", 4096, NULL, CONFIG_UNITY_FREERTOS_PRIORITY + 3, NULL);
|
test_task_eg = xEventGroupCreate();
|
||||||
|
TEST_ASSERT_NOT_NULL(test_task_eg);
|
||||||
|
|
||||||
const uint32_t a = 100, b = 200, iter = 8;
|
uint32_t a = 0, b = 0;
|
||||||
TEST_ASSERT_EQUAL_UINT32(a + b * iter, esp_tee_service_call(4, SS_ADD_IN_LOOP, a, b, iter));
|
|
||||||
|
|
||||||
world = esp_cpu_get_curr_privilege_level();
|
test_task_args_t task_args_1 = {
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "Current world is not NS");
|
.id = 1,
|
||||||
|
.val = &a,
|
||||||
|
.done_bit = TEST_TASK_1_DONE_BIT
|
||||||
|
};
|
||||||
|
|
||||||
|
test_task_args_t task_args_2 = {
|
||||||
|
.id = 2,
|
||||||
|
.val = &b,
|
||||||
|
.done_bit = TEST_TASK_2_DONE_BIT
|
||||||
|
};
|
||||||
|
|
||||||
|
xTaskCreate(test_task, "test_task_1", 4096, (void *)&task_args_1, CONFIG_UNITY_FREERTOS_PRIORITY + 3, NULL);
|
||||||
|
xTaskCreate(test_task, "test_task_2", 4096, (void *)&task_args_2, CONFIG_UNITY_FREERTOS_PRIORITY + 3, NULL);
|
||||||
|
|
||||||
|
uint32_t val = esp_tee_service_call(3, SS_ESP_TEE_TEST_PRIV_MODE_SWITCH, &a, &b);
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(ESP_TEE_TEST_INTR_ITER * 2, val);
|
||||||
|
|
||||||
|
EventBits_t bits = xEventGroupWaitBits(test_task_eg, TEST_TASK_1_DONE_BIT | TEST_TASK_2_DONE_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
|
||||||
|
TEST_ASSERT_MESSAGE((bits & TEST_TASK_1_DONE_BIT), "Task 1 did not complete");
|
||||||
|
TEST_ASSERT_MESSAGE((bits & TEST_TASK_2_DONE_BIT), "Task 2 did not complete");
|
||||||
|
vEventGroupDelete(test_task_eg);
|
||||||
|
|
||||||
|
mode = esp_cpu_get_curr_privilege_level();
|
||||||
|
TEST_ASSERT_MESSAGE((mode == ESP_CPU_NS_MODE), "Incorrect privilege mode!");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Test TEE Heap: Malloc-write-free cycles", "[heap]")
|
TEST_CASE("Test TEE Heap: Malloc-write-free cycles", "[heap]")
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include "ccomp_timer.h"
|
#include "ccomp_timer.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
#define BOOT_COUNT_NAMESPACE "boot_count"
|
#define BOOT_COUNT_NAMESPACE "boot_count"
|
||||||
#define TEST_PART_LABEL "custom"
|
#define TEST_PART_LABEL "custom"
|
||||||
@@ -29,6 +30,30 @@
|
|||||||
|
|
||||||
#define ESP_TEE_SEC_STG_PART_LABEL "secure_storage"
|
#define ESP_TEE_SEC_STG_PART_LABEL "secure_storage"
|
||||||
|
|
||||||
|
__attribute__((unused)) static const uint32_t mmu_op_fail_seq[8] = {[0 ... 7] = 0x0addbad0};
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
#define SOC_TEE_FLASH_OP_FAIL_FAULT 1
|
||||||
|
#else
|
||||||
|
#define SOC_TEE_FLASH_OP_FAIL_FAULT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SOC_TEE_FLASH_OP_FAIL_FAULT
|
||||||
|
#define CHECK_MMU_OP_FAIL(ptr_) do {} while (0)
|
||||||
|
#else
|
||||||
|
#define CHECK_MMU_OP_FAIL(ptr_) \
|
||||||
|
do { \
|
||||||
|
TEST_ASSERT_EQUAL_HEX8_ARRAY(mmu_op_fail_seq, (ptr_), 0x20); \
|
||||||
|
esp_restart(); \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SOC_TEE_FLASH_OP_FAIL_FAULT
|
||||||
|
#define CHECK_FLASH_OP_FAIL(err) TEST_ESP_ERR(ESP_FAIL, err)
|
||||||
|
#else
|
||||||
|
#define CHECK_FLASH_OP_FAIL(err) do { (void)(err); esp_restart(); } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char *TAG = "test_esp_tee_flash_prot";
|
static const char *TAG = "test_esp_tee_flash_prot";
|
||||||
|
|
||||||
static void set_boot_count_in_nvs(uint8_t boot_count)
|
static void set_boot_count_in_nvs(uint8_t boot_count)
|
||||||
@@ -77,6 +102,7 @@ static void test_esp_partition_mmap_api(void)
|
|||||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEE_0, NULL);
|
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEE_0, NULL);
|
||||||
TEST_ASSERT_NOT_NULL(part);
|
TEST_ASSERT_NOT_NULL(part);
|
||||||
TEST_ESP_OK(esp_partition_mmap(part, 0, part->size, ESP_PARTITION_MMAP_DATA, &outptr, &out_handle));
|
TEST_ESP_OK(esp_partition_mmap(part, 0, part->size, ESP_PARTITION_MMAP_DATA, &outptr, &out_handle));
|
||||||
|
CHECK_MMU_OP_FAIL(outptr);
|
||||||
ESP_LOG_BUFFER_HEXDUMP(TAG, outptr, 0x20, ESP_LOG_INFO);
|
ESP_LOG_BUFFER_HEXDUMP(TAG, outptr, 0x20, ESP_LOG_INFO);
|
||||||
TEST_FAIL_MESSAGE("System fault should have been generated");
|
TEST_FAIL_MESSAGE("System fault should have been generated");
|
||||||
break;
|
break;
|
||||||
@@ -84,6 +110,7 @@ static void test_esp_partition_mmap_api(void)
|
|||||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEE_1, NULL);
|
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEE_1, NULL);
|
||||||
TEST_ASSERT_NOT_NULL(part);
|
TEST_ASSERT_NOT_NULL(part);
|
||||||
TEST_ESP_OK(esp_partition_mmap(part, 0, part->size, ESP_PARTITION_MMAP_INST, &outptr, &out_handle));
|
TEST_ESP_OK(esp_partition_mmap(part, 0, part->size, ESP_PARTITION_MMAP_INST, &outptr, &out_handle));
|
||||||
|
CHECK_MMU_OP_FAIL(outptr);
|
||||||
ESP_LOG_BUFFER_HEXDUMP(TAG, outptr, 0x20, ESP_LOG_INFO);
|
ESP_LOG_BUFFER_HEXDUMP(TAG, outptr, 0x20, ESP_LOG_INFO);
|
||||||
TEST_FAIL_MESSAGE("System fault should have been generated");
|
TEST_FAIL_MESSAGE("System fault should have been generated");
|
||||||
break;
|
break;
|
||||||
@@ -91,6 +118,7 @@ static void test_esp_partition_mmap_api(void)
|
|||||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_TEE_OTA, NULL);
|
part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_TEE_OTA, NULL);
|
||||||
TEST_ASSERT_NOT_NULL(part);
|
TEST_ASSERT_NOT_NULL(part);
|
||||||
TEST_ESP_OK(esp_partition_mmap(part, 0, part->size, ESP_PARTITION_MMAP_DATA, &outptr, &out_handle));
|
TEST_ESP_OK(esp_partition_mmap(part, 0, part->size, ESP_PARTITION_MMAP_DATA, &outptr, &out_handle));
|
||||||
|
CHECK_MMU_OP_FAIL(outptr);
|
||||||
ESP_LOG_BUFFER_HEXDUMP(TAG, outptr, 0x20, ESP_LOG_INFO);
|
ESP_LOG_BUFFER_HEXDUMP(TAG, outptr, 0x20, ESP_LOG_INFO);
|
||||||
TEST_FAIL_MESSAGE("System fault should have been generated");
|
TEST_FAIL_MESSAGE("System fault should have been generated");
|
||||||
break;
|
break;
|
||||||
@@ -98,6 +126,7 @@ static void test_esp_partition_mmap_api(void)
|
|||||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, ESP_TEE_SEC_STG_PART_LABEL);
|
part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, ESP_TEE_SEC_STG_PART_LABEL);
|
||||||
TEST_ASSERT_NOT_NULL(part);
|
TEST_ASSERT_NOT_NULL(part);
|
||||||
TEST_ESP_OK(esp_partition_mmap(part, 0, part->size, ESP_PARTITION_MMAP_DATA, &outptr, &out_handle));
|
TEST_ESP_OK(esp_partition_mmap(part, 0, part->size, ESP_PARTITION_MMAP_DATA, &outptr, &out_handle));
|
||||||
|
CHECK_MMU_OP_FAIL(outptr);
|
||||||
ESP_LOG_BUFFER_HEXDUMP(TAG, outptr, 0x20, ESP_LOG_INFO);
|
ESP_LOG_BUFFER_HEXDUMP(TAG, outptr, 0x20, ESP_LOG_INFO);
|
||||||
TEST_FAIL_MESSAGE("System fault should have been generated");
|
TEST_FAIL_MESSAGE("System fault should have been generated");
|
||||||
break;
|
break;
|
||||||
@@ -117,7 +146,8 @@ static void test_esp_partition_api_r(const esp_partition_t *part)
|
|||||||
TEST_ASSERT_NOT_NULL(part);
|
TEST_ASSERT_NOT_NULL(part);
|
||||||
uint8_t buf_r[128];
|
uint8_t buf_r[128];
|
||||||
memset(buf_r, 0x00, sizeof(buf_r));
|
memset(buf_r, 0x00, sizeof(buf_r));
|
||||||
TEST_ESP_ERR(ESP_FAIL, esp_partition_read(part, 0x00, buf_r, sizeof(buf_r)));
|
esp_err_t err = esp_partition_read(part, 0x00, buf_r, sizeof(buf_r));
|
||||||
|
CHECK_FLASH_OP_FAIL(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_esp_partition_api_w(const esp_partition_t *part)
|
static void test_esp_partition_api_w(const esp_partition_t *part)
|
||||||
@@ -125,13 +155,15 @@ static void test_esp_partition_api_w(const esp_partition_t *part)
|
|||||||
TEST_ASSERT_NOT_NULL(part);
|
TEST_ASSERT_NOT_NULL(part);
|
||||||
uint8_t buf_w[128];
|
uint8_t buf_w[128];
|
||||||
memset(buf_w, 0xA5, sizeof(buf_w));
|
memset(buf_w, 0xA5, sizeof(buf_w));
|
||||||
TEST_ESP_ERR(ESP_FAIL, esp_partition_write(part, 0x00, buf_w, sizeof(buf_w)));
|
esp_err_t err = esp_partition_write(part, 0x00, buf_w, sizeof(buf_w));
|
||||||
|
CHECK_FLASH_OP_FAIL(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_esp_partition_api_e(const esp_partition_t *part)
|
static void test_esp_partition_api_e(const esp_partition_t *part)
|
||||||
{
|
{
|
||||||
TEST_ASSERT_NOT_NULL(part);
|
TEST_ASSERT_NOT_NULL(part);
|
||||||
TEST_ESP_ERR(ESP_FAIL, esp_partition_erase_range(part, 0x00, SPI_FLASH_SEC_SIZE));
|
esp_err_t err = esp_partition_erase_range(part, 0x00, SPI_FLASH_SEC_SIZE);
|
||||||
|
CHECK_FLASH_OP_FAIL(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_esp_partition_api(void)
|
static void test_esp_partition_api(void)
|
||||||
@@ -188,6 +220,7 @@ static void test_spi_flash_mmap_api(void)
|
|||||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEE_0, NULL);
|
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEE_0, NULL);
|
||||||
TEST_ASSERT_NOT_NULL(part);
|
TEST_ASSERT_NOT_NULL(part);
|
||||||
TEST_ESP_OK(spi_flash_mmap(part->address, part->size, SPI_FLASH_MMAP_DATA, &ptr, &handle));
|
TEST_ESP_OK(spi_flash_mmap(part->address, part->size, SPI_FLASH_MMAP_DATA, &ptr, &handle));
|
||||||
|
CHECK_MMU_OP_FAIL(ptr);
|
||||||
ESP_LOG_BUFFER_HEXDUMP(TAG, ptr, 0x20, ESP_LOG_INFO);
|
ESP_LOG_BUFFER_HEXDUMP(TAG, ptr, 0x20, ESP_LOG_INFO);
|
||||||
TEST_FAIL_MESSAGE("System fault should have been generated");
|
TEST_FAIL_MESSAGE("System fault should have been generated");
|
||||||
break;
|
break;
|
||||||
@@ -195,6 +228,7 @@ static void test_spi_flash_mmap_api(void)
|
|||||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEE_1, NULL);
|
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEE_1, NULL);
|
||||||
TEST_ASSERT_NOT_NULL(part);
|
TEST_ASSERT_NOT_NULL(part);
|
||||||
TEST_ESP_OK(spi_flash_mmap(part->address, part->size, SPI_FLASH_MMAP_INST, &ptr, &handle));
|
TEST_ESP_OK(spi_flash_mmap(part->address, part->size, SPI_FLASH_MMAP_INST, &ptr, &handle));
|
||||||
|
CHECK_MMU_OP_FAIL(ptr);
|
||||||
ESP_LOG_BUFFER_HEXDUMP(TAG, ptr, 0x20, ESP_LOG_INFO);
|
ESP_LOG_BUFFER_HEXDUMP(TAG, ptr, 0x20, ESP_LOG_INFO);
|
||||||
TEST_FAIL_MESSAGE("System fault should have been generated");
|
TEST_FAIL_MESSAGE("System fault should have been generated");
|
||||||
break;
|
break;
|
||||||
@@ -202,6 +236,7 @@ static void test_spi_flash_mmap_api(void)
|
|||||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_TEE_OTA, NULL);
|
part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_TEE_OTA, NULL);
|
||||||
TEST_ASSERT_NOT_NULL(part);
|
TEST_ASSERT_NOT_NULL(part);
|
||||||
TEST_ESP_OK(spi_flash_mmap(part->address, part->size, SPI_FLASH_MMAP_DATA, &ptr, &handle));
|
TEST_ESP_OK(spi_flash_mmap(part->address, part->size, SPI_FLASH_MMAP_DATA, &ptr, &handle));
|
||||||
|
CHECK_MMU_OP_FAIL(ptr);
|
||||||
ESP_LOG_BUFFER_HEXDUMP(TAG, ptr, 0x20, ESP_LOG_INFO);
|
ESP_LOG_BUFFER_HEXDUMP(TAG, ptr, 0x20, ESP_LOG_INFO);
|
||||||
TEST_FAIL_MESSAGE("System fault should have been generated");
|
TEST_FAIL_MESSAGE("System fault should have been generated");
|
||||||
break;
|
break;
|
||||||
@@ -222,19 +257,22 @@ static void test_esp_flash_api_r(uint32_t paddr)
|
|||||||
{
|
{
|
||||||
uint8_t buf_r[128];
|
uint8_t buf_r[128];
|
||||||
memset(buf_r, 0x00, sizeof(buf_r));
|
memset(buf_r, 0x00, sizeof(buf_r));
|
||||||
TEST_ESP_ERR(ESP_FAIL, esp_flash_read(NULL, buf_r, paddr, sizeof(buf_r)));
|
esp_err_t err = esp_flash_read(NULL, buf_r, paddr, sizeof(buf_r));
|
||||||
|
CHECK_FLASH_OP_FAIL(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_esp_flash_api_w(uint32_t paddr)
|
static void test_esp_flash_api_w(uint32_t paddr)
|
||||||
{
|
{
|
||||||
uint8_t buf_w[128];
|
uint8_t buf_w[128];
|
||||||
memset(buf_w, 0xA5, sizeof(buf_w));
|
memset(buf_w, 0xA5, sizeof(buf_w));
|
||||||
TEST_ESP_ERR(ESP_FAIL, esp_flash_write(NULL, buf_w, paddr, sizeof(buf_w)));
|
esp_err_t err = esp_flash_write(NULL, buf_w, paddr, sizeof(buf_w));
|
||||||
|
CHECK_FLASH_OP_FAIL(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_esp_flash_api_e(uint32_t paddr)
|
static void test_esp_flash_api_e(uint32_t paddr)
|
||||||
{
|
{
|
||||||
TEST_ESP_ERR(ESP_FAIL, esp_flash_erase_region(NULL, paddr, SPI_FLASH_SEC_SIZE));
|
esp_err_t err = esp_flash_erase_region(NULL, paddr, SPI_FLASH_SEC_SIZE);
|
||||||
|
CHECK_FLASH_OP_FAIL(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_esp_flash_api(void)
|
static void test_esp_flash_api(void)
|
||||||
|
@@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -17,90 +17,47 @@
|
|||||||
|
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
|
|
||||||
static const char *TAG = "test_esp_tee_intr";
|
#define TEST_TIMER_RESOLUTION_HZ (1000000ULL) // 1MHz, 1 tick = 1us
|
||||||
|
#define TIMER_ALARM_PERIOD_S (0.25f) // 250ms @ resolution 1MHz
|
||||||
|
|
||||||
|
static const char __attribute__((unused)) *TAG = "test_esp_tee_intr";
|
||||||
|
|
||||||
/* ---------------------------------------------------- Utility functions ---------------------------------------------------- */
|
/* ---------------------------------------------------- Utility functions ---------------------------------------------------- */
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint64_t event_count;
|
|
||||||
} test_queue_element_t;
|
|
||||||
|
|
||||||
static QueueHandle_t s_timer_queue;
|
|
||||||
|
|
||||||
static gptimer_handle_t gptimer = NULL;
|
static gptimer_handle_t gptimer = NULL;
|
||||||
|
|
||||||
static volatile uint32_t ns_int_count;
|
|
||||||
|
|
||||||
static bool IRAM_ATTR test_timer_on_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
|
static bool IRAM_ATTR test_timer_on_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
|
||||||
{
|
{
|
||||||
ESP_EARLY_LOGI(TAG, "Timer ISR Handler from World %d!", esp_cpu_get_curr_privilege_level());
|
uint32_t *intr_count = (uint32_t *)user_data;
|
||||||
|
*intr_count = *intr_count + 1;
|
||||||
BaseType_t high_task_awoken = pdFALSE;
|
esp_rom_printf("[mode: %d] Interrupt triggered (%d)\n", esp_cpu_get_curr_privilege_level(), *intr_count);
|
||||||
QueueHandle_t queue = (QueueHandle_t)user_data;
|
return true;
|
||||||
// Retrieve count value and send to queue
|
|
||||||
test_queue_element_t ele = {
|
|
||||||
.event_count = edata->count_value
|
|
||||||
};
|
|
||||||
ns_int_count += 1;
|
|
||||||
|
|
||||||
xQueueSendFromISR(queue, &ele, &high_task_awoken);
|
|
||||||
// return whether we need to yield at the end of ISR
|
|
||||||
return (high_task_awoken == pdTRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IRAM_ATTR timer_evt_task(void *arg)
|
static void test_timer_init(volatile uint32_t *arg)
|
||||||
{
|
{
|
||||||
int record = 3;
|
|
||||||
while (1) {
|
|
||||||
test_queue_element_t ele;
|
|
||||||
if (xQueueReceive(s_timer_queue, &ele, pdMS_TO_TICKS(2000))) {
|
|
||||||
ESP_LOGI(TAG, "Timer reloaded, count=%llu", ele.event_count);
|
|
||||||
record--;
|
|
||||||
} else {
|
|
||||||
ESP_LOGW(TAG, "Missed one count event");
|
|
||||||
}
|
|
||||||
if (!record) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_timer_init(bool for_ns_world)
|
|
||||||
{
|
|
||||||
s_timer_queue = xQueueCreate(10, sizeof(test_queue_element_t));
|
|
||||||
if (!s_timer_queue) {
|
|
||||||
ESP_LOGE(TAG, "Creating queue failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ns_int_count = 0;
|
|
||||||
|
|
||||||
/* Select and initialize basic parameters of the timer */
|
/* Select and initialize basic parameters of the timer */
|
||||||
gptimer_config_t timer_config = {
|
gptimer_config_t timer_config = {
|
||||||
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
|
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
|
||||||
.direction = GPTIMER_COUNT_UP,
|
.direction = GPTIMER_COUNT_UP,
|
||||||
.resolution_hz = 1000000, // 1MHz, 1 tick=1us
|
.resolution_hz = TEST_TIMER_RESOLUTION_HZ,
|
||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));
|
ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));
|
||||||
|
|
||||||
gptimer_event_callbacks_t cbs = {
|
gptimer_event_callbacks_t cbs = {
|
||||||
.on_alarm = test_timer_on_alarm_cb,
|
.on_alarm = test_timer_on_alarm_cb,
|
||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, s_timer_queue));
|
ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, (void *)arg));
|
||||||
|
|
||||||
ESP_ERROR_CHECK(gptimer_enable(gptimer));
|
ESP_ERROR_CHECK(gptimer_enable(gptimer));
|
||||||
|
|
||||||
gptimer_alarm_config_t alarm_config2 = {
|
gptimer_alarm_config_t alarm_config2 = {
|
||||||
.reload_count = 0,
|
.reload_count = 0,
|
||||||
.alarm_count = 250000, // Alarm target = 250ms @ resolution 1MHz
|
.alarm_count = TIMER_ALARM_PERIOD_S * TEST_TIMER_RESOLUTION_HZ,
|
||||||
.flags.auto_reload_on_alarm = true,
|
.flags.auto_reload_on_alarm = true,
|
||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config2));
|
ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config2));
|
||||||
ESP_ERROR_CHECK(gptimer_start(gptimer));
|
ESP_ERROR_CHECK(gptimer_start(gptimer));
|
||||||
|
|
||||||
if (for_ns_world) {
|
|
||||||
timer_evt_task(NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_timer_deinit(void)
|
static void test_timer_deinit(void)
|
||||||
@@ -108,109 +65,80 @@ static void test_timer_deinit(void)
|
|||||||
ESP_ERROR_CHECK(gptimer_stop(gptimer));
|
ESP_ERROR_CHECK(gptimer_stop(gptimer));
|
||||||
ESP_ERROR_CHECK(gptimer_disable(gptimer));
|
ESP_ERROR_CHECK(gptimer_disable(gptimer));
|
||||||
ESP_ERROR_CHECK(gptimer_del_timer(gptimer));
|
ESP_ERROR_CHECK(gptimer_del_timer(gptimer));
|
||||||
|
|
||||||
if (s_timer_queue != NULL) {
|
|
||||||
vQueueDelete(s_timer_queue);
|
|
||||||
s_timer_queue = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------- Test cases ---------------------------------------------------- */
|
/* ---------------------------------------------------- Test cases ---------------------------------------------------- */
|
||||||
|
|
||||||
TEST_CASE("Test Secure interrupt in Non-Secure World", "[basic]")
|
TEST_CASE("Test TEE interrupt in TEE", "[basic]")
|
||||||
{
|
{
|
||||||
esp_cpu_priv_mode_t world = esp_cpu_get_curr_privilege_level();
|
esp_cpu_priv_mode_t mode = esp_cpu_get_curr_privilege_level();
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "Current world is not NS");
|
TEST_ASSERT_MESSAGE((mode == ESP_CPU_NS_MODE), "Incorrect privilege mode!");
|
||||||
|
|
||||||
volatile uint32_t lsecure_int_count = 0;
|
uint32_t val = esp_tee_service_call(1, SS_ESP_TEE_TEST_TEE_INTR_IN_TEE);
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(ESP_TEE_TEST_INTR_ITER, val);
|
||||||
|
|
||||||
/* Pass the variable to secure world to record the interrupt count. */
|
mode = esp_cpu_get_curr_privilege_level();
|
||||||
esp_tee_service_call(2, SS_ESP_TEE_TEST_INT_COUNT, &lsecure_int_count);
|
TEST_ASSERT_MESSAGE((mode == ESP_CPU_NS_MODE), "Incorrect privilege mode!");
|
||||||
world = esp_cpu_get_curr_privilege_level();
|
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "World switch failed");
|
|
||||||
|
|
||||||
esp_tee_service_call(2, SS_ESP_TEE_TEST_TIMER_INIT, true);
|
|
||||||
world = esp_cpu_get_curr_privilege_level();
|
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "World switch failed");
|
|
||||||
|
|
||||||
/* Secure timer initialized.
|
|
||||||
* As secure timer interrupt will fire; CPU will switch to secure world.
|
|
||||||
* Secure world ISR handler will be called, Secure ISR log can be observed on console.
|
|
||||||
* After handling the secure interrupt, CPU will return to non-secure world
|
|
||||||
* and resume this loop and wait for the next secure timer interrupt.
|
|
||||||
* CPU will wait for TEE_TEST_INT_COUNT number of secure interrupts.
|
|
||||||
*/
|
|
||||||
while (lsecure_int_count < TEE_TEST_INT_COUNT);
|
|
||||||
|
|
||||||
/* After waiting for TEE_TEST_INT_COUNT secure interrupt,
|
|
||||||
* disable the secure timer and assert the test status.
|
|
||||||
*/
|
|
||||||
esp_tee_service_call(2, SS_ESP_TEE_TEST_TIMER_INIT, false);
|
|
||||||
world = esp_cpu_get_curr_privilege_level();
|
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "World switch failed");
|
|
||||||
|
|
||||||
/* Assert the number of secure interrupt occurred again. */
|
|
||||||
TEST_ASSERT_EQUAL_UINT32(TEE_TEST_INT_COUNT, lsecure_int_count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Test Secure interrupt in Secure World", "[basic]")
|
TEST_CASE("Test REE interrupt in REE", "[basic]")
|
||||||
{
|
{
|
||||||
esp_cpu_priv_mode_t world = esp_cpu_get_curr_privilege_level();
|
esp_cpu_priv_mode_t mode = esp_cpu_get_curr_privilege_level();
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "Current world is not NS");
|
TEST_ASSERT_MESSAGE((mode == ESP_CPU_NS_MODE), "Incorrect privilege mode!");
|
||||||
|
|
||||||
uint32_t cnt = esp_tee_service_call(1, SS_ESP_TEE_SECURE_INT_TEST);
|
volatile uint32_t ree_intr_count = 0;
|
||||||
TEST_ASSERT_EQUAL_UINT32(TEE_TEST_INT_COUNT, cnt);
|
test_timer_init(&ree_intr_count);
|
||||||
|
while (ree_intr_count < ESP_TEE_TEST_INTR_ITER) {
|
||||||
world = esp_cpu_get_curr_privilege_level();
|
vTaskDelay(pdMS_TO_TICKS(250));
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "World switch failed");
|
}
|
||||||
|
test_timer_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
static volatile uint32_t *get_ns_int_count(void)
|
TEST_CASE("Test REE interrupt in TEE", "[basic]")
|
||||||
{
|
{
|
||||||
return &ns_int_count;
|
esp_cpu_priv_mode_t mode = esp_cpu_get_curr_privilege_level();
|
||||||
}
|
TEST_ASSERT_MESSAGE((mode == ESP_CPU_NS_MODE), "Incorrect privilege mode!");
|
||||||
|
|
||||||
TEST_CASE("Test Non-secure interrupt in Secure World", "[basic]")
|
volatile uint32_t ree_intr_count = 0;
|
||||||
{
|
volatile uint32_t *volatile ree_intr_count_ptr = &ree_intr_count;
|
||||||
esp_cpu_priv_mode_t world = esp_cpu_get_curr_privilege_level();
|
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "Current world is not W1");
|
|
||||||
|
|
||||||
/* Non-secure world timer initialization. */
|
test_timer_init(ree_intr_count_ptr);
|
||||||
ESP_LOGI(TAG, "Enabling test timer from non-secure world");
|
|
||||||
test_timer_init(false);
|
|
||||||
|
|
||||||
volatile uint32_t *volatile lns_int_count;
|
uint32_t val = esp_tee_service_call(2, SS_ESP_TEE_TEST_REE_INTR_IN_TEE, ree_intr_count_ptr);
|
||||||
lns_int_count = get_ns_int_count();
|
|
||||||
|
|
||||||
/* After non-secure timer initialization,
|
|
||||||
* CPU will switch to secure world by using a service call to test API.
|
|
||||||
* CPU will wait in finite loop in secure world.
|
|
||||||
* And as non-secure timer interrupt fires, CPU will switch to non-secure world.
|
|
||||||
* Non-secure world ISR handler will be called, non-secure ISR log can be obsereved on console.
|
|
||||||
* After handling the interrupt in non-secure world, CPU will switch back to secure world
|
|
||||||
* and wait for the next timer interrupt.
|
|
||||||
* In secure world CPU will wait for TEE_TEST_INT_COUNT non-secure interrupts.
|
|
||||||
*/
|
|
||||||
uint32_t val = esp_tee_service_call(2, SS_ESP_TEE_NON_SECURE_INT_TEST, lns_int_count);
|
|
||||||
TEST_ASSERT_EQUAL_UINT32(0, val);
|
TEST_ASSERT_EQUAL_UINT32(0, val);
|
||||||
|
|
||||||
world = esp_cpu_get_curr_privilege_level();
|
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "World switch failed");
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Disabling test timer from non-secure world");
|
|
||||||
test_timer_deinit();
|
test_timer_deinit();
|
||||||
|
|
||||||
|
mode = esp_cpu_get_curr_privilege_level();
|
||||||
|
TEST_ASSERT_MESSAGE((mode == ESP_CPU_NS_MODE), "Incorrect privilege mode!");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Test Non-secure interrupt in Non-Secure World", "[basic]")
|
TEST_CASE("Test TEE interrupt in REE", "[basic]")
|
||||||
{
|
{
|
||||||
esp_cpu_priv_mode_t world = esp_cpu_get_curr_privilege_level();
|
esp_cpu_priv_mode_t mode = esp_cpu_get_curr_privilege_level();
|
||||||
TEST_ASSERT_MESSAGE((world == ESP_CPU_NS_MODE), "Current world is not NS");
|
TEST_ASSERT_MESSAGE((mode == ESP_CPU_NS_MODE), "Incorrect privilege mode!");
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Enabling test timer from non-secure world");
|
volatile uint32_t tee_intr_count = 0;
|
||||||
test_timer_init(true);
|
volatile uint32_t *volatile tee_intr_count_ptr = &tee_intr_count;
|
||||||
|
esp_tee_service_call(3, SS_ESP_TEE_TEST_TEE_INTR_IN_REE, 0, tee_intr_count_ptr);
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
uint32_t prev_count = 0;
|
||||||
|
while (true) {
|
||||||
|
uint32_t curr_count = *tee_intr_count_ptr;
|
||||||
|
if (curr_count > prev_count) {
|
||||||
|
prev_count = curr_count;
|
||||||
|
esp_rom_printf("[mode: %d] Interrupt received (%d)\n", esp_cpu_get_curr_privilege_level(), curr_count);
|
||||||
|
}
|
||||||
|
if (curr_count >= ESP_TEE_TEST_INTR_ITER) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1));
|
||||||
|
}
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Disabling test timer from non-secure world");
|
esp_tee_service_call(3, SS_ESP_TEE_TEST_TEE_INTR_IN_REE, 1, NULL);
|
||||||
test_timer_deinit();
|
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(ESP_TEE_TEST_INTR_ITER, tee_intr_count);
|
||||||
|
|
||||||
|
mode = esp_cpu_get_curr_privilege_level();
|
||||||
|
TEST_ASSERT_MESSAGE((mode == ESP_CPU_NS_MODE), "Incorrect privilege mode!");
|
||||||
}
|
}
|
||||||
|
@@ -35,102 +35,117 @@ extern uint32_t _instruction_reserved_start;
|
|||||||
#define TEST_APM_EFUSE_PROT_REG EFUSE_RD_KEY5_DATA0_REG
|
#define TEST_APM_EFUSE_PROT_REG EFUSE_RD_KEY5_DATA0_REG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST_CASE("Test APM violation interrupt: eFuse", "[apm_violation]")
|
TEST_CASE("Test APM violation: eFuse", "[apm_violation]")
|
||||||
{
|
{
|
||||||
uint32_t val = UINT32_MAX;
|
uint32_t val = UINT32_MAX;
|
||||||
val = REG_READ(TEST_APM_EFUSE_PROT_REG);
|
val = REG_READ(TEST_APM_EFUSE_PROT_REG);
|
||||||
TEST_ASSERT_EQUAL(0, val);
|
TEST_ASSERT_EQUAL(0, val);
|
||||||
TEST_FAIL_MESSAGE("APM violation interrupt should have been generated");
|
TEST_FAIL_MESSAGE("APM violation should have been generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Test APM violation interrupt: MMU", "[apm_violation]")
|
TEST_CASE("Test APM violation: MMU", "[apm_violation]")
|
||||||
{
|
{
|
||||||
uint32_t val = UINT32_MAX;
|
uint32_t val = UINT32_MAX;
|
||||||
REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), SOC_MMU_ENTRY_NUM - 2);
|
REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), SOC_MMU_ENTRY_NUM - 2);
|
||||||
val = REG_READ(SPI_MEM_MMU_ITEM_CONTENT_REG(0));
|
val = REG_READ(SPI_MEM_MMU_ITEM_CONTENT_REG(0));
|
||||||
TEST_ASSERT_EQUAL(0, val);
|
TEST_ASSERT_EQUAL(0, val);
|
||||||
TEST_FAIL_MESSAGE("APM violation interrupt should have been generated");
|
TEST_FAIL_MESSAGE("APM violation should have been generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Test APM violation interrupt: AES", "[apm_violation]")
|
TEST_CASE("Test APM violation: AES", "[apm_violation]")
|
||||||
{
|
{
|
||||||
uint32_t val = UINT32_MAX;
|
uint32_t val = UINT32_MAX;
|
||||||
val = REG_READ(AES_KEY_2_REG);
|
val = REG_READ(AES_KEY_2_REG);
|
||||||
TEST_ASSERT_EQUAL(0, val);
|
TEST_ASSERT_EQUAL(0, val);
|
||||||
TEST_FAIL_MESSAGE("APM violation interrupt should have been generated");
|
TEST_FAIL_MESSAGE("APM violation should have been generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Test APM violation interrupt: HMAC", "[apm_violation]")
|
TEST_CASE("Test APM violation: HMAC", "[apm_violation]")
|
||||||
{
|
{
|
||||||
uint32_t val = UINT32_MAX;
|
uint32_t val = UINT32_MAX;
|
||||||
val = REG_READ(HMAC_SET_PARA_KEY_REG);
|
val = REG_READ(HMAC_SET_PARA_KEY_REG);
|
||||||
TEST_ASSERT_EQUAL(0, val);
|
TEST_ASSERT_EQUAL(0, val);
|
||||||
TEST_FAIL_MESSAGE("APM violation interrupt should have been generated");
|
TEST_FAIL_MESSAGE("APM violation should have been generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Test APM violation interrupt: DS", "[apm_violation]")
|
TEST_CASE("Test APM violation: DS", "[apm_violation]")
|
||||||
{
|
{
|
||||||
uint32_t val = UINT32_MAX;
|
uint32_t val = UINT32_MAX;
|
||||||
val = REG_READ(DS_Z_MEM);
|
val = REG_READ(DS_Z_MEM);
|
||||||
TEST_ASSERT_EQUAL(0, val);
|
TEST_ASSERT_EQUAL(0, val);
|
||||||
TEST_FAIL_MESSAGE("APM violation interrupt should have been generated");
|
TEST_FAIL_MESSAGE("APM violation should have been generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Test APM violation interrupt: SHA PCR", "[apm_violation]")
|
TEST_CASE("Test APM violation: SHA PCR", "[apm_violation]")
|
||||||
{
|
{
|
||||||
uint32_t val = 0;
|
uint32_t val = 0;
|
||||||
REG_WRITE(PCR_SHA_CONF_REG, val);
|
REG_WRITE(PCR_SHA_CONF_REG, val);
|
||||||
TEST_FAIL_MESSAGE("APM violation interrupt should have been generated");
|
TEST_FAIL_MESSAGE("APM violation should have been generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Test APM violation interrupt: ECC PCR", "[apm_violation]")
|
TEST_CASE("Test APM violation: ECC PCR", "[apm_violation]")
|
||||||
{
|
{
|
||||||
uint32_t val = 0;
|
uint32_t val = 0;
|
||||||
REG_WRITE(PCR_ECC_CONF_REG, val);
|
REG_WRITE(PCR_ECC_CONF_REG, val);
|
||||||
TEST_FAIL_MESSAGE("APM violation interrupt should have been generated");
|
TEST_FAIL_MESSAGE("APM violation should have been generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TEE IRAM: Reserved/Vector-table boundary */
|
// NOTE: For C6/H2, SWDT and BOD are protected using PMP, thus this test
|
||||||
TEST_CASE("Test TEE-TEE violation: IRAM (W1)", "[exception]")
|
// generates a store access fault instead of APM violation
|
||||||
|
TEST_CASE("Test APM violation: SWDT/BOD", "[exception]")
|
||||||
{
|
{
|
||||||
esp_tee_service_call(1, SS_ESP_TEE_TEST_IRAM_REG1_WRITE_VIOLATION);
|
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
REG_WRITE(LP_ANALOG_PERI_LP_ANA_FIB_ENABLE_REG, 0);
|
||||||
|
#else
|
||||||
|
REG_WRITE(LP_ANA_FIB_ENABLE_REG, 0);
|
||||||
|
#endif
|
||||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Illegal memory space: Write */
|
/* Illegal memory space: Write */
|
||||||
TEST_CASE("Test TEE-TEE violation: Reserved (W1)", "[exception]")
|
TEST_CASE("Test TEE-TEE violation: Reserved-W1", "[exception]")
|
||||||
{
|
{
|
||||||
esp_tee_service_call(1, SS_ESP_TEE_TEST_RESV_REG1_WRITE_VIOLATION);
|
esp_tee_service_call(1, SS_ESP_TEE_TEST_RESV_REG1_WRITE_VIOLATION);
|
||||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Illegal memory space: Execution */
|
/* Illegal memory space: Execution */
|
||||||
TEST_CASE("Test TEE-TEE violation: Reserved (X1)", "[exception]")
|
TEST_CASE("Test TEE-TEE violation: Reserved-X1", "[exception]")
|
||||||
{
|
{
|
||||||
esp_tee_service_call(1, SS_ESP_TEE_TEST_RESV_REG1_EXEC_VIOLATION);
|
esp_tee_service_call(1, SS_ESP_TEE_TEST_RESV_REG1_EXEC_VIOLATION);
|
||||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
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]")
|
||||||
|
{
|
||||||
|
esp_tee_service_call(1, SS_ESP_TEE_TEST_IRAM_REG1_WRITE_VIOLATION);
|
||||||
|
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||||
|
}
|
||||||
|
|
||||||
/* TEE IRAM: Vector table region */
|
/* TEE IRAM: Vector table region */
|
||||||
TEST_CASE("Test TEE-TEE violation: IRAM (W2)", "[exception]")
|
TEST_CASE("Test TEE-TEE violation: IRAM-W2", "[exception]")
|
||||||
{
|
{
|
||||||
esp_tee_service_call(1, SS_ESP_TEE_TEST_IRAM_REG2_WRITE_VIOLATION);
|
esp_tee_service_call(1, SS_ESP_TEE_TEST_IRAM_REG2_WRITE_VIOLATION);
|
||||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TEE DRAM: Stack region */
|
/* TEE DRAM: Stack region */
|
||||||
TEST_CASE("Test TEE-TEE violation: DRAM (X1)", "[exception]")
|
TEST_CASE("Test TEE-TEE violation: DRAM-X1", "[exception]")
|
||||||
{
|
{
|
||||||
esp_tee_service_call(1, SS_ESP_TEE_TEST_DRAM_REG1_EXEC_VIOLATION);
|
esp_tee_service_call(1, SS_ESP_TEE_TEST_DRAM_REG1_EXEC_VIOLATION);
|
||||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TEE DRAM: Heap region */
|
/* TEE DRAM: Heap region */
|
||||||
TEST_CASE("Test TEE-TEE violation: DRAM (X2)", "[exception]")
|
TEST_CASE("Test TEE-TEE violation: DRAM-X2", "[exception]")
|
||||||
{
|
{
|
||||||
esp_tee_service_call(1, SS_ESP_TEE_TEST_DRAM_REG2_EXEC_VIOLATION);
|
esp_tee_service_call(1, SS_ESP_TEE_TEST_DRAM_REG2_EXEC_VIOLATION);
|
||||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Illegal Instruction */
|
/* Illegal Instruction */
|
||||||
TEST_CASE("Test TEE-TEE violation: Illegal Instruction", "[exception]")
|
TEST_CASE("Test TEE-TEE violation: Illegal Instruction", "[exception]")
|
||||||
@@ -140,7 +155,7 @@ TEST_CASE("Test TEE-TEE violation: Illegal Instruction", "[exception]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TEE DRAM -REE IRAM Boundary */
|
/* TEE DRAM -REE IRAM Boundary */
|
||||||
TEST_CASE("Test REE-TEE isolation: DRAM (R1)", "[exception]")
|
TEST_CASE("Test REE-TEE isolation: DRAM-R1", "[exception]")
|
||||||
{
|
{
|
||||||
uint32_t* val = (uint32_t *)(&_iram_start - 0x04);
|
uint32_t* val = (uint32_t *)(&_iram_start - 0x04);
|
||||||
TEST_ASSERT_EQUAL(0, *val);
|
TEST_ASSERT_EQUAL(0, *val);
|
||||||
@@ -148,14 +163,14 @@ TEST_CASE("Test REE-TEE isolation: DRAM (R1)", "[exception]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TEE DRAM -REE IRAM Boundary */
|
/* TEE DRAM -REE IRAM Boundary */
|
||||||
TEST_CASE("Test REE-TEE isolation: DRAM (W1)", "[exception]")
|
TEST_CASE("Test REE-TEE isolation: DRAM-W1", "[exception]")
|
||||||
{
|
{
|
||||||
*(uint32_t *)(&_iram_start - 0x04) = 0xbadc0de;
|
*(uint32_t *)(&_iram_start - 0x04) = 0xbadc0de;
|
||||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TEE IRAM region */
|
/* TEE IRAM region */
|
||||||
TEST_CASE("Test REE-TEE isolation: IRAM (R1)", "[exception]")
|
TEST_CASE("Test REE-TEE isolation: IRAM-R1", "[exception]")
|
||||||
{
|
{
|
||||||
uint32_t *val = (uint32_t *)(&_iram_start - (CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE) + 0x04);
|
uint32_t *val = (uint32_t *)(&_iram_start - (CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE) + 0x04);
|
||||||
TEST_ASSERT_EQUAL(0, *val);
|
TEST_ASSERT_EQUAL(0, *val);
|
||||||
@@ -163,14 +178,14 @@ TEST_CASE("Test REE-TEE isolation: IRAM (R1)", "[exception]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TEE IRAM region */
|
/* TEE IRAM region */
|
||||||
TEST_CASE("Test REE-TEE isolation: IRAM (W1)", "[exception]")
|
TEST_CASE("Test REE-TEE isolation: IRAM-W1", "[exception]")
|
||||||
{
|
{
|
||||||
*(uint32_t *)(&_iram_start - (CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE) + 0x04) = 0xbadc0de;
|
*(uint32_t *)(&_iram_start - (CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE) + 0x04) = 0xbadc0de;
|
||||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TEE IROM region */
|
/* TEE IROM region */
|
||||||
TEST_CASE("Test REE-TEE isolation: IROM (R1)", "[exception]")
|
TEST_CASE("Test REE-TEE isolation: IROM-R1", "[exception]")
|
||||||
{
|
{
|
||||||
uint32_t *val = (uint32_t *)(SOC_IROM_LOW + 0x04);
|
uint32_t *val = (uint32_t *)(SOC_IROM_LOW + 0x04);
|
||||||
TEST_ASSERT_EQUAL(0, *val);
|
TEST_ASSERT_EQUAL(0, *val);
|
||||||
@@ -178,14 +193,14 @@ TEST_CASE("Test REE-TEE isolation: IROM (R1)", "[exception]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TEE IROM region */
|
/* TEE IROM region */
|
||||||
TEST_CASE("Test REE-TEE isolation: IROM (W1)", "[exception]")
|
TEST_CASE("Test REE-TEE isolation: IROM-W1", "[exception]")
|
||||||
{
|
{
|
||||||
*(uint32_t *)(SOC_IROM_LOW + 0x04) = 0xbadc0de;
|
*(uint32_t *)(SOC_IROM_LOW + 0x04) = 0xbadc0de;
|
||||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TEE DROM - REE IROM boundary */
|
/* TEE DROM - REE IROM boundary */
|
||||||
TEST_CASE("Test REE-TEE isolation: DROM (R1)", "[exception]")
|
TEST_CASE("Test REE-TEE isolation: DROM-R1", "[exception]")
|
||||||
{
|
{
|
||||||
const uint32_t test_addr = ALIGN_DOWN_TO_MMU_PAGE_SIZE((uint32_t)&_instruction_reserved_start);
|
const uint32_t test_addr = ALIGN_DOWN_TO_MMU_PAGE_SIZE((uint32_t)&_instruction_reserved_start);
|
||||||
uint32_t *val = (uint32_t *)(test_addr - 0x04);
|
uint32_t *val = (uint32_t *)(test_addr - 0x04);
|
||||||
@@ -194,16 +209,9 @@ TEST_CASE("Test REE-TEE isolation: DROM (R1)", "[exception]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TEE DROM - REE IROM boundary */
|
/* TEE DROM - REE IROM boundary */
|
||||||
TEST_CASE("Test REE-TEE isolation: DROM (W1)", "[exception]")
|
TEST_CASE("Test REE-TEE isolation: DROM-W1", "[exception]")
|
||||||
{
|
{
|
||||||
const uint32_t test_addr = ALIGN_DOWN_TO_MMU_PAGE_SIZE((uint32_t)&_instruction_reserved_start);
|
const uint32_t test_addr = ALIGN_DOWN_TO_MMU_PAGE_SIZE((uint32_t)&_instruction_reserved_start);
|
||||||
*(uint32_t *)(test_addr - 0x04) = 0xbadc0de;
|
*(uint32_t *)(test_addr - 0x04) = 0xbadc0de;
|
||||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SWDT/BOD Reset register */
|
|
||||||
TEST_CASE("Test REE-TEE isolation: SWDT/BOD (W)", "[exception]")
|
|
||||||
{
|
|
||||||
REG_WRITE(LP_ANALOG_PERI_LP_ANA_FIB_ENABLE_REG, 0);
|
|
||||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
|
||||||
}
|
|
||||||
|
@@ -2,8 +2,6 @@
|
|||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
import re
|
import re
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Dict
|
|
||||||
from typing import Tuple
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from pytest_embedded_idf import IdfDut
|
from pytest_embedded_idf import IdfDut
|
||||||
@@ -11,7 +9,7 @@ from pytest_embedded_idf.utils import idf_parametrize
|
|||||||
|
|
||||||
# ---------------- Pytest build parameters ----------------
|
# ---------------- Pytest build parameters ----------------
|
||||||
|
|
||||||
SUPPORTED_TARGETS = ['esp32c6', 'esp32h2']
|
SUPPORTED_TARGETS = ['esp32c6', 'esp32h2', 'esp32c5']
|
||||||
|
|
||||||
CONFIG_DEFAULT = [
|
CONFIG_DEFAULT = [
|
||||||
# 'config, target, markers',
|
# 'config, target, markers',
|
||||||
@@ -34,28 +32,27 @@ CONFIG_ALL = [
|
|||||||
|
|
||||||
# ---------------- Exception test-cases reasons ----------------
|
# ---------------- Exception test-cases reasons ----------------
|
||||||
|
|
||||||
TEE_VIOLATION_TEST_EXC_RSN: Dict[Tuple[str, str], str] = {
|
TEE_VIOLATION_TEST_EXC_RSN: dict[str, str] = {
|
||||||
('Reserved', 'W1'): 'Store access fault',
|
('Reserved-W1'): 'Store access fault',
|
||||||
('Reserved', 'X1'): 'Instruction access fault',
|
('Reserved-X1'): 'Instruction access fault',
|
||||||
('IRAM', 'W1'): 'Store access fault',
|
('IRAM-W1'): 'Store access fault',
|
||||||
('IRAM', 'W2'): 'Store access fault',
|
('IRAM-W2'): 'Store access fault',
|
||||||
('DRAM', 'X1'): 'Instruction access fault',
|
('DRAM-X1'): 'Instruction access fault',
|
||||||
('DRAM', 'X2'): 'Instruction access fault',
|
('DRAM-X2'): 'Instruction access fault',
|
||||||
}
|
}
|
||||||
|
|
||||||
REE_ISOLATION_TEST_EXC_RSN: Dict[Tuple[str, str], str] = {
|
REE_ISOLATION_TEST_EXC_RSN: dict[str, str] = {
|
||||||
('DRAM', 'R1'): 'Load access fault',
|
('DRAM-R1'): 'Load access fault',
|
||||||
('DRAM', 'W1'): 'Store access fault',
|
('DRAM-W1'): 'Store access fault',
|
||||||
('IRAM', 'R1'): 'Load access fault',
|
('IRAM-R1'): 'Load access fault',
|
||||||
('IRAM', 'W1'): 'Store access fault',
|
('IRAM-W1'): 'Store access fault',
|
||||||
('IROM', 'R1'): 'Load access fault',
|
('IROM-R1'): 'Load access fault',
|
||||||
('IROM', 'W1'): 'Store access fault',
|
('IROM-W1'): 'Store access fault',
|
||||||
('DROM', 'R1'): 'Load access fault',
|
('DROM-R1'): 'Load access fault',
|
||||||
('DROM', 'W1'): 'Store access fault',
|
('DROM-W1'): 'Store access fault',
|
||||||
('SWDT/BOD', 'W'): 'Store access fault',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEE_APM_VIOLATION_EXC_CHK = ['eFuse', 'MMU', 'AES', 'HMAC', 'DS', 'SHA PCR', 'ECC PCR']
|
TEE_APM_VIOLATION_EXC_CHK = ['eFuse', 'MMU', 'AES', 'HMAC', 'DS', 'SHA PCR', 'ECC PCR', 'SWDT/BOD']
|
||||||
|
|
||||||
# ---------------- TEE default tests ----------------
|
# ---------------- TEE default tests ----------------
|
||||||
|
|
||||||
@@ -118,10 +115,12 @@ def test_esp_tee_aes_perf(dut: IdfDut) -> None:
|
|||||||
def test_esp_tee_apm_violation(dut: IdfDut) -> None:
|
def test_esp_tee_apm_violation(dut: IdfDut) -> None:
|
||||||
for check in TEE_APM_VIOLATION_EXC_CHK:
|
for check in TEE_APM_VIOLATION_EXC_CHK:
|
||||||
dut.expect_exact('Press ENTER to see the list of tests')
|
dut.expect_exact('Press ENTER to see the list of tests')
|
||||||
dut.write(f'"Test APM violation interrupt: {check}"')
|
dut.write(f'"Test APM violation: {check}"')
|
||||||
exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode()
|
exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode()
|
||||||
if dut.target == 'esp32h2' and check == 'eFuse':
|
if dut.target == 'esp32c5' or (dut.target == 'esp32h2' and check == 'eFuse'):
|
||||||
exp_str = 'APM - Space exception'
|
exp_str = 'APM - Space exception'
|
||||||
|
elif check == 'SWDT/BOD':
|
||||||
|
exp_str = 'Store access fault'
|
||||||
else:
|
else:
|
||||||
exp_str = 'APM - Authority exception'
|
exp_str = 'APM - Authority exception'
|
||||||
if exc != exp_str:
|
if exc != exp_str:
|
||||||
@@ -148,13 +147,12 @@ def test_esp_tee_illegal_instruction(dut: IdfDut) -> None:
|
|||||||
)
|
)
|
||||||
def test_esp_tee_violation_checks(dut: IdfDut) -> None:
|
def test_esp_tee_violation_checks(dut: IdfDut) -> None:
|
||||||
checks_list = TEE_VIOLATION_TEST_EXC_RSN
|
checks_list = TEE_VIOLATION_TEST_EXC_RSN
|
||||||
for test in checks_list:
|
for test, expected_exc in checks_list.items():
|
||||||
memory, access_type = test
|
if expected_exc is None or dut.target == 'esp32c5':
|
||||||
expected_exc = checks_list[test]
|
# TODO: Enable when TEE SRAM is partitioned as IRAM (RX) and DRAM (RW)
|
||||||
if expected_exc is None:
|
|
||||||
continue
|
continue
|
||||||
dut.expect_exact('Press ENTER to see the list of tests')
|
dut.expect_exact('Press ENTER to see the list of tests')
|
||||||
dut.write(f'"Test TEE-TEE violation: {memory} ({access_type})"')
|
dut.write(f'"Test TEE-TEE violation: {test}"')
|
||||||
actual_exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode()
|
actual_exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode()
|
||||||
if actual_exc != expected_exc:
|
if actual_exc != expected_exc:
|
||||||
raise RuntimeError('Incorrect exception received!')
|
raise RuntimeError('Incorrect exception received!')
|
||||||
@@ -167,13 +165,11 @@ def test_esp_tee_violation_checks(dut: IdfDut) -> None:
|
|||||||
)
|
)
|
||||||
def test_esp_tee_isolation_checks(dut: IdfDut) -> None:
|
def test_esp_tee_isolation_checks(dut: IdfDut) -> None:
|
||||||
checks_list = REE_ISOLATION_TEST_EXC_RSN
|
checks_list = REE_ISOLATION_TEST_EXC_RSN
|
||||||
for test in checks_list:
|
for test, expected_exc in checks_list.items():
|
||||||
memory, access_type = test
|
|
||||||
expected_exc = checks_list[test]
|
|
||||||
if expected_exc is None:
|
if expected_exc is None:
|
||||||
continue
|
continue
|
||||||
dut.expect_exact('Press ENTER to see the list of tests')
|
dut.expect_exact('Press ENTER to see the list of tests')
|
||||||
dut.write(f'"Test REE-TEE isolation: {memory} ({access_type})"')
|
dut.write(f'"Test REE-TEE isolation: {test}"')
|
||||||
actual_exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode()
|
actual_exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode()
|
||||||
if actual_exc != expected_exc:
|
if actual_exc != expected_exc:
|
||||||
raise RuntimeError('Incorrect exception received!')
|
raise RuntimeError('Incorrect exception received!')
|
||||||
@@ -215,6 +211,8 @@ def run_multiple_stages(dut: IdfDut, test_case_num: int, stages: int, api: TeeFl
|
|||||||
|
|
||||||
flash_enc_enabled = dut.app.sdkconfig.get('SECURE_FLASH_ENC_ENABLED', True)
|
flash_enc_enabled = dut.app.sdkconfig.get('SECURE_FLASH_ENC_ENABLED', True)
|
||||||
|
|
||||||
|
SOC_TEE_FLASH_OP_FAIL_FAULT = ['esp32c6', 'esp32h2']
|
||||||
|
|
||||||
for stage in range(1, stages + 1):
|
for stage in range(1, stages + 1):
|
||||||
dut.write(str(test_case_num))
|
dut.write(str(test_case_num))
|
||||||
dut.expect(r'\s+\((\d+)\)\s+"([^"]+)"\r?\n', timeout=30)
|
dut.expect(r'\s+\((\d+)\)\s+"([^"]+)"\r?\n', timeout=30)
|
||||||
@@ -222,7 +220,10 @@ def run_multiple_stages(dut: IdfDut, test_case_num: int, stages: int, api: TeeFl
|
|||||||
|
|
||||||
if stage > 1:
|
if stage > 1:
|
||||||
if api in {TeeFlashAccessApi.ESP_PARTITION_MMAP, TeeFlashAccessApi.SPI_FLASH_MMAP}:
|
if api in {TeeFlashAccessApi.ESP_PARTITION_MMAP, TeeFlashAccessApi.SPI_FLASH_MMAP}:
|
||||||
|
if dut.target in SOC_TEE_FLASH_OP_FAIL_FAULT:
|
||||||
expect_panic_rsn(dut, 'Cache error')
|
expect_panic_rsn(dut, 'Cache error')
|
||||||
|
else:
|
||||||
|
dut.expect(r'\[_ss_mmu_hal_map_region] Illegal flash access at\s+\S+\s*\|\s*\S+', timeout=10)
|
||||||
elif api in {TeeFlashAccessApi.ESP_PARTITION, TeeFlashAccessApi.ESP_FLASH}:
|
elif api in {TeeFlashAccessApi.ESP_PARTITION, TeeFlashAccessApi.ESP_FLASH}:
|
||||||
op_index = stage - 2
|
op_index = stage - 2
|
||||||
curr_op = expected_ops[api][op_index]
|
curr_op = expected_ops[api][op_index]
|
||||||
@@ -230,7 +231,10 @@ def run_multiple_stages(dut: IdfDut, test_case_num: int, stages: int, api: TeeFl
|
|||||||
# NOTE: The esp_partition_read API handles both decrypted
|
# NOTE: The esp_partition_read API handles both decrypted
|
||||||
# and plaintext reads. When flash encryption is enabled,
|
# and plaintext reads. When flash encryption is enabled,
|
||||||
# it uses the MMU HAL instead of the SPI flash HAL.
|
# it uses the MMU HAL instead of the SPI flash HAL.
|
||||||
|
if dut.target in SOC_TEE_FLASH_OP_FAIL_FAULT:
|
||||||
expect_panic_rsn(dut, 'Cache error')
|
expect_panic_rsn(dut, 'Cache error')
|
||||||
|
else:
|
||||||
|
dut.expect(r'\[_ss_mmu_hal_map_region] Illegal flash access at\s+\S+\s*\|\s*\S+', timeout=10)
|
||||||
else:
|
else:
|
||||||
match = dut.expect(
|
match = dut.expect(
|
||||||
r'\[_ss_spi_flash_hal_(\w+)\] Illegal flash access at \s*(0x[0-9a-fA-F]+)', timeout=10
|
r'\[_ss_spi_flash_hal_(\w+)\] Illegal flash access at \s*(0x[0-9a-fA-F]+)', timeout=10
|
||||||
@@ -239,7 +243,10 @@ def run_multiple_stages(dut: IdfDut, test_case_num: int, stages: int, api: TeeFl
|
|||||||
if not re.fullmatch(curr_op, actual_op):
|
if not re.fullmatch(curr_op, actual_op):
|
||||||
raise RuntimeError(f'Unexpected flash operation: {actual_op} (expected: {curr_op})')
|
raise RuntimeError(f'Unexpected flash operation: {actual_op} (expected: {curr_op})')
|
||||||
elif api == TeeFlashAccessApi.ESP_ROM_SPIFLASH:
|
elif api == TeeFlashAccessApi.ESP_ROM_SPIFLASH:
|
||||||
|
if dut.target in SOC_TEE_FLASH_OP_FAIL_FAULT:
|
||||||
expect_panic_rsn(dut, 'APM - Authority exception')
|
expect_panic_rsn(dut, 'APM - Authority exception')
|
||||||
|
else:
|
||||||
|
expect_panic_rsn(dut, 'APM - Space exception')
|
||||||
|
|
||||||
if stage != stages:
|
if stage != stages:
|
||||||
dut.expect_exact('Press ENTER to see the list of tests.')
|
dut.expect_exact('Press ENTER to see the list of tests.')
|
||||||
@@ -340,7 +347,7 @@ def test_esp_tee_flash_prot_esp_flash(dut: IdfDut) -> None:
|
|||||||
|
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@idf_parametrize('config', ['ota'], indirect=['config'])
|
@idf_parametrize('config', ['ota'], indirect=['config'])
|
||||||
@idf_parametrize('target', ['esp32c6', 'esp32h2'], indirect=['target'])
|
@idf_parametrize('target', SUPPORTED_TARGETS, indirect=['target'])
|
||||||
def test_esp_tee_ota_negative(dut: IdfDut) -> None:
|
def test_esp_tee_ota_negative(dut: IdfDut) -> None:
|
||||||
# start test
|
# start test
|
||||||
dut.expect_exact('Press ENTER to see the list of tests')
|
dut.expect_exact('Press ENTER to see the list of tests')
|
||||||
@@ -474,8 +481,8 @@ def test_esp_tee_ota_rollback(dut: IdfDut) -> None:
|
|||||||
dut.expect('TEE otadata - Current image state: NEW', timeout=10)
|
dut.expect('TEE otadata - Current image state: NEW', timeout=10)
|
||||||
dut.expect('Loaded TEE app from partition at offset 0x40000', timeout=10)
|
dut.expect('Loaded TEE app from partition at offset 0x40000', timeout=10)
|
||||||
rst_rsn = dut.expect(r'rst:(0x[0-9A-Fa-f]+) \(([^)]+)\)', timeout=30).group(2).decode()
|
rst_rsn = dut.expect(r'rst:(0x[0-9A-Fa-f]+) \(([^)]+)\)', timeout=30).group(2).decode()
|
||||||
# NOTE: LP_WDT_SYS is for ESP32-C6 case as bootloader fails to load the dummy TEE app
|
# NOTE: LP_WDT_SYS (C6/H2) and RTC_WDT_SYS (C5) are expected as bootloader fails to load the dummy TEE app
|
||||||
if rst_rsn != 'LP_WDT_SYS':
|
if rst_rsn not in {'LP_WDT_SYS', 'RTC_WDT_SYS'}:
|
||||||
raise RuntimeError('Incorrect reset reason observed after TEE image failure!')
|
raise RuntimeError('Incorrect reset reason observed after TEE image failure!')
|
||||||
|
|
||||||
# after rollback
|
# after rollback
|
||||||
|
@@ -9,6 +9,7 @@ CONFIG_SECURE_TEE_TEST_MODE=y
|
|||||||
|
|
||||||
# Setting partition table
|
# Setting partition table
|
||||||
CONFIG_PARTITION_TABLE_SINGLE_APP_TEE=y
|
CONFIG_PARTITION_TABLE_SINGLE_APP_TEE=y
|
||||||
|
CONFIG_PARTITION_TABLE_OFFSET=0xF000
|
||||||
|
|
||||||
# TEE IRAM size
|
# TEE IRAM size
|
||||||
CONFIG_SECURE_TEE_IRAM_SIZE=0x8400
|
CONFIG_SECURE_TEE_IRAM_SIZE=0x8400
|
||||||
|
@@ -131,7 +131,15 @@ esp_err_t spi_flash_hal_configure_host_io_mode(
|
|||||||
addr_bitlen += SPI_FLASH_LL_CONTINUOUS_MODE_BIT_NUMS;
|
addr_bitlen += SPI_FLASH_LL_CONTINUOUS_MODE_BIT_NUMS;
|
||||||
#endif
|
#endif
|
||||||
spi_flash_ll_set_extra_address(dev, 0);
|
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);
|
spi_flash_ll_wb_mode_enable(dev, true);
|
||||||
#endif
|
#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) {
|
if (trans->miso_len > 0) {
|
||||||
spi_flash_ll_get_buffer_data(dev, trans->miso_data, trans->miso_len);
|
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);
|
spi_flash_ll_wb_mode_enable(dev, false);
|
||||||
#endif
|
#endif
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
@@ -22,10 +22,6 @@
|
|||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
#define UTVT_CSR (0x007)
|
|
||||||
#define UINTSTATUS_CSR (0xCB1)
|
|
||||||
#define UINTTHRESH_CSR (0x047)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@@ -22,10 +22,6 @@
|
|||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
#define UTVT_CSR (0x007)
|
|
||||||
#define UINTSTATUS_CSR (0xCB1)
|
|
||||||
#define UINTTHRESH_CSR (0x047)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -12,6 +12,11 @@
|
|||||||
#include "heap_memory_layout.h"
|
#include "heap_memory_layout.h"
|
||||||
#include "esp_heap_caps.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.
|
* @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.
|
* 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
|
// 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);
|
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
|
#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);
|
SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_slow_end, rtcram_data);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -10,15 +10,10 @@
|
|||||||
#include "mbedtls/aes.h"
|
#include "mbedtls/aes.h"
|
||||||
#include "esp_crypto_dma.h"
|
#include "esp_crypto_dma.h"
|
||||||
|
|
||||||
#include "hal/clk_gate_ll.h"
|
|
||||||
#include "hal/gdma_ll.h"
|
|
||||||
#include "hal/gdma_types.h"
|
#include "hal/gdma_types.h"
|
||||||
#include "hal/aes_hal.h"
|
#include "hal/aes_hal.h"
|
||||||
|
|
||||||
#include "soc/lldesc.h"
|
|
||||||
#include "soc/periph_defs.h"
|
|
||||||
#include "soc/gdma_channel.h"
|
#include "soc/gdma_channel.h"
|
||||||
#include "soc/gdma_struct.h"
|
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
|
|
||||||
#include "esp_tee_crypto_shared_gdma.h"
|
#include "esp_tee_crypto_shared_gdma.h"
|
||||||
@@ -27,6 +22,38 @@
|
|||||||
|
|
||||||
#define TEE_CRYPTO_GDMA_CH (0)
|
#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
|
* NOTE: [ESP-TEE] This is a low-level (LL), non-OS version of
|
||||||
* port/crypto_shared_gdma/esp_crypto_shared_gdma.c that defines
|
* port/crypto_shared_gdma/esp_crypto_shared_gdma.c that defines
|
||||||
@@ -37,30 +64,23 @@
|
|||||||
|
|
||||||
static void crypto_shared_gdma_init(void)
|
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
|
// 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
|
// setting the transfer ability
|
||||||
gdma_ll_tx_enable_data_burst(&GDMA, TEE_CRYPTO_GDMA_CH, true);
|
dma_ll_tx_enable_data_burst(&DMA_DEV, TEE_CRYPTO_GDMA_CH, true);
|
||||||
gdma_ll_tx_enable_descriptor_burst(&GDMA, 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);
|
dma_ll_rx_enable_data_burst(&DMA_DEV, TEE_CRYPTO_GDMA_CH, false);
|
||||||
gdma_ll_rx_enable_descriptor_burst(&GDMA, TEE_CRYPTO_GDMA_CH, true);
|
dma_ll_rx_enable_descriptor_burst(&DMA_DEV, TEE_CRYPTO_GDMA_CH, true);
|
||||||
|
|
||||||
#if SOC_GDMA_SUPPORT_PSRAM
|
dma_ll_tx_reset_channel(&DMA_DEV, TEE_CRYPTO_GDMA_CH);
|
||||||
gdma_ll_tx_set_block_size_psram(&GDMA, TEE_CRYPTO_GDMA_CH, GDMA_LL_EXT_MEM_BK_SIZE_16B);
|
dma_ll_tx_connect_to_periph(&DMA_DEV, TEE_CRYPTO_GDMA_CH, GDMA_TRIG_PERIPH_M2M, SOC_GDMA_TRIG_PERIPH_M2M0);
|
||||||
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_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)
|
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();
|
crypto_shared_gdma_init();
|
||||||
|
|
||||||
gdma_ll_tx_disconnect_from_periph(&GDMA, TEE_CRYPTO_GDMA_CH);
|
dma_ll_tx_disconnect_from_periph(&DMA_DEV, TEE_CRYPTO_GDMA_CH);
|
||||||
gdma_ll_rx_disconnect_from_periph(&GDMA, 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);
|
dma_ll_tx_reset_channel(&DMA_DEV, TEE_CRYPTO_GDMA_CH);
|
||||||
gdma_ll_tx_connect_to_periph(&GDMA, TEE_CRYPTO_GDMA_CH, periph, periph_inst_id);
|
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);
|
dma_ll_rx_reset_channel(&DMA_DEV, TEE_CRYPTO_GDMA_CH);
|
||||||
gdma_ll_rx_connect_to_periph(&GDMA, TEE_CRYPTO_GDMA_CH, periph, periph_inst_id);
|
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);
|
dma_ll_tx_set_desc_addr(&DMA_DEV, TEE_CRYPTO_GDMA_CH, (intptr_t)input);
|
||||||
gdma_ll_tx_start(&GDMA, TEE_CRYPTO_GDMA_CH);
|
dma_ll_tx_start(&DMA_DEV, TEE_CRYPTO_GDMA_CH);
|
||||||
|
|
||||||
gdma_ll_rx_set_desc_addr(&GDMA, TEE_CRYPTO_GDMA_CH, (intptr_t)output);
|
dma_ll_rx_set_desc_addr(&DMA_DEV, TEE_CRYPTO_GDMA_CH, (intptr_t)output);
|
||||||
gdma_ll_rx_start(&GDMA, TEE_CRYPTO_GDMA_CH);
|
dma_ll_rx_start(&DMA_DEV, TEE_CRYPTO_GDMA_CH);
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void esp_tee_crypto_shared_gdma_free(void)
|
void esp_tee_crypto_shared_gdma_free(void)
|
||||||
{
|
{
|
||||||
gdma_ll_tx_stop(&GDMA, TEE_CRYPTO_GDMA_CH);
|
dma_ll_tx_stop(&DMA_DEV, TEE_CRYPTO_GDMA_CH);
|
||||||
gdma_ll_rx_stop(&GDMA, 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);
|
dma_ll_tx_disconnect_from_periph(&DMA_DEV, TEE_CRYPTO_GDMA_CH);
|
||||||
gdma_ll_rx_disconnect_from_periph(&GDMA, 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);
|
dma_ll_tx_set_priority(&DMA_DEV, TEE_CRYPTO_GDMA_CH, 0);
|
||||||
gdma_ll_rx_set_priority(&GDMA, TEE_CRYPTO_GDMA_CH, 0);
|
dma_ll_rx_set_priority(&DMA_DEV, TEE_CRYPTO_GDMA_CH, 0);
|
||||||
|
|
||||||
// disable gdma clock
|
// disable gdma clock
|
||||||
gdma_ll_force_enable_reg_clock(&GDMA, false);
|
gdma_ll_enable_bus_clock(0, false);
|
||||||
|
gdma_ll_reset_register(0);
|
||||||
// disable APB for GDMA registers
|
dma_ll_force_enable_reg_clock(&DMA_DEV, false);
|
||||||
periph_ll_disable_clk_set_rst(PERIPH_GDMA_MODULE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------- DMA Implementations: AES ------------------------------------------------- */
|
/* ---------------------------------------------- DMA Implementations: AES ------------------------------------------------- */
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
#ifndef ESP_TEE_MBEDTLS_CONFIG_H
|
#ifndef ESP_TEE_MBEDTLS_CONFIG_H
|
||||||
@@ -50,13 +51,24 @@
|
|||||||
#define MBEDTLS_ECP_C
|
#define MBEDTLS_ECP_C
|
||||||
#define MBEDTLS_ECDSA_C
|
#define MBEDTLS_ECDSA_C
|
||||||
|
|
||||||
|
#if CONFIG_MBEDTLS_SHA1_C
|
||||||
#define MBEDTLS_SHA1_C
|
#define MBEDTLS_SHA1_C
|
||||||
|
#endif
|
||||||
#define MBEDTLS_SHA224_C
|
#define MBEDTLS_SHA224_C
|
||||||
#define MBEDTLS_SHA256_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_HARDWARE_SHA
|
||||||
|
#if CONFIG_MBEDTLS_SHA1_C
|
||||||
#define MBEDTLS_SHA1_ALT
|
#define MBEDTLS_SHA1_ALT
|
||||||
|
#endif
|
||||||
#define MBEDTLS_SHA256_ALT
|
#define MBEDTLS_SHA256_ALT
|
||||||
|
#if SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C
|
||||||
|
#define MBEDTLS_SHA512_ALT
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_MBEDTLS_HARDWARE_ECC
|
#ifdef CONFIG_MBEDTLS_HARDWARE_ECC
|
||||||
|
@@ -15,6 +15,8 @@ elseif(esp_tee_build)
|
|||||||
set(srcs "rv_utils.c")
|
set(srcs "rv_utils.c")
|
||||||
if(CONFIG_SOC_INT_PLIC_SUPPORTED)
|
if(CONFIG_SOC_INT_PLIC_SUPPORTED)
|
||||||
list(APPEND srcs "interrupt_plic.c")
|
list(APPEND srcs "interrupt_plic.c")
|
||||||
|
elseif(CONFIG_SOC_INT_CLIC_SUPPORTED)
|
||||||
|
list(APPEND srcs "interrupt_clic.c")
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
set(priv_requires soc hal)
|
set(priv_requires soc hal)
|
||||||
|
@@ -44,6 +44,7 @@ extern "C" {
|
|||||||
* @brief CSR to set the interrupt jump table address is MTVT.
|
* @brief CSR to set the interrupt jump table address is MTVT.
|
||||||
*/
|
*/
|
||||||
#define MTVT_CSR 0x307
|
#define MTVT_CSR 0x307
|
||||||
|
#define UTVT_CSR 0x007
|
||||||
|
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32P4 && CONFIG_ESP32P4_SELECTS_REV_LESS_V2
|
#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 */
|
/* 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 INTTHRESH_STANDARD 1
|
||||||
#define MINTSTATUS_CSR 0xFB1
|
#define MINTSTATUS_CSR 0xFB1
|
||||||
|
#define UINTSTATUS_CSR 0xCB1
|
||||||
#define MINTTHRESH_CSR 0x347
|
#define MINTTHRESH_CSR 0x347
|
||||||
|
#define UINTTHRESH_CSR 0x047
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "Check the implementation of the CLIC on this target."
|
#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))
|
#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)
|
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)
|
FORCE_INLINE_ATTR uint32_t rv_utils_get_interrupt_threshold(void)
|
||||||
{
|
{
|
||||||
#if INTTHRESH_STANDARD
|
#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
|
#else
|
||||||
uint32_t threshold = REG_READ(CLIC_INT_THRESH_REG);
|
uint32_t threshold = REG_READ(CLIC_INT_THRESH_REG);
|
||||||
#endif
|
#endif
|
||||||
@@ -148,6 +160,19 @@ FORCE_INLINE_ATTR void rv_utils_set_mtvt(uint32_t mtvt_val)
|
|||||||
RV_WRITE_CSR(MTVT_CSR, 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
|
#if SOC_CPU_SUPPORT_WFE
|
||||||
/**
|
/**
|
||||||
* @brief Set the MEXSTATUS_WFFEN value, used to enable/disable wait for event mode.
|
* @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)
|
FORCE_INLINE_ATTR uint32_t rv_utils_get_interrupt_level_regval(void)
|
||||||
{
|
{
|
||||||
|
if (IS_PRV_M_MODE()) {
|
||||||
return RV_READ_CSR(MINTSTATUS_CSR);
|
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)
|
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 */
|
/* 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)
|
FORCE_INLINE_ATTR void rv_utils_restore_intlevel_regval(uint32_t restoreval)
|
||||||
{
|
{
|
||||||
#if INTTHRESH_STANDARD
|
#if INTTHRESH_STANDARD
|
||||||
|
if (IS_PRV_M_MODE()) {
|
||||||
RV_WRITE_CSR(MINTTHRESH_CSR, restoreval);
|
RV_WRITE_CSR(MINTTHRESH_CSR, restoreval);
|
||||||
|
} else {
|
||||||
|
RV_WRITE_CSR(UINTTHRESH_CSR, restoreval);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
REG_WRITE(CLIC_INT_THRESH_REG, restoreval);
|
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)
|
FORCE_INLINE_ATTR uint32_t rv_utils_set_intlevel_regval(uint32_t intlevel)
|
||||||
{
|
{
|
||||||
#if INTTHRESH_STANDARD
|
#if INTTHRESH_STANDARD
|
||||||
|
if (IS_PRV_M_MODE()) {
|
||||||
return RV_SWAP_CSR(MINTTHRESH_CSR, intlevel);
|
return RV_SWAP_CSR(MINTTHRESH_CSR, intlevel);
|
||||||
|
} else {
|
||||||
|
return RV_SWAP_CSR(UINTTHRESH_CSR, intlevel);
|
||||||
|
}
|
||||||
#else // !INTTHRESH_STANDARD
|
#else // !INTTHRESH_STANDARD
|
||||||
uint32_t old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
uint32_t old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||||
uint32_t old_thresh = REG_READ(CLIC_INT_THRESH_REG);
|
uint32_t old_thresh = REG_READ(CLIC_INT_THRESH_REG);
|
||||||
|
@@ -149,7 +149,7 @@ void esprv_int_set_vectored(int rv_int_num, bool vectored);
|
|||||||
/*************************** ESP-TEE specific ***************************/
|
/*************************** ESP-TEE specific ***************************/
|
||||||
|
|
||||||
/** Function prototype executing interrupt configuration APIs as service calls */
|
/** 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
|
* @brief Setup the callback function which executes the interrupt
|
||||||
|
@@ -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)
|
FORCE_INLINE_ATTR void __attribute__((always_inline)) rv_utils_set_cycle_count(uint32_t ccount)
|
||||||
{
|
{
|
||||||
#if !SOC_CPU_HAS_CSR_PC
|
#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);
|
RV_WRITE_CSR(mcycle, ccount);
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
if (IS_PRV_M_MODE()) {
|
if (IS_PRV_M_MODE()) {
|
||||||
RV_WRITE_CSR(CSR_PCCR_MACHINE, ccount);
|
RV_WRITE_CSR(CSR_PCCR_MACHINE, ccount);
|
||||||
@@ -481,12 +485,20 @@ FORCE_INLINE_ATTR bool rv_utils_compare_and_set(volatile uint32_t *addr, uint32_
|
|||||||
#if SOC_BRANCH_PREDICTOR_SUPPORTED
|
#if SOC_BRANCH_PREDICTOR_SUPPORTED
|
||||||
FORCE_INLINE_ATTR void rv_utils_en_branch_predictor(void)
|
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);
|
RV_SET_CSR(MHCR, MHCR_RS|MHCR_BFE|MHCR_BTB);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE_ATTR void rv_utils_dis_branch_predictor(void)
|
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);
|
RV_CLEAR_CSR(MHCR, MHCR_RS|MHCR_BFE|MHCR_BTB);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -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
|
* 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);
|
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
|
||||||
|
@@ -17,6 +17,8 @@
|
|||||||
.equ EXC_ILLEGAL_INSTRUCTION, 0x2
|
.equ EXC_ILLEGAL_INSTRUCTION, 0x2
|
||||||
.equ panic_from_exception, xt_unhandled_exception
|
.equ panic_from_exception, xt_unhandled_exception
|
||||||
.equ panic_from_isr, panicHandler
|
.equ panic_from_isr, panicHandler
|
||||||
|
.equ CSR_UINTSTATUS, 0xCB1
|
||||||
|
.equ CSR_UINTTHRESH, 0x047
|
||||||
|
|
||||||
#if ( SOC_CPU_COPROC_NUM > 0 )
|
#if ( SOC_CPU_COPROC_NUM > 0 )
|
||||||
/* Targets with coprocessors present a special CSR to get Illegal Instruction exception reason */
|
/* Targets with coprocessors present a special CSR to get Illegal Instruction exception reason */
|
||||||
@@ -90,8 +92,11 @@
|
|||||||
sw t0, RV_STK_MSTATUS(sp)
|
sw t0, RV_STK_MSTATUS(sp)
|
||||||
csrr t0, utvec
|
csrr t0, utvec
|
||||||
sw t0, RV_STK_MTVEC(sp)
|
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
|
csrr t0, utval
|
||||||
sw t0, RV_STK_MTVAL(sp)
|
sw t0, RV_STK_MTVAL(sp)
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
csrr t0, mstatus
|
csrr t0, mstatus
|
||||||
sw t0, RV_STK_MSTATUS(sp)
|
sw t0, RV_STK_MSTATUS(sp)
|
||||||
@@ -467,6 +472,24 @@ _tee_interrupt_handler:
|
|||||||
li t0, INTERRUPT_CURRENT_CORE_INT_THRESH_REG
|
li t0, INTERRUPT_CURRENT_CORE_INT_THRESH_REG
|
||||||
sw s3, 0(t0)
|
sw s3, 0(t0)
|
||||||
fence
|
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
|
#endif // !SOC_INT_HW_NESTED_SUPPORTED
|
||||||
|
|
||||||
/* The RTOS will restore the current TCB stack pointer. This routine will preserve s1 and s2.
|
/* The RTOS will restore the current TCB stack pointer. This routine will preserve s1 and s2.
|
||||||
|
@@ -5,7 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "soc/soc.h"
|
#include "soc/soc.h"
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
Reference in New Issue
Block a user