RTEMS | RISC-V: Support the Smdbltrp extension (#5807)

Lucian Silistru (@lsilistr) gitlab at rtems.org
Fri Oct 9 12:38:51 UTC 2026



Task created by Lucian Silistru: https://gitlab.rtems.org/rtems/rtos/rtems/-/work_items/5807



## Summary

On a hart with Smdbltrp (machine-mode double-trap detection), RTEMS does not
boot in m-mode, and a double trap is not reported correctly. The Smrnmi
support (#5682) explicitly does not cover Smdbltrp.

Smdbltrp changes what Smrnmi delivers:
- With `mnstatus.NMIE` set, an m-mode double trap arrives as an RNMI.
- `mncause` then holds the exception code with bit MXLEN-1 cleared.
- The second trap is reported only in `mncause`/`mnepc`/`mnstatus`.
  `mcause`/`mepc`/`mstatus` still describe the first trap.
- Without Smdbltrp, every RNMI has bit MXLEN-1 of `mncause` set.

## Issues

1. **Boot (independent of Smrnmi):** `mstatus.MDT` (`mstatush.MDT` on rv32)
   is set out of reset. While MDT is set, writes that set `mstatus.MIE` have
   no effect, so every executable stops with
   `INTERNAL_ERROR_BAD_THREAD_DISPATCH_ENVIRONMENT`. `start.S` has to clear
   MDT.
2. **CPU port exception handler:** trap entry sets MDT, and the handler calls
   the fatal extensions with MDT still set. An exception in a fatal extension
   is therefore a double trap. The handler should clear MDT once the trap
   state is saved, or the double trap has to be handled as in item 3.
3. **RNMI handler:**
   - At entry, branch on bit MXLEN-1 of `mncause` instead of checking for
     zero: `bgez a0, .Lsynchronous_exception` instead of `beqz`. That covers
     an exception inside the RNMI handler (`mncause` is 0, because the
     handler clears it) and a double trap.
   - A double trap then ends through the existing `.Lsynchronous_exception`
     path as `RTEMS_FATAL_SOURCE_EXCEPTION`. It never reaches the deferred
     path, so the `mnret` loop back to the faulting instruction can't happen.
   - Add `mncause` and `mnepc` to the fatal output. On a double trap they
     identify the second trap; on an exception inside the RNMI handler,
     `mnepc` is where the RNMI interrupted. The handler clears `mncause` with
     `csrrw` at entry, but the original value is still in `a0` for the save.
     `CPU_Exception_frame` needs fields for both values, and
     `_CPU_Exception_frame_print()` should print them when `RISCV_SMRNMI` is
     set.

## Testing

- QEMU 10.0 or later with `-cpu rv64,smrnmi=true,smdbltrp=true` (`rv32` for
  the rv32 variants).
- `ts-fatal-riscv-rnmi-double-trap` from the second review of !1391 (note
  160672) is a starting point. It runs an illegal instruction in a task and
  in a fatal extension, with deferral enabled and disabled.
- The `start.S` MDT patch in the same note covers item 1.

## Related

- #5682 (Smrnmi support, no Smdbltrp)
- rtems!1391, rtems!1506

-- 
View it on GitLab: https://gitlab.rtems.org/rtems/rtos/rtems/-/work_items/5807
You're receiving this email because of your account on gitlab.rtems.org. Unsubscribe from this thread: https://gitlab.rtems.org/-/namespace/49/sent_notifications/6-aobnlf1petgig46nv3v9kgm9u-1d/unsubscribe | Manage all notifications: https://gitlab.rtems.org/-/profile/notifications | Help: https://gitlab.rtems.org/help


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/bugs/attachments/20261009/5c6cc40e/attachment-0001.htm>


More information about the bugs mailing list