Line 488... |
Line 488... |
It provides a new operation mode called "debug mode".
|
It provides a new operation mode called "debug mode".
|
When enabled, three additional CSRs are available (section <<_cpu_debug_mode_csrs>>) and also the "return from debug mode"
|
When enabled, three additional CSRs are available (section <<_cpu_debug_mode_csrs>>) and also the "return from debug mode"
|
instruction `dret` is available when the CPU is "in" debug mode.
|
instruction `dret` is available when the CPU is "in" debug mode.
|
|
|
[IMPORTANT]
|
[IMPORTANT]
|
The CPU _debug mode_ requires the `Zicsr` CPU extension to be implemented (top generic _CPU_EXTENSION_RISCV_Zicsr_ = true).
|
The CPU _debug mode_ requires the `Zicsr` and `Zifencei` CPU extension to be implemented (top generics _CPU_EXTENSION_RISCV_Zicsr_
|
|
and _CPU_EXTENSION_RISCV_Zifencei_ = true).
|
|
|
The CPU debug mode is entered when one of the following events appear:
|
The CPU debug mode is entered when one of the following events appear:
|
|
|
[start=1]
|
[start=1]
|
. executing `ebreak` instruction (when `dcsr.ebreakm` is set and in machine mode OR when `dcsr.ebreaku` is set and in user mode)
|
. executing `ebreak` instruction (when `dcsr.ebreakm` is set and in machine mode OR when `dcsr.ebreaku` is set and in user mode)
|
Line 517... |
Line 518... |
* if an exception occurs
|
* if an exception occurs
|
* if the exception was caused by any debug-mode entry action the CPU jumps to the _normal entry point_
|
* if the exception was caused by any debug-mode entry action the CPU jumps to the _normal entry point_
|
( = _CPU_DEBUG_ADDR_) of the park loop again (for example when executing `ebreak` in debug mode)
|
( = _CPU_DEBUG_ADDR_) of the park loop again (for example when executing `ebreak` in debug mode)
|
* for all other exception sources the CPU jumps to the _exception entry point_ ( = _CPU_DEBUG_ADDR_ + 4)
|
* for all other exception sources the CPU jumps to the _exception entry point_ ( = _CPU_DEBUG_ADDR_ + 4)
|
to signal an exception to the DM and restarts the park loop again afterwards
|
to signal an exception to the DM and restarts the park loop again afterwards
|
* interrupts _including_ non-maskable interrupts are disabled; however, they will be buffered and executed when the CPU has left debug mode
|
* interrupts are disabled; however, they will be remain pending and will get executed after the CPU has left debug mode
|
* if the DM makes a resume request, the park loop exits and the CPU leaves debug mode (executing `dret`)
|
* if the DM makes a resume request, the park loop exits and the CPU leaves debug mode (executing `dret`)
|
|
|
Debug mode is left either by executing the `dret` instruction footnote:[`dret` should only be executed _inside_ the debugger
|
Debug mode is left either by executing the `dret` instruction footnote:[`dret` should only be executed _inside_ the debugger
|
"park loop" code (-> code ROM in the debug module (DM).)] (_in_ debug mode) or by performing
|
"park loop" code (-> code ROM in the debug module (DM).)] (_in_ debug mode) or by performing
|
a hardware reset of the CPU. Executing `dret` outside of debug mode will raise an illegal instruction exception.
|
a hardware reset of the CPU. Executing `dret` outside of debug mode will raise an illegal instruction exception.
|
Line 570... |
Line 571... |
| 13 | [line-through]#`ebereaks`# | r/- | `0` - supervisor mode not supported
|
| 13 | [line-through]#`ebereaks`# | r/- | `0` - supervisor mode not supported
|
| 12 | `ebereaku` | r/w | `ebreak` instructions in `user` mode will _enter_ debug mode when set
|
| 12 | `ebereaku` | r/w | `ebreak` instructions in `user` mode will _enter_ debug mode when set
|
| 11 | [line-through]#`stepie`# | r/- | `0` - IRQs are disabled during single-stepping
|
| 11 | [line-through]#`stepie`# | r/- | `0` - IRQs are disabled during single-stepping
|
| 10 | [line-through]#`stopcount`# | r/- | `0` - counters increment as usual
|
| 10 | [line-through]#`stopcount`# | r/- | `0` - counters increment as usual
|
| 9 | [line-through]#`stoptime`# | r/- | `0` - timers increment as usual
|
| 9 | [line-through]#`stoptime`# | r/- | `0` - timers increment as usual
|
| 8:6 | `cause` | r/- | cause identifier - why was debug mode entered
|
| 8:6 | `cause` | r/- | cause identifier - why debug mode was entered
|
| 5 | - | r/- | _reserved_, read as zero
|
| 5 | - | r/- | _reserved_, read as zero
|
| 4 | `mprven` | r/- | `0` - `mstatus.mprv` is ignored when in debug mode
|
| 4 | [line-through]#`mprven`# | r/- | `0` - `mstatus.mprv` is ignored when in debug mode
|
| 3 | `nmip` | r/- | set when the non-maskable CPU/processor interrupt is pending
|
| 3 | [line-through]#`nmip`# | r/- | `0` - non-maskable interrupt is pending
|
| 2 | `step` | r/w | enable single-stepping when set
|
| 2 | `step` | r/w | enable single-stepping when set
|
| 1:0 | `prv` | r/w | CPU privilege level before/after debug mode
|
| 1:0 | `prv` | r/w | CPU privilege level before/after debug mode
|
|=======================
|
|=======================
|
|
|
|
|