11/*
2- * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
2+ * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 */
1212
1313#include "riscv/encoding.h"
1414#include "riscv/rvruntime-frames.h"
15+ #include "esp_private/vectors_const.h"
1516
1617#include "esp_tee.h"
1718#include "sdkconfig.h"
2526 .equ ECALL_U_MODE, 0x8
2627 .equ ECALL_M_MODE, 0xb
2728 .equ TEE_APM_INTR_MASK_0, 0x00300000
28- .equ TEE_APM_INTR_MASK_1, 0x000000F8
29+ .equ TEE_APM_INTR_MASK_1, 0x000000f8
30+ .equ TEE_INTR_DELEG_MASK, 0xffffbfff
2931
3032 .global esp_tee_global_interrupt_handler
33+ .global esp_tee_service_dispatcher
34+
3135
3236 .section .data
3337 .align 4
@@ -177,15 +181,18 @@ _panic_handler:
177181 addi sp, sp, -16
178182 sw t0, 0 (sp)
179183
180- /* Check whether the exception is an M-mode ecall */
184+ /* Read mcause */
181185 csrr t0, mcause
182- xori t0, t0, ECALL_M_MODE
183- beqz t0, _machine_ecall
186+ li t1, VECTORS_MCAUSE_INTBIT_MASK | VECTORS_MCAUSE_REASON_MASK
187+ and t0, t0, t1
188+
189+ /* Check whether the exception is an M-mode ecall */
190+ li t1, ECALL_M_MODE
191+ beq t0, t1, _machine_ecall
184192
185193 /* Check whether the exception is an U-mode ecall */
186- csrr t0, mcause
187- xori t0, t0, ECALL_U_MODE
188- beqz t0, _user_ecall
194+ li t1, ECALL_U_MODE
195+ beq t0, t1, _user_ecall
189196
190197 /* Restore t0 from the stack */
191198 lw t0, 0 (sp)
@@ -250,6 +257,10 @@ _return_from_exception:
250257_ecall_handler:
251258 /* M-mode ecall handler */
252259_machine_ecall:
260+ /* Set the privilege mode to transition to after mret to U-mode */
261+ li t0, MSTATUS_MPP
262+ csrc mstatus, t0
263+
253264 /* Check whether this is the first M-mode ecall (see esp_tee_init) and skip context restoration */
254265 lui t0, ESP_TEE_M2U_SWITCH_MAGIC
255266 beq a1, t0, _skip_ctx_restore
@@ -267,15 +278,10 @@ _machine_ecall:
267278 restore_general_regs RV_STK_FRMSZ
268279 csrrw a0, mscratch, zero
269280
270- /* This point is reached only after the first M-mode ecall, never again (see esp_tee_init) */
271281_skip_ctx_restore:
272282 /* Copy the ra register to mepc which contains the user app entry point (i.e. call_start_cpu0) */
273283 csrw mepc, ra
274284
275- /* Set the privilege mode to transition to after mret to U-mode */
276- li t3, MSTATUS_MPP
277- csrc mstatus, t3
278-
279285 /* Jump to the REE */
280286 mret
281287
@@ -291,28 +297,34 @@ _user_ecall:
291297 lw t0, 0 (sp)
292298 addi sp, sp, 16
293299
294- /* This point is reached after a secure service call is issued from the REE */
295- /* Save register context and the mepc */
300+ /* This point is reached when a secure service call is issued from the REE */
301+ /* Save register context and mepc */
296302 save_general_regs RV_STK_FRMSZ
297303 save_mepc
298304
299- /* Saving the U-mode (i.e. REE) stack pointer */
305+ /* Save the U-mode (i.e. REE) stack pointer */
300306 la t0, _ns_sp
301307 sw sp, 0 (t0)
302308
303- /* Switching to the M-mode (i.e. TEE) stack */
309+ /* Switch to the M-mode (i.e. TEE) stack */
304310 la sp, _tee_stack
305311
306- /* Load the TEE entry point (see sec_world_entry) in the mepc */
307- la t2, esp_tee_app_config
308- lw t2, ESP_TEE_CFG_OFFS_S_ENTRY_ADDR(t2)
309- csrw mepc, t2
312+ /* Disable the U-mode delegation of all interrupts */
313+ csrwi mideleg, 0
310314
311- /* Set the privilege mode to transition to after mret to M-mode */
312- li t3, MSTATUS_MPP
313- csrs mstatus, t3
315+ /* Enable interrupts */
316+ csrsi mstatus, MSTATUS_MIE
314317
315- mret
318+ /* Jump to the secure service dispatcher */
319+ jal esp_tee_service_dispatcher
320+
321+ /* Enable the U-mode delegation of all interrupts (except the TEE secure interrupt) */
322+ li t0, TEE_INTR_DELEG_MASK
323+ csrs mideleg, t0
324+
325+ /* Fire an M-ecall */
326+ mv a1, zero
327+ ecall
316328
317329 /* This point is reached after servicing a U-mode interrupt occurred
318330 * while executing a secure service */
@@ -333,7 +345,7 @@ _rtn_from_ns_int:
333345
334346 /* Restore register context and resume the secure service */
335347 restore_mepc
336- restore_general_regs
348+ restore_general_regs RV_STK_FRMSZ
337349
338350 mret
339351
@@ -347,7 +359,7 @@ _rtn_from_ns_int:
347359_tee_ns_intr_handler:
348360 /* Start by saving the general purpose registers and the PC value before
349361 * the interrupt happened. */
350- save_general_regs
362+ save_general_regs RV_STK_FRMSZ
351363 save_mepc
352364
353365 /* Though it is not necessary we save GP and SP here.
@@ -357,7 +369,7 @@ _tee_ns_intr_handler:
357369 /* As gp register is not saved by the macro, save it here */
358370 sw gp, RV_STK_GP(sp)
359371 /* Same goes for the SP value before trapping */
360- addi t0, sp, CONTEXT_SIZE /* restore sp with the value when interrupt happened */
372+ addi t0, sp, RV_STK_FRMSZ /* restore sp with the value when interrupt happened */
361373 /* Save SP */
362374 sw t0, RV_STK_SP(sp)
363375
@@ -395,8 +407,8 @@ _tee_ns_intr_handler:
395407 csrw mscratch, t0
396408
397409 /* Enable the U-mode interrupt delegation (except for the TEE secure interrupt) */
398- li t0, 0xffffbfff
399- csrw mideleg, t0
410+ li t0, TEE_INTR_DELEG_MASK
411+ csrs mideleg, t0
400412
401413 /* Place magic bytes in all the general registers */
402414 store_magic_general_regs
@@ -413,7 +425,7 @@ _tee_ns_intr_handler:
413425_tee_s_intr_handler:
414426 /* Start by saving the general purpose registers and the PC value before
415427 * the interrupt happened. */
416- save_general_regs
428+ save_general_regs RV_STK_FRMSZ
417429 save_mepc
418430
419431 /* Though it is not necessary we save GP and SP here.
@@ -423,7 +435,7 @@ _tee_s_intr_handler:
423435 /* As gp register is not saved by the macro, save it here */
424436 sw gp, RV_STK_GP(sp)
425437 /* Same goes for the SP value before trapping */
426- addi t0, sp, CONTEXT_SIZE /* restore sp with the value when interrupt happened */
438+ addi t0, sp, RV_STK_FRMSZ /* restore sp with the value when interrupt happened */
427439 /* Save SP */
428440 sw t0, RV_STK_SP(sp)
429441
@@ -457,7 +469,7 @@ _save_reg_ctx:
457469_continue:
458470 /* Before doing anything preserve the stack pointer */
459471 mv s11, sp
460- /* Switching to the TEE interrupt stack */
472+ /* Switch to the TEE interrupt stack */
461473 la sp, _tee_intr_stack
462474 /* If this is a non-nested interrupt, SP now points to the interrupt stack */
463475
@@ -527,7 +539,7 @@ _intr_hdlr_exec:
527539 mv sp, s11
528540
529541 restore_mepc
530- restore_general_regs
542+ restore_general_regs RV_STK_FRMSZ
531543 /* exit, this will also re-enable the interrupts */
532544 mret
533545
0 commit comments