summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorClément Léger <[email protected]>2024-10-18 10:40:08 +0200
committerAnup Patel <[email protected]>2024-10-26 00:00:12 +0530
commitc46a937fd9071660979ff68e5c6310e62c9d1770 (patch)
treee126795690adf22d8c1ee1c0188dd66661ee50ed /firmware
parent3bc86854ab5e26de580433cf67ed47bae148d777 (diff)
lib: sbi: add Smdbltrp ISA extension support
Add support for the Smdbltrp[1] ISA extension. First thing to do is clearing MDT on entry after setting the first MTVEC (since MDT is reset to 1). Additionally, during trap handling, clear MDT once all critical CSRs have been saved and in return path, restore MSTATUS/H before restoring MEPC to avoid taking another trap which would clobber it. Link: https://github.com/riscv/riscv-double-trap/releases/download/v0.56/riscv-double-trap.pdf [1] Signed-off-by: Clément Léger <[email protected]> Reviewed-by: Samuel Holland <[email protected]>
Diffstat (limited to 'firmware')
-rw-r--r--firmware/fw_base.S37
1 files changed, 32 insertions, 5 deletions
diff --git a/firmware/fw_base.S b/firmware/fw_base.S
index 4a2652e9..d027e5e2 100644
--- a/firmware/fw_base.S
+++ b/firmware/fw_base.S
@@ -31,6 +31,16 @@
add \__d4, \__s4, zero
.endm
+.macro CLEAR_MDT tmp
+#if __riscv_xlen == 32
+ li \tmp, MSTATUSH_MDT
+ csrc CSR_MSTATUSH, \tmp
+#else
+ li \tmp, MSTATUS_MDT
+ csrc CSR_MSTATUS, \tmp
+#endif
+.endm
+
.section .entry, "ax", %progbits
.align 3
.globl _start
@@ -91,6 +101,14 @@ _bss_zero:
lla s4, _start_hang
csrw CSR_MTVEC, s4
+ /*
+ * While at this point, trap handling is rudimentary, if a trap happens,
+ * it will end up in _start_hang which is enough to hook up a GDB. Clear
+ * MDT to avoid generating a double trap and thus entering a
+ * critical-error state.
+ */
+ CLEAR_MDT t0
+
/* Setup temporary stack */
lla s4, _fw_end
li s5, (SBI_SCRATCH_SIZE * 2)
@@ -348,6 +366,9 @@ _start_warm:
_skip_trap_handler_hyp:
csrw CSR_MTVEC, a4
+ /* Clear MDT here again for all harts */
+ CLEAR_MDT t0
+
/* Initialize SBI runtime */
csrr a0, CSR_MSCRATCH
call sbi_init
@@ -545,6 +566,9 @@ memcmp:
li t0, 0
.endif
REG_S t0, (SBI_TRAP_REGS_SIZE + SBI_TRAP_INFO_OFFSET(gva))(sp)
+
+ /* We are ready to take another trap, clear MDT */
+ CLEAR_MDT t0
.endm
.macro TRAP_CALL_C_ROUTINE
@@ -587,15 +611,18 @@ memcmp:
.endm
.macro TRAP_RESTORE_MEPC_MSTATUS have_mstatush
- /* Restore MEPC and MSTATUS CSRs */
- REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(a0)
- csrw CSR_MEPC, t0
- REG_L t0, SBI_TRAP_REGS_OFFSET(mstatus)(a0)
- csrw CSR_MSTATUS, t0
+ /*
+ * Restore MSTATUS and MEPC CSRs starting with MSTATUS/H to set MDT
+ * flags since we can not take a trap now or MEPC would be cloberred
+ */
.if \have_mstatush
REG_L t0, SBI_TRAP_REGS_OFFSET(mstatusH)(a0)
csrw CSR_MSTATUSH, t0
.endif
+ REG_L t0, SBI_TRAP_REGS_OFFSET(mstatus)(a0)
+ csrw CSR_MSTATUS, t0
+ REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(a0)
+ csrw CSR_MEPC, t0
.endm
.macro TRAP_RESTORE_A0_T0