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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [docs/] [datasheet/] [on_chip_debugger.adoc] - Diff between revs 64 and 65

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 64 Rev 65
Line 17... Line 17...
  pre-built binaries can be obtained for example from https://www.sifive.com/software[SiFive]
  pre-built binaries can be obtained for example from https://www.sifive.com/software[SiFive]
 
 
.OCD Security Note
.OCD Security Note
[IMPORTANT]
[IMPORTANT]
Access via the OCD is _always authenticated_ (`dmstatus.authenticated` == `1`). Hence, the
Access via the OCD is _always authenticated_ (`dmstatus.authenticated` == `1`). Hence, the
_whole system_ can always be accessed via the on-chip debugger.
_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_).
 
 
[NOTE]
[NOTE]
The OCD requires additional resources for implementation and _might_ also increase the critical path resulting in less
The OCD requires additional resources for implementation and _might_ also increase the critical path resulting in less
performance. If the OCD is not really required for the _final_ implementation, it can be disabled and thus,
performance. If the OCD is not really required for the _final_ implementation, it can be disabled and thus,
discarded from implementation. In this case all circuitry of the debugger is completely removed (no impact
discarded from implementation. In this case all circuitry of the debugger is completely removed (no impact
Line 350... Line 352...
 
 
.`command` - abstract command register - "access register" commands only
.`command` - abstract command register - "access register" commands only
[cols="^1,^2,<8"]
[cols="^1,^2,<8"]
[options="header",grid="rows"]
[options="header",grid="rows"]
|=======================
|=======================
| Bit   | Name [RISC-V]      | Description / required value
| Bit   | Name [RISC-V]      | R/W | Description / required value
| 31:24 | `cmdtype`          | `00000000` to indicate "access register" command
| 31:24 | `cmdtype`          | -/w | `00000000` to indicate "access register" command
| 23    | _reserved_         | reserved, has to be `0` when writing
| 23    | _reserved_         | -/w | reserved, has to be `0` when writing
| 22:20 | `aarsize`          | `010` to indicate 32-bit accesses
| 22:20 | `aarsize`          | -/w | `010` to indicate 32-bit accesses
| 21    | `aarpostincrement` | `0`, postincrement is not supported
| 21    | `aarpostincrement` | -/w | `0`, postincrement is not supported
| 18    | `postexec`         | if set the program buffer is executed _after_ the command
| 18    | `postexec`         | -/w | if set the program buffer is executed _after_ the command
| 17    | `transfer`         | if set the operation in `write` is conducted
| 17    | `transfer`         | -/w | if set the operation in `write` is conducted
| 16    | `write`            | `1`: copy `data0` to `[regno]`; `0` copy `[regno]` to `data0`
| 16    | `write`            | -/w | `1`: copy `data0` to `[regno]`; `0` copy `[regno]` to `data0`
| 15:0  | `regno`            | GPR-access only; has to be `0x1000` - `0x101f`
| 15:0  | `regno`            | -/w | GPR-access only; has to be `0x1000` - `0x101f`
|=======================
|=======================
 
 
 
 
:sectnums!:
:sectnums!:
===== **`abstractauto`**
===== **`abstractauto`**
Line 491... Line 493...
 
 
[IMPORTANT]
[IMPORTANT]
The CPU _debug mode_ requires the `Zicsr` and `Zifencei` CPU extension to be implemented (top generics _CPU_EXTENSION_RISCV_Zicsr_
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).
and _CPU_EXTENSION_RISCV_Zifencei_ = true).
 
 
The CPU debug mode is entered when one of the following events appear:
.Hardware Watchpoints and Breakpoints
 
[NOTE]
 
The NEORV32 CPU _debug mode_ does not provide a hardware "trigger module" (which is optional in the RISC-V debug spec). However, gdb
 
provides a native _emulation_ for code (breakpoints using `break` instruction) and data (polling data watchpoints in automated
 
single-stepping) triggers.
 
 
 
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)
. debug halt request from external DM (via CPU signal `db_halt_req_i`, high-active, triggering on rising-edge)
. 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`)
. finished executing of a single instruction while in single-step debugging mode (enabled via `dcsr.step`)
 
 
From a hardware point of view, these "entry conditions" are special synchronous (`ebreak` instruction) or asynchronous
From a hardware point of view, these "entry conditions" are special synchronous (`ebreak` instruction) or asynchronous
(single-stepping "interrupt"; halt request "interrupt") traps, that are handled invisibly by the control logic.
(single-stepping "interrupt"; halt request "interrupt") traps, that are handled invisibly by the control logic.
 
 
Whenever the CPU **enters debug mode** it performs the following operations:
.WFI instruction
 
[WARNING]
 
The wait-for-interrupt instruction `wfi` puts the CPU into sleep mode. The CPU will resume normale operation
 
when at least one interrupt source becomes pending (= at least one bit in `mip` CSR is set).
 
However, the CPU will _also resume_ from sleep mode if there is a halt request from the debug module (DM).
 
 
 
Whenever the CPU **enters debug-mode** it performs the following operations:
 
 
* move `pc` to `dpcs`
* move `pc` to `dpcs`
* copy the hart's current privilege level to `dcsr.prv`
* copy the hart's current privilege level to `dcsr.prv`
* set `dcrs.cause` according to the cause why debug mode is entered
* set `dcrs.cause` according to the cause why debug mode is entered
* **no update** of `mtval`, `mcause`, `mtval` and `mstatus` CSRs
* **no update** of `mtval`, `mcause`, `mtval` and `mstatus` CSRs
* 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)
* 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)
 
 
When the CPU **is in debug mode** the following things are important:
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
* 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, PMP is not active
* effective CPU privilege level is `machine` mode, any PMP configuration is bypassed
* if an exception occurs
* the `wfi` instruction acts as a `nop` (also during single-stepping)
  * if the exception was caused by any debug-mode entry action the CPU jumps to the _normal entry point_
* if an exception occurs:
    ( = _CPU_DEBUG_ADDR_) of the park loop again (for example when executing `ebreak` in debug mode)
** if the exception was caused by any debug-mode entry action the CPU jumps to the _normal entry point_
  * for all other exception sources the CPU jumps to the _exception entry point_ ( = _CPU_DEBUG_ADDR_ + 4)
   (= _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 and restarts the park loop again afterwards
    to signal an exception to the DM and restarts the park loop again afterwards
* interrupts are disabled; however, they will be remain pending and will get executed after the CPU has left debug mode
* 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`)
* 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.

powered by: WebSVN 2.1.0

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