RTEMS | RISC-V implementation does not support for Smdbltrp extension (#5274)

Matteo Concas (@matteo.concas) gitlab at rtems.org
Thu Jun 19 13:21:10 UTC 2025



Matteo Concas created an issue: https://gitlab.rtems.org/rtems/rtos/rtems/-/issues/5274



## Summary

It seems the current RISC-V implementation isn't compatible with processors using the Smdbltrp extension. This extension introduces the MDT (M-mode-disable-trap) bit in the status register which is set when a trap is taken in M mode. If MDT is set then the MIE (Machine Interrupt Enable) bit cannot be set so the MDT bit needs to be cleared at some point.

>From section 3.6.1.2 of the RISC-V Instruction Set Manual Volume II:

> The M-mode-disable-trap (MDT) bit is a WARL field introduced by the Smdbltrp extension. Upon reset, the MDT field is set to 1. When the MDT bit is set to 1 by an explicit CSR write, the MIE (Machine Interrupt Enable) bit is cleared to 0. For RV64, this clearing occurs regardless of the value written, if any, to the MIE bit by the same write. The MIE bit can only be set to 1 by an explicit CSR write if the MDT bit is already 0 or, for RV64, is being set to 0 by the same write (For RV32, the MDT bit is in mstatush and the MIE bit in mstatus register).
>
> When a trap is to be taken into M-mode, if the MDT bit is currently 0, it is then set to 1, and the trap is delivered as expected. However, if MDT is already set to 1, then this is an unexpected trap. When the Smrnmi extension is implemented, a trap caused by an RNMI is not considered an unexpected trap irrespective of the state of the MDT bit. A trap caused by an RNMI does not set the MDT bit. However, a trap that occurs when executing in M-mode with mnstatus.NMIE set to 0 is an unexpected trap. 

This means a call to `_Thread_Do_dispatch` might result in a `INTERNAL_ERROR_BAD_THREAD_DISPATCH_ENVIRONMENT` error because it checks if interrupts are disabled by looking at the MIE bit.

We fixed it with this quick patch:

```diff
diff --git a/cpukit/score/cpu/riscv/riscv-exception-handler.S b/cpukit/score/cpu/riscv/riscv-exception-handler.S
index 34e7cbb0b3..8d36f36741 100644
--- a/cpukit/score/cpu/riscv/riscv-exception-handler.S
+++ b/cpukit/score/cpu/riscv/riscv-exception-handler.S
@@ -161,6 +161,10 @@ SYM(_RISCV_Exception_handler):
     sw    t0, PER_CPU_ISR_DISPATCH_DISABLE(s0)
     sw    t0, PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL(s0)
 
+    /* Clear MDT bit */
+    li    t0, (1 << 42)
+    csrrc    zero, mstatus, t0
+
     /* Call _Thread_Do_dispatch(), this function will enable interrupts */
     mv    a0, s0
     li    a1, RISCV_MSTATUS_MIE
```

This will clear the MDT bit before `_Thread_Do_dispatch()` is called.

It would probably be good to discuss how to properly implement this.

-- 
View it on GitLab: https://gitlab.rtems.org/rtems/rtos/rtems/-/issues/5274
You're receiving this email because of your account on gitlab.rtems.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/bugs/attachments/20250619/fe43f275/attachment.htm>


More information about the bugs mailing list