refactor(esp_tee): Reduce the default TEE DRAM size

- Decreased from 32KB to 24KB, keeping in mind the current maximum TEE heap
  usage and some overhead
- Make the TEE panic handler logs concise, saving some DRAM
This commit is contained in:
Laukik Hase
2025-04-09 19:01:47 +05:30
parent 8e27be344b
commit a845be0149
13 changed files with 164 additions and 154 deletions

View File

@@ -14,18 +14,18 @@ menu "ESP-TEE (Trusted Execution Environment)"
config SECURE_TEE_IRAM_SIZE
hex "IRAM region size"
default 0x8000
range 0x8000 0x10000
range 0x7000 0xA000
help
This configuration sets the IRAM size for the TEE module.
This should be a multiple of 0x1000.
This should be 256-byte (0x100) aligned.
config SECURE_TEE_DRAM_SIZE
hex "DRAM region size"
default 0x8000
range 0x8000 0x10000
default 0x6000
range 0x5000 0x7000
help
This configuration sets the DRAM size for the TEE module.
This should be a multiple of 0x1000.
This should be 256-byte (0x100) aligned.
config SECURE_TEE_STACK_SIZE
hex "Stack size"
@@ -34,7 +34,7 @@ menu "ESP-TEE (Trusted Execution Environment)"
help
This configuration sets the stack size for the TEE module.
The TEE stack will be allocated from the TEE DRAM region.
This should be a multiple of 0x100.
This should be 16-byte (0x10) aligned.
config SECURE_TEE_INTR_STACK_SIZE
hex "Interrupt Stack size"
@@ -43,7 +43,7 @@ menu "ESP-TEE (Trusted Execution Environment)"
help
This configuration sets the interrupt stack size for the TEE module.
The TEE interrupt stack will be allocated from the TEE DRAM region.
This should be a multiple of 0x100.
This should be 16-byte (0x10) aligned.
config SECURE_TEE_IROM_SIZE
hex

View File

@@ -23,6 +23,22 @@ extern "C" {
#define ALIGN_UP_TO_MMU_PAGE_SIZE(addr) (((addr) + (SOC_MMU_PAGE_SIZE) - 1) & ~((SOC_MMU_PAGE_SIZE) - 1))
#define ALIGN_DOWN_TO_MMU_PAGE_SIZE(addr) ((addr) & ~((SOC_MMU_PAGE_SIZE) - 1))
#if ((CONFIG_SECURE_TEE_IRAM_SIZE) & (0xFF))
#error "CONFIG_SECURE_TEE_IRAM_SIZE must be 256-byte (0x100) aligned"
#endif
#if ((CONFIG_SECURE_TEE_DRAM_SIZE) & (0xFF))
#error "CONFIG_SECURE_TEE_DRAM_SIZE must be 256-byte (0x100) aligned"
#endif
#if ((CONFIG_SECURE_TEE_STACK_SIZE) & 0xF)
#error "CONFIG_SECURE_TEE_STACK_SIZE must be 16-byte (0x10) aligned"
#endif
#if ((CONFIG_SECURE_TEE_INTR_STACK_SIZE) & 0xF)
#error "CONFIG_SECURE_TEE_INTR_STACK_SIZE must be 16-byte (0x10) aligned"
#endif
/* NOTE: ESP32-C6 - TEE/REE memory regions */
/* TEE I/DRAM */
#define SOC_S_IRAM_START (SOC_IRAM_LOW)

View File

@@ -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
*/
@@ -20,12 +20,12 @@
#include "esp_tee.h"
#include "esp_tee_apm_intr.h"
#include "esp_tee_rv_utils.h"
#include "panic_helper.h"
#include "sdkconfig.h"
#define RV_FUNC_STK_SZ (32)
#define tee_panic_print(format, ...) esp_rom_printf(DRAM_STR(format), ##__VA_ARGS__)
static void tee_panic_end(void)
{
// Disable interrupts
@@ -67,26 +67,27 @@ void abort(void)
ESP_INFINITE_LOOP();
}
static void panic_handler(void *frame, bool pseudo_exccause)
static void panic_print_info(const void *frame, int core)
{
int fault_core = esp_cpu_get_core_id();
tee_panic_print("\n=================================================\n");
tee_panic_print("Secure exception occurred on Core %d\n", fault_core);
if (pseudo_exccause) {
panic_print_isrcause((const void *)frame, fault_core);
} else {
panic_print_exccause((const void *)frame, fault_core);
}
tee_panic_print("=================================================\n");
panic_print_registers((const void *)frame, fault_core);
panic_print_registers((const void *)frame, core);
tee_panic_print("\n");
panic_print_backtrace((const void *)frame, 100);
tee_panic_print("\n");
tee_panic_print("Rebooting...\r\n\n");
tee_panic_end();
}
static void panic_handler(void *frame, bool pseudo_exccause)
{
int fault_core = esp_cpu_get_core_id();
if (pseudo_exccause) {
panic_print_isrcause((const void *)frame, fault_core);
} else {
panic_print_exccause((const void *)frame, fault_core);
}
panic_print_info((const void *)frame, fault_core);
ESP_INFINITE_LOOP();
}
@@ -105,34 +106,24 @@ void tee_apm_violation_isr(void *arg)
intptr_t exc_sp = RV_READ_CSR(mscratch);
RvExcFrame *frame = (RvExcFrame *)exc_sp;
apm_ctrl_path_t *apm_excp_type = NULL;
apm_ctrl_exception_info_t excp_info;
apm_ctrl_path_t *apm_excp_type = (apm_ctrl_path_t *)arg;
apm_ctrl_exception_info_t excp_info = {
.apm_path = {
.apm_ctrl = apm_excp_type->apm_ctrl,
.apm_m_path = apm_excp_type->apm_m_path,
}
};
apm_excp_type = (apm_ctrl_path_t *)arg;
excp_info.apm_path.apm_ctrl = apm_excp_type->apm_ctrl;
excp_info.apm_path.apm_m_path = apm_excp_type->apm_m_path;
apm_hal_apm_ctrl_get_exception_info(&excp_info);
/* Clear APM M path interrupt. */
apm_hal_apm_ctrl_exception_clear(apm_excp_type);
int fault_core = esp_cpu_get_core_id();
panic_print_rsn((const void *)frame, fault_core, esp_tee_apm_excp_type_to_str(excp_info.excp_type));
tee_panic_print("\n=================================================\n");
tee_panic_print("APM permission violation occurred on Core %d\n", fault_core);
tee_panic_print("Guru Meditation Error: Core %d panic'ed (%s). ", fault_core, esp_tee_apm_excp_type_to_str(excp_info.excp_type));
tee_panic_print("Exception was unhandled.\n");
tee_panic_print("Fault addr: 0x%x | Mode: %s\n", excp_info.excp_addr, esp_tee_apm_excp_mode_to_str(excp_info.excp_mode));
tee_panic_print("Module: %s | Path: 0x%02x\n", esp_tee_apm_excp_ctrl_to_str(excp_info.apm_path.apm_ctrl), excp_info.apm_path.apm_m_path);
tee_panic_print("Master: %s | Region: 0x%02x\n", esp_tee_apm_excp_mid_to_str(excp_info.excp_id), excp_info.excp_regn);
tee_panic_print("=================================================\n");
panic_print_registers((const void *)frame, fault_core);
tee_panic_print("\n");
panic_print_backtrace((const void *)frame, 100);
tee_panic_print("\n");
tee_panic_print("Rebooting...\r\n\n");
tee_panic_print("Access addr: 0x%x | Mode: %s\n", excp_info.excp_addr, esp_tee_apm_excp_mode_to_str(excp_info.excp_mode));
tee_panic_print("Module: %s | Path: %d\n", esp_tee_apm_excp_ctrl_to_str(excp_info.apm_path.apm_ctrl), excp_info.apm_path.apm_m_path);
tee_panic_print("Master: %s | Region: %d\n", esp_tee_apm_excp_mid_to_str(excp_info.excp_id), (excp_info.excp_regn == 0) ? 0 : (__builtin_ffs(excp_info.excp_regn) - 1));
tee_panic_end();
panic_print_info((const void *)frame, fault_core);
ESP_INFINITE_LOOP();
}

View File

@@ -3,11 +3,21 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdarg.h>
#include "esp_rom_sys.h"
#if CONFIG_SECURE_TEE_DEBUG_MODE
#define tee_panic_print(format, ...) esp_rom_printf(DRAM_STR(format), ##__VA_ARGS__)
#else
#define tee_panic_print(format, ...)
#endif
void panic_print_backtrace(const void *f, int depth);
void panic_print_registers(const void *f, int core);
void panic_print_rsn(const void *f, int core, const char *rsn);
void panic_print_exccause(const void *f, int core);
void panic_print_isrcause(const void *f, int core);

View File

@@ -13,8 +13,8 @@
#include "riscv/rvruntime-frames.h"
#include "esp_tee.h"
#define tee_panic_print(format, ...) esp_rom_printf(DRAM_STR(format), ##__VA_ARGS__)
#include "panic_helper.h"
#include "sdkconfig.h"
void panic_print_backtrace(const void *f, int depth)
{
@@ -55,23 +55,47 @@ void panic_print_registers(const void *f, int core)
}
}
tee_panic_print("MIE : 0x%08x ", RV_READ_CSR(mie));
tee_panic_print("MIP : 0x%08x ", RV_READ_CSR(mip));
tee_panic_print("MSCRATCH: 0x%08x\n", RV_READ_CSR(mscratch));
tee_panic_print("UEPC : 0x%08x ", RV_READ_CSR(uepc));
tee_panic_print("USTATUS : 0x%08x ", RV_READ_CSR(ustatus));
tee_panic_print("UTVEC : 0x%08x ", RV_READ_CSR(utvec));
tee_panic_print("UCAUSE : 0x%08x\n", RV_READ_CSR(ucause));
tee_panic_print("UTVAL : 0x%08x ", RV_READ_CSR(utval));
tee_panic_print("UIE : 0x%08x ", RV_READ_CSR(uie));
tee_panic_print("UIP : 0x%08x\n", RV_READ_CSR(uip));
#if CONFIG_SECURE_TEE_TEST_MODE
struct {
const char *name;
uint32_t value;
} csr_regs[] = {
{ "MIE ", RV_READ_CSR(mie) },
{ "MIP ", RV_READ_CSR(mip) },
{ "MSCRATCH", RV_READ_CSR(mscratch) },
{ "UEPC ", RV_READ_CSR(uepc) },
{ "USTATUS ", RV_READ_CSR(ustatus) },
{ "UTVEC ", RV_READ_CSR(utvec) },
{ "UCAUSE ", RV_READ_CSR(ucause) },
{ "UTVAL ", RV_READ_CSR(utval) },
{ "UIE ", RV_READ_CSR(uie) },
{ "UIP ", RV_READ_CSR(uip) },
};
tee_panic_print("\n\n");
for (int i = 0; i < sizeof(csr_regs) / sizeof(csr_regs[0]); i++) {
tee_panic_print("%s: 0x%08x ", csr_regs[i].name, csr_regs[i].value);
if ((i + 1) % 4 == 0 || i == sizeof(csr_regs) / sizeof(csr_regs[0]) - 1) {
tee_panic_print("\n");
}
}
#endif
}
void panic_print_rsn(const void *f, int core, const char *rsn)
{
const RvExcFrame *regs = (const RvExcFrame *)f;
const void *addr = (const void *)regs->mepc;
tee_panic_print("Guru Meditation Error: Core %d panic'ed (%s). Exception was unhandled.\n", core, rsn);
tee_panic_print("Fault addr: %p | Origin: %s\n", addr, (regs->mstatus & MSTATUS_MPP) ? "M-mode" : "U-mode");
}
void panic_print_exccause(const void *f, int core)
{
RvExcFrame *regs = (RvExcFrame *) f;
const RvExcFrame *regs = (const RvExcFrame *)f;
//Please keep in sync with PANIC_RSN_* defines
static const char *reason[] = {
"Instruction address misaligned",
"Instruction access fault",
@@ -98,27 +122,14 @@ void panic_print_exccause(const void *f, int core)
}
}
const char *desc = "Exception was unhandled.";
const void *addr = (void *) regs->mepc;
tee_panic_print("Guru Meditation Error: Core %d panic'ed (%s). %s\n", core, rsn, desc);
const char *exc_origin = "U-mode";
if (regs->mstatus & MSTATUS_MPP) {
exc_origin = "M-mode";
}
tee_panic_print("Fault addr: %p | Exception origin: %s\n", addr, exc_origin);
panic_print_rsn(f, core, rsn);
}
void panic_print_isrcause(const void *f, int core)
{
RvExcFrame *regs = (RvExcFrame *) f;
const void *addr = (void *) regs->mepc;
const RvExcFrame *regs = (const RvExcFrame *)f;
const char *rsn = "Unknown reason";
/* The mcause has been set by the CPU when the panic occurred.
* All SoC-level panic will call this function, thus, this register
* lets us know which error was triggered. */
switch (regs->mcause) {
case ETS_CACHEERR_INUM:
rsn = "Cache error";
@@ -131,16 +142,7 @@ void panic_print_isrcause(const void *f, int core)
rsn = "Interrupt wdt timeout on CPU1";
break;
#endif
default:
break;
}
const char *desc = "Exception was unhandled.";
tee_panic_print("Guru Meditation Error: Core %d panic'ed (%s). %s\n", core, rsn, desc);
const char *exc_origin = "U-mode";
if (regs->mstatus & MSTATUS_MPP) {
exc_origin = "M-mode";
}
tee_panic_print("Fault addr: %p | Exception origin: %s\n", addr, exc_origin);
panic_print_rsn(f, core, rsn);
}

View File

@@ -120,7 +120,7 @@ SECTIONS
.dram.tee.heap :
{
. = ALIGN (8);
. = ALIGN (16);
_tee_heap_start = ABSOLUTE(.);
. = ORIGIN(dram_tee_seg) + LENGTH(dram_tee_seg);
_tee_heap_end = ABSOLUTE(.);
@@ -128,19 +128,17 @@ SECTIONS
.dram.tee.stack :
{
. = ALIGN (8);
. = ALIGN (16);
_tee_stack_bottom = ABSOLUTE(.);
. = ORIGIN(stack_tee_seg) + LENGTH(stack_tee_seg);
. = ALIGN (8);
_tee_stack = ABSOLUTE(.);
} > stack_tee_seg
.dram.tee.intr_stack :
{
. = ALIGN (8);
. = ALIGN (16);
_tee_intr_stack_bottom = ABSOLUTE(.);
. = ORIGIN(intr_stack_tee_seg) + LENGTH(intr_stack_tee_seg);
. = ALIGN (8);
_tee_intr_stack = ABSOLUTE(.);
} > intr_stack_tee_seg
@@ -222,7 +220,6 @@ SECTIONS
.iram.tee.text :
{
. = ALIGN(4);
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
_tee_vec_start = ABSOLUTE(.);

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -12,69 +12,39 @@
#include "esp_tee.h"
#include "esp_tee_apm_intr.h"
static const char *const excp_mid_strs[] = {
[APM_LL_MASTER_HPCORE] = "HPCORE",
[APM_LL_MASTER_LPCORE] = "LPCORE",
[APM_LL_MASTER_REGDMA] = "REGDMA",
[APM_LL_MASTER_SDIOSLV] = "SDIOSLV",
[APM_LL_MASTER_MODEM] = "MODEM",
[APM_LL_MASTER_MEM_MONITOR] = "MEM_MONITOR",
[APM_LL_MASTER_TRACE] = "TRACE",
[APM_LL_MASTER_GDMA_SPI2] = "GDMA_SPI2",
[APM_LL_MASTER_GDMA_UHCI0] = "GDMA_UHCI0",
[APM_LL_MASTER_GDMA_I2S0] = "GDMA_I2S0",
[APM_LL_MASTER_GDMA_AES] = "GDMA_AES",
[APM_LL_MASTER_GDMA_SHA] = "GDMA_SHA",
[APM_LL_MASTER_GDMA_ADC] = "GDMA_ADC",
[APM_LL_MASTER_GDMA_PARLIO] = "GDMA_PARLIO",
};
const char *esp_tee_apm_excp_mid_to_str(uint8_t mid)
{
char *excp_mid = NULL;
switch (mid) {
case APM_LL_MASTER_HPCORE:
excp_mid = "HPCORE";
break;
case APM_LL_MASTER_LPCORE:
excp_mid = "LPCORE";
break;
case APM_LL_MASTER_REGDMA:
excp_mid = "REGDMA";
break;
case APM_LL_MASTER_SDIOSLV:
excp_mid = "SDIOSLV";
break;
case APM_LL_MASTER_MODEM:
excp_mid = "MODEM";
break;
case APM_LL_MASTER_MEM_MONITOR:
excp_mid = "MEM_MONITOR";
break;
case APM_LL_MASTER_TRACE:
excp_mid = "TRACE";
break;
case APM_LL_MASTER_GDMA_SPI2:
excp_mid = "GDMA_SPI2";
break;
case APM_LL_MASTER_GDMA_UHCI0:
excp_mid = "GDMA_UHCI0";
break;
case APM_LL_MASTER_GDMA_I2S0:
excp_mid = "GDMA_I2S0";
break;
case APM_LL_MASTER_GDMA_AES:
excp_mid = "GDMA_AES";
break;
case APM_LL_MASTER_GDMA_SHA:
excp_mid = "GDMA_SHA";
break;
case APM_LL_MASTER_GDMA_ADC:
excp_mid = "GDMA_ADC";
break;
case APM_LL_MASTER_GDMA_PARLIO:
excp_mid = "GDMA_PARLIO";
break;
default:
excp_mid = "Unknown";
break;
if (mid < sizeof(excp_mid_strs) / sizeof(excp_mid_strs[0]) && excp_mid_strs[mid]) {
return excp_mid_strs[mid];
}
return excp_mid;
return "Unknown";
}
const char *esp_tee_apm_excp_type_to_str(uint8_t type)
{
char *excp_type = "Unknown exception";
char *excp_type = "APM - Unknown exception";
if (type & 0x01) {
excp_type = "Authority exception";
excp_type = "APM - Authority exception";
} else if (type & 0x02) {
excp_type = "Space exception";
excp_type = "APM - Space exception";
}
return excp_type;

View File

@@ -1,6 +1,11 @@
idf_component_register(SRCS "tee_srv_att.c"
"tee_srv_ota.c"
"tee_srv_sec_str.c"
"tee_cmd_wifi.c"
"app_main.c"
set(srcs "tee_srv_ota.c"
"tee_srv_sec_str.c"
"tee_cmd_wifi.c"
"app_main.c")
if(CONFIG_SECURE_TEE_ATTESTATION)
list(APPEND srcs "tee_srv_att.c")
endif()
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS ".")

View File

@@ -41,7 +41,9 @@ static void setup_console(void)
register_cmd_wifi();
register_srv_tee_ota();
register_srv_user_ota();
#if CONFIG_SECURE_TEE_ATTESTATION
register_srv_attestation();
#endif
register_cmd_msg_sha256();
register_srv_sec_stg_gen_key();
register_srv_sec_stg_sign();

View File

@@ -0,0 +1,18 @@
# Minimal TEE configuration
CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE=y
CONFIG_SECURE_TEE_SEC_STG_KEY_EFUSE_BLK=9
# Reducing TEE DRAM and STACK sizes
# 21KB
CONFIG_SECURE_TEE_DRAM_SIZE=0x5400
# 2.5KB
CONFIG_SECURE_TEE_STACK_SIZE=0xa00
# Disabling ATTESTATION
CONFIG_SECURE_TEE_ATTESTATION=n
# Disabling flash protection over SPI1
CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1=n
# Disabling support for SECP192R1 signature
CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN=n

View File

@@ -1,6 +1,5 @@
# Enabling TEE
CONFIG_SECURE_ENABLE_TEE=y
CONFIG_SECURE_TEE_IRAM_SIZE=0x9000
# Enabling flash protection over SPI1
CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1=y

View File

@@ -94,7 +94,7 @@ def test_esp_tee_apm_violation(dut: IdfDut) -> None:
dut.expect_exact('Press ENTER to see the list of tests')
dut.write(f'"Test APM violation interrupt: {check}"')
exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode()
if exc != 'Authority exception':
if exc != 'APM - Authority exception':
raise RuntimeError('Incorrect exception received!')
@@ -141,7 +141,7 @@ def test_esp_tee_isolation_checks(dut: IdfDut) -> None:
actual_exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode()
if actual_exc != expected_exc:
raise RuntimeError('Incorrect exception received!')
dut.expect('Exception origin: U-mode')
dut.expect('Origin: U-mode')
# ---------------- TEE Flash Protection Tests ----------------
@@ -158,7 +158,7 @@ class TeeFlashAccessApi(Enum):
def check_panic_or_reset(dut: IdfDut) -> None:
try:
exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=5).group(2).decode()
if exc not in {'Cache error', 'Authority exception'}:
if exc not in {'Cache error', 'APM - Authority exception'}:
raise RuntimeError('Flash operation incorrect exception')
except Exception:
rst_rsn = dut.expect(r'rst:(0x[0-9A-Fa-f]+) \(([^)]+)\)', timeout=5).group(2).decode()

View File

@@ -13,4 +13,4 @@ CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
# TEE IRAM size
CONFIG_SECURE_TEE_IRAM_SIZE=0x9000
CONFIG_SECURE_TEE_IRAM_SIZE=0x8400