<<<
:sectnums:
== On-Chip Debugger (OCD)

The NEORV32 Processor features an _on-chip debugger_ (OCD) implementing **execution-based debugging** that is compatible
to the **Minimal RISC-V Debug Specification Version 0.13.2**. Please refer to this spec for in-deep information.
A copy of the specification is available in `docs/references/riscv-debug-release.pdf`.

The NEORV32 OCD provides the following key features:

* JTAG access port
* run-control of the CPU: halting, single-stepping and resuming
* executing arbitrary programs during debugging
* accessing core registers
* indirect access to the whole processor address space (via program buffer)
* trigger module for hardware breakpoints
* compatible with upstream OpenOCD

.OCD Security Note
[NOTE]
Access via the OCD is _always authenticated_ (`dmstatus.authenticated` == `1`). Hence, the
_whole system_ can always be accessed via the on-chip debugger. Currently, there is no option
to disable the OCD via software. The OCD can only be disabled by disabling implementation
(setting _ON_CHIP_DEBUGGER_EN_ generic to _false_).

.Hands-On Tutorial
[TIP]
A simple example on how to use NEORV32 on-chip debugger in combination with OpenOCD and the GNU debugger
is shown in section https://stnolting.github.io/neorv32/ug/#_debugging_using_the_on_chip_debugger[Debugging using the On-Chip Debugger]
of the User Guide.

The NEORV32 on-chip debugger complex is based on four hardware modules:

.NEORV32 on-chip debugger complex
image::neorv32_ocd_complex.png[align=center]

[start=1]
. <<_debug_transport_module_dtm>> (`rtl/core/neorv32_debug_dtm.vhd`): External JTAG access tap to allow an external
  adapter to interface with the _debug module(DM)_ using the _debug module interface (dmi)_.
. <<_debug_module_dm>> (`rtl/core/neorv32_debug_tm.vhd`): Debugger control unit that is configured by the DTM via the
  the _dmi_. Form the CPU's "point of view" this module behaves as a memory-mapped "peripheral" that can be accessed
  via the processor-internal bus. The memory-mapped registers provide an internal _data buffer_ for data transfer
  from/to the DM, a _code ROM_ containing the "park loop" code,   a _program buffer_ to allow the debugger to
  execute small programs defined by the DM and a _status register_ that is used to communicate
  _halt_, _resume_ and _execute_ requests/acknowledges from/to the DM.
. CPU <<_cpu_debug_mode>> extension (part of`rtl/core/neorv32_cpu_control.vhd`):
  This extension provides the "debug execution mode" which executes the "park loop" code from the DM.
  The mode also provides additional CSRs.
. (CPU <<_trigger_module>> (also part of`rtl/core/neorv32_cpu_control.vhd`):
  This module provides a single _hardware_ breakpoint, which allows to debug code executed from ROM.)

**Theory of Operation**

When debugging the system using the OCD, the debugger issues a halt request to the CPU (via the CPU's
`db_halt_req_i` signal) to make the CPU enter _debug mode_. In this state, the application-defined architectural
state of the system/CPU is "frozen" so the debugger can monitor and even modify it.
While in debug mode, the CPU executes the "park loop" code from the _code ROM_ of the DM.
This park loop implements an endless loop, in which the CPU polls the memory-mapped _status register_ that is
controlled by the _debug module (DM)_. The flags of these register are used to communicate _requests_ from
the DM and to _acknowledge_ them by the CPU: trigger execution of the program buffer or resume the halted
application.



<<<
// ####################################################################################################################
:sectnums:
=== Debug Transport Module (DTM)

The debug transport module (VHDL module: `rtl/core/neorv32_debug_dtm.vhd`) provides a JTAG test access port (TAP).
The DTM is the first entity in the debug system, which connects and external debugger via JTAG to the next debugging
entity: the debug module (DM).
External JTAG access is provided by the following top-level ports.

.JTAG top level signals
[cols="^2,^2,^2,<8"]
[options="header",grid="rows"]
|=======================
| Name          | Width | Direction | Description
| `jtag_trst_i` | 1     | in        | TAP reset (low-active); this signal is optional, make sure to pull it _high_ if it is not used
| `jtag_tck_i`  | 1     | in        | serial clock
| `jtag_tdi_i`  | 1     | in        | serial data input
| `jtag_tdo_o`  | 1     | out       | serial data output
| `jtag_tms_i`  | 1     | in        | mode select
|=======================

.Maximum JTAG Clock
[IMPORTANT]
All JTAG signals are synchronized to the processor clock domain by oversampling them in DTM. Hence, no additional
clock domain is required for the DTM. However, this constraints the maximal JTAG clock frequency (`jtag_tck_i`) to be less
than or equal to **1/5** of the processor clock frequency (`clk_i`).

[NOTE]
If the on-chip debugger is disabled (_ON_CHIP_DEBUGGER_EN_ = false) the JTAG serial input `jtag_tdi_i` is directly
connected to the JTAG serial output `jtag_tdo_o` to maintain the JTAG chain.

[WARNING]
The NEORV32 JTAG TAP does not provide a _boundary check_ function (yet?). Hence, physical device pins cannot be accessed.

The DTM uses the "debug module interface (dmi)" to access the actual debug module (DM).
These accesses are controlled by TAP-internal registers.
Each registers is selected by the JTAG instruction register (`IR`) and accessed through the JTAG data register (`DR`).

[NOTE]
The DTM's instruction and data registers can be accessed using OpenOCDs `irscan` and `drscan` commands.
The RISC-V port of OpenOCD also provides low-level command (`riscv dmi_read` & `riscv dmi_write`) to access the _dmi_
debug module interface.

JTAG access is conducted via the *instruction register* `IR`, which is 5 bit wide, and several *data registers* `DR`
with different sizes.
The data registers are accessed by writing the according address to the instruction register.
The following table shows the available data registers:

.JTAG TAP registers
[cols="^2,^2,^2,<8"]
[options="header",grid="rows"]
|=======================
| Address (via `IR`) | Name     | Size [bits] | Description
| `00001`            | `IDCODE` | 32          | identifier, default: `0x0CAFE001` (configurable via package's `jtag_tap_idcode_*` constants)
| `10000`            | `DTMCS`  | 32          | debug transport module control and status register
| `10001`            | `DMI`    | 41          | debug module interface (_dmi_); 7-bit address, 32-bit read/write data, 2-bit operation (`00` = NOP; `10` = write; `01` = read)
| others             | `BYPASS` | 1           | default JTAG bypass register
|=======================

.`DTMCS` - DTM Control and Status Register
[cols="^2,^3,^1,<8"]
[options="header",grid="rows"]
|=======================
| Bit(s) | Name           | r/w | Description
| 31:18  | -              | r/- | _reserved_, hardwired to zero
| 17     | `dmihardreset` | r/w | setting this bit will reset the DM interface; this bit auto-clears
| 16     | `dmireset`     | r/w | setting this bit will clear ste sticky error state; this bit auto-clears
| 15     | -              | r/- | _reserved_, hardwired to zero
| 14:12  | `idle`         | r/- | recommended idle states (= 0, no idle states required)
| 11:10  | `dmistat`      | r/- | DMI statu: `00` = no error, `01` = reserved, `10` = operation failed, `11` = failed operation during pending DMI operation
| 9:4    | `abits`        | r/- | number of DMI address bits (= 7)
| 3:0    | `version`      | r/- | `0001` = spec version 0.13
|=======================

[INFO]
See the https://github.com/riscv/riscv-debug-spec[RISC-V debug specification] for more information regarding the data
registers and operations. A local copy can be found in `docs/references`.



<<<
// ####################################################################################################################
:sectnums:
=== Debug Module (DM)

According to the RISC-V debug specification, the DM (VHDL module: `rtl/core/neorv32_debug_dm.vhd`)
acts as a translation interface between abstract operations issued by the debugger and the platform-specific
debugger implementation. It supports the following features (excerpt from the debug spec):

* Gives the debugger necessary information about the implementation.
* Allows the hart to be halted and resumed and provides status of the current state.
* Provides abstract read and write access to the halted hart's GPRs.
* Provides access to a reset signal that allows debugging from the very first instruction after reset.
* Provides a mechanism to allow debugging the hart immediately out of reset. (_still experimental_)
* Provides a Program Buffer to force the hart to execute arbitrary instructions.
* Allows memory access from a hart's point of view.

The NEORV32 DM follows the "Minimal RISC-V External Debug Specification" to provide full debugging
capabilities while keeping resource (area) requirements at a minimum level.
It implements the **execution based debugging scheme** for a single hart and provides the following
hardware features:

* program buffer with 2 entries and implicit `ebreak` instruction afterwards
* no _direct_ bus access (indirect bus access via the CPU)
* abstract commands: "access register" plus auto-execution
* no _dedicated_ halt-on-reset capabilities yet (but can be emulated)

The DM provides two "sides of access": access from the DTM via the _debug module interface (dmi)_ and access from the
CPU via the processor-internal bus. From the DTM's point of view, the DM implements a set of <<_dm_registers>> that
are used to control and monitor the actual debugging. From the CPU's point of view, the DM implements several
memory-mapped registers (within the _normal_ address space) that are used for communicating debugging control
and status (<<_dm_cpu_access>>).


:sectnums:
==== DM Registers

The DM is controlled via a set of registers that are accessed via the DTM's _dmi_.
The "Minimal RISC-V Debug Specification" requires only a subset of the registers specified in the spec.
The following registers are implemented.
Write accesses to any other registers are ignored and read accesses will always return zero.
Register names that are encapsulated in "( )" are not actually implemented; however, they are listed to explicitly show
their functionality.

.Available DM registers
[cols="^2,^3,<7"]
[options="header",grid="rows"]
|=======================
| Address | Name           | Description
|  `0x04` | `data0`        | Abstract data 0, used for data transfer between debugger and processor
|  `0x10` | `dmcontrol`    | Debug module control
|  `0x11` | `dmstatus`     | Debug module status
|  `0x12` | `hartinfo`     | Hart information
|  `0x16` | `abstracts`    | Abstract control and status
|  `0x17` | `command`      | Abstract command
|  `0x18` | `abstractauto` | Abstract command auto-execution
|  `0x1d` | (`nextdm`)     | Base address of _next_ DM; read as zero to indicate there is only _one_ DM
|  `0x20` | `progbuf0`     | Program buffer 0
|  `0x21` | `progbuf1`     | Program buffer 1
|  `0x38` | (`sbcs`)       | System bus access control and status; read as zero to indicate there is no _direct_ system bus access
|  `0x40` | `haltsum0`     | Halt summary 0
|=======================


:sectnums!:
===== **`data`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x04 | **Abstract data 0** | `data0`
3+| Reset value: _UNDEFINED_
3+| Basic read/write registers to be used with abstract command (for example to read/write data from/to CPU GPRs).
|======


:sectnums!:
===== **`dmcontrol`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x10 | **Debug module control register** | `dmcontrol`
3+| Reset value: 0x00000000
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
read-only. Writing '1' to these bits/fields will be ignored.
|======

.`dmcontrol` - debug module control register bits
[cols="^1,^2,^1,<8"]
[options="header",grid="rows"]
|=======================
| Bit | Name [RISC-V]  | R/W | Description
| 31  | `haltreq`      | -/w | set/clear hart halt request
| 30  | `resumereq`    | -/w | request hart to resume
| 28  | `ackhavereset` | -/w | write `1` to clear `*havereset` flags
|  1  | `ndmreset`     | r/w | put whole processor into reset when `1`
|  0  | `dmactive`     | r/w | DM enable; writing `0`-`1` will reset the DM
|=======================


:sectnums!:
===== **`dmstatus`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x11 | **Debug module status register** | `dmstatus`
3+| Reset value: 0x00000000
3+| Current status of the overall debug module and the hart. The entire register is read-only.
|======

.`dmstatus` - debug module status register bits
[cols="^1,^2,<10"]
[options="header",grid="rows"]
|=======================
| Bit   | Name [RISC-V]     | Description
| 31:23 | _reserved_        | reserved; always zero
| 22    | `impebreak`       | always `1`; indicates an implicit `ebreak` instruction after the last program buffer entry
| 21:20 | _reserved_        | reserved; always zero
| 19    | `allhavereset`    .2+| `1` when the hart is in reset
| 18    | `anyhavereset`
| 17    | `allresumeack`    .2+| `1` when the hart has acknowledged a resume request
| 16    | `anyresumeack`
| 15    | `allnonexistent`  .2+| always zero to indicate the hart is always existent
| 14    | `anynonexistent`
| 13    | `allunavail`      .2+| `1` when the DM is disabled to indicate the hart is unavailable
| 12    | `anyunavail`
| 11    | `allrunning`      .2+| `1` when the hart is running
| 10    | `anyrunning`
|  9    | `allhalted`       .2+| `1` when the hart is halted
|  8    | `anyhalted`
|  7    | `authenticated`   | always `1`; there is no authentication
|  6    | `authbusy`        | always `0`; there is no authentication
|  5    | `hasresethaltreq` | always `0`; halt-on-reset is not supported (directly)
|  4    | `confstrptrvalid` | always `0`; no configuration string available
| 3:0   | `version`         | `0010` - DM is compatible to version 0.13
|=======================


:sectnums!:
===== **`hartinfo`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x12 | **Hart information** | `hartinfo`
3+| Reset value: see below
3+| This register gives information about the hart. The entire register is read-only.
|======

.`hartinfo` - hart information register bits
[cols="^1,^2,<8"]
[options="header",grid="rows"]
|=======================
| Bit   | Name [RISC-V] | Description
| 31:24 | _reserved_    | reserved; always zero
| 23:20 | `nscratch`    | `0001`, number of `dscratch*` CPU registers = 1
| 19:17 | _reserved_    | reserved; always zero
| 16    | `dataccess`   | `0`, the `data` registers are shadowed in the hart's address space
| 15:12 | `datasize`    | `0001`, number of 32-bit words in the address space dedicated to shadowing the `data` registers (1 register)
| 11:0  | `dataaddr`    | = `dm_data_base_c(11:0)`, signed base address of `data` words (see address map in <<_dm_cpu_access>>)
|=======================


:sectnums!:
===== **`abstracts`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x16 | **Abstract control and status** | `abstracts`
3+| Reset value: see below
3+| Command execution info and status.
|======

.`abstracts` - abstract control and status register bits
[cols="^1,^2,^1,<8"]
[options="header",grid="rows"]
|=======================
| Bit   | Name [RISC-V] | R/W | Description
| 31:29 | _reserved_    | r/- | reserved; always zero
| 28:24 | `progbufsize` | r/- | `0010`; size of the program buffer (`progbuf`) = 2 entries
| 23:11 | _reserved_    | r/- | reserved; always zero
| 12    | `busy`        | r/- | `1` when a command is being executed
| 11    | _reserved_    | r/- | reserved; always zero
| 10:8  | `cmerr`       | r/w | error during command execution (see below); has to be cleared by writing `111`
| 7:4   | _reserved_    | r/- | reserved; always zero
| 3:0   | `datacount`   | r/- | `0001`; number of implemented `data` registers for abstract commands = 1
|=======================

Error codes in `cmderr` (highest priority first):

* `000` - no error
* `100` - command cannot be executed since hart is not in expected state
* `011` - exception during command execution
* `010` - unsupported command
* `001` - invalid DM register read/write while command is/was executing


:sectnums!:
===== **`command`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x17 | **Abstract command** | `command`
3+| Reset value: 0x00000000
3+| Writing this register will trigger the execution of an abstract command. New command can only be executed if
`cmderr` is zero. The entire register in write-only (reads will return zero).
|======

[NOTE]
The NEORV32 DM only supports **Access Register** abstract commands. These commands can only access the
hart's GPRs (abstract command register index `0x1000` - `0x101f`).

.`command` - abstract command register - "access register" commands only
[cols="^1,^2,^1,<8"]
[options="header",grid="rows"]
|=======================
| Bit   | Name [RISC-V]      | R/W | Description / required value
| 31:24 | `cmdtype`          | -/w | `00000000` to indicate "access register" command
| 23    | _reserved_         | -/w | reserved, has to be `0` when writing
| 22:20 | `aarsize`          | -/w | `010` to indicate 32-bit accesses
| 21    | `aarpostincrement` | -/w | `0`, post-increment is not supported
| 18    | `postexec`         | -/w | if set the program buffer is executed _after_ the command
| 17    | `transfer`         | -/w | if set the operation in `write` is conducted
| 16    | `write`            | -/w | `1`: copy `data0` to `[regno]`, `0`: copy `[regno]` to `data0`
| 15:0  | `regno`            | -/w | GPR-access only; has to be `0x1000` - `0x101f`
|=======================


:sectnums!:
===== **`abstractauto`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x18 | **Abstract command auto-execution** | `abstractauto`
3+| Reset value: 0x00000000s
3+| Register to configure when a read/write access to a DM repeats execution of the last abstract command.
|======

.`abstractauto` - Abstract command auto-execution register bits
[cols="^1,^2,^1,<8"]
[options="header",grid="rows"]
|=======================
| Bit   | Name [RISC-V]        | R/W | Description
| 17    | `autoexecprogbuf[1]` | r/w | when set reading/writing from/to `progbuf1` will execute `command again`
| 16    | `autoexecprogbuf[0]` | r/w | when set reading/writing from/to `progbuf0` will execute `command again`
|  0    | `autoexecdata[0]`    | r/w | when set reading/writing from/to `data0` will execute `command again`
|=======================


:sectnums!:
===== **`progbuf`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x20 | **Program buffer 0** | `progbuf0`
| 0x21 | **Program buffer 1** | `progbuf1`
3+| Reset value: `NOP`-instruction
3+| General purpose program buffer (two entries) for the DM.
|======


:sectnums!:
===== **`haltsum0`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x40 | **Halt summary 0** | `haltsum0`
3+| Reset value: _UNDEFINED_
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.
|======

:sectnums:
==== DM CPU Access

From the CPU's point of view, the DM behaves as a memory-mapped peripheral that includes

* a small ROM that contains the code for the "park loop", which is executed when the CPU is _in_ debug mode.
* a program buffer populated by the debugger host to execute small programs
* a data buffer to transfer data between the processor and the debugger host
* a status register to communicate debugging requests

.DM Register Access
[IMPORTANT]
All memory-mapped registers of the DM can only be accessed by the CPU if it is actually _in_ debug mode.
Hence, the DM registers are not "visible" for normal CPU operations.
Any access outside of debug mode will raise a bus error exception.

.Park Loop Code Sources
[NOTE]
The assembly sources of the **park loop code** are available in `sw/ocd-firmware/park_loop.S`. Please note, that these
sources are not intended to be changed by the used. Hence, the makefile does not provide an automatic option
to compile and "install" the debugger ROM code into the HDL sources and require a manual copy
(see `sw/ocd-firmware/README.md`).

The DM uses a total address space of 128 words of the CPU's address space (= 512 bytes) divided into four sections
of 32 words (= 128 bytes) each.
Please note, that the program buffer, the data buffer and the status register only uses a few effective words in this
address space. However, these effective addresses are mirrored to fill up the whole 128 bytes of the section.
Hence, any CPU access within this address space will succeed.

.DM CPU access - address map (divided into four sections)
[cols="^2,^4,^2,<7"]
[options="header",grid="rows"]
|=======================
| Base address | Name [VHDL package]              | Actual size | Description
| `0xfffff800` | `dm_code_base_c` (= `dm_base_c`) |   128 bytes | Code ROM for the "park loop" code
| `0xfffff880` | `dm_pbuf_base_c`                 |    16 bytes | Program buffer, provided by DM
| `0xfffff900` | `dm_data_base_c`                 |     4 bytes | Data buffer (`dm.data0`)
| `0xfffff980` | `dm_sreg_base_c`                 |     4 bytes | Control and status register
|=======================

[NOTE]
From the CPU's point of view, the DM is mapped to an _"unused"_ address range within the processor's
<<_address_space>> right between the bootloader ROM (BOOTROM) and the actual processor-internal IO
space at addresses `0xfffff800` - `0xfffff9ff`

When the CPU enters or re-enters (for example via `ebreak` in the DM's program buffer) debug mode, it jumps to
the beginning of the DM's "park loop" code ROM at `dm_code_base_c`. This is the _normal entry point_ for the
park loop code. If an exception is encountered during debug mode, the CPU jumps to `dm_code_base_c + 4`,
which is the _exception entry point_.

**Status Register**

The status register provides a direct communication channel between the CPU executing the park loop and the
host-controlled controller of the DM. Note that all bits that can be written by the CPU (acknowledge flags)
cause a single-shot (1-cycle) signal to the DM controller and auto-clear (always read as zero).
The bits that are driven by the DM controller and are read-only to the CPU and keep their state until the CPU
acknowledges the according request.

.DM CPU access - status register
[cols="^2,^2,^2,<8"]
[options="header",grid="rows"]
|=======================
| Bit | Name            | CPU access | Description
| 0   | `halt_ack`      | -/w        | Set by the CPU to indicate that the CPU is halted and keeps iterating in the park loop
| 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)
| 2   | `resume_ack`    | -/w        | Set by the CPU to acknowledge that the CPU is now going to leave parking loop & debug mode
| 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
| 4   | `execute_ack`   | -/w        | Set by the CPU to acknowledge that the CPU is now going to execute the program buffer
| 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
|=======================



<<<
// ####################################################################################################################
:sectnums:
=== CPU Debug Mode

The NEORV32 CPU Debug Mode `DB` or `DEBUG` (part of `rtl/core/neorv32_cpu_control.vhd`) is compatible to the
"Minimal RISC-V Debug Specification 0.13.2".
It is enabled/implemented by setting the CPU generic _CPU_EXTENSION_RISCV_DEBUG_ to "true" (done by setting processor
generic _ON_CHIP_DEBUGGER_EN_).
It provides a new operation mode called "debug mode". When enabled, three additional CSRs are available
(section <<_cpu_debug_mode_csrs>>) and the "return from debug mode" instruction `dret` are available.

[IMPORTANT]
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:

[start=1]
. executing the `ebreak` instruction (when in machine-mode and `dcsr.ebreakm` is set OR when in user-mode and `dcsr.ebreaku` is set)
. debug halt request from external DM (via CPU signal `db_halt_req_i`, high-active, triggering on rising-edge)
. finished executing of a single instruction while in single-step debugging mode (enabled via `dcsr.step`)
. hardware trigger by the <<_trigger_module>>

From a hardware point of view, these "entry conditions" are special synchronous (e.g. `ebreak` instruction) and asynchronous
(e.g. halt request "interrupt") traps, that are handled invisibly by the control logic.

**Whenever the CPU enters debug-mode it performs the following operations:**

* wake-up CPU if it was send to sleep mode by the `wfi` instruction
* move `pc` to `dpc`
* copy the hart's current privilege level to `dcsr.prv`
* set `dcrs.cause` according to the cause why debug mode is entered
* **no update** of `mtval`, `mcause`, `mtval` and `mstatus` CSRs
* load the address configured via the CPU's _CPU_DEBUG_ADDR_ generic to the `pc` to jump to the "debugger park loop" code stored in the debug module (DM)

**When the CPU is in debug-mode the following things are important:**

* while in debug mode, the CPU executes the parking loop and the program buffer provided by the DM if requested
* effective CPU privilege level is `machine` mode, any active physical memory protection (PMP) configuration is bypassed
* the `wfi` instruction acts as a `nop` (also during single-stepping)
* if an exception occurs:
** 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)
** for all other exception sources the CPU jumps to the _exception entry point_ ( = _CPU_DEBUG_ADDR_ + 4)
   to signal an exception to the DM; the CPU restarts the park loop again afterwards
* interrupts are disabled; however, they will 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`)
* the standard counters <<_machine_counter_and_timer_csrs>> `[m]cycle[h]` and `[m]instret[h]` are stopped; note that the
<<_machine_system_timer_mtime>> keep running as well as it's shadowed copies in the `[m]time[h]` CSRs
* all <<_hardware_performance_monitors_hpm_csrs>> are stopped

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
a hardware reset of the CPU. Executing `dret` outside of debug mode will raise an illegal instruction exception.

**Whenever the CPU leaves debug mode it performs the following operations:**

* set the hart's current privilege level according to `dcsr.prv`
* restore `pc` from `dpcs`
* resume normal operation at `pc`


:sectnums:
==== CPU Debug Mode CSRs

Two additional CSRs are required by the _Minimal RISC-V Debug Specification_: The debug mode control and status register
`dcsr` and the program counter `dpc`. Providing a general purpose scratch register for debug mode (`dscratch0`) allows
faster execution of program provided by the debugger, since _one_ general purpose register can be backup-ed and
directly used.

[NOTE]
The debug-mode control and status registers (CSRs) are only accessible when the CPU is _in_ debug mode.
If these CSRs are accessed outside of debug mode (for example when in `machine` mode) an illegal instruction exception
is raised.


:sectnums!:
===== **`dcsr`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x7b0 | **Debug control and status register** | `dcsr`
3+| Reset value: 0x40000000
3+| The `dcsr` CSR is compatible to the RISC-V debug spec. It is used to configure debug mode and provides additional status information.
The following bits are implemented. The reaming bits are read-only and always read as zero.
|======

.Debug control and status register `dcsr` bits
[cols="^1,^2,^1,<8"]
[options="header",grid="rows"]
|=======================
| Bit   | Name [RISC-V] | R/W | Description
| 31:28 | `xdebugver`   | r/- | `0100` - indicates external debug support exists
| 27:16 | -             | r/- | `000000000000` - _reserved_
| 15    | `ebereakm`    | r/w | `ebreak` instructions in `machine` mode will _enter_ debug mode when set
| 14    | `ebereakh`    | r/- | `0` - hypervisor mode not supported
| 13    | `ebereaks`    | r/- | `0` - supervisor mode not supported
| 12    | `ebereaku`    | r/w | `ebreak` instructions in `user` mode will _enter_ debug mode when set
| 11    | `stepie`      | r/- | `0` - IRQs are disabled during single-stepping
| 10    | `stopcount`   | r/- | `1` - standard counters and HPMs are stopped when in debug mode
| 9     | `stoptime`    | r/- | `0` - timers increment as usual
| 8:6   | `cause`       | r/- | cause identifier - why debug mode was entered (see below)
| 5     | -             | r/- | `0` - _reserved_
| 4     | `mprven`      | r/- | `0` - `mstatus.mprv` is ignored when in debug mode
| 3     | `nmip`        | r/- | `0` - non-maskable interrupt is pending
| 2     | `step`        | r/w | enable single-stepping when set
| 1:0   | `prv`         | r/w | CPU privilege level before/after debug mode
|=======================

Cause codes in `dcsr.cause` (highest priority first):

* `010` - trigger by hardware <<_trigger_module>>
* `001` - executed EBREAK instruction
* `011` - external halt request (from DM)
* `100` - return from single-stepping


:sectnums!:
===== **`dpc`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x7b1 | **Debug program counter** | `dpc`
3+| Reset value: _UNDEFINED_
3+| The `dcsr` CSR is compatible to the RISC-V debug spec. It is used to store the current program counter when
debug mode is entered. The `dret` instruction will return to `dpc` by moving `dpc` to `pc`.
|======


:sectnums!:
===== **`dscratch0`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x7b2 | **Debug scratch register 0** | `dscratch0`
3+| Reset value: _UNDEFINED_
3+| The `dscratch0` CSR is compatible to the RISC-V debug spec. It provides a general purpose debug mode-only scratch register.
|======


<<<
// ####################################################################################################################
:sectnums:
=== Trigger Module

The NEORV32 trigger module implements a subset of the features described in the "RISC-V Debug Specification / Trigger Module".
It is always implemented when the CPU debug mode / the on-chip debugger is implemented.

[IMPORTANT]
The trigger module only provides a single trigger of _instruction address match_ type. This trigger will fire
**after** the instruction at the specific address has been executed.

The trigger module only provides a single trigger supporting only the "instruction address match" type. This limitation
is granted by the RISC-V specs. and is sufficient to **debug code executed from read-only memory (ROM)**.
"Normal" _software_ breakpoints (using gdb's `b`/`break` command) are implemented by temporarily replacing the according
instruction word by a BREAK instruction. This is not possible when debugging code that is executed from read-only memory
(for example when debugging programs that are executed via the <<_execute_in_place_module_xip>>).
Therefore, the NEORV32 trigger module provides a single "instruction address match" trigger to enter debug mode when
executing the instruction at a specific address. These "hardware-assisted breakpoints" are used by gdb's `hb`/`hbreak` command.


:sectnums:
==== Trigger Module CSRs

The trigger module provides 8 additional CSRs, which accessible in debug mode and also in machine-mode. Since the
trigger module does not support _native mode_ writes from machine-mode software to those CSRs are ignored.
Hence, the CSRs of this module are only relevant for the debugger.


:sectnums!:
===== **`tselect`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x7a0 | **Trigger select register** | `tselect`
3+| Reset value: 0x00000000
3+| This CSR is hardwired to zero indicating there is only one trigger available. Any write access is ignored.
|======


:sectnums!:
===== **`tdata1`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x7a1 | **Trigger data register 1 / match control register** | `tdata1` / `mcontrol`
3+| Reset value: 0x28041048
3+| This CSR is used to configure the address match trigger. Only one bit is writable, the remaining bits are hardwired (see table below).
Write attempts to the hardwired bits are ignored.
|======

.Match control CSR (`tdata1`) bits
[cols="^1,^2,^1,<8"]
[options="header",grid="rows"]
|=======================
| Bit   | Name [RISC-V] | R/W | Description
| 31:28 | `type`        | r/- | `0010` - address match trigger
| 27    | `dmode`       | r/- | `1` - only debug-mode can write to the `tdata*` CSRs
| 26:21 | `maskmax`     | r/- | `000000` - only exact values
| 20    | `hit`         | r/- | `0` - feature not supported
| 19    | `select`      | r/- | `0` - fire trigger on address match
| 18    | `timing`      | r/- | `1` - trigger **after** executing the triggering instruction
| 17:16 | `sizelo`      | r/- | `00` - match against an access of any size
| 15:12 | `action`      | r/- | `0001` - enter debug mode on trigger fire
| 11    | `chain`       | r/- | `0` - chaining is not supported - there is only one trigger
| 10:6  | `match`       | r/- | `0000` - only full-address match
| 6     | `m`           | r/- | `1` - trigger enabled when in machine-mode
| 5     | `h`           | r/- | `0` - hypervisor-mode not supported
| 4     | `s`           | r/- | `0` - supervisor-mode not supported
| 3     | `u`           | r/- | trigger enabled when in user-mode, set when `U` ISA extension is enabled
| 2     | `exe`         | r/w | set to enable trigger
| 1     | `store`       | r/- | `0` - store address/data matching not supported
| 0     | `load`        | r/- | `0` - load address/data matching not supported
|=======================


:sectnums!:
===== **`tdata2`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x7a2 | **Trigger data register 2** | `tdata2`
3+| Reset value: _UNDEFINED_
3+| Since only the "address match trigger" type is supported, this r/w CSR is used to store the address of the triggering instruction.
|======


:sectnums!:
===== **`tdata3`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x7a3 | **Trigger data register 3** | `tdata3`
3+| Reset value: 0x00000000
3+| This CSR is not required for the NEORV32 trigger module. Hence, it is hardwired to zero and any write access is ignored.
|======


:sectnums!:
===== **`tinfo`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x7a4 | **Trigger information register** | `tinfo`
3+| Reset value: 0x00000004
3+| This CSR is hardwired to "4" indicating there is only an "address match trigger" available. Any write access is ignored.
|======


:sectnums!:
===== **`tcontrol`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x7a5 | **Trigger control register** | `tcontrol`
3+| Reset value: 0x00000000
3+| This CSR is not required for the NEORV32 trigger module. Hence, it is hardwired to zero and any write access is ignored.
|======


:sectnums!:
===== **`mcontext`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x7a8 | **Machine context register** | `mcontext`
3+| Reset value: 0x00000000
3+| This CSR is not required for the NEORV32 trigger module. Hence, it is hardwired to zero and any write access is ignored.
|======


:sectnums!:
===== **`scontext`**

[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x7aa | **Supervisor context register** | `scontext`
3+| Reset value: 0x00000000
3+| This CSR is not required for the NEORV32 trigger module. Hence, it is hardwired to zero and any write access is ignored.
|======

