mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 02:37:19 +02:00
Merge branch 'feature/esp_tee_h2' into 'master'
feat(esp_tee): Support for ESP32-H2 See merge request espressif/esp-idf!37708
This commit is contained in:
@ -136,7 +136,7 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
|
||||
#if ESP_TEE_BUILD
|
||||
#include "esp_fault.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "esp32c6/rom/spi_flash.h"
|
||||
#include "rom/spi_flash.h"
|
||||
|
||||
extern bool esp_tee_flash_check_paddr_in_active_tee_part(size_t paddr);
|
||||
#endif
|
||||
|
@ -1,3 +1,5 @@
|
||||
idf_build_get_property(non_os_build NON_OS_BUILD)
|
||||
|
||||
set(srcs "rtc_clk_init.c"
|
||||
"rtc_clk.c"
|
||||
"pmu_param.c"
|
||||
@ -7,7 +9,7 @@ set(srcs "rtc_clk_init.c"
|
||||
"chip_info.c"
|
||||
)
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
if(NOT non_os_build)
|
||||
list(APPEND srcs "sar_periph_ctrl.c")
|
||||
endif()
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -112,6 +112,14 @@ void esp_cpu_configure_region_protection(void)
|
||||
//
|
||||
esp_cpu_configure_invalid_regions();
|
||||
|
||||
/* NOTE: When ESP-TEE is active, only configure invalid memory regions in bootloader
|
||||
* to prevent errors before TEE initialization. TEE will handle all other
|
||||
* memory protection.
|
||||
*/
|
||||
#if CONFIG_SECURE_ENABLE_TEE && BOOTLOADER_BUILD
|
||||
return;
|
||||
#endif
|
||||
|
||||
//
|
||||
// Configure all the valid address regions using PMP
|
||||
//
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_riscv_intr.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_desc_ret)
|
||||
{
|
||||
@ -15,7 +16,18 @@ void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_
|
||||
* Interrupts 3, 4 and 7 are unavailable for PULP CPU as they are bound to Core-Local Interrupts (CLINT)
|
||||
*/
|
||||
// [TODO: IDF-2465]
|
||||
const uint32_t rsvd_mask = BIT(3) | BIT(4) | BIT(6) | BIT(7);
|
||||
const uint32_t base_rsvd_mask = BIT(3) | BIT(4) | BIT(6) | BIT(7);
|
||||
|
||||
/* On the ESP32-H2, interrupt 14 is reserved for ESP-TEE
|
||||
* for operations related to secure peripherals under its control
|
||||
* (e.g. AES, SHA, APM)
|
||||
*/
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
const uint32_t rsvd_mask = base_rsvd_mask | BIT(14);
|
||||
#else
|
||||
const uint32_t rsvd_mask = base_rsvd_mask;
|
||||
#endif
|
||||
|
||||
|
||||
intr_desc_ret->priority = 1;
|
||||
intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -10,15 +10,40 @@
|
||||
#include "../ext_mem_layout.h"
|
||||
#include "hal/mmu_types.h"
|
||||
|
||||
/* NOTE: With ESP-TEE enabled:
|
||||
* - The start address is moved by the size of TEE IDROM segments since these
|
||||
* segments are placed at the start of the linear address space
|
||||
* - TEE IROM and DROM segments are both 64KB (CONFIG_SECURE_TEE_IROM_SIZE,
|
||||
* CONFIG_SECURE_TEE_DROM_SIZE) for now. Thus, the number of reserved entries
|
||||
* from the start would be (64KB + 64KB)/MMU_PAGE_SIZE
|
||||
* - The last few MMU entries are reserved for TEE flash operations. The number
|
||||
* of reserved entries matches the size of TEE IDROM segments (IROM + DROM)
|
||||
* plus one additional entry, i.e. (64KB + 64KB)/MMU_PAGE_SIZE + 1
|
||||
*/
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
#define TEE_MMU_MEM_REG_START_OFFS (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE)
|
||||
#define TEE_MMU_RESV_PAGES ((CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE) / CONFIG_MMU_PAGE_SIZE)
|
||||
#define TEE_MMU_MEM_REG_END_OFFS ((TEE_MMU_RESV_PAGES + 1) * CONFIG_MMU_PAGE_SIZE)
|
||||
|
||||
#define MMU_MEM_REG_START_ADDR_W_TEE (SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW + TEE_MMU_MEM_REG_START_OFFS)
|
||||
#define MMU_MEM_REG_END_ADDR_W_TEE (SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH - TEE_MMU_MEM_REG_END_OFFS)
|
||||
|
||||
#define MMU_IRAM0_LINEAR_ADDRESS_LOW MMU_MEM_REG_START_ADDR_W_TEE
|
||||
#define MMU_IRAM0_LINEAR_ADDRESS_HIGH MMU_MEM_REG_END_ADDR_W_TEE
|
||||
#else
|
||||
#define MMU_IRAM0_LINEAR_ADDRESS_LOW SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW
|
||||
#define MMU_IRAM0_LINEAR_ADDRESS_HIGH SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The start addresses in this list should always be sorted from low to high, as MMU driver will need to
|
||||
* coalesce adjacent regions
|
||||
*/
|
||||
const mmu_mem_region_t g_mmu_mem_regions[SOC_MMU_LINEAR_ADDRESS_REGION_NUM] = {
|
||||
[0] = {
|
||||
.start = SOC_MMU_IRAM0_LINEAR_ADDRESS_LOW,
|
||||
.end = SOC_MMU_IRAM0_LINEAR_ADDRESS_HIGH,
|
||||
.size = SOC_BUS_SIZE(SOC_MMU_IRAM0_LINEAR),
|
||||
.start = MMU_IRAM0_LINEAR_ADDRESS_LOW,
|
||||
.end = MMU_IRAM0_LINEAR_ADDRESS_HIGH,
|
||||
.size = MMU_IRAM0_LINEAR_ADDRESS_HIGH - MMU_IRAM0_LINEAR_ADDRESS_LOW,
|
||||
.bus_id = CACHE_BUS_IBUS0 | CACHE_BUS_DBUS0,
|
||||
.targets = MMU_TARGET_FLASH0,
|
||||
.caps = MMU_MEM_CAP_EXEC | MMU_MEM_CAP_READ | MMU_MEM_CAP_32BIT | MMU_MEM_CAP_8BIT,
|
||||
|
@ -131,10 +131,8 @@ if(CONFIG_ESP_ROM_HAS_VERSION)
|
||||
endif()
|
||||
|
||||
if(ESP_TEE_BUILD)
|
||||
if(target STREQUAL "esp32c6")
|
||||
rom_linker_script("spiflash")
|
||||
rom_linker_script("heap")
|
||||
endif()
|
||||
rom_linker_script("spiflash")
|
||||
rom_linker_script("heap")
|
||||
endif()
|
||||
|
||||
if(BOOTLOADER_BUILD)
|
||||
|
@ -15,7 +15,13 @@
|
||||
#include "sdkconfig.h"
|
||||
#include "ld.common"
|
||||
|
||||
#define SRAM_SEG_START 0x40800000
|
||||
#if !CONFIG_SECURE_ENABLE_TEE
|
||||
#define SRAM_SEG_START (0x40800000)
|
||||
#else
|
||||
#define SRAM_SEG_START (0x40800000 + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE)
|
||||
#define FLASH_SEG_OFFSET (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE)
|
||||
#endif // CONFIG_SECURE_ENABLE_TEE
|
||||
|
||||
#define SRAM_SEG_END 0x4083EFD0 /* 2nd stage bootloader iram_loader_seg start address */
|
||||
#define SRAM_SEG_SIZE SRAM_SEG_END - SRAM_SEG_START
|
||||
|
||||
@ -35,8 +41,14 @@ MEMORY
|
||||
*/
|
||||
|
||||
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
/* Flash mapped instruction data */
|
||||
irom_seg (RX) : org = 0x42000020 + FLASH_SEG_OFFSET,
|
||||
len = IDRAM0_2_SEG_SIZE - FLASH_SEG_OFFSET - 0x20
|
||||
#else
|
||||
/* Flash mapped instruction data */
|
||||
irom_seg (RX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20
|
||||
#endif
|
||||
|
||||
/**
|
||||
* (0x20 offset above is a convenience for the app binary image generation.
|
||||
@ -54,8 +66,14 @@ MEMORY
|
||||
sram_seg (RWX) : org = SRAM_SEG_START, len = SRAM_SEG_SIZE
|
||||
|
||||
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
/* Flash mapped constant data */
|
||||
drom_seg (R) : org = 0x42000020 + FLASH_SEG_OFFSET,
|
||||
len = IDRAM0_2_SEG_SIZE - FLASH_SEG_OFFSET - 0x20
|
||||
#else
|
||||
/* Flash mapped instruction data */
|
||||
drom_seg (R) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20
|
||||
#endif
|
||||
|
||||
/* (See irom_seg for meaning of 0x20 offset in the above.) */
|
||||
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
|
@ -173,9 +173,22 @@ SECTIONS
|
||||
|
||||
/* Vectors go to start of IRAM */
|
||||
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
|
||||
_vector_table_start = ABSOLUTE(.);
|
||||
KEEP(*(.exception_vectors_table.text));
|
||||
KEEP(*(.exception_vectors.text));
|
||||
|
||||
ALIGNED_SYMBOL(4, _invalid_pc_placeholder)
|
||||
|
||||
/* esp_tee_config_t structure: used to share information between the TEE and REE
|
||||
* (e.g. interrupt handler addresses, REE flash text-rodata boundaries, etc.)
|
||||
* This symbol is expected by the TEE at an offset of 0x300 from the vector table start.
|
||||
*/
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
ALIGNED_SYMBOL(0x10, _esp_tee_app_cfg)
|
||||
ASSERT(ABSOLUTE(.) == _vector_table_start + 0x2e0, "esp_tee_app_cfg must be at an offset 0x2e0 from the vector table start");
|
||||
*libesp_tee.a:(.esp_tee_app_cfg);
|
||||
#endif
|
||||
|
||||
/* Code marked as running out of IRAM */
|
||||
_iram_text_start = ABSOLUTE(.);
|
||||
|
||||
|
@ -277,11 +277,14 @@ __attribute__((weak)) void esp_perip_clk_init(void)
|
||||
periph_ll_disable_clk_set_rst(PERIPH_ASSIST_DEBUG_MODULE);
|
||||
#endif
|
||||
periph_ll_disable_clk_set_rst(PERIPH_RSA_MODULE);
|
||||
#if !CONFIG_SECURE_ENABLE_TEE
|
||||
// NOTE: [ESP-TEE] The TEE is responsible for the AES and SHA peripherals
|
||||
periph_ll_disable_clk_set_rst(PERIPH_AES_MODULE);
|
||||
periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE);
|
||||
periph_ll_disable_clk_set_rst(PERIPH_ECC_MODULE);
|
||||
periph_ll_disable_clk_set_rst(PERIPH_HMAC_MODULE);
|
||||
periph_ll_disable_clk_set_rst(PERIPH_DS_MODULE);
|
||||
#endif
|
||||
periph_ll_disable_clk_set_rst(PERIPH_ECDSA_MODULE);
|
||||
|
||||
// TODO: Replace with hal implementation
|
||||
|
@ -6,8 +6,8 @@ idf_build_get_property(target IDF_TARGET)
|
||||
# headers & sources here are compiled into the app, not the esp_tee binary
|
||||
# (see subproject/ for the esp_tee binary build files)
|
||||
|
||||
# ESP-TEE is currently supported only on the ESP32-C6 SoC
|
||||
if(NOT ${target} STREQUAL "esp32c6")
|
||||
# ESP-TEE is currently supported only on the ESP32-C6 and ESP32-H2 SoCs
|
||||
if(NOT ${target} STREQUAL "esp32c6" AND NOT ${target} STREQUAL "esp32h2")
|
||||
return()
|
||||
endif()
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
menu "ESP-TEE (Trusted Execution Environment)"
|
||||
depends on IDF_TARGET_ESP32C6
|
||||
depends on IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2
|
||||
|
||||
config SECURE_ENABLE_TEE
|
||||
bool "Enable the ESP-TEE framework"
|
||||
depends on IDF_TARGET_ESP32C6
|
||||
select ESP_SYSTEM_MEMPROT_FEATURE_VIA_TEE
|
||||
help
|
||||
This configuration enables the Trusted Execution Environment (TEE) feature.
|
||||
@ -75,7 +74,6 @@ menu "ESP-TEE (Trusted Execution Environment)"
|
||||
Secure storage will be encrypted by a constant key embedded in the TEE firmware
|
||||
|
||||
config SECURE_TEE_SEC_STG_MODE_RELEASE
|
||||
depends on IDF_TARGET_ESP32C6
|
||||
bool "Release"
|
||||
help
|
||||
Secure storage will be encrypted by the data stored in eFuse block
|
||||
|
296
components/esp_tee/scripts/esp32h2/sec_srv_tbl_default.yml
Normal file
296
components/esp_tee/scripts/esp32h2/sec_srv_tbl_default.yml
Normal file
@ -0,0 +1,296 @@
|
||||
secure_services:
|
||||
- family: misc
|
||||
entries:
|
||||
- id: 0
|
||||
type: custom
|
||||
function: invalid_secure_service
|
||||
args: 0
|
||||
# ID: 1-4 (4) - External memory (Flash) protection [SPI0]
|
||||
- family: flash_protection_spi0
|
||||
entries:
|
||||
- id: 1
|
||||
type: IDF
|
||||
function: mmu_hal_map_region
|
||||
args: 6
|
||||
- id: 2
|
||||
type: IDF
|
||||
function: mmu_hal_unmap_region
|
||||
args: 3
|
||||
- id: 3
|
||||
type: IDF
|
||||
function: mmu_hal_vaddr_to_paddr
|
||||
args: 4
|
||||
- id: 4
|
||||
type: IDF
|
||||
function: mmu_hal_paddr_to_vaddr
|
||||
args: 5
|
||||
# ID: 5-21 (17) - External memory (Flash) protection [SPI1]
|
||||
- family: flash_protection_spi1
|
||||
entries:
|
||||
- id: 5
|
||||
type: IDF
|
||||
function: spi_flash_hal_check_status
|
||||
args: 1
|
||||
- id: 6
|
||||
type: IDF
|
||||
function: spi_flash_hal_common_command
|
||||
args: 2
|
||||
- id: 7
|
||||
type: IDF
|
||||
function: spi_flash_hal_device_config
|
||||
args: 1
|
||||
- id: 8
|
||||
type: IDF
|
||||
function: spi_flash_hal_erase_block
|
||||
args: 2
|
||||
- id: 9
|
||||
type: IDF
|
||||
function: spi_flash_hal_erase_chip
|
||||
args: 1
|
||||
- id: 10
|
||||
type: IDF
|
||||
function: spi_flash_hal_erase_sector
|
||||
args: 2
|
||||
- id: 11
|
||||
type: IDF
|
||||
function: spi_flash_hal_program_page
|
||||
args: 4
|
||||
- id: 12
|
||||
type: IDF
|
||||
function: spi_flash_hal_read
|
||||
args: 4
|
||||
- id: 13
|
||||
type: IDF
|
||||
function: spi_flash_hal_resume
|
||||
args: 1
|
||||
- id: 14
|
||||
type: IDF
|
||||
function: spi_flash_hal_set_write_protect
|
||||
args: 2
|
||||
- id: 15
|
||||
type: IDF
|
||||
function: spi_flash_hal_setup_read_suspend
|
||||
args: 2
|
||||
- id: 16
|
||||
type: IDF
|
||||
function: spi_flash_hal_supports_direct_read
|
||||
args: 2
|
||||
- id: 17
|
||||
type: IDF
|
||||
function: spi_flash_hal_supports_direct_write
|
||||
args: 2
|
||||
- id: 18
|
||||
type: IDF
|
||||
function: spi_flash_hal_suspend
|
||||
args: 1
|
||||
- id: 19
|
||||
type: IDF
|
||||
function: bootloader_flash_execute_command_common
|
||||
args: 7
|
||||
- id: 20
|
||||
type: IDF
|
||||
function: memspi_host_flush_cache
|
||||
args: 3
|
||||
- id: 21
|
||||
type: IDF
|
||||
function: spi_flash_chip_generic_config_host_io_mode
|
||||
args: 2
|
||||
# ID: 30-53 (24) - Interrupt Handling
|
||||
- family: interrupt_handling
|
||||
entries:
|
||||
- id: 30
|
||||
type: IDF
|
||||
function: esp_rom_route_intr_matrix
|
||||
args: 3
|
||||
- id: 31
|
||||
type: IDF
|
||||
function: rv_utils_intr_enable
|
||||
args: 1
|
||||
- id: 32
|
||||
type: IDF
|
||||
function: rv_utils_intr_disable
|
||||
args: 1
|
||||
- id: 33
|
||||
type: IDF
|
||||
function: rv_utils_intr_set_priority
|
||||
args: 2
|
||||
- id: 34
|
||||
type: IDF
|
||||
function: rv_utils_intr_set_type
|
||||
args: 2
|
||||
- id: 35
|
||||
type: IDF
|
||||
function: rv_utils_intr_set_threshold
|
||||
args: 1
|
||||
- id: 36
|
||||
type: IDF
|
||||
function: rv_utils_intr_edge_ack
|
||||
args: 1
|
||||
- id: 37
|
||||
type: IDF
|
||||
function: rv_utils_intr_global_enable
|
||||
args: 0
|
||||
# ID: 54-85 (32) - HAL
|
||||
- family: hal
|
||||
entries:
|
||||
- id: 54
|
||||
type: IDF
|
||||
function: wdt_hal_init
|
||||
args: 4
|
||||
- id: 55
|
||||
type: IDF
|
||||
function: wdt_hal_deinit
|
||||
args: 1
|
||||
# ID: 86-133 (48) - Crypto
|
||||
- family: crypto
|
||||
entries:
|
||||
- id: 86
|
||||
type: IDF
|
||||
function: esp_aes_intr_alloc
|
||||
args: 0
|
||||
- id: 87
|
||||
type: IDF
|
||||
function: esp_aes_crypt_cbc
|
||||
args: 6
|
||||
- id: 88
|
||||
type: IDF
|
||||
function: esp_aes_crypt_cfb8
|
||||
args: 6
|
||||
- id: 89
|
||||
type: IDF
|
||||
function: esp_aes_crypt_cfb128
|
||||
args: 7
|
||||
- id: 90
|
||||
type: IDF
|
||||
function: esp_aes_crypt_ctr
|
||||
args: 7
|
||||
- id: 91
|
||||
type: IDF
|
||||
function: esp_aes_crypt_ecb
|
||||
args: 4
|
||||
- id: 92
|
||||
type: IDF
|
||||
function: esp_aes_crypt_ofb
|
||||
args: 6
|
||||
- id: 93
|
||||
type: IDF
|
||||
function: esp_sha
|
||||
args: 4
|
||||
- id: 94
|
||||
type: IDF
|
||||
function: esp_sha_block
|
||||
args: 3
|
||||
- id: 95
|
||||
type: IDF
|
||||
function: esp_sha_dma
|
||||
args: 6
|
||||
- id: 96
|
||||
type: IDF
|
||||
function: esp_sha_read_digest_state
|
||||
args: 2
|
||||
- id: 97
|
||||
type: IDF
|
||||
function: esp_sha_write_digest_state
|
||||
args: 2
|
||||
- id: 98
|
||||
type: IDF
|
||||
function: esp_crypto_sha_enable_periph_clk
|
||||
args: 1
|
||||
- id: 99
|
||||
type: IDF
|
||||
function: esp_hmac_calculate
|
||||
args: 4
|
||||
- id: 100
|
||||
type: IDF
|
||||
function: esp_hmac_jtag_enable
|
||||
args: 2
|
||||
- id: 101
|
||||
type: IDF
|
||||
function: esp_hmac_jtag_disable
|
||||
args: 0
|
||||
- id: 102
|
||||
type: IDF
|
||||
function: esp_ds_sign
|
||||
args: 4
|
||||
- id: 103
|
||||
type: IDF
|
||||
function: esp_ds_start_sign
|
||||
args: 4
|
||||
- id: 104
|
||||
type: IDF
|
||||
function: esp_ds_is_busy
|
||||
args: 0
|
||||
- id: 105
|
||||
type: IDF
|
||||
function: esp_ds_finish_sign
|
||||
args: 2
|
||||
- id: 106
|
||||
type: IDF
|
||||
function: esp_ds_encrypt_params
|
||||
args: 4
|
||||
- id: 107
|
||||
type: IDF
|
||||
function: esp_crypto_mpi_enable_periph_clk
|
||||
args: 1
|
||||
- id: 108
|
||||
type: IDF
|
||||
function: esp_ecc_point_multiply
|
||||
args: 4
|
||||
- id: 109
|
||||
type: IDF
|
||||
function: esp_ecc_point_verify
|
||||
args: 1
|
||||
- id: 110
|
||||
type: IDF
|
||||
function: esp_crypto_ecc_enable_periph_clk
|
||||
args: 1
|
||||
# ID: 134-169 (36) - Reserved for future use
|
||||
- family: attestation
|
||||
entries:
|
||||
- id: 170
|
||||
type: custom
|
||||
function: esp_tee_att_generate_token
|
||||
args: 6
|
||||
# ID: 175-194 (20) - Secure Storage
|
||||
- family: secure_storage
|
||||
entries:
|
||||
- id: 175
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_clear_key
|
||||
args: 1
|
||||
- id: 176
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_gen_key
|
||||
args: 1
|
||||
- id: 177
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_ecdsa_sign
|
||||
args: 4
|
||||
- id: 178
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_ecdsa_get_pubkey
|
||||
args: 2
|
||||
- id: 179
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_aead_encrypt
|
||||
args: 4
|
||||
- id: 180
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_aead_decrypt
|
||||
args: 4
|
||||
# ID: 195-199 (5) - OTA
|
||||
- family: ota
|
||||
entries:
|
||||
- id: 195
|
||||
type: custom
|
||||
function: esp_tee_ota_begin
|
||||
args: 0
|
||||
- id: 196
|
||||
type: custom
|
||||
function: esp_tee_ota_write
|
||||
args: 3
|
||||
- id: 197
|
||||
type: custom
|
||||
function: esp_tee_ota_end
|
||||
args: 0
|
||||
# ID: 200+ - User-defined
|
@ -331,6 +331,13 @@ int __wrap_esp_ecc_point_verify(const ecc_point_t *point)
|
||||
return err;
|
||||
}
|
||||
|
||||
#if SOC_ECDSA_SUPPORTED
|
||||
void __wrap_esp_crypto_ecc_enable_periph_clk(bool enable)
|
||||
{
|
||||
esp_tee_service_call(2, SS_ESP_CRYPTO_ECC_ENABLE_PERIPH_CLK, enable);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------- MMU HAL ------------------------------------------------- */
|
||||
|
||||
void IRAM_ATTR __wrap_mmu_hal_map_region(uint32_t mmu_id, mmu_target_t mem_type, uint32_t vaddr, uint32_t paddr, uint32_t len, uint32_t *out_len)
|
||||
|
@ -20,9 +20,10 @@ list(APPEND srcs "arch/${arch}/esp_tee_vectors.S"
|
||||
# SoC specific implementation for TEE
|
||||
list(APPEND srcs "soc/${target}/esp_tee_secure_sys_cfg.c"
|
||||
"soc/${target}/esp_tee_pmp_pma_prot_cfg.c"
|
||||
"soc/${target}/esp_tee_apm_prot_cfg.c"
|
||||
"soc/${target}/esp_tee_apm_intr.c"
|
||||
"soc/${target}/esp_tee_aes_intr.c")
|
||||
"soc/${target}/esp_tee_apm_prot_cfg.c")
|
||||
|
||||
list(APPEND srcs "soc/common/esp_tee_apm_intr.c"
|
||||
"soc/common/esp_tee_aes_intr.c")
|
||||
|
||||
# Common module implementation for TEE
|
||||
|
||||
@ -35,6 +36,7 @@ list(APPEND srcs "common/brownout.c")
|
||||
|
||||
list(APPEND include "include"
|
||||
"common"
|
||||
"soc/common/include"
|
||||
"soc/${target}/include")
|
||||
|
||||
# Heap
|
||||
@ -52,6 +54,12 @@ list(APPEND srcs "common/syscall_stubs.c")
|
||||
idf_component_register(SRCS ${srcs}
|
||||
INCLUDE_DIRS ${include})
|
||||
|
||||
# NOTE: The ESP32-H2 ROM does not have sprintf/snprintf implementation,
|
||||
# thus newlib-nano implementation from the toolchain has been used.
|
||||
if(CONFIG_IDF_TARGET_ESP32H2)
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "--specs=nano.specs")
|
||||
endif()
|
||||
|
||||
# TODO: Currently only -Og optimization level works correctly at runtime
|
||||
set_source_files_properties("core/esp_secure_dispatcher.c" PROPERTIES COMPILE_FLAGS "-Og")
|
||||
|
||||
|
@ -7,14 +7,12 @@
|
||||
#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/vectors_const.h"
|
||||
|
||||
#include "esp_tee.h"
|
||||
#include "esp_tee_intr_defs.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
.equ SAVE_REGS, 32
|
||||
@ -25,13 +23,10 @@
|
||||
.equ RTNVAL, 0xc0de
|
||||
.equ ECALL_U_MODE, 0x8
|
||||
.equ ECALL_M_MODE, 0xb
|
||||
.equ TEE_APM_INTR_MASK_0, 0x00300000
|
||||
.equ TEE_APM_INTR_MASK_1, 0x000000f8
|
||||
.equ TEE_INTR_DELEG_MASK, 0xffffbfff
|
||||
|
||||
.global esp_tee_global_interrupt_handler
|
||||
.global esp_tee_service_dispatcher
|
||||
|
||||
.global esp_tee_service_dispatcher
|
||||
|
||||
.section .data
|
||||
.align 4
|
||||
@ -441,22 +436,24 @@ _tee_s_intr_handler:
|
||||
|
||||
/* Check if the interrupt source is related to an APM exception */
|
||||
/* Define the addresses of the registers */
|
||||
li t0, INTMTX_CORE0_INT_STATUS_REG_0_REG
|
||||
li t0, INTMTX_STATUS_REG_0
|
||||
/* Load the values from the registers */
|
||||
lw t1, 0(t0)
|
||||
/* Define the masks */
|
||||
li t2, TEE_APM_INTR_MASK_0
|
||||
li t2, TEE_SECURE_INT_APM_MASK_0
|
||||
/* Apply the masks */
|
||||
and t1, t1, t2
|
||||
/* Check if any of the masked bits are set */
|
||||
bnez t1, _save_reg_ctx
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C6
|
||||
/* Repeat for the other status register */
|
||||
li t0, INTMTX_CORE0_INT_STATUS_REG_1_REG
|
||||
li t0, INTMTX_STATUS_REG_1
|
||||
lw t1, 0(t0)
|
||||
li t2, TEE_APM_INTR_MASK_1
|
||||
li t2, TEE_SECURE_INT_APM_MASK_1
|
||||
and t1, t1, t2
|
||||
bnez t1, _save_reg_ctx
|
||||
#endif
|
||||
|
||||
/* Continue normal execution */
|
||||
j _continue
|
||||
@ -464,6 +461,11 @@ _tee_s_intr_handler:
|
||||
_save_reg_ctx:
|
||||
/* Save CSR context here */
|
||||
save_mcsr
|
||||
csrr t0, mcause
|
||||
sw t0, RV_STK_MCAUSE(sp)
|
||||
/* NOTE: With ESP-TEE, since APM violations trigger a panic, it's safe to use the mscratch
|
||||
* register to pass on the stack pointer to the APM violation handler */
|
||||
csrw mscratch, sp
|
||||
j _intr_hdlr_exec
|
||||
|
||||
_continue:
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_rom_tlsf.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "tlsf_block_functions.h"
|
||||
#include "multi_heap.h"
|
||||
|
||||
@ -153,15 +154,15 @@ size_t esp_tee_heap_get_min_free_size(void)
|
||||
static void heap_dump_tlsf(void* ptr, size_t size, int used, void* user)
|
||||
{
|
||||
(void)user;
|
||||
printf("Block %p data, size: %d bytes, Free: %s\n",
|
||||
(void *)ptr,
|
||||
size,
|
||||
used ? "No" : "Yes");
|
||||
esp_rom_printf("Block %p data, size: %d bytes, Free: %s\n",
|
||||
(void *)ptr,
|
||||
size,
|
||||
used ? "No" : "Yes");
|
||||
}
|
||||
|
||||
void esp_tee_heap_dump_info(void)
|
||||
{
|
||||
printf("Showing data for TEE heap: %p (%uB)\n", (void *)tee_heap, tee_heap->pool_size);
|
||||
esp_rom_printf("Showing data for TEE heap: %p (%uB)\n", (void *)tee_heap, tee_heap->pool_size);
|
||||
tlsf_walk_pool(tlsf_get_pool(tee_heap->heap_data), heap_dump_tlsf, NULL);
|
||||
}
|
||||
|
||||
|
@ -130,6 +130,13 @@ int __cxa_thread_atexit(void (*func)(void *), void *arg, void *dso)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32H2
|
||||
void *_sbrk(ptrdiff_t incr)
|
||||
{
|
||||
return (void *) -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void esp_tee_include_syscalls_impl(void)
|
||||
{
|
||||
|
||||
|
@ -345,6 +345,11 @@ int _ss_esp_ecc_point_verify(const ecc_point_t *point)
|
||||
return esp_ecc_point_verify(point);
|
||||
}
|
||||
|
||||
void _ss_esp_crypto_ecc_enable_periph_clk(bool enable)
|
||||
{
|
||||
esp_crypto_ecc_enable_periph_clk(enable);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------- OTA ------------------------------------------------- */
|
||||
|
||||
int _ss_esp_tee_ota_begin(void)
|
||||
|
@ -1,24 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_cpu.h"
|
||||
|
||||
#include "hal/cpu_ll.h"
|
||||
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/interrupts.h"
|
||||
#include "soc/interrupt_reg.h"
|
||||
|
||||
#include "esp_tee.h"
|
||||
#include "esp_tee_intr.h"
|
||||
#include "esp_tee_intr_defs.h"
|
||||
#include "esp_tee_rv_utils.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/interrupt_reg.h"
|
||||
#include "hal/cpu_ll.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
/* For ESP32-C6 */
|
||||
#define INTR_MAX_SOURCE (77)
|
||||
|
||||
#define INTR_SET_SIZE (32)
|
||||
#define INTR_SET_COUNT ((((INTR_MAX_SOURCE) + ((INTR_SET_SIZE) - 1)) & ~((INTR_SET_SIZE) - 1)) / INTR_SET_SIZE)
|
||||
#define INTR_DISABLED_INUM (6)
|
||||
#define INTR_SET_COUNT ((((ETS_MAX_INTR_SOURCE) + ((INTR_SET_SIZE) - 1)) & ~((INTR_SET_SIZE) - 1)) / INTR_SET_SIZE)
|
||||
|
||||
static const char *TAG = "esp_tee_intr";
|
||||
|
||||
@ -27,7 +28,7 @@ typedef struct tee_handler_table_entry {
|
||||
void *arg;
|
||||
} tee_handler_table_entry;
|
||||
|
||||
static tee_handler_table_entry tee_interrupt_table[INTR_MAX_SOURCE * portNUM_PROCESSORS];
|
||||
static tee_handler_table_entry tee_interrupt_table[ETS_MAX_INTR_SOURCE * portNUM_PROCESSORS];
|
||||
|
||||
static uint32_t protected_sources[INTR_SET_COUNT];
|
||||
|
||||
@ -60,14 +61,6 @@ void esp_tee_route_intr_matrix(int cpu_no, uint32_t model_num, uint32_t intr_num
|
||||
return;
|
||||
}
|
||||
|
||||
if (intr_num != ETS_INVALID_INUM) {
|
||||
if (intr_num == INTR_DISABLED_INUM) {
|
||||
rv_utils_tee_intr_disable(BIT(intr_num));
|
||||
} else {
|
||||
rv_utils_tee_intr_enable(BIT(intr_num));
|
||||
}
|
||||
}
|
||||
|
||||
esp_rom_route_intr_matrix(cpu_no, model_num, intr_num);
|
||||
}
|
||||
|
||||
@ -126,60 +119,45 @@ int esp_tee_intr_deregister(void *arg)
|
||||
tee_set_interrupt_handler(vd);
|
||||
|
||||
// Setting back the default value for interrupt pin.
|
||||
esp_rom_route_intr_matrix(cpu, vd->source, INTR_DISABLED_INUM);
|
||||
esp_rom_route_intr_matrix(cpu, vd->source, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define FIND_MSB_SET(n) (31 - __builtin_clz((uint32_t)(n)))
|
||||
// LP_APM_M0_INTR, LP_APM_M1_INTR
|
||||
#define TEE_SECURE_INT_APM_MASK_0 (0x00300000)
|
||||
// EFUSE_INTR, LP_RTC_TIMER_INTR
|
||||
#define TEE_SECURE_INT_MASK_0 (TEE_SECURE_INT_APM_MASK_0 | 0x0000C000)
|
||||
// HP_APM_M0_INTR, HP_APM_M1_INTR, HP_APM_M2_INTR, HP_APM_M3_INTR, LP_APM0_INTR
|
||||
#define TEE_SECURE_INT_APM_MASK_1 (0x000000F8)
|
||||
#if !CONFIG_SECURE_TEE_TEST_MODE
|
||||
#define TEE_SECURE_INT_MASK_1 (TEE_SECURE_INT_APM_MASK_1)
|
||||
#else
|
||||
// + TG0_T0_INTR (only for test mode)
|
||||
#define TEE_SECURE_INT_MASK_1 (TEE_SECURE_INT_APM_MASK_1 | 0x00080000)
|
||||
#endif
|
||||
// AES_INTR, SHA_INTR, RSA_INTR, ECC_INTR
|
||||
#define TEE_SECURE_INT_MASK_2 (0x00001E00)
|
||||
|
||||
/* called from esp_tee_vectors.S */
|
||||
void esp_tee_global_interrupt_handler(intptr_t sp, int mcause)
|
||||
{
|
||||
uint32_t status, source;
|
||||
|
||||
while (1) {
|
||||
if ((status = TEE_SECURE_INT_MASK_0 &
|
||||
REG_READ(INTMTX_CORE0_INT_STATUS_REG_0_REG))) {
|
||||
do {
|
||||
status = REG_READ(INTMTX_STATUS_REG_0) & TEE_SECURE_INT_MASK_0;
|
||||
if (status) {
|
||||
source = FIND_MSB_SET(status);
|
||||
/* NOTE: With ESP-TEE, since APM violations trigger a panic, it's safe to use the mscratch
|
||||
* register to pass on the stack pointer to the APM violation handler */
|
||||
if (status & TEE_SECURE_INT_APM_MASK_0) {
|
||||
RV_WRITE_CSR(mscratch, sp);
|
||||
}
|
||||
} else if ((status = TEE_SECURE_INT_MASK_1 &
|
||||
REG_READ(INTMTX_CORE0_INT_STATUS_REG_1_REG))) {
|
||||
source = FIND_MSB_SET(status) + 32;
|
||||
if (status & TEE_SECURE_INT_APM_MASK_1) {
|
||||
RV_WRITE_CSR(mscratch, sp);
|
||||
}
|
||||
} else if ((status = TEE_SECURE_INT_MASK_2 &
|
||||
REG_READ(INTMTX_CORE0_INT_STATUS_REG_2_REG))) {
|
||||
source = FIND_MSB_SET(status) + 64;
|
||||
}
|
||||
|
||||
if (!status) {
|
||||
break;
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "Found intr src: %d", source);
|
||||
tee_handler_table_entry ih = tee_interrupt_table[source];
|
||||
if (ih.handler) {
|
||||
(*ih.handler)(ih.arg);
|
||||
status = REG_READ(INTMTX_STATUS_REG_1) & TEE_SECURE_INT_MASK_1;
|
||||
if (status) {
|
||||
source = FIND_MSB_SET(status) + 32;
|
||||
break;
|
||||
}
|
||||
|
||||
status = REG_READ(INTMTX_STATUS_REG_2) & TEE_SECURE_INT_MASK_2;
|
||||
if (status) {
|
||||
source = FIND_MSB_SET(status) + 64;
|
||||
break;
|
||||
}
|
||||
|
||||
/* No valid interrupt found */
|
||||
ESP_LOGV(TAG, "No valid interrupt found");
|
||||
return;
|
||||
} while (0);
|
||||
|
||||
ESP_LOGV(TAG, "Found intr src: %d", source);
|
||||
tee_handler_table_entry ih = tee_interrupt_table[source];
|
||||
if (ih.handler) {
|
||||
(*ih.handler)(ih.arg);
|
||||
}
|
||||
}
|
||||
|
@ -3,4 +3,4 @@ dependencies:
|
||||
espressif/json_generator:
|
||||
version: "^1.1.2"
|
||||
rules:
|
||||
- if: "target in [esp32c6]"
|
||||
- if: "target in [esp32c6, esp32h2]"
|
||||
|
304
components/esp_tee/subproject/main/ld/esp32h2/esp_tee.ld.in
Normal file
304
components/esp_tee/subproject/main/ld/esp32h2/esp_tee.ld.in
Normal file
@ -0,0 +1,304 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#define SRAM_IRAM_START (0x40800000)
|
||||
#define SRAM_IRAM_TEE_ORG (SRAM_IRAM_START)
|
||||
#define SRAM_DRAM_TEE_ORG (SRAM_IRAM_START)
|
||||
|
||||
#define SRAM_IRAM_ORG (SRAM_IRAM_TEE_ORG + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE)
|
||||
|
||||
#define SRAM_DRAM_TEE_SIZE (CONFIG_SECURE_TEE_DRAM_SIZE - CONFIG_SECURE_TEE_STACK_SIZE - CONFIG_SECURE_TEE_INTR_STACK_SIZE)
|
||||
#define SRAM_DRAM_TEE_END (SRAM_DRAM_TEE_ORG + CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_DRAM_TEE_SIZE)
|
||||
|
||||
#define I_D_SRAM_TEE_SIZE (CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_DRAM_TEE_SIZE)
|
||||
|
||||
/* TEE interrupt stack is placed at the end of the TEE DRAM segment.
|
||||
* The top of the TEE stack is before the end of interrupt stack
|
||||
* and the bottom of the stack is at _heap_end.
|
||||
*/
|
||||
#define SRAM_STACK_TEE_ORG (SRAM_DRAM_TEE_END)
|
||||
#define SRAM_INTR_STACK_TEE_ORG (SRAM_DRAM_TEE_END + CONFIG_SECURE_TEE_STACK_SIZE)
|
||||
|
||||
#define FLASH_IROM_TEE_ORG (0x42000000)
|
||||
#define FLASH_DROM_TEE_ORG (0x42000000)
|
||||
#define I_D_FLASH_TEE_SIZE (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE)
|
||||
|
||||
/**
|
||||
* These values are the same in every app binary for the same chip target.
|
||||
*
|
||||
* Values that may change when the app is rebuilt, or in a new ESP-IDF version,
|
||||
* should be stored via esp_app_tee_config structure
|
||||
*/
|
||||
|
||||
#if CONFIG_ESP_DEBUG_INCLUDE_OCD_STUB_BINS
|
||||
PROVIDE ( esp_tee_app_config = SRAM_IRAM_ORG + 0x22e0 );
|
||||
#else
|
||||
PROVIDE ( esp_tee_app_config = SRAM_IRAM_ORG + 0x2e0 );
|
||||
#endif
|
||||
|
||||
PROVIDE ( GDMA = 0x60080000 );
|
||||
|
||||
/* Default entry point: */
|
||||
ENTRY(esp_tee_init);
|
||||
|
||||
MEMORY
|
||||
{
|
||||
/* IRAM Configuration */
|
||||
iram_tee_seg (RX) : org = SRAM_IRAM_TEE_ORG, len = I_D_SRAM_TEE_SIZE
|
||||
|
||||
/* DRAM Configuration */
|
||||
dram_tee_seg (RW) : org = SRAM_DRAM_TEE_ORG, len = I_D_SRAM_TEE_SIZE
|
||||
|
||||
/* TEE Stack Configuration */
|
||||
stack_tee_seg (RW) : org = SRAM_STACK_TEE_ORG, len = CONFIG_SECURE_TEE_STACK_SIZE
|
||||
|
||||
/* TEE Interrupt Stack Configuration */
|
||||
intr_stack_tee_seg (RW) : org = SRAM_INTR_STACK_TEE_ORG, len = CONFIG_SECURE_TEE_INTR_STACK_SIZE
|
||||
|
||||
/* TEE flash data section */
|
||||
flash_data_seg (R) : org = FLASH_DROM_TEE_ORG + 0x20, len = I_D_FLASH_TEE_SIZE - 0x20
|
||||
|
||||
/* TEE flash text section */
|
||||
flash_text_seg (RX): org = FLASH_IROM_TEE_ORG + 0x20, len = I_D_FLASH_TEE_SIZE - 0x20
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/**
|
||||
* This section is required to skip .iram.tee_text area because iram_tee_seg and
|
||||
* dram_tee_seg reflect the same address space on different buses.
|
||||
*/
|
||||
.dram.tee_dummy (NOLOAD):
|
||||
{
|
||||
. = ORIGIN(dram_tee_seg) + CONFIG_SECURE_TEE_IRAM_SIZE;
|
||||
} > dram_tee_seg
|
||||
|
||||
.dram.tee.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN (8);
|
||||
_tee_dram_start = ABSOLUTE(.);
|
||||
_tee_bss_start = ABSOLUTE(.);
|
||||
*(.bss .bss.*)
|
||||
*(.sbss .sbss.*)
|
||||
. = ALIGN (8);
|
||||
_tee_bss_end = ABSOLUTE(.);
|
||||
} > dram_tee_seg
|
||||
|
||||
.dram.tee.data :
|
||||
{
|
||||
_data_start = ABSOLUTE(.);
|
||||
*(.data .data.*)
|
||||
*(.sdata .sdata.*)
|
||||
*(.dram1 .dram1.*)
|
||||
. = ALIGN(4);
|
||||
_data_end = ABSOLUTE(.);
|
||||
} > dram_tee_seg
|
||||
|
||||
.dram.tee.rodata :
|
||||
{
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
/* TEE flash manager */
|
||||
*libtee_flash_mgr.a:*(.rodata .srodata .rodata.* .srodata.*)
|
||||
*libbootloader_support.a:bootloader_flash.*(.rodata .srodata .rodata.* .srodata.*)
|
||||
/* Secure services */
|
||||
*libmain.a:esp_secure_services_iram.c.*(.rodata .srodata .rodata.* .srodata.*)
|
||||
*libmain.a:esp_secure_dispatcher.c.*(.rodata .srodata .rodata.* .srodata.*)
|
||||
/* Panic handler */
|
||||
*libmain.a:panic_helper_riscv.*(.rodata .srodata .rodata.* .srodata.*)
|
||||
*libmain.a:esp_tee_apm_intr.c.*(.rodata .srodata .rodata.* .srodata.*)
|
||||
/* HAL (noflash) */
|
||||
*libhal.a:mmu_hal.c*(.rodata .srodata .rodata.* .srodata.*)
|
||||
*libhal.a:cache_hal.c*(.rodata .srodata .rodata.* .srodata.*)
|
||||
_rodata_end = ABSOLUTE(.);
|
||||
_tee_dram_end = ABSOLUTE(.);
|
||||
} > dram_tee_seg
|
||||
|
||||
.dram.tee.heap :
|
||||
{
|
||||
. = ALIGN (16);
|
||||
_tee_heap_start = ABSOLUTE(.);
|
||||
. = ORIGIN(dram_tee_seg) + LENGTH(dram_tee_seg);
|
||||
_tee_heap_end = ABSOLUTE(.);
|
||||
} > dram_tee_seg
|
||||
|
||||
.dram.tee.stack :
|
||||
{
|
||||
. = ALIGN (16);
|
||||
_tee_stack_bottom = ABSOLUTE(.);
|
||||
. = ORIGIN(stack_tee_seg) + LENGTH(stack_tee_seg);
|
||||
_tee_stack = ABSOLUTE(.);
|
||||
} > stack_tee_seg
|
||||
|
||||
.dram.tee.intr_stack :
|
||||
{
|
||||
. = ALIGN (16);
|
||||
_tee_intr_stack_bottom = ABSOLUTE(.);
|
||||
. = ORIGIN(intr_stack_tee_seg) + LENGTH(intr_stack_tee_seg);
|
||||
_tee_intr_stack = ABSOLUTE(.);
|
||||
} > intr_stack_tee_seg
|
||||
|
||||
.flash.rodata :
|
||||
{
|
||||
_tee_xip_data_start = ABSOLUTE(.);
|
||||
*(.rodata_desc .rodata_desc.*) /* Should be the first. TEE App version info. DO NOT PUT ANYTHING BEFORE IT! */
|
||||
*(.rodata .rodata.*)
|
||||
*(.srodata .srodata.*)
|
||||
*(.gcc_except_table .gcc_except_table.*)
|
||||
_tee_xip_data_end = ABSOLUTE(.);
|
||||
} > flash_data_seg
|
||||
|
||||
.flash.text_dummy (NOLOAD):
|
||||
{
|
||||
. = ALIGN(ALIGNOF(.flash.rodata));
|
||||
/* Create an empty gap as big as .flash.rodata section */
|
||||
. = . + SIZEOF(.flash.rodata);
|
||||
/* Prepare the alignment of the section above. Few bytes (0x20) must be
|
||||
* added for the mapping header. */
|
||||
. = ALIGN(CONFIG_MMU_PAGE_SIZE) + 0x20;
|
||||
} > flash_text_seg
|
||||
|
||||
|
||||
/* HAL modules and their memory placement:
|
||||
*
|
||||
* +-----------+---------------+--------+
|
||||
* | Module | Section | Memory |
|
||||
* +-----------+---------------+--------+
|
||||
* | MMU | text+rodata | SRAM |
|
||||
* | CACHE | text+rodata | SRAM |
|
||||
* | WDT | text | SRAM |
|
||||
* | APM | text | Flash* |
|
||||
* | AES | text | Flash |
|
||||
* | SHA | text | Flash |
|
||||
* | HMAC | text | Flash |
|
||||
* | DS | text | Flash |
|
||||
* | ECC | text | Flash |
|
||||
* | BROWNOUT | text | Flash |
|
||||
* | EFUSE | text | Flash |
|
||||
* | LPTIMER | text | Flash |
|
||||
* | SPI_FLASH | text | Flash |
|
||||
* +-----------+---------------+--------+
|
||||
*
|
||||
* By default, for ESP-TEE, text sections are placed in SRAM while rodata sections go to the flash.
|
||||
* Therefore, only HAL modules that require SRAM placement for proper functionality are located there,
|
||||
* while the remaining modules are placed in flash memory.
|
||||
*/
|
||||
|
||||
.flash.text :
|
||||
{
|
||||
_tee_xip_text_start = ABSOLUTE(.);
|
||||
/* Secure Services */
|
||||
*libmain.a:esp_secure_services.c*(.literal .text .literal.* .text.*)
|
||||
/* HAL */
|
||||
*libhal.a:aes_hal.c*(.literal .text .literal.* .text.*)
|
||||
*libhal.a:sha_hal.c*(.literal .text .literal.* .text.*)
|
||||
*libhal.a:hmac_hal.c*(.literal .text .literal.* .text.*)
|
||||
*libhal.a:ds_hal.c*(.literal .text .literal.* .text.*)
|
||||
*libhal.a:ecc_hal.c*(.literal .text .literal.* .text.*)
|
||||
/* NOTE: There is a possibility of APM violations (SPI1 flash protection)
|
||||
* being triggered with the flash cache disabled */
|
||||
#if !CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||
*libhal.a:apm_hal.c*(.literal .text .literal.* .text.*)
|
||||
#endif
|
||||
*libhal.a:brownout_hal.c*(.literal .text .literal.* .text.*)
|
||||
*libhal.a:spi_flash_hal.c*(.literal .text .literal.* .text.*)
|
||||
/* These HAL modules have functions marked with the IRAM_ATTR attribute which get placed in the SRAM */
|
||||
*libhal.a:efuse_hal.c*(.literal .text .literal.* .text.*)
|
||||
*libhal.a:lp_timer_hal.c*(.literal .text .literal.* .text.*)
|
||||
/* Mbedtls for TEE */
|
||||
*libmbedtls.a:*(.literal .text .literal.* .text.*)
|
||||
*libmbedcrypto.a:*(.literal .text .literal.* .text.*)
|
||||
/* HMAC-DS layer */
|
||||
*libesp_security.a:*(.literal .text .literal.* .text.*)
|
||||
/* NVS flash and related modules */
|
||||
*libnvs_flash.a:*(.literal .text .literal.* .text.*)
|
||||
*libstdc++.a:*(.literal .text .literal.* .text.*)
|
||||
*libgcc.a:*(.literal .text .literal.* .text.*)
|
||||
/* esp_partition API */
|
||||
*libesp_partition.a:*(.literal .text .literal.* .text.*)
|
||||
/* TEE attestation module */
|
||||
*libattestation.a:*(.literal .text .literal.* .text.*)
|
||||
*json_generator.a:*(.literal .text .literal.* .text.*)
|
||||
/* snprintf-related functions */
|
||||
*libc_nano.a:(.literal .text .literal.* .text.*)
|
||||
/* TEE test module */
|
||||
*libtest_sec_srv.a:*(.literal .text .literal.* .text.*)
|
||||
_tee_xip_text_end = ABSOLUTE(.);
|
||||
_tee_xip_end = ABSOLUTE(.);
|
||||
} > flash_text_seg
|
||||
|
||||
.iram.tee.text :
|
||||
{
|
||||
/* Vectors go to start of IRAM */
|
||||
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
|
||||
_tee_vec_start = ABSOLUTE(.);
|
||||
KEEP(*(.exception_vectors_table.text));
|
||||
KEEP(*(.exception_vectors.text));
|
||||
. = ALIGN(4);
|
||||
_invalid_pc_placeholder = ABSOLUTE(.);
|
||||
_tee_vec_end = ABSOLUTE(.);
|
||||
|
||||
_tee_iram_start = ABSOLUTE(.);
|
||||
*(.literal .text .iram1 .literal.* .text.* .iram1.*)
|
||||
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||
_tee_iram_end = ABSOLUTE(.);
|
||||
} > iram_tee_seg
|
||||
|
||||
.riscv.attributes 0: { *(.riscv.attributes) }
|
||||
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
/* DWARF 3 */
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* GNU DWARF 2 extensions */
|
||||
.debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) }
|
||||
.debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) }
|
||||
/* DWARF 4 */
|
||||
.debug_types 0 : { *(.debug_types) }
|
||||
/* DWARF 5 */
|
||||
.debug_addr 0 : { *(.debug_addr) }
|
||||
.debug_line_str 0 : { *(.debug_line_str) }
|
||||
.debug_loclists 0 : { *(.debug_loclists) }
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.debug_names 0 : { *(.debug_names) }
|
||||
.debug_rnglists 0 : { *(.debug_rnglists) }
|
||||
.debug_str_offsets 0 : { *(.debug_str_offsets) }
|
||||
|
||||
.comment 0 : { *(.comment) }
|
||||
.note.GNU-stack 0: { *(.note.GNU-stack) }
|
||||
|
||||
/**
|
||||
* Discarding .rela.* sections results in the following mapping:
|
||||
* .rela.text.* -> .text.*
|
||||
* .rela.data.* -> .data.*
|
||||
* And so forth...
|
||||
*/
|
||||
/DISCARD/ : { *(.rela.*) }
|
||||
}
|
||||
|
||||
ASSERT ((_tee_iram_end < _tee_dram_start), "Error: TEE IRAM segment overflowed into the DRAM segment!");
|
@ -8,10 +8,9 @@
|
||||
|
||||
#include "hal/aes_hal.h"
|
||||
#include "soc/interrupts.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "esp_tee_intr.h"
|
||||
#include "esp_tee_aes_intr.h"
|
||||
|
||||
volatile DRAM_ATTR bool intr_flag;
|
||||
|
@ -4,13 +4,12 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "hal/apm_ll.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_bit_defs.h"
|
||||
|
||||
#include "hal/apm_hal.h"
|
||||
|
||||
#include "esp_tee.h"
|
||||
#include "esp_tee_apm_intr.h"
|
||||
#include "hal/apm_ll.h"
|
||||
|
||||
static const char *const excp_mid_strs[] = {
|
||||
[APM_LL_MASTER_HPCORE] = "HPCORE",
|
||||
@ -41,9 +40,9 @@ const char *esp_tee_apm_excp_type_to_str(uint8_t type)
|
||||
{
|
||||
char *excp_type = "APM - Unknown exception";
|
||||
|
||||
if (type & 0x01) {
|
||||
if (type & BIT(0)) {
|
||||
excp_type = "APM - Authority exception";
|
||||
} else if (type & 0x02) {
|
||||
} else if (type & BIT(1)) {
|
||||
excp_type = "APM - Space exception";
|
||||
}
|
||||
|
||||
@ -55,9 +54,11 @@ const char *esp_tee_apm_excp_ctrl_to_str(apm_ll_apm_ctrl_t apm_ctrl)
|
||||
char *excp_ctrl = NULL;
|
||||
|
||||
switch (apm_ctrl) {
|
||||
#if SOC_APM_LP_APM0_SUPPORTED
|
||||
case LP_APM0_CTRL:
|
||||
excp_ctrl = "LP_APM0";
|
||||
break;
|
||||
#endif
|
||||
case HP_APM_CTRL:
|
||||
excp_ctrl = "HP_APM";
|
||||
break;
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "riscv/rv_utils.h"
|
||||
#include "riscv/encoding.h"
|
||||
#include "esp_private/interrupt_plic.h"
|
||||
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_log.h"
|
||||
@ -28,9 +29,6 @@
|
||||
asm volatile("ecall" : :"r"(ra), "r"(a1) : ); \
|
||||
})
|
||||
|
||||
#define SET_BIT(t, n) (t |= (1UL << (n)))
|
||||
#define CLR_BIT(t, n) (t &= ~(1UL << (n)))
|
||||
|
||||
static const char *TAG = "esp_tee_secure_sys_cfg";
|
||||
|
||||
extern uint32_t _vector_table;
|
||||
@ -58,9 +56,8 @@ void esp_tee_soc_secure_sys_init(void)
|
||||
RV_WRITE_CSR(uie, 0x00);
|
||||
|
||||
/* All interrupts except the TEE secure interrupt are delegated to the U-mode */
|
||||
uint32_t mideleg_val = UINT32_MAX;
|
||||
CLR_BIT(mideleg_val, TEE_SECURE_INUM);
|
||||
RV_WRITE_CSR(mideleg, mideleg_val);
|
||||
RV_WRITE_CSR(mideleg, UINT32_MAX);
|
||||
RV_CLEAR_CSR(mideleg, TEE_SECURE_INUM);
|
||||
|
||||
/* TODO: IDF-8958
|
||||
* The values for the secure interrupt number and priority and
|
||||
@ -71,7 +68,7 @@ void esp_tee_soc_secure_sys_init(void)
|
||||
/* TODO: Currently, we do not allow interrupts to be set up with a priority greater than 7, see intr_alloc.c */
|
||||
esprv_int_set_priority(TEE_SECURE_INUM, 7);
|
||||
esprv_int_set_type(TEE_SECURE_INUM, ESP_CPU_INTR_TYPE_LEVEL);
|
||||
esprv_int_set_threshold(1);
|
||||
esprv_int_set_threshold(RVHAL_INTR_ENABLE_THRESH);
|
||||
esprv_int_enable(BIT(TEE_SECURE_INUM));
|
||||
#endif
|
||||
|
||||
@ -93,7 +90,6 @@ void esp_tee_soc_secure_sys_init(void)
|
||||
esp_tee_protect_intr_src(ETS_HP_APM_M2_INTR_SOURCE); // HP_APM_M2
|
||||
esp_tee_protect_intr_src(ETS_HP_APM_M3_INTR_SOURCE); // HP_APM_M3
|
||||
esp_tee_protect_intr_src(ETS_LP_APM0_INTR_SOURCE); // LP_APM0
|
||||
esp_tee_protect_intr_src(ETS_EFUSE_INTR_SOURCE); // eFuse
|
||||
esp_tee_protect_intr_src(ETS_AES_INTR_SOURCE); // AES
|
||||
esp_tee_protect_intr_src(ETS_SHA_INTR_SOURCE); // SHA
|
||||
esp_tee_protect_intr_src(ETS_ECC_INTR_SOURCE); // ECC
|
||||
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "soc/interrupt_matrix_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// LP_APM_M0_INTR, LP_APM_M1_INTR
|
||||
#define TEE_SECURE_INT_APM_MASK_0 (0x00300000)
|
||||
// HP_APM_M0_INTR, HP_APM_M1_INTR, HP_APM_M2_INTR, HP_APM_M3_INTR, LP_APM0_INTR
|
||||
#define TEE_SECURE_INT_APM_MASK_1 (0x000000F8)
|
||||
|
||||
// LP_RTC_TIMER_INTR
|
||||
#define TEE_SECURE_INT_MASK_0 (TEE_SECURE_INT_APM_MASK_0 | 0x00008000)
|
||||
#if !CONFIG_SECURE_TEE_TEST_MODE
|
||||
#define TEE_SECURE_INT_MASK_1 (TEE_SECURE_INT_APM_MASK_1)
|
||||
#else
|
||||
// + TG0_T0_INTR (only for test mode)
|
||||
#define TEE_SECURE_INT_MASK_1 (TEE_SECURE_INT_APM_MASK_1 | 0x00080000)
|
||||
#endif
|
||||
// AES_INTR, SHA_INTR, ECC_INTR
|
||||
#define TEE_SECURE_INT_MASK_2 (0x00001600)
|
||||
|
||||
#define INTMTX_STATUS_REG_0 (INTMTX_CORE0_INT_STATUS_REG_0_REG)
|
||||
#define INTMTX_STATUS_REG_1 (INTMTX_CORE0_INT_STATUS_REG_1_REG)
|
||||
#define INTMTX_STATUS_REG_2 (INTMTX_CORE0_INT_STATUS_REG_2_REG)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,303 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "esp_log.h"
|
||||
#include "esp_tee.h"
|
||||
#include "esp_tee_intr.h"
|
||||
|
||||
#include "hal/apm_hal.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/spi_mem_reg.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/pcr_reg.h"
|
||||
|
||||
extern void tee_apm_violation_isr(void *arg);
|
||||
|
||||
static const char *TAG = "esp_tee_apm_prot_cfg";
|
||||
|
||||
/* NOTE: Figuring out the eFuse protection range based on where the TEE secure storage key is stored */
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID < 0
|
||||
#error "TEE: eFuse protection region for APM out of range! (see CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID)"
|
||||
#endif
|
||||
#define LP_APM_EFUSE_REG_START \
|
||||
(EFUSE_RD_KEY0_DATA0_REG + (CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID * 0x20))
|
||||
|
||||
#define LP_APM_EFUSE_REG_END \
|
||||
(EFUSE_RD_KEY1_DATA0_REG + (CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID * 0x20))
|
||||
#elif CONFIG_SECURE_TEE_SEC_STG_MODE_DEVELOPMENT
|
||||
#define LP_APM_EFUSE_REG_START EFUSE_RD_KEY5_DATA0_REG
|
||||
#if CONFIG_SECURE_TEE_TEST_MODE
|
||||
#define LP_APM_EFUSE_REG_END EFUSE_RD_SYS_PART2_DATA0_REG
|
||||
#else
|
||||
#define LP_APM_EFUSE_REG_END LP_APM_EFUSE_REG_START
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* NOTE: Flash protection over the SPI1 controller */
|
||||
#define HP_APM_SPI1_REG_START DR_REG_SPI1_BASE
|
||||
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||
#define HP_APM_SPI1_REG_END DR_REG_I2C_EXT0_BASE
|
||||
#else
|
||||
#define HP_APM_SPI1_REG_END HP_APM_SPI1_REG_START
|
||||
#endif
|
||||
|
||||
/*----------------------- HP APM range and filter configuration -----------------------*/
|
||||
|
||||
/* HP_APM: TEE mode accessible regions */
|
||||
apm_ctrl_region_config_data_t hp_apm_pms_data_tee[] = {
|
||||
/* Region 0: Entire memory region (RWX)*/
|
||||
{
|
||||
.regn_num = 0,
|
||||
.regn_start_addr = 0x0,
|
||||
.regn_end_addr = ~0x0,
|
||||
.regn_pms = 0x7,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/* HP_APM: REE0 mode accessible regions */
|
||||
apm_ctrl_region_config_data_t hp_apm_pms_data[] = {
|
||||
/* NOTE: Without this entry, the REE SRAM region becomes inaccessible to
|
||||
* the MODEM master, resulting in an APM violation during Wi-Fi initialization.
|
||||
*/
|
||||
/* Region 1: REE SRAM region (RW) */
|
||||
{
|
||||
.regn_num = 1,
|
||||
.regn_start_addr = SOC_NS_IRAM_START,
|
||||
.regn_end_addr = SOC_IRAM_HIGH,
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 2: RTC memory (RWX) */
|
||||
{
|
||||
.regn_num = 2,
|
||||
.regn_start_addr = SOC_RTC_IRAM_LOW,
|
||||
.regn_end_addr = SOC_RTC_IRAM_HIGH,
|
||||
.regn_pms = 0x7,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 3: Peripherals [Start - MMU] (RW) */
|
||||
/* Protected: MMU */
|
||||
{
|
||||
.regn_num = 3,
|
||||
.regn_start_addr = SOC_PERIPHERAL_LOW,
|
||||
.regn_end_addr = (SPI_MEM_MMU_ITEM_CONTENT_REG(0) - 0x4),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 4: Peripherals [MMU - SPI1] (RW) */
|
||||
/* Protected: SPI1 */
|
||||
{
|
||||
.regn_num = 4,
|
||||
.regn_start_addr = SPI_MEM_MMU_POWER_CTRL_REG(0),
|
||||
.regn_end_addr = (HP_APM_SPI1_REG_START - 0x4),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 5: Peripherals [SPI1 - Interrupt Matrix] (RW) */
|
||||
/* Protected: Interrupt Matrix */
|
||||
{
|
||||
.regn_num = 5,
|
||||
.regn_start_addr = HP_APM_SPI1_REG_END,
|
||||
.regn_end_addr = (DR_REG_INTMTX_BASE - 0x4),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 6/7: Peripherals [H/W Lock - HMAC] (RW) */
|
||||
/* Protected: AES, SHA, ECC, DS, HMAC */
|
||||
{
|
||||
.regn_num = 6,
|
||||
.regn_start_addr = DR_REG_PCNT_BASE,
|
||||
.regn_end_addr = (DR_REG_AES_BASE - 0x4),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
{
|
||||
.regn_num = 7,
|
||||
.regn_start_addr = DR_REG_RSA_BASE,
|
||||
.regn_end_addr = (DR_REG_ECC_MULT_BASE - 0x4),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 8/9/10: Peripherals [IO_MUX - TEE Controller & APM] (RW) */
|
||||
/* Protected: AES, SHA, ECC, DS and HMAC PCRs, APM, TEE Controller */
|
||||
{
|
||||
.regn_num = 8,
|
||||
.regn_start_addr = DR_REG_ECDSA_BASE,
|
||||
.regn_end_addr = (PCR_AES_CONF_REG - 0x4),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
{
|
||||
.regn_num = 9,
|
||||
.regn_start_addr = PCR_RSA_CONF_REG,
|
||||
.regn_end_addr = (PCR_ECC_CONF_REG - 0x4),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
{
|
||||
.regn_num = 10,
|
||||
.regn_start_addr = PCR_ECDSA_CONF_REG,
|
||||
.regn_end_addr = (DR_REG_TEE_BASE - 0x4),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 11: Peripherals [Miscellaneous - PMU] (RW) */
|
||||
{
|
||||
.regn_num = 11,
|
||||
.regn_start_addr = DR_REG_MISC_BASE,
|
||||
.regn_end_addr = (DR_REG_PMU_BASE - 0x04),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 12: Peripherals [DEBUG - PWDET] (RW) */
|
||||
{
|
||||
.regn_num = 12,
|
||||
.regn_start_addr = DR_REG_TRACE_BASE,
|
||||
.regn_end_addr = 0x600D0000,
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/* NOTE: Following are the master IDs for setting the security mode and access through APM:
|
||||
* +---------+-------------+
|
||||
* | Bit | Source |
|
||||
* +---------+-------------+
|
||||
* | 0 | HP CPU |
|
||||
* | 1 | LP CPU |
|
||||
* | 2 | reserved |
|
||||
* | 3 | SDIO_SLV |
|
||||
* | 4 | reserved |
|
||||
* | 5 | MEM_MONITOR |
|
||||
* | 6 | TRACE |
|
||||
* | 7~15 | reserved |
|
||||
* | 16 | SPI2 |
|
||||
* | 17 | Dummy-1 |
|
||||
* | 18 | UHCI |
|
||||
* | 19 | I2S |
|
||||
* | 20 | Dummy-4 |
|
||||
* | 21 | Dummy-5 |
|
||||
* | 22 | AES |
|
||||
* | 23 | SHA |
|
||||
* | 24 | ADC |
|
||||
* | 25 | PARLIO |
|
||||
* | 26~31 | Dummy-10~15 |
|
||||
* +---------+-------------+
|
||||
*/
|
||||
|
||||
/* HP_APM: TEE mode masters' configuration */
|
||||
apm_ctrl_secure_mode_config_t hp_apm_sec_mode_data_tee = {
|
||||
.apm_ctrl = HP_APM_CTRL,
|
||||
.apm_m_cnt = HP_APM_MAX_ACCESS_PATH,
|
||||
.sec_mode = APM_LL_SECURE_MODE_TEE,
|
||||
/* Crypto DMA (AES/SHA) and HP_CPU */
|
||||
.master_ids = 0xC00001,
|
||||
.pms_data = hp_apm_pms_data_tee,
|
||||
};
|
||||
|
||||
/* HP_APM: REE0 mode masters' configuration */
|
||||
apm_ctrl_secure_mode_config_t hp_apm_sec_mode_data = {
|
||||
.apm_ctrl = HP_APM_CTRL,
|
||||
.apm_m_cnt = HP_APM_MAX_ACCESS_PATH,
|
||||
.sec_mode = APM_LL_SECURE_MODE_REE0,
|
||||
/* All masters except crypto DMA (AES/SHA) and HP CPU */
|
||||
.master_ids = 0xFF3FFFFE,
|
||||
.pms_data = hp_apm_pms_data,
|
||||
};
|
||||
|
||||
/*----------------------- LP_APM range and filter configuration -----------------------*/
|
||||
|
||||
/* NOTE: Due to ESP32-H2's limited LP_APM module regions, neither TEE nor REE can directly
|
||||
* access the protected eFuse region. However, since the HMAC peripheral can access the
|
||||
* key stored in eFuse for TEE secure storage, this access restriction does not impact
|
||||
* functionality.
|
||||
*/
|
||||
/* LP_APM: REE0 mode accessible regions */
|
||||
apm_ctrl_region_config_data_t lp_apm_pms_data[] = {
|
||||
/* Region 0: LP Peripherals [PMU - eFuse BLK x] (RW) */
|
||||
/* Protected: eFuse BLK x */
|
||||
{
|
||||
.regn_num = 0,
|
||||
.regn_start_addr = DR_REG_PMU_BASE,
|
||||
.regn_end_addr = (LP_APM_EFUSE_REG_START - 0x04),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 1: LP Peripherals [eFuse - END] (RW) */
|
||||
{
|
||||
.regn_num = 1,
|
||||
.regn_start_addr = LP_APM_EFUSE_REG_END,
|
||||
.regn_end_addr = (DR_REG_TRACE_BASE - 0x04),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/* LP_APM: REE0 mode masters' configuration */
|
||||
apm_ctrl_secure_mode_config_t lp_apm_sec_mode_data = {
|
||||
.apm_ctrl = LP_APM_CTRL,
|
||||
.apm_m_cnt = LP_APM_MAX_ACCESS_PATH,
|
||||
.sec_mode = APM_LL_SECURE_MODE_REE0,
|
||||
/* HP_CPU */
|
||||
.master_ids = 0x1,
|
||||
.pms_data = lp_apm_pms_data,
|
||||
};
|
||||
|
||||
/*---------------- TEE APM API-----------------------*/
|
||||
|
||||
void esp_tee_apm_int_enable(apm_ctrl_secure_mode_config_t *sec_mode_data)
|
||||
{
|
||||
for (int i = 0; i < sec_mode_data->apm_m_cnt; i++) {
|
||||
apm_ctrl_path_t *apm_excp_data = calloc(1, sizeof(apm_ctrl_path_t));
|
||||
assert(apm_excp_data != NULL);
|
||||
|
||||
apm_excp_data->apm_ctrl = sec_mode_data->apm_ctrl;
|
||||
apm_excp_data->apm_m_path = i;
|
||||
|
||||
int intr_src_num = apm_hal_apm_ctrl_get_int_src_num(apm_excp_data);
|
||||
|
||||
struct vector_desc_t apm_vd = {0};
|
||||
apm_vd.source = intr_src_num;
|
||||
apm_vd.isr = tee_apm_violation_isr;
|
||||
apm_vd.arg = (void *)apm_excp_data;
|
||||
|
||||
/* Register interrupt handler with TEE. */
|
||||
esp_tee_intr_register((void *)&apm_vd);
|
||||
|
||||
/* Enable APM Ctrl intewrrupt for access path(M[0:n]) */
|
||||
apm_hal_apm_ctrl_exception_clear(apm_excp_data);
|
||||
apm_hal_apm_ctrl_interrupt_enable(apm_excp_data, true);
|
||||
}
|
||||
}
|
||||
|
||||
void esp_tee_configure_apm_protection(void)
|
||||
{
|
||||
/* Disable all control filter first to have full access of address rage. */
|
||||
apm_hal_apm_ctrl_filter_enable_all(false);
|
||||
|
||||
/* Switch HP_CPU to TEE mode */
|
||||
apm_tee_hal_set_master_secure_mode(HP_APM_CTRL, APM_LL_MASTER_HPCORE, APM_LL_SECURE_MODE_TEE);
|
||||
|
||||
/* LP APM TEE configuration. */
|
||||
lp_apm_sec_mode_data.regn_count = sizeof(lp_apm_pms_data) / sizeof(apm_ctrl_region_config_data_t);
|
||||
apm_hal_apm_ctrl_master_sec_mode_config(&lp_apm_sec_mode_data);
|
||||
/* LP APM interrupt configuration. */
|
||||
esp_tee_apm_int_enable(&lp_apm_sec_mode_data);
|
||||
ESP_LOGD(TAG, "[REE0] LP_APM configured");
|
||||
|
||||
/* HP APM TEE configuration. */
|
||||
hp_apm_sec_mode_data_tee.regn_count = sizeof(hp_apm_pms_data_tee) / sizeof(apm_ctrl_region_config_data_t);
|
||||
apm_hal_apm_ctrl_master_sec_mode_config(&hp_apm_sec_mode_data_tee);
|
||||
ESP_LOGD(TAG, "[TEE] HP_APM configured");
|
||||
|
||||
/* HP APM configuration. */
|
||||
hp_apm_sec_mode_data.regn_count = sizeof(hp_apm_pms_data) / sizeof(apm_ctrl_region_config_data_t);
|
||||
apm_hal_apm_ctrl_master_sec_mode_config(&hp_apm_sec_mode_data);
|
||||
/* HP APM interrupt configuration. */
|
||||
esp_tee_apm_int_enable(&hp_apm_sec_mode_data);
|
||||
ESP_LOGD(TAG, "[REE0] HP_APM configured");
|
||||
}
|
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/ext_mem_defs.h"
|
||||
#include "soc/lp_analog_peri_reg.h"
|
||||
#include "soc/lp_wdt_reg.h"
|
||||
#include "soc/plic_reg.h"
|
||||
#include "soc/clint_reg.h"
|
||||
#include "riscv/csr.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_fault.h"
|
||||
#include "esp_tee.h"
|
||||
|
||||
#define CONDITIONAL_NONE 0x0
|
||||
#define CONDITIONAL_R PMP_R
|
||||
#define CONDITIONAL_RX PMP_R | PMP_X
|
||||
#define CONDITIONAL_RW PMP_R | PMP_W
|
||||
#define CONDITIONAL_RWX PMP_R | PMP_W | PMP_X
|
||||
|
||||
#define IS_PMA_ENTRY_UNLOCKED(ENTRY) \
|
||||
((RV_READ_CSR((CSR_PMACFG0) + (ENTRY)) & PMA_L) == 0)
|
||||
|
||||
#define SWD_PROT_REG_START (LP_WDT_SWD_CONFIG_REG)
|
||||
#define SWD_PROT_REG_END (LP_WDT_INT_CLR_REG)
|
||||
#define BOD_PROT_REG_START (DR_REG_LP_ANALOG_PERI_BASE)
|
||||
#define BOD_PROT_REG_END (DR_REG_LP_ANALOG_PERI_BASE + 0x40)
|
||||
|
||||
static void esp_tee_configure_invalid_regions(void)
|
||||
{
|
||||
const unsigned PMA_NONE = PMA_L | PMA_EN;
|
||||
__attribute__((unused)) const unsigned PMA_RW = PMA_L | PMA_EN | PMA_R | PMA_W;
|
||||
__attribute__((unused)) const unsigned PMA_RX = PMA_L | PMA_EN | PMA_R | PMA_X;
|
||||
__attribute__((unused)) const unsigned PMA_RWX = PMA_L | PMA_EN | PMA_R | PMA_W | PMA_X;
|
||||
|
||||
// 1. Gap at bottom of address space
|
||||
PMA_ENTRY_SET_TOR(0, SOC_CPU_SUBSYSTEM_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 2. Gap between CPU subsystem region & IROM
|
||||
PMA_ENTRY_SET_TOR(1, SOC_CPU_SUBSYSTEM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(2, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 3. Gap between ROM & RAM
|
||||
PMA_ENTRY_SET_TOR(3, SOC_DROM_MASK_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(4, SOC_IRAM_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 4. Gap between DRAM and I_Cache
|
||||
PMA_ENTRY_SET_TOR(5, SOC_IRAM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(6, SOC_IROM_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 5. Gap between D_Cache & LP_RAM
|
||||
PMA_ENTRY_SET_TOR(7, SOC_DROM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(8, SOC_RTC_IRAM_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 6. Gap between LP memory & peripheral addresses
|
||||
PMA_ENTRY_SET_TOR(9, SOC_RTC_IRAM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(10, SOC_PERIPHERAL_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 7. End of address space
|
||||
PMA_ENTRY_SET_TOR(11, SOC_PERIPHERAL_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(12, UINT32_MAX, PMA_TOR | PMA_NONE);
|
||||
|
||||
/* 8. Using PMA to configure the TEE text and data section access attribute. */
|
||||
assert(IS_PMA_ENTRY_UNLOCKED(13));
|
||||
assert(IS_PMA_ENTRY_UNLOCKED(14));
|
||||
assert(IS_PMA_ENTRY_UNLOCKED(15));
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(13, SOC_S_IRAM_START, PMA_NONE);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(14, SOC_S_IRAM_END, PMA_TOR | PMA_RX);
|
||||
PMA_RESET_AND_ENTRY_SET_TOR(15, SOC_S_DRAM_END, PMA_TOR | PMA_RW);
|
||||
}
|
||||
|
||||
void esp_tee_configure_region_protection(void)
|
||||
{
|
||||
/* Notes on implementation:
|
||||
*
|
||||
* 1) Note: ESP32-C6 CPU doesn't support overlapping PMP regions
|
||||
*
|
||||
* 2) ESP32-C6 supports 16 PMA regions so we use this feature to block all the invalid address ranges
|
||||
*
|
||||
* 3) We use combination of NAPOT (Naturally Aligned Power Of Two) and TOR (top of range)
|
||||
* entries to map all the valid address space, bottom to top. This leaves us with some extra PMP entries
|
||||
* which can be used to provide more granular access
|
||||
*
|
||||
* 4) Entries are grouped in order with some static asserts to try and verify everything is
|
||||
* correct.
|
||||
*/
|
||||
const unsigned NONE = PMP_L;
|
||||
const unsigned R = PMP_L | PMP_R;
|
||||
const unsigned RW = PMP_L | PMP_R | PMP_W;
|
||||
const unsigned RX = PMP_L | PMP_R | PMP_X;
|
||||
const unsigned RWX = PMP_L | PMP_R | PMP_W | PMP_X;
|
||||
|
||||
//
|
||||
// Configure all the invalid address regions using PMA
|
||||
//
|
||||
// We lock the PMA entries since they mark the invalid regions and is applicable to both the privilege modes
|
||||
//
|
||||
esp_tee_configure_invalid_regions();
|
||||
|
||||
// 1.1 I/D-ROM
|
||||
const uint32_t pmpaddr0 = PMPADDR_NAPOT(SOC_IROM_MASK_LOW, SOC_IROM_MASK_HIGH);
|
||||
PMP_ENTRY_SET(0, pmpaddr0, PMP_NAPOT | RX);
|
||||
_Static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH, "Invalid I/D-ROM region");
|
||||
|
||||
/* TODO: Check whether changes are required here */
|
||||
if (esp_cpu_dbgr_is_attached()) {
|
||||
// Anti-FI check that cpu is really in ocd mode
|
||||
ESP_FAULT_ASSERT(esp_cpu_dbgr_is_attached());
|
||||
|
||||
// 2. IRAM and DRAM
|
||||
PMP_ENTRY_SET(1, SOC_IRAM_LOW, NONE);
|
||||
PMP_ENTRY_SET(2, SOC_IRAM_HIGH, PMP_TOR | RWX);
|
||||
_Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid RAM region");
|
||||
} else {
|
||||
// 2. IRAM and DRAM
|
||||
// Splitting the REE SRAM region into IRAM and DRAM
|
||||
PMP_ENTRY_SET(1, (int)SOC_NS_IRAM_START, NONE);
|
||||
PMP_ENTRY_SET(2, (int)esp_tee_app_config.ns_iram_end, PMP_TOR | RX);
|
||||
PMP_ENTRY_SET(3, SOC_DRAM_HIGH, PMP_TOR | RW);
|
||||
}
|
||||
|
||||
const uint32_t s_irom_resv_end = SOC_IROM_LOW + CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE;
|
||||
const uint32_t ns_irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_irom_end);
|
||||
const uint32_t ns_drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)esp_tee_app_config.ns_drom_end);
|
||||
const uint32_t ns_drom_mmap_end = (uint32_t)(SOC_S_MMU_MMAP_RESV_START_VADDR);
|
||||
|
||||
// 4. I_Cache / D_Cache (flash) - REE
|
||||
PMP_ENTRY_CFG_RESET(5);
|
||||
PMP_ENTRY_CFG_RESET(6);
|
||||
PMP_ENTRY_CFG_RESET(7);
|
||||
PMP_ENTRY_SET(4, s_irom_resv_end, NONE);
|
||||
PMP_ENTRY_SET(5, ns_irom_resv_end, PMP_TOR | RX);
|
||||
PMP_ENTRY_SET(6, ns_drom_resv_end, PMP_TOR | R);
|
||||
PMP_ENTRY_SET(7, ns_drom_mmap_end, PMP_TOR | RX);
|
||||
|
||||
// 5. LP memory
|
||||
/* Reset the corresponding PMP config because PMP_ENTRY_SET only sets the given bits
|
||||
* Bootloader might have given extra permissions and those won't be cleared
|
||||
*/
|
||||
const uint32_t pmpaddr8 = PMPADDR_NAPOT(SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH);
|
||||
PMP_ENTRY_SET(8, pmpaddr8, PMP_NAPOT | RWX);
|
||||
_Static_assert(SOC_RTC_IRAM_LOW < SOC_RTC_IRAM_HIGH, "Invalid RTC IRAM region");
|
||||
|
||||
// 6. Super WDT and Brownout detector
|
||||
PMP_ENTRY_SET(9, SWD_PROT_REG_START, CONDITIONAL_NONE);
|
||||
PMP_ENTRY_SET(10, SWD_PROT_REG_END, PMP_TOR | CONDITIONAL_NONE);
|
||||
_Static_assert(SWD_PROT_REG_START < SWD_PROT_REG_END, "Invalid peripheral region");
|
||||
|
||||
/* NOTE: Due to the limited number of PMP entries, NAPOT address matching had to be
|
||||
* utilized here. To meet the requirements of NAPOT, the adjacent 20 bytes have also
|
||||
* been protected along with the intended region.
|
||||
*/
|
||||
const uint32_t pmpaddr11 = PMPADDR_NAPOT(BOD_PROT_REG_START, BOD_PROT_REG_END);
|
||||
PMP_ENTRY_SET(11, pmpaddr11, PMP_NAPOT | CONDITIONAL_NONE);
|
||||
_Static_assert(BOD_PROT_REG_START < BOD_PROT_REG_END, "Invalid peripheral region");
|
||||
|
||||
// 7. Peripheral addresses
|
||||
const uint32_t pmpaddr12 = PMPADDR_NAPOT(SOC_PERIPHERAL_LOW, SOC_PERIPHERAL_HIGH);
|
||||
PMP_ENTRY_SET(12, pmpaddr12, PMP_NAPOT | RW);
|
||||
_Static_assert(SOC_PERIPHERAL_LOW < SOC_PERIPHERAL_HIGH, "Invalid peripheral region");
|
||||
|
||||
// 8. User-mode interrupt controller registers
|
||||
const uint32_t pmpaddr13 = PMPADDR_NAPOT(DR_REG_PLIC_UX_BASE, DR_REG_PLIC_UX_END);
|
||||
PMP_ENTRY_SET(13, pmpaddr13, PMP_NAPOT | RW);
|
||||
_Static_assert(DR_REG_PLIC_UX_BASE < DR_REG_PLIC_UX_END, "Invalid User mode PLIC region");
|
||||
|
||||
const uint32_t pmpaddr14 = PMPADDR_NAPOT(DR_REG_CLINT_U_BASE, DR_REG_CLINT_U_END);
|
||||
PMP_ENTRY_SET(14, pmpaddr14, PMP_NAPOT | RW);
|
||||
_Static_assert(DR_REG_CLINT_U_BASE < DR_REG_CLINT_U_END, "Invalid User mode CLINT region");
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "riscv/rv_utils.h"
|
||||
#include "riscv/encoding.h"
|
||||
#include "esp_private/interrupt_plic.h"
|
||||
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_log.h"
|
||||
#include "hal/apm_hal.h"
|
||||
#include "hal/aes_ll.h"
|
||||
#include "hal/sha_ll.h"
|
||||
#include "hal/hmac_ll.h"
|
||||
#include "hal/ds_ll.h"
|
||||
#include "hal/ecc_ll.h"
|
||||
|
||||
#include "esp_tee.h"
|
||||
#include "esp_tee_intr.h"
|
||||
|
||||
#define _m2u_switch(arg0, arg1) \
|
||||
({ \
|
||||
register uintptr_t ra asm("ra") = (uintptr_t)(arg0); \
|
||||
register uintptr_t a1 asm("a1") = (uintptr_t)(arg1); \
|
||||
asm volatile("ecall" : :"r"(ra), "r"(a1) : ); \
|
||||
})
|
||||
|
||||
static const char *TAG = "esp_tee_secure_sys_cfg";
|
||||
|
||||
extern uint32_t _vector_table;
|
||||
|
||||
void esp_tee_soc_secure_sys_init(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Current privilege level - %d", esp_cpu_get_curr_privilege_level());
|
||||
|
||||
/* NOTE: M/U-mode PLIC Special Configuration Register
|
||||
* Bit 0: Use the external PLIC registers (legacy) from the SoC (default)
|
||||
* Bit 1: Use the internal PLIC registers as per the new SoC address map
|
||||
*/
|
||||
REG_SET_BIT(PLIC_MXINT_CONF_REG, BIT(0));
|
||||
REG_SET_BIT(PLIC_UXINT_CONF_REG, BIT(0));
|
||||
|
||||
/* Setting the M-mode vector table */
|
||||
rv_utils_set_mtvec((uint32_t)&_vector_table);
|
||||
|
||||
/* Disable global interrupts */
|
||||
RV_CLEAR_CSR(mstatus, MSTATUS_UIE);
|
||||
RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||
|
||||
/* Clear all interrupts */
|
||||
RV_WRITE_CSR(mie, 0x00);
|
||||
RV_WRITE_CSR(uie, 0x00);
|
||||
|
||||
/* All interrupts except the TEE secure interrupt are delegated to the U-mode */
|
||||
RV_WRITE_CSR(mideleg, UINT32_MAX);
|
||||
RV_CLEAR_CSR(mideleg, TEE_SECURE_INUM);
|
||||
|
||||
/* TODO: IDF-8958
|
||||
* The values for the secure interrupt number and priority and
|
||||
* the interrupt priority threshold (for both M and U mode) need
|
||||
* to be investigated further
|
||||
*/
|
||||
#ifdef SOC_CPU_HAS_FLEXIBLE_INTC
|
||||
/* TODO: Currently, we do not allow interrupts to be set up with a priority greater than 7, see intr_alloc.c */
|
||||
esprv_int_set_priority(TEE_SECURE_INUM, 7);
|
||||
esprv_int_set_type(TEE_SECURE_INUM, ESP_CPU_INTR_TYPE_LEVEL);
|
||||
esprv_int_set_threshold(RVHAL_INTR_ENABLE_THRESH);
|
||||
esprv_int_enable(BIT(TEE_SECURE_INUM));
|
||||
#endif
|
||||
|
||||
ESP_LOGD(TAG, "Initial interrupt config -");
|
||||
ESP_LOGD(TAG, "mideleg: 0x%08x", RV_READ_CSR(mideleg));
|
||||
ESP_LOGD(TAG, "mie: 0x%08x | uie: 0x%08x", RV_READ_CSR(mie), RV_READ_CSR(uie));
|
||||
ESP_LOGD(TAG, "mstatus: 0x%08x | ustatus: 0x%08x", RV_READ_CSR(mstatus), RV_READ_CSR(ustatus));
|
||||
ESP_LOGD(TAG, "[PLIC] MX: 0x%08x | UX: 0x%08x", REG_READ(PLIC_MXINT_ENABLE_REG), REG_READ(PLIC_UXINT_ENABLE_REG));
|
||||
|
||||
/* PMP, PMA and APM configuration to isolate the resources between TEE and REE. */
|
||||
esp_tee_configure_region_protection();
|
||||
esp_tee_configure_apm_protection();
|
||||
|
||||
/* Protect secure interrupt sources */
|
||||
esp_tee_protect_intr_src(ETS_LP_APM_M0_INTR_SOURCE); // LP_APM_M0
|
||||
esp_tee_protect_intr_src(ETS_HP_APM_M0_INTR_SOURCE); // HP_APM_M0
|
||||
esp_tee_protect_intr_src(ETS_HP_APM_M1_INTR_SOURCE); // HP_APM_M1
|
||||
esp_tee_protect_intr_src(ETS_HP_APM_M2_INTR_SOURCE); // HP_APM_M2
|
||||
esp_tee_protect_intr_src(ETS_HP_APM_M3_INTR_SOURCE); // HP_APM_M3
|
||||
esp_tee_protect_intr_src(ETS_AES_INTR_SOURCE); // AES
|
||||
esp_tee_protect_intr_src(ETS_SHA_INTR_SOURCE); // SHA
|
||||
esp_tee_protect_intr_src(ETS_ECC_INTR_SOURCE); // ECC
|
||||
|
||||
/* Disable protected crypto peripheral clocks; they will be toggled as needed when the peripheral is in use */
|
||||
aes_ll_enable_bus_clock(false);
|
||||
sha_ll_enable_bus_clock(false);
|
||||
hmac_ll_enable_bus_clock(false);
|
||||
ds_ll_enable_bus_clock(false);
|
||||
ecc_ll_enable_bus_clock(false);
|
||||
}
|
||||
|
||||
IRAM_ATTR inline void esp_tee_switch_to_ree(uint32_t ree_entry_addr)
|
||||
{
|
||||
/* 2nd argument is used as magic value to detect very first M2U switch */
|
||||
/* TBD: clean this up and use proper temporary register instead of a1 */
|
||||
/* Switch to non-secure world and launch App. */
|
||||
_m2u_switch(ree_entry_addr, ESP_TEE_M2U_SWITCH_MAGIC << 12);
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "soc/interrupt_matrix_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// LP_APM_M0_INTR, HP_APM_M0_INTR, HP_APM_M1_INTR, HP_APM_M2_INTR, HP_APM_M3_INTR
|
||||
#define TEE_SECURE_INT_APM_MASK_0 (0x3C000040)
|
||||
|
||||
// LP_RTC_TIMER_INTR
|
||||
#define TEE_SECURE_INT_MASK_0 (TEE_SECURE_INT_APM_MASK_0 | 0x00000004)
|
||||
// AES_INTR, SHA_INTR, ECC_INTR
|
||||
#if !CONFIG_SECURE_TEE_TEST_MODE
|
||||
#define TEE_SECURE_INT_MASK_1 (0xB0000000)
|
||||
#else
|
||||
// + TG0_T0_INTR (only for test mode)
|
||||
#define TEE_SECURE_INT_MASK_1 (0xB0000200)
|
||||
#endif
|
||||
#define TEE_SECURE_INT_MASK_2 (0U)
|
||||
|
||||
#define INTMTX_STATUS_REG_0 (INTMTX_CORE0_INT_STATUS_REG_0_REG)
|
||||
#define INTMTX_STATUS_REG_1 (INTMTX_CORE0_INT_STATUS_REG_1_REG)
|
||||
#define INTMTX_STATUS_REG_2 (INTMTX_CORE0_INT_STATUS_REG_2_REG)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "riscv/csr.h"
|
||||
#include "riscv/interrupt.h"
|
||||
|
||||
#include "soc/interrupt_reg.h"
|
||||
#include "soc/plic_reg.h"
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "esp_tee.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_tee_intr_global_enable(void)
|
||||
{
|
||||
/*
|
||||
* Set the the U-mode previous enable global interrupts state
|
||||
*
|
||||
* NOTE: The TICK interrupt is setup before this service call and thus,
|
||||
* it occurs in the return path of this call.
|
||||
*
|
||||
* Before entering the U-mode interrupt handler routine, USTATUS:UIE is
|
||||
* cleared to disable U-mode interrupts temporarily.
|
||||
*
|
||||
* While exiting the above routine, URET is executed, setting USTATUS:UIE
|
||||
* to the value of USTATUS:UPIE. However, since no interrupts were enabled
|
||||
* previously, USTATUS:UPIE and thus, USTATUS:UIE is cleared.
|
||||
*
|
||||
* The service call completes and returns to U-mode with USTATUS:UIE disabled,
|
||||
* preventing any further interrupts in U-mode.
|
||||
*
|
||||
*/
|
||||
RV_SET_CSR(ustatus, USTATUS_UPIE);
|
||||
/* Enabling the global M-mode and U-mode interrupts */
|
||||
RV_SET_CSR(ustatus, USTATUS_UIE);
|
||||
RV_SET_CSR(mstatus, MSTATUS_UIE);
|
||||
RV_SET_CSR(mstatus, MSTATUS_MIE);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_tee_intr_global_disable(void)
|
||||
{
|
||||
RV_CLEAR_CSR(ustatus, USTATUS_UIE);
|
||||
RV_CLEAR_CSR(mstatus, MSTATUS_UIE);
|
||||
RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_tee_intr_enable(uint32_t intr_mask)
|
||||
{
|
||||
unsigned old_xstatus;
|
||||
|
||||
// Machine mode
|
||||
// Disable all interrupts to make updating of the interrupt mask atomic.
|
||||
old_xstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||
REG_SET_BIT(PLIC_MXINT_ENABLE_REG, intr_mask);
|
||||
RV_SET_CSR(mie, intr_mask);
|
||||
RV_SET_CSR(mstatus, old_xstatus & MSTATUS_MIE);
|
||||
|
||||
// User mode
|
||||
// Disable all interrupts to make updating of the interrupt mask atomic.
|
||||
old_xstatus = RV_CLEAR_CSR(ustatus, USTATUS_UIE);
|
||||
REG_SET_BIT(PLIC_UXINT_ENABLE_REG, intr_mask);
|
||||
RV_SET_CSR(uie, intr_mask);
|
||||
RV_SET_CSR(ustatus, old_xstatus & USTATUS_UIE);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_tee_intr_disable(uint32_t intr_mask)
|
||||
{
|
||||
unsigned old_xstatus;
|
||||
|
||||
// Machine mode
|
||||
// Disable all interrupts to make updating of the interrupt mask atomic.
|
||||
old_xstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||
REG_CLR_BIT(PLIC_MXINT_ENABLE_REG, intr_mask);
|
||||
RV_CLEAR_CSR(mie, intr_mask);
|
||||
RV_SET_CSR(mstatus, old_xstatus & MSTATUS_MIE);
|
||||
|
||||
// User mode
|
||||
// Disable all interrupts to make updating of the interrupt mask atomic.
|
||||
old_xstatus = RV_CLEAR_CSR(ustatus, USTATUS_UIE);
|
||||
REG_CLR_BIT(PLIC_UXINT_ENABLE_REG, intr_mask);
|
||||
RV_CLEAR_CSR(uie, intr_mask);
|
||||
RV_SET_CSR(ustatus, old_xstatus & USTATUS_UIE);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_tee_intr_set_type(int intr_num, enum intr_type type)
|
||||
{
|
||||
assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM);
|
||||
|
||||
if (type == INTR_TYPE_LEVEL) {
|
||||
REG_CLR_BIT(PLIC_MXINT_TYPE_REG, BIT(intr_num));
|
||||
REG_CLR_BIT(PLIC_UXINT_TYPE_REG, BIT(intr_num));
|
||||
} else {
|
||||
REG_SET_BIT(PLIC_MXINT_TYPE_REG, BIT(intr_num));
|
||||
REG_SET_BIT(PLIC_UXINT_TYPE_REG, BIT(intr_num));
|
||||
}
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_tee_intr_set_priority(int rv_int_num, int priority)
|
||||
{
|
||||
assert(rv_int_num >= 0 && rv_int_num < SOC_CPU_INTR_NUM);
|
||||
|
||||
REG_WRITE(PLIC_MXINT_PRI_REG(rv_int_num), priority);
|
||||
REG_WRITE(PLIC_UXINT_PRI_REG(rv_int_num), priority);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_tee_intr_set_threshold(int priority_threshold)
|
||||
{
|
||||
REG_WRITE(PLIC_MXINT_THRESH_REG, priority_threshold);
|
||||
REG_WRITE(PLIC_UXINT_THRESH_REG, priority_threshold);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_tee_intr_edge_ack(int intr_num)
|
||||
{
|
||||
assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM);
|
||||
|
||||
REG_SET_BIT(PLIC_MXINT_CLEAR_REG, intr_num);
|
||||
REG_SET_BIT(PLIC_UXINT_CLEAR_REG, intr_num);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -7,5 +7,5 @@ components/esp_tee/test_apps/tee_cli_app:
|
||||
|
||||
components/esp_tee/test_apps/tee_test_fw:
|
||||
disable:
|
||||
- if: IDF_TARGET not in ["esp32c6"]
|
||||
reason: only supported with esp32c6 for now
|
||||
- if: IDF_TARGET not in ["esp32c6", "esp32h2"]
|
||||
reason: only supported with esp32c6 and esp32h2 for now
|
||||
|
@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32-C6 |
|
||||
| ----------------- | -------- |
|
||||
| Supported Targets | ESP32-C6 | ESP32-H2 |
|
||||
| ----------------- | -------- | -------- |
|
||||
|
||||
## ESP-TEE: Test Suite
|
||||
|
||||
|
@ -63,6 +63,47 @@ esp_tee_empty_bin = {
|
||||
0xF4, 0xA4, 0xCF, 0x06, 0xAE, 0x94, 0x75, 0x47, 0xBC, 0x88, 0xA2, 0xCA,
|
||||
0x52, 0x97, 0x7A, 0x5C, 0x55, 0x43, 0xD9, 0xF5, 0xD3, 0x45, 0xD1, 0x34,
|
||||
0xFC, 0x74, 0xB2, 0xB9, 0x34, 0x72, 0xC3, 0x00
|
||||
],
|
||||
'esp32h2': [
|
||||
0xE9, 0x04, 0x02, 0x1F, 0x00, 0x00, 0x80, 0x40, 0xEE, 0x00, 0x00, 0x00,
|
||||
0x10, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
# DROM segment
|
||||
0x20, 0x00, 0x00, 0x42, 0x00, 0x02, 0x00, 0x00,
|
||||
# esp_app_desc structure
|
||||
0x32, 0x54, 0xCD, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x76, 0x35, 0x2E, 0x35, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x65, 0x73, 0x70, 0x5F, 0x74, 0x65, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0x30, 0x3A, 0x30, 0x30, 0x3A, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x4E, 0x6F, 0x76, 0x20, 0x31, 0x31, 0x20, 0x32,
|
||||
0x30, 0x32, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x35, 0x2E, 0x35,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x2D, 0x63, 0x66, 0x8B, 0x75, 0xFA, 0x59, 0x05,
|
||||
0x53, 0x34, 0x91, 0x71, 0x51, 0x33, 0x91, 0xDD, 0xF8, 0xB1, 0xFE, 0x83,
|
||||
0x06, 0xEB, 0x03, 0x80, 0x45, 0xC9, 0x18, 0x20, 0x83, 0x7E, 0x2E, 0x43,
|
||||
*([0x00] * 0x58),
|
||||
# Padding
|
||||
*([0x00] * 0x100),
|
||||
# IRAM segment
|
||||
0x00, 0x00, 0x80, 0x40, 0x20, 0x00, 0x00, 0x00,
|
||||
*([0x00] * 0x20),
|
||||
# PADDING segment
|
||||
0x00, 0x00, 0x00, 0x00, 0xC8, 0x7D, 0x00, 0x00,
|
||||
*([0x00] * 0x7DC8),
|
||||
# IROM segment
|
||||
0x20, 0x80, 0x00, 0x42, 0x00, 0x01, 0x00, 0x00,
|
||||
*([0x00] * 0x100),
|
||||
# Padding
|
||||
*([0x00] * 0x0F),
|
||||
# CRC8 checksum
|
||||
0x56,
|
||||
# Image SHA256
|
||||
0xDC, 0x60, 0x86, 0x6C, 0x37, 0x76, 0xAA, 0x30, 0x1F, 0x61, 0x48, 0x23,
|
||||
0xEA, 0x34, 0xAA, 0x19, 0xE8, 0xDE, 0x04, 0x7D, 0x2A, 0x30, 0xC1, 0xDD,
|
||||
0x61, 0x38, 0x9D, 0xB5, 0xCA, 0x13, 0x5A, 0x79
|
||||
]
|
||||
}
|
||||
# fmt: on
|
||||
|
@ -119,7 +119,7 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp256r1)", "[sec_stora
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN && !TEMPORARY_DISABLED_FOR_TARGETS(ESP32H2)
|
||||
TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp192r1)", "[sec_storage]")
|
||||
{
|
||||
const size_t buf_sz = 16 * 1024 + 6; // NOTE: Not an exact multiple of SHA block size
|
||||
@ -507,7 +507,7 @@ static void test_ecdsa_sign(mbedtls_ecp_group_id gid)
|
||||
TEST_CASE("Test TEE Secure Storage - mbedtls ECDSA signing", "[mbedtls]")
|
||||
{
|
||||
test_ecdsa_sign(MBEDTLS_ECP_DP_SECP256R1);
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN && !TEMPORARY_DISABLED_FOR_TARGETS(ESP32H2)
|
||||
test_ecdsa_sign(MBEDTLS_ECP_DP_SECP192R1);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,42 +1,57 @@
|
||||
# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import Tuple
|
||||
|
||||
import pytest
|
||||
from pytest_embedded_idf import IdfDut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
CONFIGS_DEFAULT = [pytest.param('default', marks=[pytest.mark.esp32c6])]
|
||||
# ---------------- Pytest build parameters ----------------
|
||||
|
||||
CONFIGS_OTA = [pytest.param('ota', marks=[pytest.mark.esp32c6])]
|
||||
SUPPORTED_TARGETS = ['esp32c6', 'esp32h2']
|
||||
|
||||
CONFIGS_ALL = [pytest.param('default', marks=[pytest.mark.esp32c6]), pytest.param('ota', marks=[pytest.mark.esp32c6])]
|
||||
CONFIG_DEFAULT = [
|
||||
# 'config, target, markers',
|
||||
('default', target, (pytest.mark.generic,))
|
||||
for target in SUPPORTED_TARGETS
|
||||
]
|
||||
|
||||
TEE_VIOLATION_TEST_EXC_RSN: Dict[str, Any] = {
|
||||
'esp32c6': {
|
||||
('Reserved', 'W1'): 'Store access fault',
|
||||
('Reserved', 'X1'): 'Instruction access fault',
|
||||
('IRAM', 'W1'): 'Store access fault',
|
||||
('IRAM', 'W2'): 'Store access fault',
|
||||
('DRAM', 'X1'): 'Instruction access fault',
|
||||
('DRAM', 'X2'): 'Instruction access fault',
|
||||
}
|
||||
CONFIG_OTA = [
|
||||
# 'config, target, skip_autoflash, markers',
|
||||
('ota', target, 'y', (pytest.mark.generic,))
|
||||
for target in SUPPORTED_TARGETS
|
||||
]
|
||||
|
||||
CONFIG_ALL = [
|
||||
# 'config, target, markers',
|
||||
(config, target, (pytest.mark.generic,))
|
||||
for config in ['default', 'ota']
|
||||
for target in SUPPORTED_TARGETS
|
||||
]
|
||||
|
||||
# ---------------- Exception test-cases reasons ----------------
|
||||
|
||||
TEE_VIOLATION_TEST_EXC_RSN: Dict[Tuple[str, str], str] = {
|
||||
('Reserved', 'W1'): 'Store access fault',
|
||||
('Reserved', 'X1'): 'Instruction access fault',
|
||||
('IRAM', 'W1'): 'Store access fault',
|
||||
('IRAM', 'W2'): 'Store access fault',
|
||||
('DRAM', 'X1'): 'Instruction access fault',
|
||||
('DRAM', 'X2'): 'Instruction access fault',
|
||||
}
|
||||
|
||||
REE_ISOLATION_TEST_EXC_RSN: Dict[str, Any] = {
|
||||
'esp32c6': {
|
||||
('DRAM', 'R1'): 'Load access fault',
|
||||
('DRAM', 'W1'): 'Store access fault',
|
||||
('IRAM', 'R1'): 'Load access fault',
|
||||
('IRAM', 'W1'): 'Store access fault',
|
||||
('IROM', 'R1'): 'Load access fault',
|
||||
('IROM', 'W1'): 'Store access fault',
|
||||
('DROM', 'R1'): 'Load access fault',
|
||||
('DROM', 'W1'): 'Store access fault',
|
||||
('SWDT/BOD', 'W'): 'Store access fault',
|
||||
}
|
||||
REE_ISOLATION_TEST_EXC_RSN: Dict[Tuple[str, str], str] = {
|
||||
('DRAM', 'R1'): 'Load access fault',
|
||||
('DRAM', 'W1'): 'Store access fault',
|
||||
('IRAM', 'R1'): 'Load access fault',
|
||||
('IRAM', 'W1'): 'Store access fault',
|
||||
('IROM', 'R1'): 'Load access fault',
|
||||
('IROM', 'W1'): 'Store access fault',
|
||||
('DROM', 'R1'): 'Load access fault',
|
||||
('DROM', 'W1'): 'Store access fault',
|
||||
('SWDT/BOD', 'W'): 'Store access fault',
|
||||
}
|
||||
|
||||
TEE_APM_VIOLATION_EXC_CHK = ['eFuse', 'MMU', 'AES', 'HMAC', 'DS', 'SHA PCR', 'ECC PCR']
|
||||
@ -44,34 +59,42 @@ TEE_APM_VIOLATION_EXC_CHK = ['eFuse', 'MMU', 'AES', 'HMAC', 'DS', 'SHA PCR', 'EC
|
||||
# ---------------- TEE default tests ----------------
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['default'], indirect=['config'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, markers',
|
||||
CONFIG_DEFAULT,
|
||||
indirect=['config', 'target'],
|
||||
)
|
||||
def test_esp_tee(dut: IdfDut) -> None:
|
||||
dut.run_all_single_board_cases(group='basic')
|
||||
dut.run_all_single_board_cases(group='heap')
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['default', 'ota'], indirect=['config'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, markers',
|
||||
CONFIG_ALL,
|
||||
indirect=['config', 'target'],
|
||||
)
|
||||
def test_esp_tee_crypto_aes(dut: IdfDut) -> None:
|
||||
dut.run_all_single_board_cases(group='aes')
|
||||
dut.run_all_single_board_cases(group='aes-gcm')
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['default', 'ota'], indirect=['config'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, markers',
|
||||
CONFIG_ALL,
|
||||
indirect=['config', 'target'],
|
||||
)
|
||||
def test_esp_tee_crypto_sha(dut: IdfDut) -> None:
|
||||
dut.run_all_single_board_cases(group='mbedtls')
|
||||
dut.run_all_single_board_cases(group='hw_crypto')
|
||||
|
||||
|
||||
# NOTE: Stress testing the AES performance case for interrupt-related edge-cases
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['default', 'ota'], indirect=['config'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, markers',
|
||||
CONFIG_ALL,
|
||||
indirect=['config', 'target'],
|
||||
)
|
||||
def test_esp_tee_aes_perf(dut: IdfDut) -> None:
|
||||
# start test
|
||||
for i in range(24):
|
||||
@ -86,21 +109,29 @@ def test_esp_tee_aes_perf(dut: IdfDut) -> None:
|
||||
# ---------------- TEE Exceptions generation Tests ----------------
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['default'], indirect=['config'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, markers',
|
||||
CONFIG_DEFAULT,
|
||||
indirect=['config', 'target'],
|
||||
)
|
||||
def test_esp_tee_apm_violation(dut: IdfDut) -> None:
|
||||
for check in TEE_APM_VIOLATION_EXC_CHK:
|
||||
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 != 'APM - Authority exception':
|
||||
if dut.target == 'esp32h2' and check == 'eFuse':
|
||||
exp_str = 'APM - Space exception'
|
||||
else:
|
||||
exp_str = 'APM - Authority exception'
|
||||
if exc != exp_str:
|
||||
raise RuntimeError('Incorrect exception received!')
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['default'], indirect=['config'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, markers',
|
||||
CONFIG_DEFAULT,
|
||||
indirect=['config', 'target'],
|
||||
)
|
||||
def test_esp_tee_illegal_instruction(dut: IdfDut) -> None:
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
dut.write('"Test TEE-TEE violation: Illegal Instruction"')
|
||||
@ -109,11 +140,13 @@ def test_esp_tee_illegal_instruction(dut: IdfDut) -> None:
|
||||
raise RuntimeError('Incorrect exception received!')
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['default'], indirect=['config'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, markers',
|
||||
CONFIG_DEFAULT,
|
||||
indirect=['config', 'target'],
|
||||
)
|
||||
def test_esp_tee_violation_checks(dut: IdfDut) -> None:
|
||||
checks_list = TEE_VIOLATION_TEST_EXC_RSN[dut.target]
|
||||
checks_list = TEE_VIOLATION_TEST_EXC_RSN
|
||||
for test in checks_list:
|
||||
memory, access_type = test
|
||||
expected_exc = checks_list[test]
|
||||
@ -126,11 +159,13 @@ def test_esp_tee_violation_checks(dut: IdfDut) -> None:
|
||||
raise RuntimeError('Incorrect exception received!')
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['default'], indirect=['config'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, markers',
|
||||
CONFIG_DEFAULT,
|
||||
indirect=['config', 'target'],
|
||||
)
|
||||
def test_esp_tee_isolation_checks(dut: IdfDut) -> None:
|
||||
checks_list = REE_ISOLATION_TEST_EXC_RSN[dut.target]
|
||||
checks_list = REE_ISOLATION_TEST_EXC_RSN
|
||||
for test in checks_list:
|
||||
memory, access_type = test
|
||||
expected_exc = checks_list[test]
|
||||
@ -199,10 +234,11 @@ def run_multiple_stages(dut: IdfDut, test_case_num: int, stages: int, api: TeeFl
|
||||
dut.expect_exact('Press ENTER to see the list of tests.')
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['ota'], indirect=['config'])
|
||||
@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, skip_autoflash, markers',
|
||||
CONFIG_OTA,
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_flash_prot_esp_partition_mmap(dut: IdfDut) -> None:
|
||||
# Flash the bootloader, TEE and REE firmware
|
||||
dut.serial.custom_flash()
|
||||
@ -216,10 +252,11 @@ def test_esp_tee_flash_prot_esp_partition_mmap(dut: IdfDut) -> None:
|
||||
continue
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['ota'], indirect=['config'])
|
||||
@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, skip_autoflash, markers',
|
||||
CONFIG_OTA,
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_flash_prot_spi_flash_mmap(dut: IdfDut) -> None:
|
||||
# Flash the bootloader, TEE and REE firmware
|
||||
dut.serial.custom_flash()
|
||||
@ -233,10 +270,11 @@ def test_esp_tee_flash_prot_spi_flash_mmap(dut: IdfDut) -> None:
|
||||
continue
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['ota'], indirect=['config'])
|
||||
@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, skip_autoflash, markers',
|
||||
CONFIG_OTA,
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_flash_prot_esp_rom_spiflash(dut: IdfDut) -> None:
|
||||
# Flash the bootloader, TEE and REE firmware
|
||||
dut.serial.custom_flash()
|
||||
@ -250,10 +288,11 @@ def test_esp_tee_flash_prot_esp_rom_spiflash(dut: IdfDut) -> None:
|
||||
continue
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['ota'], indirect=['config'])
|
||||
@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, skip_autoflash, markers',
|
||||
CONFIG_OTA,
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_flash_prot_esp_partition(dut: IdfDut) -> None:
|
||||
# Flash the bootloader, TEE and REE firmware
|
||||
dut.serial.custom_flash()
|
||||
@ -267,10 +306,11 @@ def test_esp_tee_flash_prot_esp_partition(dut: IdfDut) -> None:
|
||||
continue
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['ota'], indirect=['config'])
|
||||
@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, skip_autoflash, markers',
|
||||
CONFIG_OTA,
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_flash_prot_esp_flash(dut: IdfDut) -> None:
|
||||
# Flash the bootloader, TEE and REE firmware
|
||||
dut.serial.custom_flash()
|
||||
@ -289,7 +329,7 @@ def test_esp_tee_flash_prot_esp_flash(dut: IdfDut) -> None:
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['ota'], indirect=['config'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize('target', ['esp32c6', 'esp32h2'], indirect=['target'])
|
||||
def test_esp_tee_ota_negative(dut: IdfDut) -> None:
|
||||
# start test
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
@ -300,10 +340,11 @@ def test_esp_tee_ota_negative(dut: IdfDut) -> None:
|
||||
dut.serial.erase_partition('tee_otadata')
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['ota'], indirect=['config'])
|
||||
@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, skip_autoflash, markers',
|
||||
CONFIG_OTA,
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_ota_corrupted_img(dut: IdfDut) -> None:
|
||||
# Flashing the TEE app to the non-secure app's passive partition
|
||||
dut.serial.custom_flash_w_test_tee_img_gen()
|
||||
@ -338,10 +379,11 @@ def tee_ota_stage_checks(dut: IdfDut, stage: TeeOtaStage, offset: str) -> None:
|
||||
raise ValueError('Undefined stage!')
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['ota'], indirect=['config'])
|
||||
@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, skip_autoflash, markers',
|
||||
CONFIG_OTA,
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_ota_reboot_without_ota_end(dut: IdfDut) -> None:
|
||||
# Flashing the TEE app to the non-secure app's passive partition
|
||||
dut.serial.custom_flash_w_test_tee_img_gen()
|
||||
@ -363,10 +405,11 @@ def test_esp_tee_ota_reboot_without_ota_end(dut: IdfDut) -> None:
|
||||
dut.serial.erase_partition('tee_otadata')
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['ota'], indirect=['config'])
|
||||
@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, skip_autoflash, markers',
|
||||
CONFIG_OTA,
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_ota_valid_img(dut: IdfDut) -> None:
|
||||
# Flashing the TEE app to the non-secure app's passive partition
|
||||
dut.serial.custom_flash_w_test_tee_img_gen()
|
||||
@ -396,10 +439,11 @@ def test_esp_tee_ota_valid_img(dut: IdfDut) -> None:
|
||||
dut.serial.erase_partition('tee_otadata')
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['ota'], indirect=['config'])
|
||||
@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, skip_autoflash, markers',
|
||||
CONFIG_OTA,
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_ota_rollback(dut: IdfDut) -> None:
|
||||
# Flashing the TEE app to the non-secure app's passive partition
|
||||
dut.serial.custom_flash_w_test_tee_img_rb()
|
||||
@ -434,10 +478,11 @@ def test_esp_tee_ota_rollback(dut: IdfDut) -> None:
|
||||
# ---------------- TEE Secure Storage tests ----------------
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['ota'], indirect=['config'])
|
||||
@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, skip_autoflash, markers',
|
||||
CONFIG_OTA,
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_secure_storage(dut: IdfDut) -> None:
|
||||
# Flash image and erase the secure_storage partition
|
||||
dut.serial.custom_flash_with_empty_sec_stg()
|
||||
@ -445,10 +490,11 @@ def test_esp_tee_secure_storage(dut: IdfDut) -> None:
|
||||
dut.run_all_single_board_cases(group='sec_storage')
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['ota'], indirect=['config'])
|
||||
@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, skip_autoflash, markers',
|
||||
CONFIG_OTA,
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_secure_storage_with_host_img(dut: IdfDut) -> None:
|
||||
# Flash image and write the secure_storage partition with host-generated keys
|
||||
dut.serial.custom_flash_with_host_gen_sec_stg_img()
|
||||
@ -459,10 +505,11 @@ def test_esp_tee_secure_storage_with_host_img(dut: IdfDut) -> None:
|
||||
# ---------------- TEE Attestation tests ----------------
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('config', ['ota'], indirect=['config'])
|
||||
@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash'])
|
||||
@idf_parametrize('target', ['esp32c6'], indirect=['target'])
|
||||
@idf_parametrize(
|
||||
'config, target, skip_autoflash, markers',
|
||||
CONFIG_OTA,
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_attestation(dut: IdfDut) -> None:
|
||||
# Flash image and erase the secure_storage partition
|
||||
dut.serial.custom_flash_with_empty_sec_stg()
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -12,6 +12,11 @@
|
||||
#include "heap_memory_layout.h"
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
#define SRAM_DIRAM_TEE_ORG (SOC_DIRAM_IRAM_LOW)
|
||||
#define SRAM_DIRAM_TEE_END (SRAM_DIRAM_TEE_ORG + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Memory type descriptors. These describe the capabilities of a type of memory in the SoC.
|
||||
* Each type of memory map consists of one or more regions in the address space.
|
||||
@ -94,6 +99,14 @@ SOC_RESERVE_MEMORY_REGION((intptr_t)&_data_start, (intptr_t)&_heap_start, dram_d
|
||||
// Target has a shared D/IRAM virtual address, no need to calculate I_D_OFFSET like previous chips
|
||||
SOC_RESERVE_MEMORY_REGION((intptr_t)&_iram_start, (intptr_t)&_iram_end, iram_code);
|
||||
|
||||
/* NOTE: When ESP-TEE is enabled, the start of the internal SRAM
|
||||
* is used by the TEE and is protected from any REE access using
|
||||
* memory protection mechanisms employed by ESP-TEE.
|
||||
*/
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
SOC_RESERVE_MEMORY_REGION((intptr_t)SRAM_DIRAM_TEE_ORG, (intptr_t)(SRAM_DIRAM_TEE_END), tee_diram);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
|
||||
SOC_RESERVE_MEMORY_REGION(SOC_RTC_DRAM_LOW, (intptr_t)&_rtc_force_slow_end, rtcram_data);
|
||||
#endif
|
||||
|
@ -22,15 +22,18 @@
|
||||
|
||||
#if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
|
||||
#include "esp_tee_sec_storage.h"
|
||||
#else
|
||||
#include "hal/ecc_ll.h"
|
||||
#endif
|
||||
#if SOC_ECDSA_SUPPORTED
|
||||
#include "hal/ecdsa_ll.h"
|
||||
#include "hal/ecdsa_hal.h"
|
||||
#include "esp_efuse.h"
|
||||
#endif
|
||||
#if SOC_ECC_SUPPORTED
|
||||
#include "hal/ecc_ll.h"
|
||||
#endif
|
||||
#if SOC_MPI_SUPPORTED
|
||||
#include "hal/mpi_ll.h"
|
||||
#endif
|
||||
#include "esp_efuse.h"
|
||||
#endif
|
||||
|
||||
#define ECDSA_KEY_MAGIC (short) 0xECD5A
|
||||
#define ECDSA_KEY_MAGIC_TEE (short) 0xA5DCE
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -9,16 +9,36 @@
|
||||
#include "soc/plic_reg.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __has_include
|
||||
# if __has_include("sdkconfig.h")
|
||||
# include "sdkconfig.h"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
#define INTERRUPT_PRIO_REG(n) (PLIC_UXINT0_PRI_REG + (n)*4)
|
||||
#define INTERRUPT_CURRENT_CORE_INT_THRESH_REG PLIC_UXINT_THRESH_REG
|
||||
#else
|
||||
#define INTERRUPT_PRIO_REG(n) (PLIC_MXINT0_PRI_REG + (n)*4)
|
||||
#define INTERRUPT_CURRENT_CORE_INT_THRESH_REG PLIC_MXINT_THRESH_REG
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ESP32H2 should use the PLIC controller as the interrupt controller instead of INTC (SOC_INT_PLIC_SUPPORTED = y)
|
||||
* Keep the following macros for backward compatibility reasons
|
||||
*/
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
#define INTERRUPT_CORE0_CPU_INT_ENABLE_REG PLIC_UXINT_ENABLE_REG
|
||||
#define INTERRUPT_CORE0_CPU_INT_THRESH_REG PLIC_UXINT_THRESH_REG
|
||||
#define INTERRUPT_CORE0_CPU_INT_CLEAR_REG PLIC_UXINT_CLEAR_REG
|
||||
#define INTERRUPT_CORE0_CPU_INT_TYPE_REG PLIC_UXINT_TYPE_REG
|
||||
#define INTC_INT_PRIO_REG(n) (PLIC_UXINT0_PRI_REG + (n)*4)
|
||||
#else
|
||||
#define INTERRUPT_CORE0_CPU_INT_ENABLE_REG PLIC_MXINT_ENABLE_REG
|
||||
#define INTERRUPT_CORE0_CPU_INT_THRESH_REG PLIC_MXINT_THRESH_REG
|
||||
#define INTERRUPT_CORE0_CPU_INT_CLEAR_REG PLIC_MXINT_CLEAR_REG
|
||||
#define INTERRUPT_CORE0_CPU_INT_TYPE_REG PLIC_MXINT_TYPE_REG
|
||||
#define INTC_INT_PRIO_REG(n) (PLIC_MXINT0_PRI_REG + (n)*4)
|
||||
#endif
|
||||
|
||||
#define DR_REG_INTERRUPT_BASE DR_REG_INTMTX_BASE
|
||||
|
@ -11,6 +11,7 @@ extern "C" {
|
||||
|
||||
#define DR_REG_CLINT_M_BASE ( 0x20001800)
|
||||
#define DR_REG_CLINT_U_BASE ( 0x20001C00)
|
||||
#define DR_REG_CLINT_U_END ( 0x20002000)
|
||||
|
||||
/*CLINT MINT*/
|
||||
#define CLINT_MINT_SIP_REG (DR_REG_CLINT_M_BASE + 0x0)
|
||||
|
@ -12,6 +12,7 @@ extern "C" {
|
||||
|
||||
#define DR_REG_PLIC_MX_BASE ( 0x20001000 )
|
||||
#define DR_REG_PLIC_UX_BASE ( 0x20001400 )
|
||||
#define DR_REG_PLIC_UX_END ( 0x20001800 )
|
||||
#define PLIC_MXINT_CONF_REG ( 0x200013FC )
|
||||
#define PLIC_UXINT_CONF_REG ( 0x200017FC )
|
||||
|
||||
|
Reference in New Issue
Block a user