diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index 815576c30f..1af6ab17a0 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -128,7 +128,7 @@ /components/freertos/ @esp-idf-codeowners/system /components/hal/ @esp-idf-codeowners/peripherals /components/hal/test_apps/crypto/ @esp-idf-codeowners/peripherals @esp-idf-codeowners/security -/components/hal/test_apps/tee_apm/ @esp-idf-codeowners/peripherals @esp-idf-codeowners/security +/components/hal/test_apps/tee/ @esp-idf-codeowners/peripherals @esp-idf-codeowners/security /components/heap/ @esp-idf-codeowners/system /components/http_parser/ @esp-idf-codeowners/app-utilities /components/idf_test/ @esp-idf-codeowners/peripherals @esp-idf-codeowners/system diff --git a/components/hal/.build-test-rules.yml b/components/hal/.build-test-rules.yml index b4e746e70e..648fa21a5f 100644 --- a/components/hal/.build-test-rules.yml +++ b/components/hal/.build-test-rules.yml @@ -12,6 +12,6 @@ components/hal/test_apps/hal_utils: enable: - if: IDF_TARGET == "linux" -components/hal/test_apps/tee_apm: +components/hal/test_apps/tee: disable: - if: IDF_TARGET not in ["esp32c6", "esp32h2", "esp32c5", "esp32c61"] diff --git a/components/hal/test_apps/tee_apm/CMakeLists.txt b/components/hal/test_apps/tee/CMakeLists.txt similarity index 95% rename from components/hal/test_apps/tee_apm/CMakeLists.txt rename to components/hal/test_apps/tee/CMakeLists.txt index 582823ff35..ea3b3840cb 100644 --- a/components/hal/test_apps/tee_apm/CMakeLists.txt +++ b/components/hal/test_apps/tee/CMakeLists.txt @@ -6,7 +6,7 @@ set(COMPONENTS main) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(test_tee_apm) +project(test_tee_pms_cpu_intr) include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake) message(STATUS "Checking tee/apm registers are not read-write by half-word") diff --git a/components/hal/test_apps/tee_apm/README.md b/components/hal/test_apps/tee/README.md similarity index 82% rename from components/hal/test_apps/tee_apm/README.md rename to components/hal/test_apps/tee/README.md index 62a5fdcd03..262aed3209 100644 --- a/components/hal/test_apps/tee_apm/README.md +++ b/components/hal/test_apps/tee/README.md @@ -1,15 +1,21 @@ | Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | | ----------------- | -------- | -------- | --------- | -------- | -# APM (Access Permission Management) Peripheral Test App +# TEE (Trusted Execution Environment) Test Application -This application validates region-based memory and peripheral access control via the APM (Access Permission Management) subsystem. It is primarily intended for bring-up and SoC-level functional testing. +This application is designed to validate the key components of the **ESP-TEE** framework, with a focus on: -Tests exercise various master-to-region accesses under different security modes (`TEE`, `REE0`, `REE1`, `REE2`). Outcomes are validated against expected APM behavior and known SoC-specific quirks. +1. **Permission Management (PMS: TEE controller + APM module)** + - Region-based memory and peripheral access control using the TEE controller and the Access Permission Management (APM) module + +2. **Interrupts** + - Interrupt handling in Machine mode (M), User mode (U), and cross-mode contexts + +It is primarily intended for early bring-up and SoC-level functional validation. --- -## Test Coverage +## Test Coverage: PMS (TEE + APM module) ### TEE mode default access behavior @@ -51,6 +57,13 @@ Validates the per-peripheral access permissions for all security modes. --- +## Test Coverage: Interrupts + +- **M-mode interrupts in M-mode** +- **U-mode interrupts in U-mode** +- **M-mode interrupts in U-mode** +- **U-mode interrupts in M-mode** + ## Target Extension Guide To add support for a new SoC target, create a test configuration header at: diff --git a/components/hal/test_apps/tee_apm/components/pms/CMakeLists.txt b/components/hal/test_apps/tee/components/pms_and_cpu_intr/CMakeLists.txt similarity index 51% rename from components/hal/test_apps/tee_apm/components/pms/CMakeLists.txt rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/CMakeLists.txt index 2e9541335e..bd32b9da64 100644 --- a/components/hal/test_apps/tee_apm/components/pms/CMakeLists.txt +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/CMakeLists.txt @@ -1,14 +1,21 @@ cmake_minimum_required(VERSION 3.16) idf_build_get_property(target IDF_TARGET) -set(srcs "src/test_tee_vectors.S" - "src/test_panic_handler.c" - "src/test_intr_utils.c" - "src/test_apm_utils.c" - "src/test_setup_utils.c" - "src/test_tee_sys_apm.c") -if(CONFIG_SOC_APM_SUPPORT_TEE_PERI_ACCESS_CTRL) - list(APPEND srcs "src/test_tee_peri_apm.c") +set(srcs "src/common/test_apm_utils.c" + "src/common/test_intr_utils.c" + "src/common/test_setup_utils.c" + "src/common/test_panic_handler.c") + +list(APPEND srcs "src/pms/test_tee_sys_apm.c" + "src/pms/test_tee_vectors.S") +if(CONFIG_SOC_SUPPORT_TEE_PERI_APM_TEST) + list(APPEND srcs "src/pms/test_tee_peri_apm.c") +endif() + +if(CONFIG_SOC_SUPPORT_TEE_INTR_TEST) + list(APPEND srcs "src/cpu_intr/test_interrupt.c" + "src/cpu_intr/test_vectors_m.S" + "src/cpu_intr/test_vectors_u.S") endif() idf_component_register(SRCS "${srcs}" @@ -20,6 +27,5 @@ idf_component_register(SRCS "${srcs}" if(CONFIG_ULP_COPROC_ENABLED) set(ulp_app_name ulp_lp_core_${COMPONENT_NAME}) set(ulp_rv_srcs "src/ulp/ulp_lp_core_main.c" "src/ulp/ulp_vectors.S") - set(ulp_exp_dep_srcs "src/test_tee_apm_pms.c") ulp_embed_binary(${ulp_app_name} "${ulp_rv_srcs}" "${ulp_exp_dep_srcs}") endif() diff --git a/components/hal/test_apps/tee/components/pms_and_cpu_intr/Kconfig b/components/hal/test_apps/tee/components/pms_and_cpu_intr/Kconfig new file mode 100644 index 0000000000..eab435ae2f --- /dev/null +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/Kconfig @@ -0,0 +1,18 @@ +menu "Test-app related" + + config SOC_SUPPORT_TEE_SYS_APM_TEST + bool + depends on SOC_APM_CTRL_FILTER_SUPPORTED + default y + + config SOC_SUPPORT_TEE_PERI_APM_TEST + bool + depends on SOC_APM_SUPPORT_TEE_PERI_ACCESS_CTRL + default y + + config SOC_SUPPORT_TEE_INTR_TEST + bool + depends on IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C61 + default y + +endmenu diff --git a/components/hal/test_apps/tee/components/pms_and_cpu_intr/include/test_cpu_intr.h b/components/hal/test_apps/tee/components/pms_and_cpu_intr/include/test_cpu_intr.h new file mode 100644 index 0000000000..59a17c5b29 --- /dev/null +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/include/test_cpu_intr.h @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +/* Test-cases */ +void test_m_mode_intr_in_m_mode(void); + +void test_u_mode_intr_in_u_mode(void); + +void test_m_mode_intr_in_u_mode(void); + +void test_u_mode_intr_in_m_mode(void); diff --git a/components/hal/test_apps/tee_apm/components/pms/include/test_pms.h b/components/hal/test_apps/tee/components/pms_and_cpu_intr/include/test_pms.h similarity index 100% rename from components/hal/test_apps/tee_apm/components/pms/include/test_pms.h rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/include/test_pms.h diff --git a/components/hal/test_apps/tee_apm/components/pms/linker.lf b/components/hal/test_apps/tee/components/pms_and_cpu_intr/linker.lf similarity index 53% rename from components/hal/test_apps/tee_apm/components/pms/linker.lf rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/linker.lf index 0af8398a7e..2826c5bff2 100644 --- a/components/hal/test_apps/tee_apm/components/pms/linker.lf +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/linker.lf @@ -1,5 +1,5 @@ -[mapping:pms] -archive: libpms.a +[mapping:test_pms_and_cpu_intr] +archive: libpms_and_cpu_intr.a entries: test_intr_utils (noflash) test_panic_handler (noflash) diff --git a/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c5/test_cpu_intr_params.h b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c5/test_cpu_intr_params.h new file mode 100644 index 0000000000..ec36c77598 --- /dev/null +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c5/test_cpu_intr_params.h @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#define TEST_INTR_NUM_PASS_IN_SEC (31) + +#ifndef __ASSEMBLER__ +#include "soc/interrupts.h" + +#define TG0_T0_INTR_SRC (ETS_TG0_T0_LEVEL_INTR_SOURCE) +#define CPU_FROM_CPU_N_INTR_SRC(n) (ETS_FROM_CPU_INTR0_SOURCE + n) +#endif diff --git a/components/hal/test_apps/tee_apm/components/pms/priv_include/esp32c5/test_pms_params.h b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c5/test_pms_params.h similarity index 88% rename from components/hal/test_apps/tee_apm/components/pms/priv_include/esp32c5/test_pms_params.h rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c5/test_pms_params.h index 0a78d3d6b3..b8ff56f4f9 100644 --- a/components/hal/test_apps/tee_apm/components/pms/priv_include/esp32c5/test_pms_params.h +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c5/test_pms_params.h @@ -198,3 +198,45 @@ #define TEST_LP_PERI_ADDR7 TEST_LP_PERI_REGION7_START #define TEST_LP_PERI_RESV_MASK BIT(0) | BIT(2) + +/********* For PERI_APM *********/ + +#include "soc/reg_base.h" + +/********* For PERI_APM *********/ +#include "soc/uart_reg.h" +#include "soc/i2c_reg.h" +#include "soc/i2s_reg.h" +#include "soc/mcpwm_reg.h" +#include "soc/twaifd_reg.h" +#include "soc/ahb_dma_reg.h" +#include "soc/pau_reg.h" +#include "soc/interrupt_matrix_reg.h" +#include "soc/apb_saradc_reg.h" +#include "soc/timer_group_reg.h" +#include "soc/pcnt_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/hp_system_reg.h" +#include "soc/pcr_reg.h" +#include "soc/spi_mem_reg.h" +#include "soc/hp_apm_reg.h" +#include "soc/cpu_apm_reg.h" +#include "soc/sha_reg.h" +#include "soc/cache_reg.h" +#include "soc/spi_reg.h" +#include "soc/bitscrambler_reg.h" +#include "soc/keymng_reg.h" +#include "soc/sdio_slc_host_reg.h" + +#include "soc/efuse_reg.h" +#include "soc/pmu_reg.h" +#include "soc/lp_clkrst_reg.h" +#include "soc/lp_aon_reg.h" +#include "soc/lp_wdt_reg.h" +#include "soc/lpperi_reg.h" +#include "soc/lp_analog_peri_reg.h" +#include "soc/lp_uart_reg.h" +#include "soc/lp_i2c_reg.h" +#include "soc/lp_i2c_ana_mst_reg.h" +#include "soc/huk_reg.h" +#include "soc/lp_apm_reg.h" diff --git a/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c5/test_rv_utils.h b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c5/test_rv_utils.h new file mode 100644 index 0000000000..8865e9076b --- /dev/null +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c5/test_rv_utils.h @@ -0,0 +1,152 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include + +#include "esp_attr.h" + +#include "soc/soc_caps.h" +#include "soc/clic_reg.h" +#include "hal/interrupt_clic_ll.h" + +#include "riscv/csr.h" +#include "riscv/encoding.h" +#include "riscv/interrupt.h" +#include "esp_private/interrupt_clic.h" + +#include "sdkconfig.h" + +#define UTVT_CSR (0x007) +#define UINTSTATUS_CSR (0xCB1) +#define UINTTHRESH_CSR (0x047) + +#ifdef __cplusplus +extern "C" { +#endif + +FORCE_INLINE_ATTR void test_rv_utils_set_xtvec(uint32_t xtvec_val, int mode) +{ + xtvec_val |= MTVEC_MODE_CSR; + if (mode == PRV_M) { + RV_WRITE_CSR(mtvec, xtvec_val); + } else { + RV_WRITE_CSR(utvec, xtvec_val); + } +} + +FORCE_INLINE_ATTR void test_rv_utils_set_xtvt(uint32_t xtvt_val, int mode) +{ + if (mode == PRV_M) { + RV_WRITE_CSR(MTVT_CSR, xtvt_val); + } else { + RV_WRITE_CSR(UTVT_CSR, xtvt_val); + } +} + +FORCE_INLINE_ATTR void test_rv_utils_intr_global_enable(int mode) +{ + if (mode == PRV_M) { + RV_SET_CSR(mstatus, MSTATUS_MIE); + RV_SET_CSR(mstatus, MSTATUS_UIE); + } else { + RV_SET_CSR(ustatus, USTATUS_UIE); + } +} + +FORCE_INLINE_ATTR void test_rv_utils_intr_global_disable(int mode) +{ + if (mode == PRV_M) { + RV_CLEAR_CSR(mstatus, MSTATUS_MIE); + RV_CLEAR_CSR(mstatus, MSTATUS_UIE); + } else { + RV_CLEAR_CSR(ustatus, USTATUS_UIE); + } +} + +FORCE_INLINE_ATTR void test_rv_utils_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 test_rv_utils_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 test_rv_utils_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 test_rv_utils_intr_set_priority(int intr_num, int priority) +{ + assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); + *(uint8_t volatile *)(BYTE_CLIC_INT_CTL_REG(intr_num + CLIC_EXT_INTR_NUM_OFFSET)) = (priority << BYTE_CLIC_INT_CTL_S); +} + +FORCE_INLINE_ATTR void test_rv_utils_intr_set_threshold(int priority_threshold, int mode) +{ + uint32_t adj_threshold = ((priority_threshold << (8 - NLBITS)) | 0x1f); + if (mode == PRV_M) { + REG_SET_FIELD(CLIC_INT_THRESH_REG, CLIC_CPU_INT_THRESH, adj_threshold); + RV_WRITE_CSR(MINTTHRESH_CSR, adj_threshold); + } else { + RV_WRITE_CSR(UINTTHRESH_CSR, adj_threshold); + } +} + +FORCE_INLINE_ATTR void test_rv_utils_intr_set_mode(int intr_num, int mode) +{ + assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); + REG_SET_FIELD(CLIC_INT_CTRL_REG(intr_num + CLIC_EXT_INTR_NUM_OFFSET), CLIC_INT_ATTR_MODE, mode); +} + +FORCE_INLINE_ATTR void test_rv_utils_intr_set_vectored(int intr_num, bool vectored) +{ + REG_SET_FIELD(CLIC_INT_CTRL_REG(intr_num + CLIC_EXT_INTR_NUM_OFFSET), CLIC_INT_ATTR_SHV, vectored ? 1 : 0); +} + +FORCE_INLINE_ATTR void test_rv_utils_intr_enable_u_mode(bool enable) +{ + REG_SET_FIELD(CLIC_INT_CONFIG_REG, CLIC_INT_CONFIG_NMBITS, enable ? 0x01 : 0x00); + REG_SET_FIELD(CLIC_INT_CONFIG_REG, CLIC_INT_CONFIG_UNLBITS, NLBITS); + REG_SET_FIELD(CLIC_INT_CONFIG_REG, CLIC_INT_CONFIG_MNLBITS, NLBITS); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/test_apps/tee_apm/components/pms/priv_include/esp32c6/test_pms_params.h b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c6/test_pms_params.h similarity index 100% rename from components/hal/test_apps/tee_apm/components/pms/priv_include/esp32c6/test_pms_params.h rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c6/test_pms_params.h diff --git a/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c61/test_cpu_intr_params.h b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c61/test_cpu_intr_params.h new file mode 100644 index 0000000000..3aa7729291 --- /dev/null +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c61/test_cpu_intr_params.h @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#define TEST_INTR_NUM_PASS_IN_SEC (31) + +#ifndef __ASSEMBLER__ +#include "soc/interrupts.h" + +#define TG0_T0_INTR_SRC (ETS_TG0_T0_INTR_SOURCE) +#define CPU_FROM_CPU_N_INTR_SRC(n) (ETS_CPU_INTR_FROM_CPU_0_SOURCE + n) +#endif diff --git a/components/hal/test_apps/tee_apm/components/pms/priv_include/esp32c61/test_pms_params.h b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c61/test_pms_params.h similarity index 100% rename from components/hal/test_apps/tee_apm/components/pms/priv_include/esp32c61/test_pms_params.h rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c61/test_pms_params.h diff --git a/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c61/test_rv_utils.h b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c61/test_rv_utils.h new file mode 100644 index 0000000000..8865e9076b --- /dev/null +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32c61/test_rv_utils.h @@ -0,0 +1,152 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include + +#include "esp_attr.h" + +#include "soc/soc_caps.h" +#include "soc/clic_reg.h" +#include "hal/interrupt_clic_ll.h" + +#include "riscv/csr.h" +#include "riscv/encoding.h" +#include "riscv/interrupt.h" +#include "esp_private/interrupt_clic.h" + +#include "sdkconfig.h" + +#define UTVT_CSR (0x007) +#define UINTSTATUS_CSR (0xCB1) +#define UINTTHRESH_CSR (0x047) + +#ifdef __cplusplus +extern "C" { +#endif + +FORCE_INLINE_ATTR void test_rv_utils_set_xtvec(uint32_t xtvec_val, int mode) +{ + xtvec_val |= MTVEC_MODE_CSR; + if (mode == PRV_M) { + RV_WRITE_CSR(mtvec, xtvec_val); + } else { + RV_WRITE_CSR(utvec, xtvec_val); + } +} + +FORCE_INLINE_ATTR void test_rv_utils_set_xtvt(uint32_t xtvt_val, int mode) +{ + if (mode == PRV_M) { + RV_WRITE_CSR(MTVT_CSR, xtvt_val); + } else { + RV_WRITE_CSR(UTVT_CSR, xtvt_val); + } +} + +FORCE_INLINE_ATTR void test_rv_utils_intr_global_enable(int mode) +{ + if (mode == PRV_M) { + RV_SET_CSR(mstatus, MSTATUS_MIE); + RV_SET_CSR(mstatus, MSTATUS_UIE); + } else { + RV_SET_CSR(ustatus, USTATUS_UIE); + } +} + +FORCE_INLINE_ATTR void test_rv_utils_intr_global_disable(int mode) +{ + if (mode == PRV_M) { + RV_CLEAR_CSR(mstatus, MSTATUS_MIE); + RV_CLEAR_CSR(mstatus, MSTATUS_UIE); + } else { + RV_CLEAR_CSR(ustatus, USTATUS_UIE); + } +} + +FORCE_INLINE_ATTR void test_rv_utils_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 test_rv_utils_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 test_rv_utils_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 test_rv_utils_intr_set_priority(int intr_num, int priority) +{ + assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); + *(uint8_t volatile *)(BYTE_CLIC_INT_CTL_REG(intr_num + CLIC_EXT_INTR_NUM_OFFSET)) = (priority << BYTE_CLIC_INT_CTL_S); +} + +FORCE_INLINE_ATTR void test_rv_utils_intr_set_threshold(int priority_threshold, int mode) +{ + uint32_t adj_threshold = ((priority_threshold << (8 - NLBITS)) | 0x1f); + if (mode == PRV_M) { + REG_SET_FIELD(CLIC_INT_THRESH_REG, CLIC_CPU_INT_THRESH, adj_threshold); + RV_WRITE_CSR(MINTTHRESH_CSR, adj_threshold); + } else { + RV_WRITE_CSR(UINTTHRESH_CSR, adj_threshold); + } +} + +FORCE_INLINE_ATTR void test_rv_utils_intr_set_mode(int intr_num, int mode) +{ + assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); + REG_SET_FIELD(CLIC_INT_CTRL_REG(intr_num + CLIC_EXT_INTR_NUM_OFFSET), CLIC_INT_ATTR_MODE, mode); +} + +FORCE_INLINE_ATTR void test_rv_utils_intr_set_vectored(int intr_num, bool vectored) +{ + REG_SET_FIELD(CLIC_INT_CTRL_REG(intr_num + CLIC_EXT_INTR_NUM_OFFSET), CLIC_INT_ATTR_SHV, vectored ? 1 : 0); +} + +FORCE_INLINE_ATTR void test_rv_utils_intr_enable_u_mode(bool enable) +{ + REG_SET_FIELD(CLIC_INT_CONFIG_REG, CLIC_INT_CONFIG_NMBITS, enable ? 0x01 : 0x00); + REG_SET_FIELD(CLIC_INT_CONFIG_REG, CLIC_INT_CONFIG_UNLBITS, NLBITS); + REG_SET_FIELD(CLIC_INT_CONFIG_REG, CLIC_INT_CONFIG_MNLBITS, NLBITS); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/test_apps/tee_apm/components/pms/priv_include/esp32h2/test_pms_params.h b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32h2/test_pms_params.h similarity index 100% rename from components/hal/test_apps/tee_apm/components/pms/priv_include/esp32h2/test_pms_params.h rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/esp32h2/test_pms_params.h diff --git a/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/test_cpu_intr_priv.h b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/test_cpu_intr_priv.h new file mode 100644 index 0000000000..9c041820a8 --- /dev/null +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/test_cpu_intr_priv.h @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +/********************************** Utility *********************************/ + +void test_intr_utils_init(void); +void test_intr_utils_deinit(void); + +void test_intr_alloc(int mode, int priority, int intr_src, intr_handler_t func, void *arg); +void test_intr_free_all(void); diff --git a/components/hal/test_apps/tee_apm/components/pms/priv_include/test_pms_priv.h b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/test_pms_priv.h similarity index 98% rename from components/hal/test_apps/tee_apm/components/pms/priv_include/test_pms_priv.h rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/test_pms_priv.h index 3aa99c41a0..bcc278ed08 100644 --- a/components/hal/test_apps/tee_apm/components/pms/priv_include/test_pms_priv.h +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/priv_include/test_pms_priv.h @@ -96,4 +96,4 @@ void test_gdma_deinit(void); void test_gdma_m2m_transfer(uint8_t *src, uint8_t *dest, size_t size); void test_gdma_wait_done(void); -void test_delay_us(uint32_t us); +void test_delay_ms(uint32_t ms); diff --git a/components/hal/test_apps/tee_apm/components/pms/src/test_apm_utils.c b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/common/test_apm_utils.c similarity index 100% rename from components/hal/test_apps/tee_apm/components/pms/src/test_apm_utils.c rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/src/common/test_apm_utils.c diff --git a/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/common/test_intr_utils.c b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/common/test_intr_utils.c new file mode 100644 index 0000000000..6332eeb8e4 --- /dev/null +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/common/test_intr_utils.c @@ -0,0 +1,251 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "soc/soc_caps.h" +#include "soc/reg_base.h" +#include "soc/interrupts.h" +#include "soc/interrupt_matrix_reg.h" + +#include "riscv/encoding.h" +#include "riscv/csr.h" +#include "riscv/rv_utils.h" + +#include "esp_cpu.h" +#include "esp_rom_sys.h" + +#if SOC_INT_PLIC_SUPPORTED +#include "esp_private/interrupt_plic.h" +#elif SOC_INT_CLIC_SUPPORTED +#include "esp_private/interrupt_clic.h" +#else +#include "esp_private/interrupt_intc.h" +#endif + +#if CONFIG_SOC_SUPPORT_TEE_INTR_TEST +#include "test_rv_utils.h" +#include "test_cpu_intr_params.h" +#endif + +/********************************** Vector Table Redirection *******************************/ + +void set_test_vector_table(void) +{ + extern int _test_vector_table; + rv_utils_intr_global_disable(); + rv_utils_set_mtvec((uintptr_t)&_test_vector_table); + rv_utils_intr_global_enable(); +} + +void restore_default_vector_table(void) +{ + extern int _vector_table; + rv_utils_intr_global_disable(); + rv_utils_set_mtvec((uintptr_t)&_vector_table); + rv_utils_intr_global_enable(); +} + +/********************************** Privilege Mode Switch *********************************/ + +void test_m2u_switch(void) +{ + int mode = esp_cpu_get_curr_privilege_level(); + assert(mode == PRV_M); + + asm volatile("ecall\n"); + + mode = esp_cpu_get_curr_privilege_level(); + assert(mode == PRV_U); +} + +void test_u2m_switch(void) +{ + int mode = esp_cpu_get_curr_privilege_level(); + assert(mode == PRV_U); + + asm volatile("ecall\n"); + + mode = esp_cpu_get_curr_privilege_level(); + assert(mode == PRV_M); +} + +/********************************** Interrupt Handler *************************************/ + +extern void _global_interrupt_handler(intptr_t sp, int mcause); + +/* called from test_tee_vectors.S */ +void _test_global_interrupt_handler(intptr_t sp, int mcause) +{ + _global_interrupt_handler(sp, mcause); +} + +#if CONFIG_SOC_SUPPORT_TEE_INTR_TEST + +extern int _vector_table; +extern int _mtvt_table; +extern int _test_mtvec_table; +extern int _test_mtvt_table; +extern int _test_utvec_table; +extern int _test_utvt_table; + +static void test_redirect_vector_table(bool redirect) +{ + if (redirect) { + test_rv_utils_set_xtvec((uintptr_t)&_test_mtvec_table, PRV_M); + test_rv_utils_set_xtvt((uintptr_t)&_test_mtvt_table, PRV_M); + test_rv_utils_set_xtvec((uintptr_t)&_test_utvec_table, PRV_U); + test_rv_utils_set_xtvt((uintptr_t)&_test_utvt_table, PRV_U); +#if !SOC_CPU_HAS_CSR_PC + RV_SET_CSR(mcounteren, 0x07); +#endif + } else { + test_rv_utils_set_xtvt((uintptr_t)&_mtvt_table, PRV_M); + test_rv_utils_set_xtvec((uintptr_t)&_vector_table, PRV_M); + } +} + +/***************************** Miscellaneous: Interrupts (CLIC configuration save/restore) *****************************/ + +#define INTMTX_REG(i) (DR_REG_INTMTX_BASE + ((i) * 4)) + +static uint32_t s_intr_src_map[ETS_MAX_INTR_SOURCE]; +static uint32_t s_intr_clic_ctrl_reg[SOC_CPU_INTR_NUM]; + +static bool is_intr_ctx_saved = false; + +static void test_save_intr_ctx(void) +{ + // Save and unroute all interrupt matrix sources + for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) { + uint32_t offs = INTMTX_REG(i); + s_intr_src_map[i] = REG_READ(offs); + REG_WRITE(offs, 0x00U); + } + + // Save CLIC configuration registers + for (int i = 0; i < SOC_CPU_INTR_NUM; i++) { + s_intr_clic_ctrl_reg[i] = REG_READ(CLIC_INT_CTRL_REG(CLIC_EXT_INTR_NUM_OFFSET + i)); + REG_WRITE(CLIC_INT_CTRL_REG(i), 0x00U); + } + + is_intr_ctx_saved = true; +} + +static void test_restore_intr_ctx(void) +{ + if (!is_intr_ctx_saved) { + return; + } + + // Restore interrupt matrix sources + for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) { + REG_WRITE(INTMTX_REG(i), s_intr_src_map[i]); + } + + // Restore CLIC configuration registers + for (int i = 0; i < SOC_CPU_INTR_NUM; i++) { + REG_WRITE(CLIC_INT_CTRL_REG(CLIC_EXT_INTR_NUM_OFFSET + i), s_intr_clic_ctrl_reg[i]); + } + + is_intr_ctx_saved = false; +} + +void test_intr_utils_init(void) +{ + test_rv_utils_intr_global_disable(PRV_M); + test_save_intr_ctx(); + test_redirect_vector_table(true); + test_rv_utils_intr_set_threshold(RVHAL_INTR_ENABLE_THRESH, PRV_M); + test_rv_utils_intr_set_threshold(RVHAL_INTR_ENABLE_THRESH, PRV_U); + test_rv_utils_intr_enable_u_mode(true); + test_rv_utils_intr_global_enable(PRV_M); +} + +void test_intr_utils_deinit(void) +{ + test_rv_utils_intr_global_disable(PRV_M); + test_rv_utils_intr_enable_u_mode(false); + test_redirect_vector_table(false); + test_restore_intr_ctx(); + test_rv_utils_intr_global_enable(PRV_M); +} + +/***************************** Miscellaneous: Interrupts (test allocation/freeing) *****************************/ + +#define TEST_INTR_NUM_MIN (12) +#define TEST_INTR_NUM_MAX (16) +#define TEST_INTR_NUM_COUNT (TEST_INTR_NUM_MAX - TEST_INTR_NUM_MIN) +#define TEST_INTR_ALLOC_MASK (((1U << TEST_INTR_NUM_COUNT) - 1) << TEST_INTR_NUM_MIN) +#define TEST_INTR_IDX(num) ((num) - TEST_INTR_NUM_MIN) + +typedef struct { + int mode; + int intr_src; +} test_intr_entry_t; + +static uint32_t s_intr_status = 0x00U; +static test_intr_entry_t s_intr_table[TEST_INTR_NUM_COUNT]; + +void test_intr_alloc(int mode, int priority, int intr_src, intr_handler_t func, void *arg) +{ + int intr_num = -1; + + if (intr_src == ETS_MAX_INTR_SOURCE) { + intr_num = TEST_INTR_NUM_PASS_IN_SEC; + } else { + intr_num = __builtin_ctz(~s_intr_status & TEST_INTR_ALLOC_MASK); + if (intr_num < TEST_INTR_NUM_MIN || intr_num > TEST_INTR_NUM_MAX) { + return; // No free interrupts + } + + intr_handler_set(intr_num, func, arg); + esp_rom_route_intr_matrix(0, intr_src, intr_num); + } + + s_intr_status |= BIT(intr_num); + s_intr_table[TEST_INTR_IDX(intr_num)] = (test_intr_entry_t){ + .mode = mode, + .intr_src = intr_src, + }; + + test_rv_utils_intr_set_type(intr_num, INTR_TYPE_LEVEL); + test_rv_utils_intr_set_priority(intr_num, priority); + test_rv_utils_intr_set_vectored(intr_num, true); + test_rv_utils_intr_set_mode(intr_num, mode); + + if (mode == PRV_U) { + REG_SET_BIT(DR_REG_INTMTX_BASE + 4 * intr_src, BIT(8)); + } + if (mode == PRV_M && intr_src == ETS_MAX_INTR_SOURCE) { + REG_WRITE(INTERRUPT_CORE0_SIG_IDX_ASSERT_IN_SEC_REG, intr_num + CLIC_EXT_INTR_NUM_OFFSET); + } + + test_rv_utils_intr_enable(BIT(intr_num)); +} + +void test_intr_free_all(void) +{ + for (int intr_num = TEST_INTR_NUM_MIN; intr_num <= TEST_INTR_NUM_MAX; intr_num++) { + if (!(s_intr_status & BIT(intr_num))) { + continue; + } + + test_intr_entry_t *entry = &s_intr_table[TEST_INTR_IDX(intr_num)]; + intr_handler_set(intr_num, NULL, NULL); + interrupt_clic_ll_route(0, entry->intr_src, ETS_INVALID_INUM); + if (entry->mode == PRV_U) { + REG_CLR_BIT(DR_REG_INTMTX_BASE + 4 * entry->intr_src, BIT(8)); + } + if (entry->mode == PRV_M && entry->intr_src == ETS_MAX_INTR_SOURCE) { + REG_WRITE(INTERRUPT_CORE0_SIG_IDX_ASSERT_IN_SEC_REG, ETS_INVALID_INUM); + } + + test_rv_utils_intr_disable(BIT(intr_num)); + s_intr_status &= ~BIT(intr_num); + } +} +#endif diff --git a/components/hal/test_apps/tee_apm/components/pms/src/test_panic_handler.c b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/common/test_panic_handler.c similarity index 89% rename from components/hal/test_apps/tee_apm/components/pms/src/test_panic_handler.c rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/src/common/test_panic_handler.c index df27547365..7709e4a7e3 100644 --- a/components/hal/test_apps/tee_apm/components/pms/src/test_panic_handler.c +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/common/test_panic_handler.c @@ -51,10 +51,16 @@ void test_panicHandler(RvExcFrame *frame, int exccause) } if (mcause == MCAUSE_ILLEGAL_INSTRUCTION) { - frame->mepc = frame->ra; + uint32_t mscratch = RV_READ_CSR(mscratch); + /* Check if panic is from the interrupt or PMS related test-cases */ + if (mscratch == 0xDEADC0DE) { + frame->mepc += 0x04U; + RV_WRITE_CSR(mscratch, 0x00U); + } else { + frame->mepc = frame->ra; + } return; } - /* PERI_APM access fault */ #if SOC_APM_SUPPORT_TEE_PERI_ACCESS_CTRL if (regs->mtval >= SOC_PERIPHERAL_LOW && regs->mtval < SOC_PERIPHERAL_HIGH) { diff --git a/components/hal/test_apps/tee_apm/components/pms/src/test_setup_utils.c b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/common/test_setup_utils.c similarity index 98% rename from components/hal/test_apps/tee_apm/components/pms/src/test_setup_utils.c rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/src/common/test_setup_utils.c index 959044d477..189f9c5db2 100644 --- a/components/hal/test_apps/tee_apm/components/pms/src/test_setup_utils.c +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/common/test_setup_utils.c @@ -38,8 +38,8 @@ /***************************** Utility - LP_CPU *****************************/ #if CONFIG_ULP_COPROC_ENABLED -extern const uint8_t ulp_lp_core_main_bin_start[] asm("_binary_ulp_lp_core_pms_bin_start"); -extern const uint8_t ulp_lp_core_main_bin_end[] asm("_binary_ulp_lp_core_pms_bin_end"); +extern const uint8_t ulp_lp_core_main_bin_start[] asm("_binary_ulp_lp_core_pms_and_cpu_intr_bin_start"); +extern const uint8_t ulp_lp_core_main_bin_end[] asm("_binary_ulp_lp_core_pms_and_cpu_intr_bin_end"); void test_boot_lp_cpu(void) { @@ -226,8 +226,9 @@ void test_gdma_wait_done(void) /***************************** Miscellaneous *****************************/ -IRAM_ATTR void test_delay_us(uint32_t us) +IRAM_ATTR void test_delay_ms(uint32_t ms) { + uint32_t us = ms * 1000U; #if SOC_CPU_HAS_CSR_PC esp_rom_delay_us(us); #else diff --git a/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/cpu_intr/test_interrupt.c b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/cpu_intr/test_interrupt.c new file mode 100644 index 0000000000..0cbfd3630c --- /dev/null +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/cpu_intr/test_interrupt.c @@ -0,0 +1,278 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "soc/soc.h" +#include "soc/soc_caps.h" + +#include "soc/intpri_reg.h" +#include "soc/pcr_reg.h" +#include "hal/timer_ll.h" + +#include "esp_cpu.h" +#include "esp_attr.h" +#include "esp_rom_sys.h" + +#include "test_rv_utils.h" + +#include "unity.h" +#include "sdkconfig.h" + +#include "test_pms_priv.h" +#include "test_cpu_intr_priv.h" +#include "test_cpu_intr_params.h" + +#define TEST_INTR_MAX_COUNT (8) + +/* ---------------------------------------------------- Utility - TIMER ---------------------------------------------------- */ + +#define TEST_TIMER_GROUP (0) +#define TEST_TIMER_ID (0) +#define TEST_TIMER_DIVIDER (80) + +#define TEST_TIMER_RESOLUTION_HZ (1000000ULL) // 1MHz, 1 tick = 1us +#define TEST_TIMER_PERIOD_S (0.01f) // 10ms @ resolution 1MHz +#define TEST_INTPRI_PERIOD_S (0.10f) // 100ms (intpri trigger interval) +#define TEST_TIMER_EXP_COUNT (TEST_INTR_MAX_COUNT * (TEST_INTPRI_PERIOD_S / TEST_TIMER_PERIOD_S)) + +static timg_dev_t *timg_dev = TIMER_LL_GET_HW(TEST_TIMER_GROUP); + +IRAM_ATTR static void test_timer_isr(void *arg) +{ + uint32_t *intr_count = (uint32_t *)arg; + *intr_count = *intr_count + 1; + esp_rom_printf("[mode: %d] TIMER-%d interrupt triggered (%d)\n", esp_cpu_get_curr_privilege_level(), TEST_TIMER_GROUP, *intr_count); + + /* Clear interrupt and re-enable the alarm */ + timer_ll_clear_intr_status(timg_dev, TIMER_LL_EVENT_ALARM(TEST_TIMER_ID)); + timer_ll_enable_alarm(timg_dev, TEST_TIMER_ID, true); +} + +static void test_timer_deinit(void) +{ + const uint32_t timer_id = TEST_TIMER_ID; + + // Disable and clear timer state + timer_ll_enable_counter(timg_dev, timer_id, false); + timer_ll_enable_auto_reload(timg_dev, timer_id, false); + timer_ll_enable_alarm(timg_dev, timer_id, false); + + 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)); + + // Reset the counter + uint64_t prev_val = timer_ll_get_reload_value(timg_dev, timer_id); + timer_ll_set_reload_value(timg_dev, timer_id, 0); + timer_ll_trigger_soft_reload(timg_dev, timer_id); + timer_ll_set_reload_value(timg_dev, timer_id, prev_val); + + timer_ll_enable_clock(TEST_TIMER_GROUP, timer_id, false); +} + +static void test_timer_init(int mode, volatile uint32_t *arg) +{ + const uint32_t group_id = TEST_TIMER_GROUP; + const uint32_t timer_id = TEST_TIMER_ID; + + 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 + test_intr_alloc(mode, 2, TG0_T0_INTR_SRC, &test_timer_isr, (void *)arg); + 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, TEST_TIMER_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); +} + +/* ---------------------------------------------------- Utility - INTPRI ---------------------------------------------------- */ + +#define TEST_INTR_TK_INIT 0x8BADF00D +#define TEST_INTR_TK_DONE 0xDEFEC8ED + +#define CPU_INTR_FROM_CPU_N_REG(n) (INTPRI_CPU_INTR_FROM_CPU_0_REG + 4 * (n)) + +typedef struct { + volatile int id; + volatile int curr_count; + volatile int max_count; + volatile int token; +} test_intr_args_ctx_t; + +FORCE_INLINE_ATTR void intpri_cpu_clr_intr(uint32_t n) +{ + WRITE_PERI_REG(CPU_INTR_FROM_CPU_N_REG(n), 0); +} + +FORCE_INLINE_ATTR void intpri_cpu_trig_intr(uint32_t n) +{ + WRITE_PERI_REG(CPU_INTR_FROM_CPU_N_REG(n), 1); +} + +FORCE_INLINE_ATTR uint32_t intpri_cpu_get_intr_state(uint32_t n) +{ + return READ_PERI_REG(CPU_INTR_FROM_CPU_N_REG(n)); +} + +IRAM_ATTR static void test_intpri_isr(void *arg) +{ + test_intr_args_ctx_t *ctx = (test_intr_args_ctx_t *)arg; + + /* Clear interrupt */ + intpri_cpu_clr_intr(ctx->id); + + ctx->curr_count++; + if (ctx->curr_count >= ctx->max_count) { + ctx->token = TEST_INTR_TK_DONE; + } + + esp_rom_printf("[mode: %d] INTPRI-%d interrupt triggered (%d)\n", esp_cpu_get_curr_privilege_level(), ctx->id, ctx->curr_count); +} + +/* ---------------------------------------------------- Test-cases ---------------------------------------------------- */ + +void test_m_mode_intr_in_m_mode(void) +{ + test_apm_ctrl_reset_all(); + test_intr_utils_init(); + + test_intr_args_ctx_t ctx = { + .id = 0, + .curr_count = 0, + .max_count = TEST_INTR_MAX_COUNT, + .token = TEST_INTR_TK_INIT, + }; + + test_intr_alloc(PRV_M, 1, CPU_FROM_CPU_N_INTR_SRC(ctx.id), &test_intpri_isr, &ctx); + + volatile uint32_t intr_count = 0; + test_timer_init(PRV_M, &intr_count); + + while (ctx.token != TEST_INTR_TK_DONE) { + intpri_cpu_trig_intr(ctx.id); + test_delay_ms(TEST_INTPRI_PERIOD_S * 1000U); + } + TEST_ASSERT(ctx.curr_count == TEST_INTR_MAX_COUNT); + + test_timer_deinit(); + TEST_ASSERT(intr_count >= TEST_TIMER_EXP_COUNT); + + test_intr_free_all(); + test_intr_utils_deinit(); +} + +void test_u_mode_intr_in_u_mode(void) +{ + test_apm_ctrl_reset_all(); + test_intr_utils_init(); + + test_intr_args_ctx_t ctx = { + .id = 0, + .curr_count = 0, + .max_count = TEST_INTR_MAX_COUNT, + .token = TEST_INTR_TK_INIT, + }; + + test_intr_alloc(PRV_U, 1, CPU_FROM_CPU_N_INTR_SRC(ctx.id), &test_intpri_isr, &ctx); + + volatile uint32_t intr_count = 0; + test_timer_init(PRV_U, &intr_count); + + test_m2u_switch(); + while (ctx.token != TEST_INTR_TK_DONE) { + intpri_cpu_trig_intr(ctx.id); + test_delay_ms(TEST_INTPRI_PERIOD_S * 1000U); + } + test_u2m_switch(); + TEST_ASSERT(ctx.curr_count == TEST_INTR_MAX_COUNT); + + test_timer_deinit(); + TEST_ASSERT(intr_count >= TEST_TIMER_EXP_COUNT); + + test_intr_free_all(); + test_intr_utils_deinit(); +} + +void test_m_mode_intr_in_u_mode(void) +{ + test_apm_ctrl_reset_all(); + test_intr_utils_init(); + + test_intr_args_ctx_t ctx = { + .id = 0, + .curr_count = 0, + .max_count = TEST_INTR_MAX_COUNT, + .token = TEST_INTR_TK_INIT, + }; + + test_intr_alloc(PRV_M, 1, CPU_FROM_CPU_N_INTR_SRC(ctx.id), &test_intpri_isr, &ctx); + + test_intr_alloc(PRV_M, 1, ETS_MAX_INTR_SOURCE, NULL, NULL); + + volatile uint32_t intr_count = 0; + test_timer_init(PRV_U, &intr_count); + + test_m2u_switch(); + while (ctx.token != TEST_INTR_TK_DONE) { + intpri_cpu_trig_intr(ctx.id); + test_delay_ms(TEST_INTPRI_PERIOD_S * 1000U); + } + test_u2m_switch(); + TEST_ASSERT(ctx.curr_count == TEST_INTR_MAX_COUNT); + + test_timer_deinit(); + TEST_ASSERT(intr_count >= TEST_TIMER_EXP_COUNT); + + test_intr_free_all(); + test_intr_utils_deinit(); +} + +void test_u_mode_intr_in_m_mode(void) +{ + test_apm_ctrl_reset_all(); + test_intr_utils_init(); + + test_intr_alloc(PRV_M, 1, ETS_MAX_INTR_SOURCE, NULL, NULL); + + test_intr_args_ctx_t ctx = { + .id = 0, + .curr_count = 0, + .max_count = TEST_INTR_MAX_COUNT, + .token = TEST_INTR_TK_INIT, + }; + + test_intr_alloc(PRV_U, 1, CPU_FROM_CPU_N_INTR_SRC(ctx.id), &test_intpri_isr, &ctx); + + volatile uint32_t intr_count = 0; + test_timer_init(PRV_M, &intr_count); + + while (ctx.token != TEST_INTR_TK_DONE) { + intpri_cpu_trig_intr(ctx.id); + test_delay_ms(TEST_INTPRI_PERIOD_S * 1000U); + } + TEST_ASSERT(ctx.curr_count == TEST_INTR_MAX_COUNT); + + test_timer_deinit(); + TEST_ASSERT(intr_count >= TEST_TIMER_EXP_COUNT); + + test_intr_free_all(); + test_intr_utils_deinit(); +} diff --git a/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/cpu_intr/test_vectors_m.S b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/cpu_intr/test_vectors_m.S new file mode 100644 index 0000000000..1e96dcc1a2 --- /dev/null +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/cpu_intr/test_vectors_m.S @@ -0,0 +1,467 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc.h" +#include "soc/soc_caps.h" +#include "soc/interrupt_reg.h" +#include "soc/interrupt_matrix_reg.h" + +#include "riscv/encoding.h" +#include "riscv/rvruntime-frames.h" +#include "esp_private/panic_reason.h" +#include "esp_private/vectors_const.h" + +#include "test_cpu_intr_params.h" +#include "sdkconfig.h" + + .equ SAVE_REGS, 32 + .equ CONTEXT_SIZE, (SAVE_REGS * 4) + .equ ECALL_U_MODE, 0x8 + .equ ECALL_M_MODE, 0xb + .equ INTR_M2U_MAGIC, 0x1f + .equ INTR_U2M_RTNVAL, 0xc0de + .equ INTMTX_SEC_STATUS_REG, INTERRUPT_CORE0_SECURE_STATUS_REG + .equ INTMTX_SIG_IDX_ASSERT_IN_SEC_REG, INTERRUPT_CORE0_SIG_IDX_ASSERT_IN_SEC_REG + .equ VECTORS_XCAUSE_XPIE_MASK, 0x08000000 + .equ panic_from_excp, test_panicHandler + + .global _test_uintr_handler + + .section .data + + .align 4 + .global _m_sp +_m_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, mcause + sw t0, RV_STK_MCAUSE(sp) + csrr t0, mtval + sw t0, RV_STK_MTVAL(sp) + csrr t0, mhartid + sw t0, RV_STK_MHARTID(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 restore_mcsr + lw t0, RV_STK_MSTATUS(sp) + csrw mstatus, t0 + lw t0, RV_STK_MTVEC(sp) + csrw mtvec, t0 + lw t0, RV_STK_MCAUSE(sp) + csrw mcause, t0 + lw t0, RV_STK_MTVAL(sp) + csrw mtval, t0 + lw t0, RV_STK_MHARTID(sp) + csrw mhartid, t0 +.endm + +.macro store_magic_general_regs + lui ra, INTR_M2U_MAGIC + lui tp, INTR_M2U_MAGIC + lui t0, INTR_M2U_MAGIC + lui t1, INTR_M2U_MAGIC + lui t2, INTR_M2U_MAGIC + lui s0, INTR_M2U_MAGIC + lui s1, INTR_M2U_MAGIC + lui a0, INTR_M2U_MAGIC + lui a1, INTR_M2U_MAGIC + lui a2, INTR_M2U_MAGIC + lui a3, INTR_M2U_MAGIC + lui a4, INTR_M2U_MAGIC + lui a5, INTR_M2U_MAGIC + lui a6, INTR_M2U_MAGIC + lui a7, INTR_M2U_MAGIC + lui s2, INTR_M2U_MAGIC + lui s3, INTR_M2U_MAGIC + lui s4, INTR_M2U_MAGIC + lui s5, INTR_M2U_MAGIC + lui s6, INTR_M2U_MAGIC + lui s7, INTR_M2U_MAGIC + lui s8, INTR_M2U_MAGIC + lui s9, INTR_M2U_MAGIC + lui s10, INTR_M2U_MAGIC + lui s11, INTR_M2U_MAGIC + lui t3, INTR_M2U_MAGIC + lui t4, INTR_M2U_MAGIC + lui t5, INTR_M2U_MAGIC + lui t6, INTR_M2U_MAGIC +.endm + + .section .iram1, "ax" + + /* Prevent the compiler from generating 2-byte instruction in the vector tables */ + .option push + .option norvc + + /** + * 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 + * + */ + .balign 0x40 + .global _test_mtvt_table + .type _test_mtvt_table, @function +_test_mtvt_table: + /* First 16 (CLIC_EXT_INTR_NUM_OFFSET) entries are system interrupts */ + .rept CLIC_EXT_INTR_NUM_OFFSET + .word _test_panic_handler + .endr + /* Next 31 entries are free interrupts (indices 16 to 46) */ + .rept 31 + .word _test_mintr_handler + .endr + /* Entry 47 is special - used for U-mode interrupt delegation */ + .word _test_uintr_deleg + .size _test_mtvt_table, .-_test_mtvt_table + + /* + * 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). + * + */ + .balign 0x40 + .global _test_mtvec_table + .type _test_mtvec_table, @function +_test_mtvec_table: + /* Backup t0, t1 on the stack before using it */ + addi sp, sp, -16 + sw t0, 0(sp) + sw t1, 4(sp) + + /* Check whether the exception is an M-mode ecall */ + csrr t0, mcause + li t1, VECTORS_MCAUSE_REASON_MASK + and t0, t0, t1 + li t1, ECALL_M_MODE + beq t0, t1, _test_machine_ecall + + /* Check whether the exception is an U-mode ecall */ + li t1, ECALL_U_MODE + beq t0, t1, _test_user_ecall + + /* Restore t0, t1 from the stack */ + lw t1, 4(sp) + lw t0, 0(sp) + addi sp, sp, 16 + + /* Not an exception raised by the ecall instruction */ +_test_panic_handler: + /* Save the register and CSR context */ + save_general_regs RV_STK_FRMSZ + sw gp, RV_STK_GP(sp) + addi t0, sp, RV_STK_FRMSZ + sw t0, RV_STK_SP(sp) + save_mepc + save_mcsr + + /* Executing the panic handler */ + li t0, 0xDEADC0DE + csrr t0, mscratch + mv a0, sp + csrr a1, mcause + li t0, VECTORS_MCAUSE_REASON_MASK + and a1, a1, t0 + jal panic_from_excp + + /* We arrive here if the exception handler has returned. */ + restore_mepc + restore_general_regs RV_STK_FRMSZ + mret + + .size _test_mtvec_table, .-_test_mtvec_table + + /* ECALL handler. */ + .type _test_ecall_handler, @function +_test_ecall_handler: + /* M-mode ecall handler */ + /* Currently in M-mode and switch to U-mode */ +_test_machine_ecall: + csrr t0, mepc + addi t0, t0, 4 + csrw mepc, t0 + li t1, MSTATUS_MPP + csrc mstatus, t1 + + /* Restore t0, t1 from the stack */ + lw t1, 4(sp) + lw t0, 0(sp) + addi sp, sp, 16 + mret + + /* U-mode ecall handler */ + /* Currently in U-mode and switch to M-mode */ +_test_user_ecall: + /* Check whether we are returning after servicing an U-mode interrupt */ + lui t0, INTR_U2M_RTNVAL + csrrw t1, mscratch, zero + beq t0, t1, _rtn_from_u_intr + + csrr t0, mepc + addi t0, t0, 4 + csrw mepc, t0 + li t1, MSTATUS_MPP + csrs mstatus, t1 + + /* Restore t0, t1 from the stack */ + lw t1, 4(sp) + lw t0, 0(sp) + addi sp, sp, 16 + mret + + /* This point is reached after servicing a U-mode interrupt occurred in M-mode */ +_rtn_from_u_intr: + /* Disable the U-mode delegation of all interrupts */ + li t0, INTMTX_SIG_IDX_ASSERT_IN_SEC_REG + li t1, TEST_INTR_NUM_PASS_IN_SEC + CLIC_EXT_INTR_NUM_OFFSET + sw t1, 0(t0) + fence + /* Verify the interrupt remap */ +_1: + lw t2, 0(t0) + bne t2, t1, _1 + + /* Restore the secure stack pointer */ + la t0, _m_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 _test_ecall_handler, .-_test_ecall_handler + + /* Interrupt handler */ + .type _test_mintr_handler, @function +_test_mintr_handler: + /* Start by saving the general purpose registers and the PC value before + * the interrupt happened. */ + save_general_regs + save_mepc + + /* Save GP and SP here. */ + sw gp, RV_STK_GP(sp) + addi a0, sp, CONTEXT_SIZE + sw a0, RV_STK_SP(sp) + + /* Save mcause */ + csrr s1, mcause + csrr s2, mstatus + + /* Enable nested interrupts */ + csrsi mstatus, MSTATUS_MIE + + /* 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_REASON_MASK + and a1, a1, t0 + jal _test_global_interrupt_handler + + /* Disable nested interrupts */ + csrci mstatus, MSTATUS_MIE + + /* Restore the rest of the registers. */ + csrw mcause, s1 + csrw mstatus, s2 + + restore_mepc + restore_general_regs + /* exit, this will also re-enable the interrupts */ + mret + + .size _test_mintr_handler, .-_test_mintr_handler + + /* U-mode to M-mode switch */ + .balign 4 + .global _test_u2m_switch + .type _test_u2m_switch, @function +_test_u2m_switch: + ecall + fence + ret + + .size _test_u2m_switch, .-_test_u2m_switch + + /* U-mode interrupt delegation */ + .global _test_uintr_deleg + .type _test_uintr_deleg, @function +_test_uintr_deleg: + /* Start by saving the general purpose registers and the PC value before + * the interrupt happened. */ + save_general_regs + save_mepc + + /* Save GP and SP here. */ + sw gp, RV_STK_GP(sp) + addi a0, sp, CONTEXT_SIZE + sw a0, RV_STK_SP(sp) + + /* 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 t0, t1, CLIC_EXT_INTR_NUM_OFFSET + csrr t1, ucause + or t1, t1, t0 + li t2, (VECTORS_MCAUSE_INTBIT_MASK | VECTORS_XCAUSE_XPIE_MASK) + or t1, t1, t2 + csrw ucause, t1 + + /* 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 interrupt remap */ +_2: + 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 _test_u2m_switch) so that we can + * return to M-mode after handling the interrupt */ + la t0, _test_u2m_switch + csrw uepc, t0 + + /* Set the program counter to the U-mode global interrupt handler (see _test_uintr_handler) */ + la t0, _test_uintr_handler + csrw mepc, t0 + + /* 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 */ + la t0, _m_sp + sw sp, 0(t0) + + /* Set a flag to identify the next U2M switch would be after handling a U-mode interrupt */ + lui t0, INTR_U2M_RTNVAL + csrw mscratch, t0 + + /* Place magic bytes in all the general registers */ + store_magic_general_regs + + mret + + .size _test_uintr_deleg, .-_test_uintr_deleg + + .option pop diff --git a/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/cpu_intr/test_vectors_u.S b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/cpu_intr/test_vectors_u.S new file mode 100644 index 0000000000..817c6c98f4 --- /dev/null +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/cpu_intr/test_vectors_u.S @@ -0,0 +1,208 @@ +/* + * SPDX-FileCopyrightText: 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 "soc/interrupt_reg.h" + +#include "riscv/encoding.h" +#include "riscv/rvruntime-frames.h" +#include "esp_private/panic_reason.h" +#include "esp_private/vectors_const.h" + +#include "sdkconfig.h" + + .equ SAVE_REGS, 32 + .equ CONTEXT_SIZE, (SAVE_REGS * 4) + .equ UINTTHRESH_CSR, 0x047 + .equ RV_INTR_NUM, (CLIC_EXT_INTR_NUM_OFFSET + SOC_CPU_INTR_NUM) + +/* 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_uepc + csrr t0, uepc + sw t0, RV_STK_MEPC(sp) +.endm + +.macro save_ucsr + csrr t0, ustatus + sw t0, RV_STK_MSTATUS(sp) + csrr t0, utvec + sw t0, RV_STK_MTVEC(sp) + csrr t0, ucause + 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_uepc + lw t0, RV_STK_MEPC(sp) + csrw uepc, t0 +.endm + +.macro restore_ucsr + lw t0, RV_STK_MSTATUS(sp) + csrw ustatus, t0 + lw t0, RV_STK_MTVEC(sp) + csrw utvec, t0 + lw t0, RV_STK_MCAUSE(sp) + csrw ucause, t0 +.endm + + .section .iram1, "ax" + + /* Prevent the compiler from generating 2-byte instruction in the vector tables */ + .option push + .option norvc + + /** + * 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 + * + */ + .balign 0x40 + .global _test_utvt_table + .type _test_utvt_table, @function +_test_utvt_table: + .rept RV_INTR_NUM + .word _test_uintr_handler + .endr + .size _test_utvt_table, .-_test_utvt_table + + /* + * 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). + * + */ + .balign 0x40 + .global _test_utvec_table + .type _test_utvec_table, @function +_test_utvec_table: + /* Do nothing */ + mret + + .size _test_utvec_table, .-_test_utvec_table + + /* Interrupt handler */ + .global _test_uintr_handler + .type _test_uintr_handler, @function +_test_uintr_handler: + /* Start by saving the general purpose registers and the PC value before + * the interrupt happened. */ + save_general_regs + save_uepc + + /* Save GP and SP here. */ + sw gp, RV_STK_GP(sp) + addi a0, sp, CONTEXT_SIZE + sw a0, RV_STK_SP(sp) + + /* Save ucause */ + csrr s1, ucause + csrr s2, ustatus + + /* Enable nested interrupts */ + csrsi ustatus, USTATUS_UIE + + /* 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_REASON_MASK + and a1, a1, t0 + jal _test_global_interrupt_handler + + /* Disable nested interrupts */ + csrci ustatus, USTATUS_UIE + + /* Restore the rest of the registers. */ + csrw ucause, s1 + csrw ustatus, s2 + + restore_uepc + restore_general_regs + + /* exit, this will also re-enable the interrupts */ + uret + + .size _test_uintr_handler, .-_test_uintr_handler + + .option pop diff --git a/components/hal/test_apps/tee_apm/components/pms/src/test_tee_peri_apm.c b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/pms/test_tee_peri_apm.c similarity index 98% rename from components/hal/test_apps/tee_apm/components/pms/src/test_tee_peri_apm.c rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/src/pms/test_tee_peri_apm.c index 6641bdac60..3baa6a135f 100644 --- a/components/hal/test_apps/tee_apm/components/pms/src/test_tee_peri_apm.c +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/pms/test_tee_peri_apm.c @@ -20,7 +20,6 @@ #include "test_pms_priv.h" #include "test_pms_params.h" -#include "test_peri_apm_reg.h" #include "unity.h" @@ -114,7 +113,7 @@ IRAM_ATTR static void hp_cpu_peri_addr_rw(uint32_t peri_addr, uint32_t attr) RV_WRITE_CSR(uscratch, 0x00); reg_write(peri_addr, TEST_VAL); - test_delay_us(10000); + test_delay_ms(10); bool can_write = (attr & APM_PERM_W); if (!can_write) { @@ -125,7 +124,7 @@ IRAM_ATTR static void hp_cpu_peri_addr_rw(uint32_t peri_addr, uint32_t attr) volatile uint32_t val = reg_read(peri_addr); (void)val; - test_delay_us(10000); + test_delay_ms(10); bool can_read = (attr & APM_PERM_R); if (!can_read) { @@ -142,7 +141,7 @@ IRAM_ATTR static void lp_cpu_peri_addr_rw(uint32_t peri_addr, uint32_t attr) SEND_EXCP(0); SEND_MSG(MSG_SLAVE_WRITE); SEND_ADDR(peri_addr); - test_delay_us(10000); + test_delay_ms(10); bool can_write = (attr & APM_PERM_W); if (!can_write) { @@ -154,7 +153,7 @@ IRAM_ATTR static void lp_cpu_peri_addr_rw(uint32_t peri_addr, uint32_t attr) SEND_EXCP(0); SEND_MSG(MSG_SLAVE_READ); SEND_ADDR(peri_addr); - test_delay_us(10000); + test_delay_ms(10); bool can_read = (attr & APM_PERM_R); if (!can_read) { diff --git a/components/hal/test_apps/tee_apm/components/pms/src/test_tee_sys_apm.c b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/pms/test_tee_sys_apm.c similarity index 99% rename from components/hal/test_apps/tee_apm/components/pms/src/test_tee_sys_apm.c rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/src/pms/test_tee_sys_apm.c index 7d2321e547..edb0ae720a 100644 --- a/components/hal/test_apps/tee_apm/components/pms/src/test_tee_sys_apm.c +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/pms/test_tee_sys_apm.c @@ -84,12 +84,12 @@ static void gdma_xmem_addr_rw(uint8_t *src, uint8_t *dest, size_t size, uint32_t #endif if (!test_attr) { - test_delay_us(10000); + test_delay_ms(10); TEST_ASSERT(apm_master_excp_flag[TEST_GDMA_APM_MASTER_ID]); test_gdma_wait_done(); } else { test_gdma_wait_done(); - test_delay_us(10000); + test_delay_ms(10); TEST_ASSERT_FALSE(apm_master_excp_flag[TEST_GDMA_APM_MASTER_ID]); TEST_ASSERT_EQUAL_HEX8_ARRAY(src, dest, size); } @@ -202,7 +202,7 @@ static void hp_cpu_peri_addr_rw(uint32_t peri_addr, uint32_t attr) apm_master_excp_flag[APM_MASTER_HPCORE] = false; REG_WRITE(peri_addr, TEST_VAL); - test_delay_us(10000); + test_delay_ms(10); bool can_write = (attr & APM_PERM_W); TEST_ASSERT(apm_master_excp_flag[APM_MASTER_HPCORE] != can_write); @@ -211,7 +211,7 @@ static void hp_cpu_peri_addr_rw(uint32_t peri_addr, uint32_t attr) volatile uint32_t val = REG_READ(peri_addr); (void)val; - test_delay_us(10000); + test_delay_ms(10); bool can_read = (attr & APM_PERM_R); TEST_ASSERT(apm_master_excp_flag[APM_MASTER_HPCORE] != can_read); @@ -227,7 +227,7 @@ static void lp_cpu_peri_addr_rw(uint32_t peri_addr, uint32_t attr) SEND_MSG(MSG_SLAVE_WRITE); SEND_ADDR(peri_addr); - test_delay_us(10000); + test_delay_ms(10); bool can_write = (attr & APM_PERM_W); TEST_ASSERT(apm_master_excp_flag[APM_MASTER_LPCORE] != can_write); @@ -236,7 +236,7 @@ static void lp_cpu_peri_addr_rw(uint32_t peri_addr, uint32_t attr) SEND_MSG(MSG_SLAVE_READ); SEND_ADDR(peri_addr); - test_delay_us(10000); + test_delay_ms(10); bool can_read = (attr & APM_PERM_R); TEST_ASSERT(apm_master_excp_flag[APM_MASTER_LPCORE] != can_read); @@ -490,7 +490,7 @@ static void hp_cpu_xmem_addr_rw(uint32_t mem_addr, size_t size, uint32_t attr) for (uint32_t offs = 0; offs < num_words; offs += step) { addr[offs] = TEST_VAL; asm volatile ("nop"); - test_delay_us(10000); + test_delay_ms(10); bool can_write = (attr & APM_PERM_W); TEST_ASSERT(apm_master_excp_flag[APM_MASTER_HPCORE] != can_write); @@ -500,7 +500,7 @@ static void hp_cpu_xmem_addr_rw(uint32_t mem_addr, size_t size, uint32_t attr) uint32_t val = addr[offs]; (void)val; asm volatile ("fence"); - test_delay_us(10000); + test_delay_ms(10); bool can_read = (attr & APM_PERM_R); TEST_ASSERT(apm_master_excp_flag[APM_MASTER_HPCORE] != can_read); @@ -520,7 +520,7 @@ static void hp_cpu_xmem_addr_x(uint32_t mem_addr, size_t size, uint32_t attr) void (*func_ptr)(void); func_ptr = (void(*)(void))(mem_addr); func_ptr(); - test_delay_us(10000); + test_delay_ms(10); bool can_execute = attr & APM_PERM_X; TEST_ASSERT(apm_master_excp_flag[APM_MASTER_HPCORE] != can_execute); @@ -538,7 +538,7 @@ static void lp_cpu_xmem_addr_rw(uint32_t mem_addr, size_t size, uint32_t attr) SEND_MSG(MSG_SLAVE_WRITE); SEND_ADDR(mem_addr); SEND_SIZE(sizeof(uint32_t)); - test_delay_us(10000); + test_delay_ms(10); bool can_write = (attr & APM_PERM_W); TEST_ASSERT(apm_master_excp_flag[APM_MASTER_LPCORE] != can_write); @@ -547,7 +547,7 @@ static void lp_cpu_xmem_addr_rw(uint32_t mem_addr, size_t size, uint32_t attr) SEND_MSG(MSG_SLAVE_READ); SEND_ADDR(mem_addr); - test_delay_us(10000); + test_delay_ms(10); bool can_read = (attr & APM_PERM_R); TEST_ASSERT(apm_master_excp_flag[APM_MASTER_LPCORE] != can_read); @@ -564,7 +564,7 @@ static void lp_cpu_xmem_addr_x(uint32_t mem_addr, size_t size, uint32_t attr) SEND_MSG(MSG_SLAVE_EXEC); SEND_ADDR(mem_addr); - test_delay_us(10000); + test_delay_ms(10); bool can_execute = (attr & APM_PERM_X); TEST_ASSERT(apm_master_excp_flag[APM_MASTER_LPCORE] != can_execute); diff --git a/components/hal/test_apps/tee_apm/components/pms/src/test_tee_vectors.S b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/pms/test_tee_vectors.S similarity index 100% rename from components/hal/test_apps/tee_apm/components/pms/src/test_tee_vectors.S rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/src/pms/test_tee_vectors.S diff --git a/components/hal/test_apps/tee_apm/components/pms/src/ulp/ulp_lp_core_main.c b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/ulp/ulp_lp_core_main.c similarity index 100% rename from components/hal/test_apps/tee_apm/components/pms/src/ulp/ulp_lp_core_main.c rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/src/ulp/ulp_lp_core_main.c diff --git a/components/hal/test_apps/tee_apm/components/pms/src/ulp/ulp_vectors.S b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/ulp/ulp_vectors.S similarity index 100% rename from components/hal/test_apps/tee_apm/components/pms/src/ulp/ulp_vectors.S rename to components/hal/test_apps/tee/components/pms_and_cpu_intr/src/ulp/ulp_vectors.S diff --git a/components/hal/test_apps/tee/main/CMakeLists.txt b/components/hal/test_apps/tee/main/CMakeLists.txt new file mode 100644 index 0000000000..4e96a101a4 --- /dev/null +++ b/components/hal/test_apps/tee/main/CMakeLists.txt @@ -0,0 +1,9 @@ +set(srcs "test_main.c" "test_pms.c") +if(CONFIG_SOC_SUPPORT_TEE_INTR_TEST) + list(APPEND srcs "test_cpu_intr.c") +endif() + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS "" + PRIV_REQUIRES pms_and_cpu_intr esp_psram + WHOLE_ARCHIVE) diff --git a/components/hal/test_apps/tee_apm/main/idf_component.yml b/components/hal/test_apps/tee/main/idf_component.yml similarity index 100% rename from components/hal/test_apps/tee_apm/main/idf_component.yml rename to components/hal/test_apps/tee/main/idf_component.yml diff --git a/components/hal/test_apps/tee/main/test_cpu_intr.c b/components/hal/test_apps/tee/main/test_cpu_intr.c new file mode 100644 index 0000000000..dff6daa878 --- /dev/null +++ b/components/hal/test_apps/tee/main/test_cpu_intr.c @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "test_cpu_intr.h" + +#include "unity.h" +#include "sdkconfig.h" + +/** + * @brief Test M-mode interrupts in M-mode + * + * This test verifies interrupt handling behavior in M-mode: + * - Sets up a timer interrupt firing every 10ms (priority 2) in M-mode + * - Triggers INTPRI interrupt every 100ms (priority 1) in M-mode + * - Verifies that both interrupts are handled correctly + * - Checks interrupt counts match expected values + */ +TEST_CASE("Test M-mode interrupts in M-mode", "[CPU]") +{ + test_m_mode_intr_in_m_mode(); +} + +/** + * @brief Test U-mode interrupts in U-mode + * + * This test verifies interrupt handling behavior in U-mode: + * - Sets up a timer interrupt firing every 10ms (priority 2) in U-mode + * - Triggers INTPRI interrupt every 100ms (priority 1) in U-mode + * - Verifies that both interrupts are handled correctly + * - Checks interrupt counts match expected values + */ +TEST_CASE("Test U-mode interrupts in U-mode", "[CPU]") +{ + test_u_mode_intr_in_u_mode(); +} + +/** + * @brief Test M-mode interrupts in U-mode + * + * This test verifies interrupt handling behavior in U-mode: + * - Sets up a timer interrupt firing every 10ms (priority 2) in U-mode + * - Triggers INTPRI interrupt every 100ms (priority 1) in M-mode + * - Verifies that both interrupts are handled correctly + * - Checks interrupt counts match expected values + */ +TEST_CASE("Test M-mode interrupts in U-mode", "[CPU]") +{ + test_m_mode_intr_in_u_mode(); +} + +/** + * @brief Test U-mode interrupts in M-mode + * + * This test verifies interrupt handling behavior in M-mode: + * - Sets up a timer interrupt firing every 10ms (priority 2) in M-mode + * - Triggers INTPRI interrupt every 100ms (priority 1) in U-mode + * - Verifies that both interrupts are handled correctly + * - Checks interrupt counts match expected values + */ +TEST_CASE("Test U-mode interrupts in M-mode", "[CPU]") +{ + test_u_mode_intr_in_m_mode(); +} diff --git a/components/hal/test_apps/tee_apm/main/test_main.c b/components/hal/test_apps/tee/main/test_main.c similarity index 100% rename from components/hal/test_apps/tee_apm/main/test_main.c rename to components/hal/test_apps/tee/main/test_main.c diff --git a/components/hal/test_apps/tee_apm/main/test_pms.c b/components/hal/test_apps/tee/main/test_pms.c similarity index 100% rename from components/hal/test_apps/tee_apm/main/test_pms.c rename to components/hal/test_apps/tee/main/test_pms.c diff --git a/components/hal/test_apps/tee_apm/pytest_tee_apm_pms.py b/components/hal/test_apps/tee/pytest_pms_and_cpu_intr.py similarity index 56% rename from components/hal/test_apps/tee_apm/pytest_tee_apm_pms.py rename to components/hal/test_apps/tee/pytest_pms_and_cpu_intr.py index 12801bef72..a24ec3c15d 100644 --- a/components/hal/test_apps/tee_apm/pytest_tee_apm_pms.py +++ b/components/hal/test_apps/tee/pytest_pms_and_cpu_intr.py @@ -6,22 +6,29 @@ from pytest_embedded_idf.utils import idf_parametrize # ---------------- Pytest build parameters ---------------- -SOC_SYS_APM_SUPPORTED = ['esp32c6', 'esp32h2', 'esp32c5', 'esp32c61'] -SOC_PERI_APM_SUPPORTED = ['esp32c5'] +SOC_SUPPORT_SYS_APM_TEST = ['esp32c6', 'esp32h2', 'esp32c5', 'esp32c61'] +SOC_SUPPORT_PERI_APM_TEST = ['esp32c5'] +SOC_SUPPORT_INTR_TEST = ['esp32c5', 'esp32c61'] CONFIG_SYS_APM = [ # 'config, target, markers', ('default', target, (pytest.mark.generic,)) - for target in SOC_SYS_APM_SUPPORTED + for target in SOC_SUPPORT_SYS_APM_TEST ] CONFIG_PERI_APM = [ # 'config, target, markers', ('default', target, (pytest.mark.generic,)) - for target in SOC_PERI_APM_SUPPORTED + for target in SOC_SUPPORT_PERI_APM_TEST ] -# ---------------- TEE default tests ---------------- +CONFIG_INTR_TEST = [ + # 'config, target, markers', + ('default', target, (pytest.mark.generic,)) + for target in SOC_SUPPORT_INTR_TEST +] + +# ---------------- TEE APM tests ---------------- @idf_parametrize( @@ -40,3 +47,15 @@ def test_tee_sys_apm(dut: IdfDut) -> None: ) def test_tee_peri_apm(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='PERI_APM') + + +# ---------------- TEE Interrupt tests ---------------- + + +@idf_parametrize( + 'config, target, markers', + CONFIG_INTR_TEST, + indirect=['config', 'target'], +) +def test_tee_interrupts(dut: IdfDut) -> None: + dut.run_all_single_board_cases() diff --git a/components/hal/test_apps/tee_apm/sdkconfig.defaults b/components/hal/test_apps/tee/sdkconfig.defaults similarity index 100% rename from components/hal/test_apps/tee_apm/sdkconfig.defaults rename to components/hal/test_apps/tee/sdkconfig.defaults diff --git a/components/hal/test_apps/tee_apm/sdkconfig.defaults.esp32c5 b/components/hal/test_apps/tee/sdkconfig.defaults.esp32c5 similarity index 100% rename from components/hal/test_apps/tee_apm/sdkconfig.defaults.esp32c5 rename to components/hal/test_apps/tee/sdkconfig.defaults.esp32c5 diff --git a/components/hal/test_apps/tee_apm/sdkconfig.defaults.esp32c6 b/components/hal/test_apps/tee/sdkconfig.defaults.esp32c6 similarity index 100% rename from components/hal/test_apps/tee_apm/sdkconfig.defaults.esp32c6 rename to components/hal/test_apps/tee/sdkconfig.defaults.esp32c6 diff --git a/components/hal/test_apps/tee_apm/sdkconfig.defaults.esp32c61 b/components/hal/test_apps/tee/sdkconfig.defaults.esp32c61 similarity index 100% rename from components/hal/test_apps/tee_apm/sdkconfig.defaults.esp32c61 rename to components/hal/test_apps/tee/sdkconfig.defaults.esp32c61 diff --git a/components/hal/test_apps/tee_apm/sdkconfig.defaults.esp32h2 b/components/hal/test_apps/tee/sdkconfig.defaults.esp32h2 similarity index 100% rename from components/hal/test_apps/tee_apm/sdkconfig.defaults.esp32h2 rename to components/hal/test_apps/tee/sdkconfig.defaults.esp32h2 diff --git a/components/hal/test_apps/tee_apm/components/pms/priv_include/esp32c5/test_peri_apm_reg.h b/components/hal/test_apps/tee_apm/components/pms/priv_include/esp32c5/test_peri_apm_reg.h deleted file mode 100644 index 6c2025bb12..0000000000 --- a/components/hal/test_apps/tee_apm/components/pms/priv_include/esp32c5/test_peri_apm_reg.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include "soc/reg_base.h" - -/********* For PERI_APM *********/ -#include "soc/uart_reg.h" -#include "soc/i2c_reg.h" -#include "soc/i2s_reg.h" -#include "soc/mcpwm_reg.h" -#include "soc/twaifd_reg.h" -#include "soc/ahb_dma_reg.h" -#include "soc/pau_reg.h" -#include "soc/interrupt_matrix_reg.h" -#include "soc/apb_saradc_reg.h" -#include "soc/timer_group_reg.h" -#include "soc/pcnt_reg.h" -#include "soc/io_mux_reg.h" -#include "soc/hp_system_reg.h" -#include "soc/pcr_reg.h" -#include "soc/spi_mem_reg.h" -#include "soc/hp_apm_reg.h" -#include "soc/cpu_apm_reg.h" -#include "soc/sha_reg.h" -#include "soc/cache_reg.h" -#include "soc/spi_reg.h" -#include "soc/bitscrambler_reg.h" -#include "soc/keymng_reg.h" -#include "soc/sdio_slc_host_reg.h" - -#include "soc/efuse_reg.h" -#include "soc/pmu_reg.h" -#include "soc/lp_clkrst_reg.h" -#include "soc/lp_aon_reg.h" -#include "soc/lp_wdt_reg.h" -#include "soc/lpperi_reg.h" -#include "soc/lp_analog_peri_reg.h" -#include "soc/lp_uart_reg.h" -#include "soc/lp_i2c_reg.h" -#include "soc/lp_i2c_ana_mst_reg.h" -#include "soc/huk_reg.h" -#include "soc/lp_apm_reg.h" diff --git a/components/hal/test_apps/tee_apm/components/pms/src/test_intr_utils.c b/components/hal/test_apps/tee_apm/components/pms/src/test_intr_utils.c deleted file mode 100644 index 92972cb881..0000000000 --- a/components/hal/test_apps/tee_apm/components/pms/src/test_intr_utils.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include "soc/soc_caps.h" -#include "esp_cpu.h" - -#include "riscv/encoding.h" -#include "riscv/csr.h" -#include "riscv/rv_utils.h" - -#include "esp_rom_sys.h" - -#if SOC_INT_PLIC_SUPPORTED -#include "esp_private/interrupt_plic.h" -#elif SOC_INT_CLIC_SUPPORTED -#include "esp_private/interrupt_clic.h" -#else -#include "esp_private/interrupt_intc.h" -#endif - -/********************************** Vector Table Redirection *******************************/ - -extern int _vector_table; -extern int _test_vector_table; - -void set_test_vector_table(void) -{ - rv_utils_intr_global_disable(); - rv_utils_set_mtvec((uintptr_t)&_test_vector_table); - rv_utils_intr_global_enable(); -} - -void restore_default_vector_table(void) -{ - rv_utils_intr_global_disable(); - rv_utils_set_mtvec((uintptr_t)&_vector_table); - rv_utils_intr_global_enable(); -} - -/********************************** Privilege Mode Switch *********************************/ - -void test_m2u_switch(void) -{ - int mode = esp_cpu_get_curr_privilege_level(); - assert(mode == PRV_M); - - asm volatile("ecall\n"); - - mode = esp_cpu_get_curr_privilege_level(); - assert(mode == PRV_U); -} - -void test_u2m_switch(void) -{ - int mode = esp_cpu_get_curr_privilege_level(); - assert(mode == PRV_U); - - asm volatile("ecall\n"); - - mode = esp_cpu_get_curr_privilege_level(); - assert(mode == PRV_M); -} - -/********************************** Interrupt Handler *************************************/ - -extern void _global_interrupt_handler(intptr_t sp, int mcause); - -/* called from test_tee_vectors.S */ -void _test_global_interrupt_handler(intptr_t sp, int mcause) -{ - _global_interrupt_handler(sp, mcause); -} diff --git a/components/hal/test_apps/tee_apm/main/CMakeLists.txt b/components/hal/test_apps/tee_apm/main/CMakeLists.txt deleted file mode 100644 index ce32878745..0000000000 --- a/components/hal/test_apps/tee_apm/main/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -idf_component_register(SRCS "test_main.c" "test_pms.c" - INCLUDE_DIRS "" - PRIV_REQUIRES pms esp_psram - WHOLE_ARCHIVE) diff --git a/components/soc/esp32c5/register/soc/interrupt_matrix_reg.h b/components/soc/esp32c5/register/soc/interrupt_matrix_reg.h index 6c6bc860bd..f605501d18 100644 --- a/components/soc/esp32c5/register/soc/interrupt_matrix_reg.h +++ b/components/soc/esp32c5/register/soc/interrupt_matrix_reg.h @@ -5,7 +5,6 @@ */ #pragma once -#include #include "soc/soc.h" #ifdef __cplusplus extern "C" { diff --git a/components/soc/esp32c61/register/soc/interrupt_matrix_reg.h b/components/soc/esp32c61/register/soc/interrupt_matrix_reg.h index ad4026911d..fe67e24229 100644 --- a/components/soc/esp32c61/register/soc/interrupt_matrix_reg.h +++ b/components/soc/esp32c61/register/soc/interrupt_matrix_reg.h @@ -5,7 +5,6 @@ */ #pragma once -#include #include "soc/soc.h" #ifdef __cplusplus extern "C" {