Skip to content

Add DCSR and DPC CSRs #614

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
38e64d7
add dcsr and dpc csrs
neverlandiz Apr 14, 2025
abef190
Merge branch 'main' into add-dcsr-and-dpc-csrs
neverlandiz May 12, 2025
05af687
docs(debug csrs): change dcsr and dpc to D mode
neverlandiz May 12, 2025
a5c6bab
docs(debug csrs): add definedBy to fields
neverlandiz May 13, 2025
c47a850
docs(debug csrs): add DXLEN length type
neverlandiz May 13, 2025
36de286
docs(debug csrs): fix privilege mode
neverlandiz May 13, 2025
fd39d4e
docs(debug csrs): add params and sw_write for checking MPRVEN impleme…
neverlandiz May 15, 2025
cc34768
docs(debug csrs): fix description
neverlandiz May 15, 2025
ba6b5d4
docs(debug csrs): fix MPRVEN param
neverlandiz May 23, 2025
ee80efe
docs(debug csrs): add type() and reset_value()
neverlandiz May 23, 2025
beaeb61
docs(debug csr): add DXLEN to csr.rb
neverlandiz May 28, 2025
d885542
docs(debug csrs): removed DXLEN
neverlandiz May 28, 2025
0ee560a
docs(Sdext): fix CI failures
neverlandiz Jun 3, 2025
8a9525d
docs(dcsr): fix syntax error
neverlandiz Jun 3, 2025
51aafde
docs(dcsr): fix syntax error
neverlandiz Jun 3, 2025
b4b3927
docs(debug mode): add D-mode to modes_with_access
neverlandiz Jun 3, 2025
3ec854b
docs(debug mode): add D mode to multi_xlen_in_mode
neverlandiz Jun 3, 2025
871382b
docs(dcsr): add STEPIE, STOPCOUNT, and STOPTIME params
neverlandiz Jun 13, 2025
fab9c49
docs(dcsr): add return statements
neverlandiz Jun 18, 2025
1d4351b
docs(dcsr): add asserts
neverlandiz Jun 19, 2025
d360f7b
docs(Sdext): change tied-to to read-only
neverlandiz Jun 19, 2025
e6b9c80
fix(debug csrs): file rebase
neverlandiz Jun 20, 2025
9aba8e6
Merge branch 'main' into add-dcsr-and-dpc-csrs
neverlandiz Jun 20, 2025
39978d9
Update cfg_arch.rb
neverlandiz Jun 20, 2025
82fadef
docs(debug csrs): add copyright and license information
neverlandiz Jun 20, 2025
0edfaf8
fix(debug csrs): edit copyright information
neverlandiz Jun 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion spec/schemas/csr_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@
"virtual_address": true,
"$comment": "Conditionally required; see below",
"priv_mode": {
"enum": ["M", "S", "U", "VS"]
"enum": ["M", "S", "U", "VS", "D"]
},
"length": {
"description": "Length, in bits, of the CSR. Can either be a 32, 64 or MXLEN, SXLEN, VSXLEN to indicate that it is dependent on the effective XLEN for a given mode. XLEN here refers to the effective XLEN in the current execution mode.",
Expand Down
276 changes: 276 additions & 0 deletions spec/std/isa/csr/dcsr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
# Copyright (c) Katherine Hsu
# SPDX-License-Identifier: BSD-3-Clause-Clear

# yaml-language-server: $schema=../../schemas/csr_schema.json

$schema: "csr_schema.json#"
kind: csr
name: dcsr
long_name: Debug Control and Status Register
address: 0x7B0
priv_mode: D
length: 32
description: |
Upon entry into Debug Mode, v and prv are updated with the privilege level the hart was previously in,
and cause is updated with the reason for Debug Mode entry. Other than these fields and nmip, the
other fields of dcsr are only writable by the external debugger.

Priority of reasons for entering Debug Mode from highest to lowest is shown below.
5:: resethaltreq
6:: halt group
3:: haltreq
2:: trigger
1:: ebreak
4:: step

For compatibility with old versions of this spec, resethaltreq and
haltreq are allowed to be at different positions than shown as long as:
1. resethaltreq is higher priority than haltreq
2. the relative order of the other four causes is maintained

This CSR is read/write.

definedBy: Sdext
fields:
DEBUGVER:
location: 31-28
type: RO
description: |
0 (none):: There is no debug support.
4 (1.0):: Debug support exists as it is described in this document.
15 (custom):: There is debug support, but it does not conform to any available version of this spec.
reset_value: UNDEFINED_LEGAL
EXTCAUSE:
location: 26-24
type: RO
description: |
When cause is 7, this optional field contains the value of a more specific halt reason than "other."
Otherwise it contains 0.

0 (critical error):: The hart entered a critical error state, as defined in the Smdbltrp extension.

All other values are reserved for future versions of this spec, or for use by other RISC-V extensions.
reset_value: 0
CETRIG:
location: 19
type: RW
definedBy: Smdbltrp
description: |
This bit is part of Smdbltrp and only exists when that extension is implemented.
0 (disabled):: A hart in a critical error state does not enter
Debug Mode but instead asserts the critical-error signal to
the platform.
1 (enabled):: A hart in a critical error state enters Debug
Mode instead of asserting the critical-error signal to the
platform. Upon such entry into Debug Mode, the cause
field is set to 7, and the extcause field is set to 0, indicating
a critical error triggered the Debug Mode entry. This cause
has the highest priority among all reasons for entering
Debug Mode. Resuming from Debug Mode following an
entry from the critical error state returns the hart to the
critical error state.

When cetrig is 1, resuming from Debug Mode following an entry due to a critical
error will result in an immediate re-entry into Debug Mode due to the critical error.
The debugger may resume with cetrig set to 0 to allow the platform defined actions on
critical-error signal to occur. Other possible actions include initiating a hart or platform
reset using the Debug Module reset control.
reset_value: 0
PELP:
location: 18
type: RW
definedBy: Zicfilp
description: |
This bit is part of Zicfilp and only exists when that extension is implemented.
0 (NO_LP_EXPECTED):: No landing pad instruction expected.
1 (LP_EXPECTED):: A landing pad instruction is expected.
reset_value: 0
EBREAKVS:
location: 17
type: RW
definedBy: H
description: |
0 (exception):: ebreak instructions in VS-mode behave as described in the Privileged Spec.
1 (debug mode):: ebreak instructions in VS-mode enter Debug Mode.
This bit is hardwired to 0 if the hart does not support virtualization mode.
reset_value: 0
EBREAKVU:
location: 16
type: RW
definedBy: H
description: |
0 (exception):: ebreak instructions in VU-mode behave as described in the Privileged Spec.
1 (debug mode):: ebreak instructions in VU-mode enter Debug Mode.
This bit is hardwired to 0 if the hart does not support virtualization mode.
reset_value: 0
EBREAKM:
location: 15
type: RW
description: |
0 (exception):: ebreak instructions in M-mode behave as described in the Privileged Spec.
1 (debug mode):: ebreak instructions in M-mode enter Debug Mode.
reset_value: 0
EBREAKS:
location: 13
type: RW
definedBy: S
description: |
0 (exception):: ebreak instructions in S-mode behave as described in the Privileged Spec.
1 (debug mode):: ebreak instructions in S-mode enter Debug Mode.
This bit is hardwired to 0 if the hart does not support S-mode.
reset_value: 0
EBREAKU:
location: 12
type: RW
definedBy: U
description: |
0 (exception):: ebreak instructions in U-mode behave as described in the Privileged Spec.
1 (debug mode):: ebreak instructions in U-mode enter Debug Mode.
This bit is hardwired to 0 if the hart does not support U-mode.
reset_value: 0
STEPIE:
location: 11
description: |
0 (interrupts disabled):: Interrupts (including NMI) are disabled during single stepping with step set.
This value should be supported.
1 (interrupts enabled):: Interrupts (including NMI) are enabled during single stepping with step set.
Implementations may hard wire this bit to 0. In that case interrupt behavior can be emulated by the
debugger. The debugger must not change the value of this bit while the hart is running.
type(): |
if (DCSR_STEPIE_TYPE == "read-only-0" || DCSR_STEPIE_TYPE == "read-only-1") {
return CsrFieldType::RO;
}
assert(DCSR_STEPIE_TYPE == "rw", "Unhandled DCSR_STEPIE_TYPE value");
return CsrFieldType::RW;
reset_value(): |
if (DCSR_STEPIE_TYPE == "read-only-0") {
return 0;
} else if (DCSR_STEPIE_TYPE == "read-only-1") {
return 1;
}
assert(DCSR_STEPIE_TYPE == "rw", "Unhandled DCSR_STEPIE_TYPE value");
return UNDEFINED_LEGAL;
STOPCOUNT:
location: 10
description: |
0 (normal):: Increment counters as usual.
1 (freeze):: Don’t increment any hart-local counters while in Debug Mode or on ebreak instructions
that cause entry into Debug Mode. These counters include the instret CSR. On single-hart cores cycle
should be stopped, but on multi-hart cores it must keep incrementing.
An implementation may hardwire this bit to 0 or 1.
type(): |
if (DCSR_STOPCOUNT_TYPE == "read-only-0" || DCSR_STOPCOUNT_TYPE == "read-only-1") {
return CsrFieldType::RO;
}
assert(DCSR_STOPCOUNT_TYPE == "rw", "Unhandled DCSR_STOPCOUNT_TYPE value");
return CsrFieldType::RW;
reset_value(): |
if (DCSR_STOPCOUNT_TYPE == "read-only-0") {
return 0;
} else if (DCSR_STOPCOUNT_TYPE == "read-only-1") {
return 1;
}
assert(DCSR_STOPCOUNT_TYPE == "rw", "Unhandled DCSR_STOPCOUNT_TYPE value");
return UNDEFINED_LEGAL;
STOPTIME:
location: 9
description: |
0 (normal):: time continues to reflect mtime.
1 (freeze):: time is frozen at the time that Debug Mode was entered. When leaving Debug Mode,
time will reflect the latest value of mtime again.
While all harts have stoptime=1 and are in Debug Mode, mtime is allowed to stop incrementing.
An implementation may hardwire this bit to 0 or 1.
type(): |
if (DCSR_STOPTIME_TYPE == "read-only-0" || DCSR_STOPTIME_TYPE == "read-only-1") {
return CsrFieldType::RO;
}
assert(DCSR_STOPTIME_TYPE == "rw", "Unhandled DCSR_STOPTIME_TYPE value");
return CsrFieldType::RW;
reset_value(): |
if (DCSR_STOPTIME_TYPE == "read-only-0") {
return 0;
} else if (DCSR_STOPTIME_TYPE == "read-only-1") {
return 1;
}
assert(DCSR_STOPTIME_TYPE == "rw", "Unhandled DCSR_STOPTIME_TYPE value");
return UNDEFINED_LEGAL;
CAUSE:
location: 8-6
type: RO
description: |
Explains why Debug Mode was entered.
When there are multiple reasons to enter Debug Mode in a
single cycle, hardware should set cause to the cause with
the highest priority.
1 (ebreak):: An ebreak instruction was executed.
2 (trigger):: A Trigger Module trigger fired with action=1.
3 (haltreq):: The debugger requested entry to Debug Mode
using haltreq.
4 (step):: The hart single stepped because step was set.
5 (resethaltreq):: The hart halted directly out of reset due to
resethaltreq It is also acceptable to report 3 when this
happens.
6 (group):: The hart halted because it’s part of a halt group.
Harts may report 3 for this cause instead.
7 (other):: The hart halted for a reason other than the ones
mentioned above. extcause may contain a more specific
reason.
reset_value: 0
V:
location: 5
type: RW
definedBy: H
description: |
Extends the prv field with the virtualization mode the hart was operating in
when Debug Mode was entered. A debugger can change this value to change the
hart’s virtualization mode when exiting Debug Mode. This bit is hardwired to 0 on harts
that do not support virtualization mode.
reset_value: 0
MPRVEN:
location: 4
description: |
0 (disabled):: mprv in mstatus is ignored in Debug Mode.
1 (enabled):: mprv in mstatus takes effect in Debug Mode.
Implementing this bit is optional. It may be tied to either 0 or 1.
type(): |
if (DCSR_MPRVEN_TYPE == "read-only-0" || DCSR_MPRVEN_TYPE == "read-only-1") {
return CsrFieldType::RO;
}
assert(DCSR_MPRVEN_TYPE == "rw", "Unhandled DCSR_MPRVEN_TYPE value");
return CsrFieldType::RW;
reset_value(): |
if (DCSR_MPRVEN_TYPE == "read-only-0") {
return 0;
} else if (DCSR_MPRVEN_TYPE == "read-only-1") {
return 1;
}
assert(DCSR_MPRVEN_TYPE == "rw", "Unhandled DCSR_MPRVEN_TYPE value");
return UNDEFINED_LEGAL;
NMIP:
location: 3
type: RO
description: |
When set, there is a Non-Maskable-Interrupt (NMI) pending for the hart.
Since an NMI can indicate a hardware error condition, reliable debugging
may no longer be possible once this bit becomes set. This is implementation-dependent.
reset_value: 0
STEP:
location: 2
type: RW
description: |
When set and not in Debug Mode, the hart will only execute a single instruction
and then enter Debug Mode.
The debugger must not change the value of this bit while the hart is running.
reset_value: 0
PRV:
location: 1-0
type: RW
description: |
Contains the privilege mode the hart was operating in when Debug Mode was entered.
A debugger can change this value to change the hart’s privilege mode when exiting
Debug Mode.

Not all privilege modes are supported on all harts. If the encoding written is not
supported or the debugger is not allowed to change to it, the hart may change to any
supported privilege mode.
reset_value: 3
42 changes: 42 additions & 0 deletions spec/std/isa/csr/dpc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright (c) Katherine Hsu
# SPDX-License-Identifier: BSD-3-Clause-Clear

# yaml-language-server: $schema=../../schemas/csr_schema.json

$schema: "csr_schema.json#"
kind: csr
name: dpc
long_name: Debug PC Register
address: 0x7B1
priv_mode: D
length: MXLEN
description: |
Upon entry to debug mode, dpc is updated with the virtual address of the next instruction to be executed.

Executing the Program Buffer may cause the value of dpc to become UNSPECIFIED. If that is the case,
it must be possible to read/write dpc using an abstract command with postexec not set. The debugger
must attempt to save dpc between halting and executing a Program Buffer, and then restore dpc before
leaving Debug Mode.

If the Access Register abstract command supports reading dpc while the hart is running, then the
value read should be the address of a recently executed instruction.

If the Access Register abstract command supports writing dpc while the hart is running, then the
executing program should jump to the written address shortly after the write occurs.

The writability of dpc follows the same rules as mepc as defined in the Privileged Spec. In particular,
dpc must be able to hold all valid virtual addresses and the writability of the low bits depends on
IALIGN.

When resuming, the hart’s PC is updated to the virtual address stored in dpc. A debugger may write
dpc to change where the hart resumes.

This CSR is read/write.
definedBy: Sdext
fields:
DPC:
location_rv32: 31-0
location_rv64: 63-0
type: RW
description: Debug PC Value
reset_value: UNDEFINED_LEGAL
51 changes: 50 additions & 1 deletion spec/std/isa/ext/Sdext.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,53 @@ type: privileged
versions:
- version: "1.0.0"
state: ratified
ratification_date: null
ratification_date: 2025-02
params:
DCSR_MPRVEN_TYPE:
schema:
type: string
enum: [read-only-0, read-only-1, rw]
description: |
Implementation of dcsr.MPRVEN is optional.
It may be tied to either 0 or 1.

Behavior of the dcsr.MPRVEN bit:
* 'read-only-0': tied to 0
* 'read-only-1': tied to 1
* 'rw': read-write
DCSR_STEPIE_TYPE:
schema:
type: string
enum: [read-only-0, read-only-1, rw]
description: |
Implementation of dcsr.STEPIE is optional.
It may be tied to either 0 or 1.

Behavior of the dcsr.STEPIE bit:
* 'read-only-0': tied to 0
* 'read-only-1': tied to 1
* 'rw': read-write
DCSR_STOPCOUNT_TYPE:
schema:
type: string
enum: [read-only-0, read-only-1, rw]
description: |
Implementation of dcsr.STOPCOUNT is optional.
It may be tied to either 0 or 1.

Behavior of the dcsr.STOPCOUNT bit:
* 'read-only-0': tied to 0
* 'read-only-1': tied to 1
* 'rw': read-write
DCSR_STOPTIME_TYPE:
schema:
type: string
enum: [read-only-0, read-only-1, rw]
description: |
Implementation of dcsr.STOPTIME is optional.
It may be tied to either 0 or 1.

Behavior of the dcsr.STOPTIME bit:
* 'read-only-0': tied to 0
* 'read-only-1': tied to 1
* 'rw': read-write
Loading
Loading