feat(esp_tee): Support for ESP-TEE - esp_system component

This commit is contained in:
Laukik Hase
2024-07-01 14:42:08 +05:30
parent 54c3f1bae4
commit 733741bbac
8 changed files with 105 additions and 9 deletions

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -10,15 +10,40 @@
#include "../ext_mem_layout.h"
#include "hal/mmu_types.h"
/* NOTE: With ESP-TEE enabled:
* - The start address is moved by the size of TEE IDROM segments since these
* segments are placed at the start of the linear address space
* - TEE IROM and DROM segments are both 64KB (CONFIG_SECURE_TEE_IROM_SIZE,
* CONFIG_SECURE_TEE_DROM_SIZE) for now. Thus, the number of reserved entries
* from the start would be (64KB + 64KB)/MMU_PAGE_SIZE
* - The last few MMU entries are reserved for TEE flash operations. The number
* of reserved entries matches the size of TEE IDROM segments (IROM + DROM)
* plus one additional entry, i.e. (64KB + 64KB)/MMU_PAGE_SIZE + 1
*/
#if CONFIG_SECURE_ENABLE_TEE
#define TEE_MMU_MEM_REG_START_OFFS (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE)
#define TEE_MMU_RESV_PAGES ((CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE) / CONFIG_MMU_PAGE_SIZE)
#define TEE_MMU_MEM_REG_END_OFFS ((TEE_MMU_RESV_PAGES + 1) * CONFIG_MMU_PAGE_SIZE)
#define MMU_MEM_REG_START_ADDR_W_TEE (SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW + TEE_MMU_MEM_REG_START_OFFS)
#define MMU_MEM_REG_END_ADDR_W_TEE (SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH - TEE_MMU_MEM_REG_END_OFFS)
#define MMU_IRAM0_LINEAR_ADDRESS_LOW MMU_MEM_REG_START_ADDR_W_TEE
#define MMU_IRAM0_LINEAR_ADDRESS_HIGH MMU_MEM_REG_END_ADDR_W_TEE
#else
#define MMU_IRAM0_LINEAR_ADDRESS_LOW SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW
#define MMU_IRAM0_LINEAR_ADDRESS_HIGH SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH
#endif
/**
* The start addresses in this list should always be sorted from low to high, as MMU driver will need to
* coalesce adjacent regions
*/
const mmu_mem_region_t g_mmu_mem_regions[SOC_MMU_LINEAR_ADDRESS_REGION_NUM] = {
[0] = {
.start = SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW,
.end = SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH,
.size = SOC_BUS_SIZE(SOC_MMU_IRAM0_LINEAR),
.start = MMU_IRAM0_LINEAR_ADDRESS_LOW,
.end = MMU_IRAM0_LINEAR_ADDRESS_HIGH,
.size = MMU_IRAM0_LINEAR_ADDRESS_HIGH - MMU_IRAM0_LINEAR_ADDRESS_LOW,
.bus_id = CACHE_BUS_IBUS0 | CACHE_BUS_DBUS0,
.targets = MMU_TARGET_FLASH0,
.caps = MMU_MEM_CAP_EXEC | MMU_MEM_CAP_READ | MMU_MEM_CAP_32BIT | MMU_MEM_CAP_8BIT,

View File

@@ -1,4 +1,5 @@
idf_build_get_property(target IDF_TARGET)
idf_build_get_property(esp_tee_build ESP_TEE_BUILD)
# On Linux, we only support a few features, hence this simple component registration
if(${target} STREQUAL "linux")
@@ -22,7 +23,7 @@ if(CONFIG_IDF_ENV_FPGA OR CONFIG_ESP_BRINGUP_BYPASS_RANDOM_SETTING)
list(APPEND srcs "fpga_overrides_rng.c")
endif()
if(BOOTLOADER_BUILD)
if(BOOTLOADER_BUILD OR esp_tee_build)
# "_esp_error_check_failed()" requires spi_flash module
# Bootloader relies on some Kconfig options defined in esp_system.
idf_component_register(SRCS "${srcs}" REQUIRES spi_flash)

View File

@@ -121,7 +121,7 @@ menu "ESP System Settings"
config ESP_SYSTEM_PMP_IDRAM_SPLIT
bool "Enable IRAM/DRAM split protection"
depends on SOC_CPU_IDRAM_SPLIT_USING_PMP
depends on SOC_CPU_IDRAM_SPLIT_USING_PMP && !SECURE_ENABLE_TEE
default "y"
help
If enabled, the CPU watches all the memory access and raises an exception in case
@@ -141,6 +141,13 @@ menu "ESP System Settings"
Warning: on ESP32-P4 this will also mark the memory area used for BOOTLOADER_RESERVE_RTC_MEM
as executable. If you consider this a security risk then do not activate this option.
config ESP_SYSTEM_MEMPROT_FEATURE_VIA_TEE
bool "Enable memory protection (via TEE)"
depends on SECURE_ENABLE_TEE
default "y"
help
This option enables the default memory protection provided by TEE.
config ESP_SYSTEM_MEMPROT_FEATURE
bool "Enable memory protection"
depends on SOC_MEMPROT_SUPPORTED
@@ -592,7 +599,8 @@ menu "ESP System Settings"
config ESP_SYSTEM_HW_STACK_GUARD
bool "Hardware stack guard"
depends on SOC_ASSIST_DEBUG_SUPPORTED
# TODO: [ESP-TEE] IDF-10770
depends on SOC_ASSIST_DEBUG_SUPPORTED && !SECURE_ENABLE_TEE
default y
help
This config allows to trigger a panic interrupt when Stack Pointer register goes out of allocated stack

View File

@@ -15,7 +15,13 @@
#include "sdkconfig.h"
#include "ld.common"
#define SRAM_SEG_START 0x40800000
#if !CONFIG_SECURE_ENABLE_TEE
#define SRAM_SEG_START (0x40800000)
#else
#define SRAM_SEG_START (0x40800000 + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE)
#define FLASH_SEG_OFFSET (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE)
#endif // CONFIG_SECURE_ENABLE_TEE
#define SRAM_SEG_END 0x4086E610 /* 2nd stage bootloader iram_loader_seg start address */
#define SRAM_SEG_SIZE SRAM_SEG_END - SRAM_SEG_START
@@ -35,8 +41,14 @@ MEMORY
*/
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
#if CONFIG_SECURE_ENABLE_TEE
/* Flash mapped instruction data */
irom_seg (RX) : org = 0x42000020 + FLASH_SEG_OFFSET,
len = IDRAM0_2_SEG_SIZE - FLASH_SEG_OFFSET - 0x20
#else
/* Flash mapped instruction data */
irom_seg (RX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20
#endif
/**
* (0x20 offset above is a convenience for the app binary image generation.
@@ -54,8 +66,14 @@ MEMORY
sram_seg (RWX) : org = SRAM_SEG_START, len = SRAM_SEG_SIZE
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
#if CONFIG_SECURE_ENABLE_TEE
/* Flash mapped constant data */
drom_seg (R) : org = 0x42000020 + FLASH_SEG_OFFSET,
len = IDRAM0_2_SEG_SIZE - FLASH_SEG_OFFSET - 0x20
#else
/* Flash mapped instruction data */
drom_seg (R) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20
#endif
/* (See irom_seg for meaning of 0x20 offset in the above.) */
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS

View File

@@ -173,11 +173,22 @@ SECTIONS
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
_vector_table_start = ABSOLUTE(.);
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
ALIGNED_SYMBOL(4, _invalid_pc_placeholder)
/* esp_tee_config_t structure: used to share information between the TEE and REE
* (e.g. interrupt handler addresses, REE flash text-rodata boundaries, etc.)
* This symbol is expected by the TEE at an offset of 0x300 from the vector table start.
*/
#if CONFIG_SECURE_ENABLE_TEE
ALIGNED_SYMBOL(0x10, _esp_tee_app_cfg)
ASSERT(ABSOLUTE(.) == _vector_table_start + 0x2e0, "esp_tee_app_cfg must be at an offset 0x2e0 from the vector table start");
*libesp_tee.a:(.esp_tee_app_cfg);
#endif
/* Code marked as running out of IRAM */
_iram_text_start = ABSOLUTE(.);

View File

@@ -419,6 +419,15 @@ void IRAM_ATTR call_start_cpu0(void)
esp_cpu_intr_set_mtvt_addr(&_mtvt_table);
#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
rst_reas[0] = esp_rom_get_reset_reason(0);
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
rst_reas[1] = esp_rom_get_reset_reason(1);
@@ -606,8 +615,12 @@ void IRAM_ATTR call_start_cpu0(void)
#else
ESP_EARLY_LOGI(TAG, "Multicore app");
#endif
/* NOTE: When ESP-TEE is enabled, it configures its own memory protection
* scheme using the CPU-inherent features PMP and PMA and the APM peripheral.
*/
#if !CONFIG_SECURE_ENABLE_TEE
bootloader_init_mem();
#endif
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
s_cpu_up[0] = true;

View File

@@ -63,6 +63,12 @@ ESP_SYSTEM_INIT_FN(init_show_cpu_freq, CORE, BIT(0), 10)
return ESP_OK;
}
/* NOTE: When ESP-TEE is enabled, the Brownout Detection module is part
* of the TEE and is initialized in the TEE startup routine itself.
* It is protected from all REE accesses through memory protection mechanisms,
* as it is a critical module for device functioning.
*/
#if !CONFIG_SECURE_ENABLE_TEE
ESP_SYSTEM_INIT_FN(init_brownout, CORE, BIT(0), 104)
{
// [refactor-todo] leads to call chain rtc_is_register (driver) -> esp_intr_alloc (esp32/esp32s2) ->
@@ -76,6 +82,7 @@ ESP_SYSTEM_INIT_FN(init_brownout, CORE, BIT(0), 104)
#endif // CONFIG_ESP_BROWNOUT_DET
return ESP_OK;
}
#endif
ESP_SYSTEM_INIT_FN(init_newlib_time, CORE, BIT(0), 105)
{

View File

@@ -12,6 +12,11 @@
#include "heap_memory_layout.h"
#include "esp_heap_caps.h"
#if CONFIG_SECURE_ENABLE_TEE
#define SRAM_DIRAM_TEE_ORG (SOC_DIRAM_IRAM_LOW)
#define SRAM_DIRAM_TEE_END (SRAM_DIRAM_TEE_ORG + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE)
#endif
/**
* @brief Memory type descriptors. These describe the capabilities of a type of memory in the SoC.
* Each type of memory map consists of one or more regions in the address space.
@@ -95,6 +100,14 @@ SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_d
// Target has a shared D/IRAM virtual address, no need to calculate I_D_OFFSET like previous chips
SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code);
/* NOTE: When ESP-TEE is enabled, the start of the internal SRAM
* is used by the TEE and is protected from any REE access using
* memory protection mechanisms employed by ESP-TEE.
*/
#if CONFIG_SECURE_ENABLE_TEE
SOC_RESERVE_MEMORY_REGION((intptr_t)SRAM_DIRAM_TEE_ORG, (intptr_t)(SRAM_DIRAM_TEE_END), tee_diram);
#endif
#ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_slow_end, rtcram_data);
#endif