forked from riscv/riscv-debug-spec
-
Notifications
You must be signed in to change notification settings - Fork 0
/
core_debug.tex
176 lines (139 loc) · 7.78 KB
/
core_debug.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
\chapter{RISC-V Debug}
\label{sec:core_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.
\section{Debug Mode} \label{debugmode}
Debug Mode is a special processor mode used only when a hart is halted for
external debugging. Because the hart is halted, there is no forward progress in
the normal instruction stream.
How Debug Mode is implemented is not specified here.
\begin{steps}{When executing code due to an abstract command, the hart stays in
Debug Mode and the following apply:}
\item All operations are executed at machine mode privilege level, except that
\FcsrMcontrolMprv in \Rmstatus may be ignored according to \FcsrDcsrMprven.
\item All interrupts (including NMI) are masked.
\item Exceptions don't update any registers. That includes {\tt cause}, {\tt
epc}, {\tt tval}, {\tt dpc}, and \Rmstatus. They do end execution of the
Program Buffer.
\item No action is taken if a trigger matches.
\item If \FcsrDcsrStopcount is 0 then counters continue. If it is 1 then
counters are stopped.
\item If \FcsrDcsrStoptime is 0 then timers continue. If it is 1 then
timers are stopped.
\item The {\tt wfi} instruction acts as a {\tt nop}.
\item Almost all instructions that change the privilege level have undefined
behavior. This includes {\tt ecall}, {\tt mret}, {\tt sret},
and {\tt uret}. (To change the privilege level, the debugger can write
\FcsrDcsrPrv in \RcsrDcsr). The only exception is {\tt ebreak}, which ends
execution of the Program Buffer when executed.
\item \label{fence} Completing Program Buffer execution is considered output for the purpose
of {\tt fence} instructions.
\item 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 illegal
instructions.
\item 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
illegal instructions.
\item Instructions that depend on the value of the PC (e.g.\ {\tt auipc}) may act
as illegal instructions.
\item Effective XLEN is DXLEN.
\item Forward progress is guaranteed.
\end{steps}
\begin{commentary}
In general, the debugger is expected to be able to simulate all the effects of \FcsrMcontrolMprv.
The exception is the case of Sv32 systems, which need \FcsrMcontrolMprv functionality in order to access
34-bit physical addresses. Other systems are likely to tie \FcsrDcsrMprven to 0.
\end{commentary}
\section{Load-Reserved/Store-Conditional Instructions}
The reservation registered by an {\tt 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 {\tt lr} and {\tt
sc} pairs.
\begin{commentary}
This is a behavior that debug users must be aware of. If they have a
breakpoint set between a {\tt lr} and {\tt sc} pair, or are stepping
through such code, the {\tt 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 {\tt sc} and run to it. A higher level debugger may choose to
automate this.
\end{commentary}
\section{Wait for Interrupt Instruction}
If halt is requested while {\tt wfi} is executing, then the hart must leave the
stalled state, completing this instruction's execution, and then enter Debug
Mode.
\section{Single Step}
\subsection{Step Bit In Dcsr} \label{stepBit}
This method is only available to external debuggers, and is the preferred way
to single step.
An external debugger can cause a halted hart to execute a single instruction or
trap
and then re-enter Debug Mode by setting \FcsrDcsrStep before setting
\FdmDmcontrolResumereq.
If control is transferred to a trap handler while executing the instruction,
then Debug Mode is re-entered immediately after the PC is changed to the trap
handler, and the appropriate {\tt tval} and {\tt cause} registers are updated.
In this case none of the trap handler is executed, and if the cause was a
pending interrupt no instructions might be executed at all.
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 \FcsrDcsrCause 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 occur 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 {\tt wfi} and would normally stall the
hart, then instead the instruction is treated as {\tt nop}.
\subsection{Icount Trigger}
Native debuggers won't have access to \RcsrDcsr, but can use the \RcsrIcount
trigger by setting \FcsrIcountCount to 1.
\begin{steps}{This approach does have some limitations:}
\item Interrupts will fire as usual. Debuggers that want to disable
interrupts while stepping must disable them by changing \Rmstatus, and
specially handle instructions that read \Rmstatus.
\item {\tt wfi} instructions are not treated specially and might take a
very long time to complete.
\end{steps}
\section{Reset}
If the halt signal (driven by the hart's halt request bit in the Debug Module)
or \Fresethaltreq 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.
\section{Resume}
\begin{steps}{When a hart resumes:}
\item \Rpc changes to the value stored in \RcsrDpc.
\item The current privilege mode is changed to that specified by
\FcsrDcsrPrv.
\item If the new privilege mode is less privileged than M mode,
\FcsrMcontrolMprv in \Rmstatus is cleared.
\item The hart is no longer in debug mode.
\end{steps}
\section{{\tt dret} Instruction} \label{dret}
To return from Debug Mode, a new instruction is defined: {\tt dret}. It has an
encoding of 0x7b200073. On harts which support this instruction,
executing {\tt dret} in Debug Mode cause the hart to resume as described above.
Executing {\tt dret} outside of Debug Mode causes an illegal instruction exception.
It is not necessary for the debugger to know whether an implementation supports
{\tt 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.
\section{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 \Rmisa) and to clearly
communicate this to the user.
\section{Core Debug Registers} \label{debreg}
The supported Core Debug Registers must be implemented for each hart that can
be debugged. They are CSRs, accessible using the RISC-V {\tt csr} opcodes and
optionally also using abstract debug commands.
\input{core_registers.tex}
\section{Virtual Debug Registers} \label{virtreg}
\input{sw_registers.tex}