OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [docs/] [datasheet/] [on_chip_debugger.adoc] - Blame information for rev 62

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 60 zero_gravi
<<<
2
:sectnums:
3
== On-Chip Debugger (OCD)
4
 
5
The NEORV32 Processor features an _on-chip debugger_ (OCD) implementing **execution-based debugging** that is compatible
6
to the **Minimal RISC-V Debug Specification Version 0.13.2**.
7
Please refer to this spec for in-deep information.
8
A copy of the specification is available in `docs/references/riscv-debug-release.pdf`.
9
The NEORV32 OCD provides the following key features:
10
 
11
* JTAG test access port
12
* run-control of the CPU: halting, single-stepping and resuming
13
* executing arbitrary programs during debugging
14
* accessing core registers (direct access to GPRs, indirect access to CSRs via program buffer)
15
* indirect access to the whole processor address space (via program buffer))
16
* compatible to the https://github.com/riscv/riscv-openocd[RISC-V port of OpenOCD];
17
  pre-built binaries can be obtained for example from https://www.sifive.com/software[SiFive]
18
 
19 61 zero_gravi
.OCD Security Note
20
[IMPORTANT]
21
Access via the OCD is _always authenticated_ (`dmstatus.authenticated` == `1`). Hence, the
22
_whole system_ can always be accessed via the on-chip debugger.
23
 
24 60 zero_gravi
[NOTE]
25
The OCD requires additional resources for implementation and _might_ also increase the critical path resulting in less
26
performance. If the OCD is not really required for the _final_ implementation, it can be disabled and thus,
27
discarded from implementation. In this case all circuitry of the debugger is completely removed (no impact
28
on area, energy or timing at all).
29
 
30
[TIP]
31
A simple example on how to use NEORV32 on-chip debugger in combination with `OpenOCD` and `gdb`
32 62 zero_gravi
is shown in section https://stnolting.github.io/neorv32/ug/#_debugging_using_the_on_chip_debugger[Debugging using the On-Chip Debugger]
33
of the User Guide.
34 60 zero_gravi
 
35
The NEORV32 on-chip debugger complex is based on three hardware modules:
36
 
37
.NEORV32 on-chip debugger complex
38
image::neorv32_ocd_complex.png[align=center]
39
 
40
[start=1]
41
. <<_debug_transport_module_dtm>> (`rtl/core/neorv32_debug_dtm.vhd`): External JTAG access tap to allow an external
42
  adapter to interface with the _debug module(DM)_ using the _debug module interface (dmi)_.
43
. <<_debug_module_dm>> (`rtl/core/neorv32_debug_tm.vhd`): Debugger control unit that is configured by the DTM via the
44
  the _dmi_. Form the CPU's "point of view" this module behaves as a memory-mapped "peripheral" that can be accessed
45
  via the processor-internal bus. The memory-mapped registers provide an internal _data buffer_ for data transfer
46
  from/to the DM, a _code ROM_ containing the "park loop" code,   a _program buffer_ to allow the debugger to
47
  execute small programs defined by the DM and a _status register_ that is used to communicate
48
  _halt_, _resume_ and _execute_ requests/acknowledges from/to the DM.
49
. CPU <<_cpu_debug_mode>> extension (part of`rtl/core/neorv32_cpu_control.vhd`):
50
  This extension provides the "debug execution mode" which executes the "park loop" code from the DM.
51
  The mode also provides additional CSRs.
52
 
53
**Theory of Operation**
54
 
55
When debugging the system using the OCD, the debugger issues a halt request to the CPU (via the CPU's
56
`db_halt_req_i` signal) to make the CPU enter _debug mode_. In this state, the application-defined architectural
57
state of the system/CPU is "frozen" so the debugger can monitor and even modify it.
58
While in debug mode, the CPU executes the "park loop" code from the _code ROM_ of the DM.
59
This park loop implements an endless loop, in which the CPU polls the memory-mapped _status register_ that is
60
controlled by the _debug module (DM)_. The flags of these register are used to communicate _requests_ from
61
the DM and to _acknowledge_ them by the CPU: trigger execution of the program buffer or resume the halted
62
application.
63
 
64
 
65
 
66
<<<
67
// ####################################################################################################################
68
:sectnums:
69
=== Debug Transport Module (DTM)
70
 
71
The debug transport module (VHDL module: `rtl/core/neorv32_debug_dtm.vhd`) provides a JTAG test access port (TAP).
72
The DTM is the first entity in the debug system, which connects and external debugger via JTAG to the next debugging
73
entity: the debug module (DM).
74 61 zero_gravi
External JTAG access is provided by the following top-level ports.
75 60 zero_gravi
 
76
.JTAG top level signals
77
[cols="^2,^2,^2,<8"]
78
[options="header",grid="rows"]
79
|=======================
80
| Name          | Width | Direction | Description
81
| `jtag_trst_i` | 1     | in        | TAP reset (low-active); this signal is optional, make sure to pull it _high_ if it is not used
82
| `jtag_tck_i`  | 1     | in        | serial clock
83
| `jtag_tdi_i`  | 1     | in        | serial data input
84
| `jtag_tdo_o`  | 1     | out       | serial data output
85
| `jtag_tms_i`  | 1     | in        | mode select
86
|=======================
87
 
88
.JTAG Clock
89
[IMPORTANT]
90
The actual JTAG clock signal is **not** used as primary clock. Instead it is used to synchronize
91
JTGA accesses, while all internal operations trigger on the system clock. Hence, no additional clock domain is required
92
for integration of this module.
93
However, this constraints the maximal JTAG clock (`jtag_tck_i`) frequency to be less than or equal to
94
1/4 of the system clock (`clk_i`) frequency.
95
 
96
[NOTE]
97
If the on-chip debugger is disabled (_ON_CHIP_DEBUGGER_EN_ = false) the JTAG serial input `jtag_tdi_i` is directly
98
connected to the JTAG serial output `jtag_tdo_o` to maintain the JTAG chain.
99
 
100
[WARNING]
101
The NEORV32 JTAG TAP does not provide a _boundary check_ function (yet?). Hence, physical device pins cannot be accessed.
102
 
103
The DTM uses the "debug module interface (dmi)" to access the actual debug module (DM).
104
These accesses are controlled by TAP-internal registers.
105
Each registers is selected by the JTAG instruction register (`IR`) and accessed through the JTAG data register (`DR`).
106
 
107
[NOTE]
108
The DTM's instruction and data registers can be accessed using OpenOCDs `irscan` and `drscan` commands.
109
The RISC-V port of OpenOCD also provides low-level command (`riscv dmi_read` & `riscv dmi_write`) to access the _dmi_
110
debug module interface.
111
 
112
JTAG access is conducted via the *instruction register* `IR`, which is 5 bit wide, and several *data registers* `DR`
113
with different sizes.
114
The data registers are accessed by writing the according address to the instruction register.
115
The following table shows the available data registers:
116
 
117
.JTAG TAP registers
118
[cols="^2,^2,^2,<8"]
119
[options="header",grid="rows"]
120
|=======================
121
| Address (via `IR`) | Name     | Size [bits] | Description
122
| `00001`            | `IDCODE` | 32          | identifier, default: `0x0CAFE001` (configurable via package's `jtag_tap_idcode_*` constants)
123
| `10000`            | `DTMCS`  | 32          | debug transport module control and status register
124
| `10001`            | `DMI`    | 41          | debug module interface (_dmi_); 7-bit address, 32-bit read/write data, 2-bit operation (`00` = NOP; `10` = write; `01` = read)
125
| others             | `BYPASS` | 1           | default JTAG bypass register
126
|=======================
127
 
128
[INFO]
129
See the https://github.com/riscv/riscv-debug-spec[RISC-V debug specification] for more information regarding the data
130
registers and operations.
131
A local copy can be found in `docs/references`.
132
 
133
 
134
 
135
<<<
136
// ####################################################################################################################
137
:sectnums:
138
=== Debug Module (DM)
139
 
140
According to the RISC-V debug specification, the DM (VHDL module: `rtl/core/neorv32_debug_dm.vhd`)
141
acts as a translation interface between abstract operations issued by the debugger and the platform-specific
142
debugger implementation. It supports the following features (excerpt from the debug spec):
143
 
144
* Gives the debugger necessary information about the implementation.
145
* Allows the hart to be halted and resumed and provides status of the current state.
146
* Provides abstract read and write access to the halted hart's GPRs.
147
* Provides access to a reset signal that allows debugging from the very first instruction after reset.
148
* Provides a mechanism to allow debugging the hart immediately out of reset. (_still experimental_)
149
* Provides a Program Buffer to force the hart to execute arbitrary instructions.
150
* Allows memory access from a hart's point of view.
151
 
152
The NEORV32 DM follows the "Minimal RISC-V External Debug Specification" to provide full debugging
153
capabilities while keeping resource (area) requirements at a minimum level.
154
It implements the **execution based debugging scheme** for a single hart and provides the following
155
hardware features:
156
 
157
* program buffer with 2 entries and implicit `ebreak` instruction afterwards
158
* no _direct_ bus access (indirect bus access via the CPU)
159
* abstract commands: "access register" plus auto-execution
160
* no _dedicated_ halt-on-reset capabilities yet (but can be emulated)
161
 
162
The DM provides two "sides of access": access from the DTM via the _debug module interface (dmi)_ and access from the
163
CPU via the processor-internal bus. From the DTM's point of view, the DM implements a set of <<_dm_registers>> that
164
are used to control and monitor the actual debugging. From the CPU's point of view, the DM implements several
165
memory-mapped registers (within the _normal_ address space) that are used for communicating debugging control
166
and status (<<_dm_cpu_access>>).
167
 
168
 
169
:sectnums:
170
==== DM Registers
171
 
172
The DM is controlled via a set of registers that are accessed via the DTM's _dmi_.
173
The "Minimal RISC-V Debug Specification" requires only a subset of the registers specified in the spec.
174
The following registers are implemented.
175
Write accesses to any other registers are ignored and read accesses will always return zero.
176
Register names that are encapsulated in "( )" are not actually implemented; however, they are listed to explicitly show
177
their functionality.
178
 
179
.Available DM registers
180
[cols="^2,^3,<7"]
181
[options="header",grid="rows"]
182
|=======================
183
| Address | Name           | Description
184
|  `0x04` | `data0`        | Abstract data 0, used for data transfer between debugger and processor
185
|  `0x10` | `dmcontrol`    | Debug module control
186
|  `0x11` | `dmstatus`     | Debug module status
187
|  `0x12` | `hartinfo`     | Hart information
188
|  `0x16` | `abstracts`    | Abstract control and status
189
|  `0x17` | `command`      | Abstract command
190
|  `0x18` | `abstractauto` | Abstract command auto-execution
191
|  `0x1d` | (`nextdm`)     | Base address of _next_ DM; read as zero to indicate there is only _one_ DM
192
|  `0x20` | `progbuf0`     | Program buffer 0
193
|  `0x21` | `progbuf1`     | Program buffer 1
194
|  `0x38` | (`sbcs`)       | System bus access control and status; read as zero to indicate there is no _direct_ system bus access
195
|  `0x40` | `haltsum0`     | Halt summary 0
196
|=======================
197
 
198
 
199
:sectnums!:
200
===== **`data`**
201
 
202
[cols="4,27,>7"]
203
[frame="topbot",grid="none"]
204
|======
205
| 0x04 | **Abstract data 0** | `data0`
206
3+| Reset value: _UNDEFINED_
207
3+| Basic read/write registers to be used with abstract command (for example to read/write data from/to CPU GPRs).
208
|======
209
 
210
 
211
:sectnums!:
212
===== **`dmcontrol`**
213
 
214
[cols="4,27,>7"]
215
[frame="topbot",grid="none"]
216
|======
217
| 0x10 | **Debug module control register** | `dmcontrol`
218
3+| Reset value: 0x00000000
219
3+| Control of the overall debug module and the hart. The following table shows all implemented bits. All remaining bits/bit-fields are configures as "zero" and are
220
read-only. Writing '1' to these bits/fields will be ignored.
221
|======
222
 
223
.`dmcontrol` - debug module control register bits
224
[cols="^1,^2,^1,<8"]
225
[options="header",grid="rows"]
226
|=======================
227
| Bit | Name [RISC-V]  | R/W | Description
228
| 31  | `haltreq`      | -/w | set/clear hart halt request
229
| 30  | `resumereq`    | -/w | request hart to resume
230
| 28  | `ackhavereset` | -/w | write `1` to clear `*havereset` flags
231
|  1  | `ndmreset`     | r/w | put whole processor into reset when `1`
232
|  0  | `dmactive`     | r/w | DM enable; writing `0`-`1` will reset the DM
233
|=======================
234
 
235
 
236
:sectnums!:
237
===== **`dmstatus`**
238
 
239
[cols="4,27,>7"]
240
[frame="topbot",grid="none"]
241
|======
242
| 0x11 | **Debug module status register** | `dmstatus`
243
3+| Reset value: 0x00000000
244
3+| Current status of the overall debug module and the hart. The entire register is read-only.
245
|======
246
 
247
.`dmstatus` - debug module status register bits
248
[cols="^1,^2,<10"]
249
[options="header",grid="rows"]
250
|=======================
251
| Bit   | Name [RISC-V]     | Description
252
| 31:23 | _reserved_        | reserved; always zero
253
| 22    | `impebreak`       | always `1`; indicates an implicit `ebreak` instruction after the last program buffer entry
254
| 21:20 | _reserved_        | reserved; always zero
255
| 19    | `allhavereset`    .2+| `1` when the hart is in reset
256
| 18    | `anyhavereset`
257
| 17    | `allresumeack`    .2+| `1` when the hart has acknowledged a resume request
258
| 16    | `anyresumeack`
259
| 15    | `allnonexistent`  .2+| always zero to indicate the hart is always existent
260
| 14    | `anynonexistent`
261
| 13    | `allunavail`      .2+| `1` when the DM is disabled to indicate the hart is unavailable
262
| 12    | `anyunavail`
263
| 11    | `allrunning`      .2+| `1` when the hart is running
264
| 10    | `anyrunning`
265
|  9    | `allhalted`       .2+| `1` when the hart is halted
266
|  8    | `anyhalted`
267
|  7    | `authenticated`   | always `1`; there is no authentication
268
|  6    | `authbusy`        | always `0`; there is no authentication
269
|  5    | `hasresethaltreq` | always `0`; halt-on-reset is not supported (directly)
270
|  4    | `confstrptrvalid` | always `0`; no configuration string available
271
| 3:0   | `version`         | `0010` - DM is compatible to version 0.13
272
|=======================
273
 
274
 
275
:sectnums!:
276
===== **`hartinfo`**
277
 
278
[cols="4,27,>7"]
279
[frame="topbot",grid="none"]
280
|======
281
| 0x12 | **Hart information** | `hartinfo`
282
3+| Reset value: see below
283
3+| This register gives information about the hart. The entire register is read-only.
284
|======
285
 
286
.`hartinfo` - hart information register bits
287
[cols="^1,^2,<8"]
288
[options="header",grid="rows"]
289
|=======================
290
| Bit   | Name [RISC-V] | Description
291
| 31:24 | _reserved_    | reserved; always zero
292
| 23:20 | `nscratch`    | `0001`, number of `dscratch*` CPU registers = 1
293
| 19:17 | _reserved_    | reserved; always zero
294
| 16    | `dataccess`   | `0`, the `data` registers are shadowed in the hart's address space
295
| 15:12 | `datasize`    | `0001`, number of 32-bit words in the address space dedicated to shadowing the `data` registers = 1
296
| 11:0  | `dataaddr`    | = `dm_data_base_c(11:0)`, signed base address of `data` words (see address map in <<_dm_cpu_access>>)
297
|=======================
298
 
299
 
300
:sectnums!:
301
===== **`abstracts`**
302
 
303
[cols="4,27,>7"]
304
[frame="topbot",grid="none"]
305
|======
306
| 0x16 | **Abstract control and status** | `abstracts`
307
3+| Reset value: see below
308
3+| Command execution info and status.
309
|======
310
 
311
.`abstracts` - abstract control and status register bits
312
[cols="^1,^2,^1,<8"]
313
[options="header",grid="rows"]
314
|=======================
315
| Bit   | Name [RISC-V] | R/W | Description
316
| 31:29 | _reserved_    | r/- | reserved; always zero
317
| 28:24 | `progbufsize` | r/- | `0010`; size of the program buffer (`progbuf`) = 2 entries
318
| 23:11 | _reserved_    | r/- | reserved; always zero
319
| 12    | `busy`        | r/- | `1` when a command is being executed
320
| 11    | _reserved_    | r/- | reserved; always zero
321
| 10:8  | `cmerr`       | r/w | error during command execution (see below); has to be cleared by writing `111`
322
| 7:4   | _reserved_    | r/- | reserved; always zero
323
| 3:0   | `datacount`   | r/- | `0001`; number of implemented `data` registers for abstract commands = 1
324
|=======================
325
 
326
Error codes in `cmderr` (highest priority first):
327
 
328
* `000` - no error
329
* `100` - command cannot be executed since hart is not in expected state
330
* `011` - exception during command execution
331
* `010` - unsupported command
332
* `001` - invalid DM register read/write while command is/was executing
333
 
334
 
335
:sectnums!:
336
===== **`command`**
337
 
338
[cols="4,27,>7"]
339
[frame="topbot",grid="none"]
340
|======
341
| 0x17 | **Abstract command** | `command`
342
3+| Reset value: 0x00000000
343
3+| Writing this register will trigger the execution of an abstract command. New command can only be executed if
344
`cmderr` is zero. The entire register in write-only (reads will return zero).
345
|======
346
 
347
[NOTE]
348
The NEORV32 DM only supports **Access Register** abstract commands. These commands can only access the
349
hart's GPRs (abstract command register index `0x1000` - `0x101f`).
350
 
351
.`command` - abstract command register - "access register" commands only
352
[cols="^1,^2,<8"]
353
[options="header",grid="rows"]
354
|=======================
355
| Bit   | Name [RISC-V]      | Description / required value
356
| 31:24 | `cmdtype`          | `00000000` to indicate "access register" command
357
| 23    | _reserved_         | reserved, has to be `0` when writing
358
| 22:20 | `aarsize`          | `010` to indicate 32-bit accesses
359
| 21    | `aarpostincrement` | `0`, postincrement is not supported
360
| 18    | `postexec`         | if set the program buffer is executed _after_ the command
361
| 17    | `transfer`         | if set the operation in `write` is conducted
362
| 16    | `write`            | `1`: copy `data0` to `[regno]`; `0` copy `[regno]` to `data0`
363
| 15:0  | `regno`            | GPR-access only; has to be `0x1000` - `0x101f`
364
|=======================
365
 
366
 
367
:sectnums!:
368
===== **`abstractauto`**
369
 
370
[cols="4,27,>7"]
371
[frame="topbot",grid="none"]
372
|======
373
| 0x18 | **Abstract command auto-execution** | `abstractauto`
374
3+| Reset value: 0x00000000s
375
3+| Register to configure when a read/write access to a DM repeats execution of the last abstract command.
376
|======
377
 
378
.`abstractauto` - Abstract command auto-execution register bits
379
[cols="^1,^2,^1,<8"]
380
[options="header",grid="rows"]
381
|=======================
382
| Bit   | Name [RISC-V]        | R/W | Description
383
| 17    | `autoexecprogbuf[1]` | r/w | when set reading/writing from/to `progbuf1` will execute `command again`
384
| 16    | `autoexecprogbuf[0]` | r/w | when set reading/writing from/to `progbuf0` will execute `command again`
385
|  0    | `autoexecdata[0]`    | r/w | when set reading/writing from/to `data0` will execute `command again`
386
|=======================
387
 
388
 
389
:sectnums!:
390
===== **`progbuf`**
391
 
392
[cols="4,27,>7"]
393
[frame="topbot",grid="none"]
394
|======
395
| 0x20 | **Program buffer 0** | `progbuf0`
396
| 0x21 | **Program buffer 1** | `progbuf1`
397
3+| Reset value: `NOP`-instruction
398
3+| General purpose program buffer for the DM.
399
|======
400
 
401
 
402
:sectnums!:
403
===== **`haltsum0`**
404
 
405
[cols="4,27,>7"]
406
[frame="topbot",grid="none"]
407
|======
408
| 0x40 | **Halt summary 0** | `haltsum0`
409
3+| Reset value: _UNDEFINED_
410
3+| Bit 0 of this register is set if the hart is halted (all remaining bits are always zero). The entire register is read-only.
411
|======
412
 
413
:sectnums:
414
==== DM CPU Access
415
 
416
From the CPU's point of view, the DM behaves as a memory-mapped peripheral that includes
417
 
418
* a small ROM that contains the code for the "park loop", which is executed when the CPU is _in_ debug mode.
419
* a program buffer populated by the debugger host to execute small programs
420
* a data buffer to transfer data between the processor and the debugger host
421
* a status register to communicate debugging requests
422
 
423
.Park Loop Code Sources
424
[NOTE]
425
The assembly sources of the **park loop code** are available in `sw/ocd-firmware/park_loop.S`. Please note, that these
426
sources are not intended to be changed by the used. Hence, the makefile does not provide an automatic option
427
to compile and "install" the debugger ROM code into the HDL sources and require a manual copy
428
(see `sw/ocd-firmware/README.md`).
429
 
430
The DM uses a total address space of 128 words of the CPU's address space (= 512 bytes) divided into four sections
431
of 32 words (= 128 bytes) each.
432
Please note, that the program buffer, the data buffer and the status register only uses a few effective words in this
433
address space. However, these effective addresses are mirrored to fill up the whole 128 bytes of the section.
434
Hence, any CPU access within this address space will succeed.
435
 
436
.DM CPU access - address map (divided into four sections)
437
[cols="^2,^4,^2,<7"]
438
[options="header",grid="rows"]
439
|=======================
440
| Base address | Name [VHDL package]              | Actual size | Description
441
| `0xfffff800` | `dm_code_base_c` (= `dm_base_c`) |   128 bytes | Code ROM for the "park loop" code
442
| `0xfffff880` | `dm_pbuf_base_c`                 |    16 bytes | Program buffer, provided by DM
443
| `0xfffff900` | `dm_data_base_c`                 |     4 bytes | Data buffer (`dm.data0`)
444
| `0xfffff980` | `dm_sreg_base_c`                 |     4 bytes | Control and status register
445
|=======================
446
 
447
[NOTE]
448
From the CPU's point of view, the DM is mapped to an _"unused"_ address range within the processor's
449
<<_address_space>> right between the bootloader ROM (BOOTROM) and the actual processor-internal IO
450
space at addresses `0xfffff800` - `0xfffff9ff`
451
 
452
When the CPU enters or re-enters (for example via `ebreak` in the DM's program buffer) debug mode, it jumps to
453
the beginning of the DM's "park loop" code ROM at `dm_code_base_c`. This is the _normal entry point_ for the
454
park loop code. If an exception is encountered during debug mode, the CPU jumps to `dm_code_base_c + 4`,
455
which is the _exception entry point_.
456
 
457
**Status Register**
458
 
459
The status register provides a direct communication channel between the CPU executing the park loop and the
460
host-controlled controller of the DM. Note that all bits that can be written by the CPU (acknowledge flags)
461
cause a single-shot (1-cycle) signal to the DM controller and auto-clear (always read as zero).
462
The bits that are driven by the DM controller and are read-only to the CPU and keep their state until the CPU
463
acknowledges the according request.
464
 
465
.DM CPU access - status register
466
[cols="^2,^2,^2,<8"]
467
[options="header",grid="rows"]
468
|=======================
469
| Bit | Name            | CPU access | Description
470
| 0   | `halt_ack`      | -/w        | Set by the CPU to indicate that the CPU is halted and keeps iterating in the park loop
471
| 1   | `resume_req`    | r/-        | Set by the DM to tell the CPU to resume normal operation (leave parking loop and leave debug mode via `dret` instruction)
472
| 2   | `resume_ack`    | -/w        | Set by the CPU to acknowledge that the CPU is now going to leave parking loop & debug mode
473
| 3   | `execute_req`   | r/-        | Set by the DM to tell the CPU to leave debug mode and execute the instructions from the program buffer; CPU will re-enter parking loop afterwards
474
| 4   | `execute_ack`   | -/w        | Set by the CPU to acknowledge that the CPU is now going to execute the program buffer
475
| 5   | `exception_ack` | -/w        | Set by the CPU to inform the DM that an exception occurred during execution of the park loop or during execution of the program buffer
476
|=======================
477
 
478
 
479
 
480
<<<
481
// ####################################################################################################################
482
:sectnums:
483
=== CPU Debug Mode
484
 
485
The NEORV32 CPU Debug Mode `DB` (part of `rtl/core/neorv32_cpu_control.vhd`) is compatible to the "Minimal RISC-V Debug Specification 0.13.2".
486
It is enabled/implemented by setting the CPU generic _CPU_EXTENSION_RISCV_DEBUG_ to "true" (done by setting processor
487
generic _ON_CHIP_DEBUGGER_EN_).
488
It provides a new operation mode called "debug mode".
489
When enabled, three additional CSRs are available (section <<_cpu_debug_mode_csrs>>) and also the "return from debug mode"
490
instruction `dret` is available when the CPU is "in" debug mode.
491
 
492
[IMPORTANT]
493
The CPU _debug mode_ requires the `Zicsr` CPU extension to be implemented (top generic _CPU_EXTENSION_RISCV_Zicsr_ = true).
494
 
495
The CPU debug mode is entered when one of the following events appear:
496
 
497
[start=1]
498
. executing `ebreak` instruction (when `dcsr.ebreakm` is set and in machine mode OR when `dcsr.ebreaku` is set and in user mode)
499
. debug halt request from external DM (via CPU signal `db_halt_req_i`, high-active, triggering on rising-edge)
500
. finished executing of a single instruction while in single-step debugging mode (enabled via `dcsr.step`)
501
 
502
From a hardware point of view, these "entry conditions" are special synchronous (`ebreak` instruction) or asynchronous
503
(single-stepping "interrupt"; halt request "interrupt") traps, that are handled invisibly by the control logic.
504
 
505
Whenever the CPU **enters debug mode** it performs the following operations:
506
 
507
* move `pc` to `dpcs`
508
* copy the hart's current privilege level to `dcsr.prv`
509
* set `dcrs.cause` according to the cause why debug mode is entered
510
* **no update** of `mtval`, `mcause`, `mtval` and `mstatus` CSRs
511
* load the address configured via the CPU _CPU_DEBUG_ADDR_ generic to the `pc` to jump to "debugger park loop" code in the debug module (DM)
512
 
513
When the CPU **is in debug mode** the following things are important:
514
 
515
* while in debug mode, the CPU executes the parking loop and the program buffer provided by the DM if requested
516
* effective CPU privilege level is `machine` mode, PMP is not active
517
* if an exception occurs
518
  * if the exception was caused by any debug-mode entry action the CPU jumps to the _normal entry point_
519
    ( = _CPU_DEBUG_ADDR_) of the park loop again (for example when executing `ebreak` in debug mode)
520
  * for all other exception sources the CPU jumps to the _exception entry point_ ( = _CPU_DEBUG_ADDR_ + 4)
521
    to signal an exception to the DM and restarts the park loop again afterwards
522
* interrupts _including_ non-maskable interrupts are disabled; however, they will be buffered and executed when the CPU has left debug mode
523
* if the DM makes a resume request, the park loop exits and the CPU leaves debug mode (executing `dret`)
524
 
525
Debug mode is left either by executing the `dret` instruction footnote:[`dret` should only be executed _inside_ the debugger
526
"park loop" code (-> code ROM in the debug module (DM).)] (_in_ debug mode) or by performing
527
a hardware reset of the CPU. Executing `dret` outside of debug mode will raise an illegal instruction exception.
528
Whenever the CPU **leaves debug mode** the following things happen:
529
 
530
* set the hart's current privilege level according to `dcsr.prv`
531
* restore `pc` from `dpcs`
532
* resume normal operation at `pc`
533
 
534
 
535
:sectnums:
536
==== CPU Debug Mode CSRs
537
 
538
Two additional CSRs are required by the _Minimal RISC-V Debug Specification_: The debug mode control and status register
539
`dcsr` and the program counter `dpc`. Providing a general purpose scratch register for debug mode (`dscratch0`) allows
540
faster execution of program provided by the debugger, since _one_ general purpose register can be backup-ed and
541
directly used.
542
 
543
[NOTE]
544
The debug-mode control and status registers (CSRs) are only accessible when the CPU is _in_ debug mode.
545
If these CSRs are accessed outside of debug mode (for example when in `machine` mode) an illegal instruction exception
546
is raised.
547
 
548
 
549
:sectnums!:
550
===== **`dcsr`**
551
 
552
[cols="4,27,>7"]
553
[frame="topbot",grid="none"]
554
|======
555
| 0x7b0 | **Debug control and status register** | `dcsr`
556
3+| Reset value: 0x00000000
557
3+| The `dcsr` CSR is compatible to the RISC-V debug spec. It is used to configure debug mode and provides additional status information.
558
The following bits are implemented. The reaming bits are read-only and always read as zero.
559
|======
560
 
561
.Debug control and status register bits
562
[cols="^1,^2,^1,<8"]
563
[options="header",grid="rows"]
564
|=======================
565
| Bit   | Name [RISC-V] | R/W | Event
566
| 31:28 | `xdebugver` | r/- | always `0100` - indicates external debug support exists
567
| 27:16 | -           | r/- | _reserved_, read as zero
568
| 15    | `ebereakm`  | r/w | `ebreak` instructions in `machine` mode will _enter_ debug mode when set
569
| 14    | [line-through]#`ebereakh`# | r/- | `0` - hypervisor mode not supported
570
| 13    | [line-through]#`ebereaks`# | r/- | `0` - supervisor mode not supported
571
| 12    | `ebereaku`  | r/w | `ebreak` instructions in `user` mode will _enter_ debug mode when set
572
| 11    | [line-through]#`stepie`# | r/- | `0` - IRQs are disabled during single-stepping
573
| 10    | [line-through]#`stopcount`# | r/- | `0` - counters increment as usual
574
| 9     | [line-through]#`stoptime`#  | r/- | `0` - timers increment as usual
575
| 8:6   | `cause`     | r/- | cause identifier - why was debug mode entered
576
| 5     | -           | r/- | _reserved_, read as zero
577
| 4     | `mprven`    | r/- | `0` - `mstatus.mprv` is ignored when in debug mode
578
| 3     | `nmip`      | r/- | set when the non-maskable CPU/processor interrupt is pending
579
| 2     | `step`      | r/w | enable single-stepping when set
580
| 1:0   | `prv`       | r/w | CPU privilege level before/after debug mode
581
|=======================
582
 
583
 
584
:sectnums!:
585
===== **`dpc`**
586
 
587
[cols="4,27,>7"]
588
[frame="topbot",grid="none"]
589
|======
590
| 0x7b1 | **Debug program counter** | `dpc`
591
3+| Reset value: _UNDEFINED_
592
3+| The `dcsr` CSR is compatible to the RISC-V debug spec. It is used to store the current program counter when
593
debug mode is entered. The `dret` instruction will return to `dpc` by moving `dpc` to `pc`.
594
|======
595
 
596
 
597
:sectnums!:
598
===== **`dscratch0`**
599
 
600
[cols="4,27,>7"]
601
[frame="topbot",grid="none"]
602
|======
603
| 0x7b2 | **Debug scratch register 0** | `dscratch0`
604
3+| Reset value: _UNDEFINED_
605
3+| The `dscratch0` CSR is compatible to the RISC-V debug spec. It provides a general purpose debug mode-only scratch register.
606
|======
607
 
608
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.