5 RISC-V Debug
Modifications to the RISC-V core to support debug are kept to a minimum. There is a special execution mode (Debug Mode) and a few extra CSRs. The DM takes care of the rest.
In order to be compliant with this specification an implementation must implement everything described in this section that is not explicitly listed as optional.
5.1 Debug Mode
Debug Mode is a special processor mode used only when a hart is halted for external debugging. How Debug Mode is implemented is not specified here.
When executing code from the optional Program Buffer, the hart stays in Debug Mode and the following apply:
All operations are executed at machine mode privilege level, except that
in mstatus
may be ignored according to mprven
.
All interrupts (including NMI) are masked.
Exceptions don’t update any registers. That includes cause
, epc
, tval
, dpc
, and mstatus
. They do end execution of the
Program Buffer.
No action is taken if a trigger matches.
Counters may be stopped, depending on stopcount
in dcsr
.
Timers may be stopped, depending on stoptime
in dcsr
.
The wfi
instruction acts as a nop
.
Almost all instructions that change the privilege level have undefined
behavior. This includes ecall
, mret
, sret
,
and uret
. (To change the privilege level, the debugger can write
prv
in dcsr
). The only exception is ebreak
. When that is executed
in Debug Mode, it halts the hart again but without updating dpc
or dcsr
.
[fence] Completing Program Buffer execution is considered output for the purpose
of fence
instructions.
All control transfer instructions may act as illegal instructions if their destination is in the Program Buffer. If one such instruction acts as an illegal instruction, all such instructions must act as an illegal instruction.
All control transfer instructions may act as illegal instructions if their destination is outside the Program Buffer. If one such instruction acts as an illegal instruction, all such instructions must act as an illegal instruction.
Instructions that depend on the value of the PC (e.g. auipc
) may act
as illegal instructions.
Effective XLEN is DXLEN.
5.2 Load-Reserved/Store-Conditional Instructions
The reservation registered by an lr
instruction on a memory address may
be lost when entering Debug Mode or while in Debug Mode. This means that there
may be no forward progress if Debug Mode is entered between lr
and sc
pairs.
This is a behavior that debug users must be aware of. If they have a
breakpoint set between a lr
and sc
pair, or are stepping
through such code, the sc
may never succeed. Fortunately in general use
there will be very few instructions in such a sequence, and anybody
debugging it will quickly notice that the reservation is not occurring.
The solution in that case is to set a breakpoint on the first instruction
after the sc
and run to it. A higher level debugger may choose to
automate this.
5.3 Wait for Interrupt Instruction
If halt is requested while wfi
is executing, then the hart must leave the
stalled state, completing this instruction’s execution, and then enter Debug
Mode.
5.4 Single Step
A debugger can cause a halted hart to execute a single instruction and then
re-enter Debug Mode by setting step
before setting resumereq
.
If executing or fetching that instruction causes an exception, Debug Mode is
re-entered immediately after the PC is changed to the exception handler and the
appropriate tval
and cause
registers are updated.
If executing or fetching the instruction causes a trigger to fire, Debug Mode
is re-entered immediately after that trigger has fired. In that case cause
is
set to 2 (trigger) instead of 4 (single step). Whether the instruction is
executed or not depends on the specific configuration of the trigger.
If the instruction that is executed causes the PC to change to an address where an instruction fetch causes an exception, that exception does not occurr until the next time the hart is resumed. Similarly, a trigger at the new address does not fire until the hart actually attempts to execute that instruction.
If the instruction being stepped over is wfi
and would normally stall the
hart, then instead the instruction is treated as nop
.
5.5 Reset
If the halt signal (driven by the hart’s halt request bit in the Debug Module)
or resethaltreq
are asserted when a hart comes out of reset, the hart must
enter Debug Mode before executing any instructions, but after performing any
initialization that would usually happen before the first instruction is
executed.
5.6 dret
Instruction
To return from Debug Mode, a new instruction is defined: dret
. It has an
encoding of 0x7b200073. On harts which support this instruction,
executing dret
in Debug Mode changes pc
to the value
stored in dpc
. The current privilege level is changed to that specified by
prv
in dcsr
. The hart is no longer in debug mode.
Executing dret
outside of Debug Mode causes an illegal instruction exception.
It is not necessary for the debugger to know whether an implementation supports
dret
, as the Debug Module will ensure that it is executed if necessary.
It is defined in this specification only to reserve the opcode and
allow for reusable Debug Module implementations.
5.7 XLEN
While in Debug Mode, XLEN is DXLEN. It is up to the debugger to determine the
XLEN during normal program execution (by looking at misa
) and to clearly
communicate this to the user.
5.8 Core Debug Registers
The supported Core Debug Registers must be implemented for each hart that can
be debugged. They are CSRs, accessible using the RISC-V csr
opcodes and
optionally also using abstract debug commands.
In general, the debugger is expected to be able to simulate all the effects of . The exception is the case of Sv32 systems, which need functionality in order to access 34-bit physical addresses. Other systems are likely to tie
mprven
to 0.