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.
_______________________________________________
bugs mailing list
[email protected]
http://lists.rtems.org/mailman/listinfo/bugs