mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 09:09:10 -04:00
feat(esp_tee): Support for ESP-TEE - riscv
component
This commit is contained in:
parent
733741bbac
commit
e51d2c1da3
@ -1,5 +1,6 @@
|
||||
idf_build_get_property(target IDF_TARGET)
|
||||
idf_build_get_property(arch IDF_TARGET_ARCH)
|
||||
idf_build_get_property(esp_tee_build ESP_TEE_BUILD)
|
||||
|
||||
if(NOT "${arch}" STREQUAL "riscv")
|
||||
return()
|
||||
@ -8,6 +9,11 @@ endif()
|
||||
|
||||
if(BOOTLOADER_BUILD)
|
||||
set(priv_requires soc)
|
||||
elseif(esp_tee_build)
|
||||
set(priv_requires soc)
|
||||
if(CONFIG_SOC_INT_PLIC_SUPPORTED)
|
||||
set(srcs "interrupt_plic.c")
|
||||
endif()
|
||||
else()
|
||||
set(priv_requires soc)
|
||||
set(srcs
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "soc/interrupt_reg.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "riscv/csr.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if SOC_INT_PLIC_SUPPORTED
|
||||
|
||||
@ -84,12 +85,34 @@ FORCE_INLINE_ATTR void rv_utils_restore_intlevel_regval(uint32_t restoreval)
|
||||
*/
|
||||
FORCE_INLINE_ATTR uint32_t rv_utils_set_intlevel_regval(uint32_t intlevel)
|
||||
{
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
unsigned prv_mode = RV_READ_CSR(CSR_PRV_MODE);
|
||||
|
||||
unsigned old_xstatus;
|
||||
if (prv_mode == PRV_M) {
|
||||
old_xstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||
} else {
|
||||
old_xstatus = RV_CLEAR_CSR(ustatus, USTATUS_UIE);
|
||||
}
|
||||
|
||||
uint32_t old_thresh = REG_READ(INTERRUPT_CURRENT_CORE_INT_THRESH_REG);
|
||||
rv_utils_restore_intlevel_regval(intlevel);
|
||||
|
||||
if (prv_mode == PRV_M) {
|
||||
RV_SET_CSR(mstatus, old_xstatus & MSTATUS_MIE);
|
||||
} else {
|
||||
RV_SET_CSR(ustatus, old_xstatus & USTATUS_UIE);
|
||||
}
|
||||
|
||||
return old_thresh;
|
||||
#else
|
||||
uint32_t old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||
uint32_t old_thresh = REG_READ(INTERRUPT_CURRENT_CORE_INT_THRESH_REG);
|
||||
rv_utils_restore_intlevel_regval(intlevel);
|
||||
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
|
||||
|
||||
return old_thresh;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -187,6 +187,13 @@ extern "C" {
|
||||
#define STPC1 0xBF1
|
||||
#define STPC2 0xBF2
|
||||
|
||||
/* Espressif's custom CSR for the current privilege mode */
|
||||
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
|
||||
#define CSR_PRV_MODE 0xC10
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61 || CONFIG_IDF_TARGET_ESP32P4
|
||||
#define CSR_PRV_MODE 0x810
|
||||
#endif
|
||||
|
||||
/* RISC-V CSR macros
|
||||
* Adapted from https://github.com/michaeljclark/riscv-probe/blob/master/libfemto/include/arch/riscv/machine.h
|
||||
*/
|
||||
|
@ -146,6 +146,21 @@ bool esprv_int_is_vectored(int rv_int_num);
|
||||
*/
|
||||
void esprv_int_set_vectored(int rv_int_num, bool vectored);
|
||||
|
||||
/*************************** ESP-TEE specific ***************************/
|
||||
|
||||
/** Function prototype executing interrupt configuration APIs as service calls */
|
||||
typedef void (*esprv_int_mgmt_t)(int argc, ...);
|
||||
|
||||
/**
|
||||
* @brief Setup the callback function which executes the interrupt
|
||||
* configuration APIs as TEE service calls
|
||||
*
|
||||
* @note This function should be called right after landing in the REE application,
|
||||
* before any system initialization
|
||||
*
|
||||
* @param fptr Pointer to the function
|
||||
*/
|
||||
void esprv_int_setup_mgmt_cb(void *fptr);
|
||||
|
||||
/**
|
||||
* Include the deprecated functions last since they will alias the functions declared above
|
||||
|
@ -15,16 +15,38 @@
|
||||
#include "riscv/csr.h"
|
||||
#include "riscv/interrupt.h"
|
||||
#include "riscv/csr_pie.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Check whether the current privilege level is Machine (M) mode */
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
#define IS_PRV_M_MODE() (RV_READ_CSR(CSR_PRV_MODE) == PRV_M)
|
||||
#else
|
||||
#define IS_PRV_M_MODE() (1UL)
|
||||
#endif
|
||||
|
||||
#if CONFIG_SECURE_ENABLE_TEE && !ESP_TEE_BUILD
|
||||
/* [ESP-TEE] Secure service call IDs for interrupt management */
|
||||
#define TEE_INTR_ENABLE_SRV_ID (2)
|
||||
#define TEE_INTR_DISABLE_SRV_ID (3)
|
||||
#define TEE_INTR_SET_PRIORITY_SRV_ID (4)
|
||||
#define TEE_INTR_SET_TYPE_SRV_ID (5)
|
||||
#define TEE_INTR_SET_THRESHOLD_SRV_ID (6)
|
||||
#define TEE_INTR_EDGE_ACK_SRV_ID (7)
|
||||
#define TEE_INTR_GLOBAL_EN_SRV_ID (8)
|
||||
/* [ESP-TEE] Callback function for accessing interrupt management services through REE */
|
||||
extern esprv_int_mgmt_t esp_tee_intr_sec_srv_cb;
|
||||
#endif
|
||||
|
||||
#if SOC_CPU_HAS_CSR_PC
|
||||
/*performance counter*/
|
||||
#define CSR_PCER_MACHINE 0x7e0
|
||||
#define CSR_PCMR_MACHINE 0x7e1
|
||||
#define CSR_PCCR_MACHINE 0x7e2
|
||||
#define CSR_PCCR_USER 0x802
|
||||
#endif /* SOC_CPU_HAS_CSR_PC */
|
||||
|
||||
#if SOC_BRANCH_PREDICTOR_SUPPORTED
|
||||
@ -89,7 +111,11 @@ FORCE_INLINE_ATTR uint32_t __attribute__((always_inline)) rv_utils_get_cycle_cou
|
||||
#if !SOC_CPU_HAS_CSR_PC
|
||||
return RV_READ_CSR(mcycle);
|
||||
#else
|
||||
return RV_READ_CSR(CSR_PCCR_MACHINE);
|
||||
if (IS_PRV_M_MODE()) {
|
||||
return RV_READ_CSR(CSR_PCCR_MACHINE);
|
||||
} else {
|
||||
return RV_READ_CSR(CSR_PCCR_USER);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -98,7 +124,11 @@ FORCE_INLINE_ATTR void __attribute__((always_inline)) rv_utils_set_cycle_count(u
|
||||
#if !SOC_CPU_HAS_CSR_PC
|
||||
RV_WRITE_CSR(mcycle, ccount);
|
||||
#else
|
||||
RV_WRITE_CSR(CSR_PCCR_MACHINE, ccount);
|
||||
if (IS_PRV_M_MODE()) {
|
||||
RV_WRITE_CSR(CSR_PCCR_MACHINE, ccount);
|
||||
} else {
|
||||
RV_WRITE_CSR(CSR_PCCR_USER, ccount);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -113,32 +143,89 @@ FORCE_INLINE_ATTR void rv_utils_set_mtvec(uint32_t mtvec_val)
|
||||
RV_WRITE_CSR(mtvec, mtvec_val | MTVEC_MODE_CSR);
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_set_xtvec(uint32_t xtvec_val)
|
||||
{
|
||||
xtvec_val |= MTVEC_MODE_CSR; // Set MODE field to treat XTVEC as a vector base address
|
||||
if (IS_PRV_M_MODE()) {
|
||||
RV_WRITE_CSR(mtvec, xtvec_val);
|
||||
} else {
|
||||
RV_WRITE_CSR(utvec, xtvec_val);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------ Interrupt Control --------------------
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_intr_enable(uint32_t intr_mask)
|
||||
{
|
||||
#if CONFIG_SECURE_ENABLE_TEE && !ESP_TEE_BUILD
|
||||
esp_tee_intr_sec_srv_cb(2, TEE_INTR_ENABLE_SRV_ID, intr_mask);
|
||||
#else
|
||||
// Disable all interrupts to make updating of the interrupt mask atomic.
|
||||
unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||
esprv_int_enable(intr_mask);
|
||||
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
|
||||
#endif
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_intr_disable(uint32_t intr_mask)
|
||||
{
|
||||
#if CONFIG_SECURE_ENABLE_TEE && !ESP_TEE_BUILD
|
||||
esp_tee_intr_sec_srv_cb(2, TEE_INTR_DISABLE_SRV_ID, intr_mask);
|
||||
#else
|
||||
// Disable all interrupts to make updating of the interrupt mask atomic.
|
||||
unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||
esprv_int_disable(intr_mask);
|
||||
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
|
||||
#endif
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_intr_global_enable(void)
|
||||
{
|
||||
#if CONFIG_SECURE_ENABLE_TEE && !ESP_TEE_BUILD
|
||||
esp_tee_intr_sec_srv_cb(1, TEE_INTR_GLOBAL_EN_SRV_ID);
|
||||
#else
|
||||
RV_SET_CSR(mstatus, MSTATUS_MIE);
|
||||
#endif
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_intr_global_disable(void)
|
||||
{
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
if (IS_PRV_M_MODE()) {
|
||||
RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||
} else {
|
||||
RV_CLEAR_CSR(ustatus, USTATUS_UIE);
|
||||
}
|
||||
#else
|
||||
RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||
#endif
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_intr_set_type(int intr_num, enum intr_type type)
|
||||
{
|
||||
#if CONFIG_SECURE_ENABLE_TEE && !ESP_TEE_BUILD
|
||||
esp_tee_intr_sec_srv_cb(3, TEE_INTR_SET_TYPE_SRV_ID, intr_num, type);
|
||||
#else
|
||||
esprv_int_set_type(intr_num, type);
|
||||
#endif
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_intr_set_priority(int rv_int_num, int priority)
|
||||
{
|
||||
#if CONFIG_SECURE_ENABLE_TEE && !ESP_TEE_BUILD
|
||||
esp_tee_intr_sec_srv_cb(3, TEE_INTR_SET_PRIORITY_SRV_ID, rv_int_num, priority);
|
||||
#else
|
||||
esprv_int_set_priority(rv_int_num, priority);
|
||||
#endif
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_intr_set_threshold(int priority_threshold)
|
||||
{
|
||||
#if CONFIG_SECURE_ENABLE_TEE && !ESP_TEE_BUILD
|
||||
esp_tee_intr_sec_srv_cb(2, TEE_INTR_SET_THRESHOLD_SRV_ID, priority_threshold);
|
||||
#else
|
||||
esprv_int_set_threshold(priority_threshold);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -352,8 +439,12 @@ FORCE_INLINE_ATTR bool rv_utils_compare_and_set(volatile uint32_t *addr, uint32_
|
||||
);
|
||||
#else
|
||||
// For a single core RV target has no atomic CAS instruction, we can achieve atomicity by disabling interrupts
|
||||
unsigned old_mstatus;
|
||||
old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||
unsigned old_xstatus;
|
||||
if (IS_PRV_M_MODE()) {
|
||||
old_xstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||
} else {
|
||||
old_xstatus = RV_CLEAR_CSR(ustatus, USTATUS_UIE);
|
||||
}
|
||||
// Compare and set
|
||||
uint32_t old_value;
|
||||
old_value = *addr;
|
||||
@ -361,7 +452,11 @@ FORCE_INLINE_ATTR bool rv_utils_compare_and_set(volatile uint32_t *addr, uint32_
|
||||
*addr = new_value;
|
||||
}
|
||||
// Restore interrupts
|
||||
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
|
||||
if (IS_PRV_M_MODE()) {
|
||||
RV_SET_CSR(mstatus, old_xstatus & MSTATUS_MIE);
|
||||
} else {
|
||||
RV_SET_CSR(ustatus, old_xstatus & USTATUS_UIE);
|
||||
}
|
||||
|
||||
#endif //__riscv_atomic
|
||||
return (old_value == compare_value);
|
||||
|
@ -4,7 +4,10 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc_caps.h"
|
||||
#include "riscv/csr.h"
|
||||
#include "riscv/interrupt.h"
|
||||
#include "riscv/rv_utils.h"
|
||||
#include "esp_private/interrupt_plic.h"
|
||||
#include "hal/interrupt_plic_ll.h"
|
||||
|
||||
@ -18,19 +21,35 @@ void intr_matrix_route(int intr_src, int intr_num)
|
||||
|
||||
uint32_t esprv_get_interrupt_unmask(void)
|
||||
{
|
||||
return interrupt_plic_ll_get_unmask();
|
||||
if (IS_PRV_M_MODE()) {
|
||||
return REG_READ(PLIC_MXINT_ENABLE_REG);
|
||||
} else {
|
||||
return REG_READ(PLIC_UXINT_ENABLE_REG);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum intr_type esprv_int_get_type(int rv_int_num)
|
||||
{
|
||||
return interrupt_plic_ll_get_type(rv_int_num) ? INTR_TYPE_EDGE : INTR_TYPE_LEVEL;
|
||||
uint32_t intr_type_reg;
|
||||
|
||||
if (IS_PRV_M_MODE()) {
|
||||
intr_type_reg = REG_READ(PLIC_MXINT_TYPE_REG);
|
||||
} else {
|
||||
intr_type_reg = REG_READ(PLIC_UXINT_TYPE_REG);
|
||||
}
|
||||
|
||||
return (intr_type_reg & (1 << rv_int_num)) ? INTR_TYPE_EDGE : INTR_TYPE_LEVEL;
|
||||
}
|
||||
|
||||
|
||||
int esprv_int_get_priority(int rv_int_num)
|
||||
{
|
||||
return interrupt_plic_ll_get_priority(rv_int_num);
|
||||
if (IS_PRV_M_MODE()) {
|
||||
return REG_READ(PLIC_MXINT0_PRI_REG + (rv_int_num) * 4);
|
||||
} else {
|
||||
return REG_READ(PLIC_UXINT0_PRI_REG + (rv_int_num) * 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -38,3 +57,44 @@ bool esprv_int_is_vectored(int rv_int_num)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if CONFIG_SECURE_ENABLE_TEE && !ESP_TEE_BUILD
|
||||
DRAM_ATTR esprv_int_mgmt_t esp_tee_intr_sec_srv_cb = NULL;
|
||||
|
||||
void esprv_int_setup_mgmt_cb(void *fptr)
|
||||
{
|
||||
esp_tee_intr_sec_srv_cb = (esprv_int_mgmt_t)fptr;
|
||||
}
|
||||
|
||||
|
||||
/* NOTE: Overriding ROM-based interrupt configuration symbols */
|
||||
void esprv_int_enable(uint32_t unmask)
|
||||
{
|
||||
rv_utils_intr_enable(unmask);
|
||||
}
|
||||
|
||||
|
||||
void esprv_int_disable(uint32_t mask)
|
||||
{
|
||||
rv_utils_intr_disable(mask);
|
||||
}
|
||||
|
||||
|
||||
void esprv_int_set_type(int intr_num, enum intr_type type)
|
||||
{
|
||||
rv_utils_intr_set_type(intr_num, type);
|
||||
}
|
||||
|
||||
|
||||
void esprv_int_set_priority(int rv_int_num, int priority)
|
||||
{
|
||||
rv_utils_intr_set_priority(rv_int_num, priority);
|
||||
}
|
||||
|
||||
|
||||
void esprv_int_set_threshold(int priority_threshold)
|
||||
{
|
||||
rv_utils_intr_set_threshold(priority_threshold);
|
||||
}
|
||||
#endif
|
||||
|
@ -76,11 +76,39 @@
|
||||
sw t6, RV_STK_T6(sp)
|
||||
.endm
|
||||
|
||||
.macro save_mepc
|
||||
/* Macro for saving special registers depending on the active execution
|
||||
* environment - REE - U-mode / TEE - M-mode */
|
||||
/* Save the XEPC register */
|
||||
.macro save_xepc
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
csrr t0, uepc
|
||||
#else
|
||||
csrr t0, mepc
|
||||
#endif
|
||||
sw t0, RV_STK_MEPC(sp)
|
||||
.endm
|
||||
|
||||
/* Save the required CSRs */
|
||||
.macro save_xcsr
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
csrr t0, ustatus
|
||||
sw t0, RV_STK_MSTATUS(sp)
|
||||
csrr t0, utvec
|
||||
sw t0, RV_STK_MTVEC(sp)
|
||||
csrr t0, utval
|
||||
sw t0, RV_STK_MTVAL(sp)
|
||||
#else
|
||||
csrr t0, mstatus
|
||||
sw t0, RV_STK_MSTATUS(sp)
|
||||
csrr t0, mtvec
|
||||
sw t0, RV_STK_MTVEC(sp)
|
||||
csrr t0, mhartid
|
||||
sw t0, RV_STK_MHARTID(sp)
|
||||
csrr t0, mtval
|
||||
sw t0, RV_STK_MTVAL(sp)
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/* Restore the general purpose registers (excluding gp) from the context on
|
||||
* the stack. The context is then deallocated. The default size is CONTEXT_SIZE
|
||||
* but it can be overridden. */
|
||||
@ -117,11 +145,49 @@
|
||||
addi sp,sp, \cxt_size
|
||||
.endm
|
||||
|
||||
.macro restore_mepc
|
||||
/* Macro for restoring special registers depending on the active execution
|
||||
* environment - REE - U-mode / TEE - M-mode */
|
||||
|
||||
/* Restore the XEPC register depending on the active execution
|
||||
* environment - REE - U-mode / TEE - M-mode */
|
||||
.macro restore_xepc
|
||||
lw t0, RV_STK_MEPC(sp)
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
csrw uepc, t0
|
||||
#else
|
||||
csrw mepc, t0
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/* Macros for enabling/disabling the global interrupts based on the
|
||||
* active execution environment - REE - U-mode / TEE - M-mode */
|
||||
.macro enable_intr
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
li t0, 0x1
|
||||
csrs ustatus, t0
|
||||
#else
|
||||
li t0, 0x8
|
||||
csrs mstatus, t0
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro disable_intr
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
li t0, 0x1
|
||||
csrc ustatus, t0
|
||||
#else
|
||||
li t0, 0x8
|
||||
csrc mstatus, t0
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro xret
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
uret
|
||||
#else
|
||||
mret
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.global rtos_int_enter
|
||||
.global rtos_int_exit
|
||||
@ -148,19 +214,15 @@ _panic_handler:
|
||||
|
||||
/* Save CSRs */
|
||||
sw t0, RV_STK_SP(sp)
|
||||
csrr t0, mepc
|
||||
sw t0, RV_STK_MEPC(sp)
|
||||
csrr t0, mstatus
|
||||
sw t0, RV_STK_MSTATUS(sp)
|
||||
csrr t0, mtvec
|
||||
sw t0, RV_STK_MTVEC(sp)
|
||||
csrr t0, mhartid
|
||||
sw t0, RV_STK_MHARTID(sp)
|
||||
csrr t0, mtval
|
||||
sw t0, RV_STK_MTVAL(sp)
|
||||
save_xepc
|
||||
save_xcsr
|
||||
|
||||
/* Keep mcause in s0, only the exception code and interrupt bit are relevant */
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
csrr s0, ucause
|
||||
#else
|
||||
csrr s0, mcause
|
||||
#endif
|
||||
li t1, VECTORS_MCAUSE_INTBIT_MASK | VECTORS_MCAUSE_REASON_MASK
|
||||
and s0, s0, t1
|
||||
|
||||
@ -274,7 +336,7 @@ _store_mcause:
|
||||
* Restore the registers and return from the exception.
|
||||
*/
|
||||
_return_from_exception:
|
||||
restore_mepc
|
||||
restore_xepc
|
||||
/* MTVEC and SP are assumed to be unmodified.
|
||||
* MSTATUS, MHARTID, MTVAL are read-only and not restored.
|
||||
*/
|
||||
@ -290,12 +352,14 @@ _return_from_exception:
|
||||
* from the stack.
|
||||
*/
|
||||
.global _interrupt_handler
|
||||
.global _tee_interrupt_handler
|
||||
.type _interrupt_handler, @function
|
||||
_interrupt_handler:
|
||||
_tee_interrupt_handler:
|
||||
/* Start by saving the general purpose registers and the PC value before
|
||||
* the interrupt happened. */
|
||||
save_general_regs
|
||||
save_mepc
|
||||
save_xepc
|
||||
|
||||
/* Though it is not necessary we save GP and SP here.
|
||||
* SP is necessary to help GDB to properly unwind
|
||||
@ -317,8 +381,13 @@ _interrupt_handler:
|
||||
/* If this is a non-nested interrupt, SP now points to the interrupt stack */
|
||||
|
||||
/* Before dispatch c handler, restore interrupt to enable nested intr */
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
csrr s1, ucause
|
||||
csrr s2, ustatus
|
||||
#else
|
||||
csrr s1, mcause
|
||||
csrr s2, mstatus
|
||||
#endif
|
||||
|
||||
#if !SOC_INT_HW_NESTED_SUPPORTED
|
||||
/* Save the interrupt threshold level */
|
||||
@ -337,7 +406,7 @@ _interrupt_handler:
|
||||
fence
|
||||
#endif // !SOC_INT_HW_NESTED_SUPPORTED
|
||||
|
||||
csrsi mstatus, 0x8
|
||||
enable_intr
|
||||
/* MIE set. Nested interrupts can now occur */
|
||||
|
||||
#ifdef CONFIG_PM_TRACE
|
||||
@ -366,7 +435,7 @@ _interrupt_handler:
|
||||
|
||||
/* After dispatch c handler, disable interrupt to make freertos make context switch */
|
||||
|
||||
csrci mstatus, 0x8
|
||||
disable_intr
|
||||
/* MIE cleared. Nested interrupts are disabled */
|
||||
|
||||
#if !SOC_INT_HW_NESTED_SUPPORTED
|
||||
@ -386,10 +455,15 @@ _interrupt_handler:
|
||||
* In case the target uses the CLIC, it is mandatory to restore `mcause` register since it contains
|
||||
* the former CPU priority. When executing `mret`, the hardware will restore the former threshold,
|
||||
* from `mcause` to `mintstatus` CSR */
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
csrw ucause, s1
|
||||
csrw ustatus, a0
|
||||
#else
|
||||
csrw mcause, s1
|
||||
csrw mstatus, a0
|
||||
restore_mepc
|
||||
#endif
|
||||
restore_xepc
|
||||
restore_general_regs
|
||||
/* exit, this will also re-enable the interrupts */
|
||||
mret
|
||||
xret
|
||||
.size _interrupt_handler, .-_interrupt_handler
|
||||
|
Loading…
x
Reference in New Issue
Block a user