Skip to content

Commit 26014bb

Browse files
committed
feat(esp_tee): ASM routine fixes and improvements
- Fix incorrect setting in the edge interrupt acknowledgement API - Avoid executing the service call dispatcher in the U-mode ecall, rather execute `mret` to jump it - Avoid `t1` register corruption when processing `ecall` - Switch back to the bootloader stack from TEE stack after the execution of the entire TEE initialization routine
1 parent 4aafa4d commit 26014bb

File tree

8 files changed

+97
-120
lines changed

8 files changed

+97
-120
lines changed

components/esp_tee/src/esp_tee_config.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ extern int _tee_interrupt_handler(void);
1212
/* U-to-M mode switch */
1313
extern uint32_t _u2m_switch(int argc, va_list ap);
1414
/* REE IRAM end */
15-
extern uint32_t _iram_end;
15+
extern uint32_t _iram_text_end;
1616
/* REE IROM end */
1717
extern uint32_t _instruction_reserved_end;
1818
/* REE DROM start */
@@ -31,7 +31,7 @@ esp_tee_config_t esp_tee_app_config __attribute__((section(".esp_tee_app_cfg")))
3131

3232
.ns_int_handler = &_tee_interrupt_handler,
3333
.ns_entry_addr = &_u2m_switch,
34-
.ns_iram_end = &_iram_end,
34+
.ns_iram_end = &_iram_text_end,
3535
.ns_irom_end = &_instruction_reserved_end,
3636
.ns_drom_start = &_rodata_reserved_start,
3737
.ns_drom_end = &_rodata_reserved_end,

components/esp_tee/subproject/main/arch/riscv/esp_tee_vector_table_plic.S

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
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
*/
@@ -11,7 +11,7 @@
1111
#endif
1212

1313
/* Handlers defined in the `esp_tee_vectors.S` file */
14-
.global _panic_handler
14+
.global _tee_panic_handler
1515
.global _tee_ns_intr_handler
1616
.global _tee_s_intr_handler
1717

@@ -36,7 +36,7 @@
3636
.global _vector_table
3737
.type _vector_table, @function
3838
_vector_table:
39-
j _panic_handler /* 0: Exception entry */
39+
j _tee_panic_handler /* 0: Exception entry */
4040
/* NOTE: All of the free interrupts are used by the REE */
4141
j _tee_ns_intr_handler /* 1: Free interrupt number */
4242
j _tee_ns_intr_handler /* 2: Free interrupt number */
@@ -61,17 +61,16 @@ _vector_table:
6161
j _tee_ns_intr_handler /* 21: Free interrupt number */
6262
j _tee_ns_intr_handler /* 22: Free interrupt number */
6363
j _tee_ns_intr_handler /* 23: Free interrupt number */
64-
j _panic_handler /* 24: ETS_INT_WDT_INUM panic-interrupt (soc-level panic) */
65-
j _panic_handler /* 25: ETS_CACHEERR_INUM panic-interrupt (soc-level panic) */
64+
j _tee_panic_handler /* 24: ETS_INT_WDT_INUM panic-interrupt (soc-level panic) */
65+
j _tee_panic_handler /* 25: ETS_CACHEERR_INUM panic-interrupt (soc-level panic) */
6666
/* NOTE: Triggers panic irrespective of the Kconfig setting with ESP-TEE */
67-
j _panic_handler /* 26: ETS_MEMPROT_ERR_INUM handler (soc-level panic) */
67+
j _tee_panic_handler /* 26: ETS_MEMPROT_ERR_INUM handler (soc-level panic) */
6868
/* TODO: [IDF-10770] Not supported yet with ESP-TEE */
69-
j _panic_handler /* 27: ETS_ASSIST_DEBUG_INUM handler (soc-level panic) */
69+
j _tee_panic_handler /* 27: ETS_ASSIST_DEBUG_INUM handler (soc-level panic) */
7070
j _tee_ns_intr_handler /* 28: Free interrupt number */
7171
j _tee_ns_intr_handler /* 29: Free interrupt number */
7272
j _tee_ns_intr_handler /* 30: Free interrupt number */
7373
j _tee_s_intr_handler /* 31: ESP-TEE: Secure interrupt handler entry */
74-
j _panic_handler /* exception handler, entry 0 */
7574

7675
.size _vector_table, .-_vector_table
7776

components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_clic.S

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -176,18 +176,14 @@ _s_sp:
176176
.global _tee_panic_handler
177177
.type _tee_panic_handler, @function
178178
_tee_panic_handler:
179-
/* Exception handler. */
180-
.global _panic_handler
181-
.type _panic_handler, @function
182-
_panic_handler:
183179
/* Backup t0, t1 on the stack before using it */
184180
addi sp, sp, -16
185181
sw t0, 0(sp)
186182
sw t1, 4(sp)
187183

188184
/* Read mcause */
189185
csrr t0, mcause
190-
li t1, VECTORS_MCAUSE_INTBIT_MASK | VECTORS_MCAUSE_REASON_MASK
186+
li t1, VECTORS_MCAUSE_REASON_MASK
191187
and t0, t0, t1
192188

193189
/* Check whether the exception is an M-mode ecall */
@@ -265,7 +261,7 @@ _return_from_exception:
265261
restore_general_regs RV_STK_FRMSZ
266262
mret
267263

268-
.size _panic_handler, .-_panic_handler
264+
.size _tee_panic_handler, .-_tee_panic_handler
269265

270266
/* ECALL handler. */
271267
.type _ecall_handler, @function
@@ -274,13 +270,12 @@ _ecall_handler:
274270
_machine_ecall:
275271
/* Enable the U-mode delegation of all interrupts */
276272
li t0, INTMTX_SIG_IDX_ASSERT_IN_SEC_REG
277-
li t1, 0x00
278-
sw t1, 0(t0)
273+
sw zero, 0(t0)
279274
fence
280275
/* Verify the above */
281276
_1:
282-
lw t2, 0(t0)
283-
bne t2, t1, _2
277+
lw t1, 0(t0)
278+
bnez t1, _1
284279

285280
/* Set the privilege mode to transition to after mret to U-mode */
286281
li t0, MSTATUS_MPP
@@ -365,7 +360,7 @@ _rtn_from_ns_int:
365360
/* Verify the above */
366361
_3:
367362
lw t2, 0(t0)
368-
bne t2, t1, _2
363+
bne t2, t1, _3
369364

370365
/* Restore the secure stack pointer */
371366
la t0, _s_sp
@@ -457,13 +452,12 @@ _found_intr:
457452

458453
/* Enable the U-mode interrupt delegation */
459454
li t0, INTMTX_SIG_IDX_ASSERT_IN_SEC_REG
460-
li t1, 0x00
461-
sw t1, 0(t0)
455+
sw zero, 0(t0)
462456
fence
463457
/* Verify the above */
464458
_4:
465-
lw t2, 0(t0)
466-
bne t2, t1, _2
459+
lw t1, 0(t0)
460+
bnez t1, _4
467461

468462
/* For U-mode interrupts, we use mret to switch to U-mode after executing the below steps - */
469463
/* Disable the U-mode global interrupts */
@@ -484,7 +478,7 @@ _4:
484478
csrc mstatus, t1
485479

486480
/* Save the current secure stack pointer and switch to the U-mode interrupt stack
487-
* saved while entering the secure service call routine (see `sec_world_entry`) */
481+
* saved while entering the secure service call routine (see `_tee_s_entry`) */
488482
la t0, _s_sp
489483
sw sp, 0(t0)
490484
la t1, _ns_sp
@@ -589,7 +583,7 @@ _intr_hdlr_exec:
589583
mv a0, sp /* argument 1, stack pointer */
590584
mv a1, s1 /* argument 2, interrupt number (mcause) */
591585
/* mask off the interrupt flag of mcause */
592-
li t0, VECTORS_MCAUSE_INTBIT_MASK | VECTORS_MCAUSE_REASON_MASK
586+
li t0, VECTORS_MCAUSE_REASON_MASK
593587
and a1, a1, t0
594588

595589
jal esp_tee_global_interrupt_handler

components/esp_tee/subproject/main/arch/riscv/esp_tee_vectors_plic.S

Lines changed: 51 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,15 @@
2727

2828
.global esp_tee_global_interrupt_handler
2929
.global esp_tee_service_dispatcher
30+
.global _tee_s_entry
3031

3132
.section .data
33+
3234
.align 4
3335
.global _ns_sp
3436
_ns_sp:
3537
.word 0
3638

37-
.section .data
3839
.align 4
3940
.global _s_sp
4041
_s_sp:
@@ -91,6 +92,8 @@ _s_sp:
9192
sw t0, RV_STK_MTVAL(sp)
9293
csrr t0, mhartid
9394
sw t0, RV_STK_MHARTID(sp)
95+
csrr t0, mcause
96+
sw t0, RV_STK_MCAUSE(sp)
9497
.endm
9598

9699
/* Restore the general purpose registers (excluding gp) from the context on
@@ -169,16 +172,17 @@ _s_sp:
169172
.section .exception_vectors.text, "ax"
170173

171174
/* Exception handler. */
172-
.global _panic_handler
173-
.type _panic_handler, @function
174-
_panic_handler:
175-
/* Backup t0 on the stack before using it */
175+
.global _tee_panic_handler
176+
.type _tee_panic_handler, @function
177+
_tee_panic_handler:
178+
/* Backup t0, t1 on the stack before using it */
176179
addi sp, sp, -16
177180
sw t0, 0(sp)
181+
sw t1, 4(sp)
178182

179183
/* Read mcause */
180184
csrr t0, mcause
181-
li t1, VECTORS_MCAUSE_INTBIT_MASK | VECTORS_MCAUSE_REASON_MASK
185+
li t1, VECTORS_MCAUSE_REASON_MASK
182186
and t0, t0, t1
183187

184188
/* Check whether the exception is an M-mode ecall */
@@ -189,10 +193,12 @@ _panic_handler:
189193
li t1, ECALL_U_MODE
190194
beq t0, t1, _user_ecall
191195

192-
/* Restore t0 from the stack */
196+
/* Restore t0, t1 from the stack */
193197
lw t0, 0(sp)
198+
lw t1, 4(sp)
194199
addi sp, sp, 16
195200

201+
_actual_panic:
196202
/* Not an ecall, proceed to the panic handler */
197203
/* Allocate space on the stack and store general purpose registers */
198204
save_general_regs RV_STK_FRMSZ
@@ -245,13 +251,17 @@ _return_from_exception:
245251
restore_general_regs RV_STK_FRMSZ
246252
mret
247253

248-
.size _panic_handler, .-_panic_handler
254+
.size _tee_panic_handler, .-_tee_panic_handler
249255

250256
/* ECALL handler. */
251257
.type _ecall_handler, @function
252258
_ecall_handler:
253259
/* M-mode ecall handler */
254260
_machine_ecall:
261+
/* Enable the U-mode delegation of all interrupts (except the TEE secure interrupt) */
262+
li t0, TEE_INTR_DELEG_MASK
263+
csrs mideleg, t0
264+
255265
/* Set the privilege mode to transition to after mret to U-mode */
256266
li t0, MSTATUS_MPP
257267
csrc mstatus, t0
@@ -270,7 +280,7 @@ _machine_ecall:
270280
* The A0 register contains the return value of the corresponding service.
271281
* After restoring the entire register context, we assign A0 the value back to the return value. */
272282
csrw mscratch, a0
273-
restore_general_regs RV_STK_FRMSZ
283+
restore_general_regs
274284
csrrw a0, mscratch, zero
275285

276286
_skip_ctx_restore:
@@ -284,17 +294,17 @@ _skip_ctx_restore:
284294
_user_ecall:
285295
/* Check whether we are returning after servicing an U-mode interrupt */
286296
lui t0, RTNVAL
287-
csrr t1, mscratch
297+
csrrw t1, mscratch, zero
288298
beq t0, t1, _rtn_from_ns_int
289-
csrwi mscratch, 0
290299

291-
/* Restore t0 from the stack */
300+
/* Restore t0, t1 from the stack */
292301
lw t0, 0(sp)
302+
lw t1, 4(sp)
293303
addi sp, sp, 16
294304

295305
/* This point is reached when a secure service call is issued from the REE */
296306
/* Save register context and mepc */
297-
save_general_regs RV_STK_FRMSZ
307+
save_general_regs
298308
save_mepc
299309

300310
/* Save the U-mode (i.e. REE) stack pointer */
@@ -304,22 +314,18 @@ _user_ecall:
304314
/* Switch to the M-mode (i.e. TEE) stack */
305315
la sp, _tee_stack
306316

317+
/* Load the TEE entry point (see _tee_s_entry) in the mepc */
318+
la t0, _tee_s_entry
319+
csrw mepc, t0
320+
307321
/* Disable the U-mode delegation of all interrupts */
308322
csrwi mideleg, 0
309323

310-
/* Enable interrupts */
311-
csrsi mstatus, MSTATUS_MIE
312-
313-
/* Jump to the secure service dispatcher */
314-
jal esp_tee_service_dispatcher
315-
316-
/* Enable the U-mode delegation of all interrupts (except the TEE secure interrupt) */
317-
li t0, TEE_INTR_DELEG_MASK
318-
csrs mideleg, t0
324+
/* Set the privilege mode to transition to after mret to M-mode */
325+
li t0, MSTATUS_MPP
326+
csrs mstatus, t0
319327

320-
/* Fire an M-ecall */
321-
mv a1, zero
322-
ecall
328+
mret
323329

324330
/* This point is reached after servicing a U-mode interrupt occurred
325331
* while executing a secure service */
@@ -331,16 +337,13 @@ _rtn_from_ns_int:
331337
la t0, _s_sp
332338
lw sp, 0(t0)
333339

334-
/* Clear the flag set marking the completion of interrupt service */
335-
csrwi mscratch, 0
336-
337340
/* Set the privilege mode to transition to after mret to M-mode */
338341
li t0, MSTATUS_MPP
339342
csrs mstatus, t0
340343

341344
/* Restore register context and resume the secure service */
342345
restore_mepc
343-
restore_general_regs RV_STK_FRMSZ
346+
restore_general_regs
344347

345348
mret
346349

@@ -354,7 +357,7 @@ _rtn_from_ns_int:
354357
_tee_ns_intr_handler:
355358
/* Start by saving the general purpose registers and the PC value before
356359
* the interrupt happened. */
357-
save_general_regs RV_STK_FRMSZ
360+
save_general_regs
358361
save_mepc
359362

360363
/* Though it is not necessary we save GP and SP here.
@@ -364,7 +367,7 @@ _tee_ns_intr_handler:
364367
/* As gp register is not saved by the macro, save it here */
365368
sw gp, RV_STK_GP(sp)
366369
/* Same goes for the SP value before trapping */
367-
addi t0, sp, RV_STK_FRMSZ /* restore sp with the value when interrupt happened */
370+
addi t0, sp, CONTEXT_SIZE /* restore sp with the value when interrupt happened */
368371
/* Save SP */
369372
sw t0, RV_STK_SP(sp)
370373

@@ -391,7 +394,7 @@ _tee_ns_intr_handler:
391394
csrc mstatus, t1
392395

393396
/* Save the current secure stack pointer and switch to the U-mode interrupt stack
394-
* saved while entering the secure service call routine (see `sec_world_entry`) */
397+
* saved while entering the secure service call routine (see `_tee_s_entry`) */
395398
la t0, _s_sp
396399
sw sp, 0(t0)
397400
la t1, _ns_sp
@@ -461,8 +464,6 @@ _tee_s_intr_handler:
461464
_save_reg_ctx:
462465
/* Save CSR context here */
463466
save_mcsr
464-
csrr t0, mcause
465-
sw t0, RV_STK_MCAUSE(sp)
466467
/* NOTE: With ESP-TEE, since APM violations trigger a panic, it's safe to use the mscratch
467468
* register to pass on the stack pointer to the APM violation handler */
468469
csrw mscratch, sp
@@ -519,7 +520,7 @@ _intr_hdlr_exec:
519520
mv a0, sp /* argument 1, stack pointer */
520521
mv a1, s1 /* argument 2, interrupt number (mcause) */
521522
/* mask off the interrupt flag of mcause */
522-
li t0, 0x7fffffff
523+
li t0, VECTORS_MCAUSE_REASON_MASK
523524
and a1, a1, t0
524525

525526
jal esp_tee_global_interrupt_handler
@@ -546,3 +547,18 @@ _intr_hdlr_exec:
546547
mret
547548

548549
.size _tee_s_intr_handler, .-_tee_s_intr_handler
550+
551+
.section .text, "ax"
552+
553+
.align 4
554+
.type _tee_s_entry, @function
555+
_tee_s_entry:
556+
/* Jump to the secure service dispatcher */
557+
jal esp_tee_service_dispatcher
558+
559+
/* Fire an M-ecall */
560+
mv a1, zero
561+
ecall
562+
fence
563+
564+
.size _tee_s_entry, .-_tee_s_entry

0 commit comments

Comments
 (0)