[[dm]]
.Debug Module Debug Bus Registers
[cols=">,<,<",options="header",]
|===
|Address |Name |Page
|_Continued on next page_ | |
|0x04 |Abstract Data 0 (`data0`) |
|0x05 |Abstract Data 1 (`data1`) |
|0x06 |Abstract Data 2 (`data2`) |
|0x07 |Abstract Data 3 (`data3`) |
|0x08 |Abstract Data 4 (`data4`) |
|0x09 |Abstract Data 5 (`data5`) |
|0x0a |Abstract Data 6 (`data6`) |
|0x0b |Abstract Data 7 (`data7`) |
|0x0c |Abstract Data 8 (`data8`) |
|0x0d |Abstract Data 9 (`data9`) |
|0x0e |Abstract Data 10 (`data10`) |
|0x0f |Abstract Data 11 (`data11`) |
|0x10 |Debug Module Control (`dmcontrol`) |
|0x11 |Debug Module Status (`dmstatus`) |
|0x12 |Hart Info (`hartinfo`) |
|0x13 |Halt Summary 1 (`haltsum1`) |
|0x14 |Hart Array Window Select (`hawindowsel`) |
|0x15 |Hart Array Window (`hawindow`) |
|0x16 |Abstract Control and Status (`abstractcs`) |
|0x17 |Abstract Command (`command`) |
|0x18 |Abstract Command Autoexec (`abstractauto`) |
|0x19 |Configuration Structure Pointer 0 (`confstrptr0`) |
|0x1a |Configuration Structure Pointer 1 (`confstrptr1`) |
|0x1b |Configuration Structure Pointer 2 (`confstrptr2`) |
|0x1c |Configuration Structure Pointer 3 (`confstrptr3`) |
|0x1d |Next Debug Module (`nextdm`) |
|0x1f |Custom Features (`custom`) |
|0x20 |Program Buffer 0 (`progbuf0`) |
|0x21 |Program Buffer 1 (`progbuf1`) |
|0x22 |Program Buffer 2 (`progbuf2`) |
|0x23 |Program Buffer 3 (`progbuf3`) |
|0x24 |Program Buffer 4 (`progbuf4`) |
|0x25 |Program Buffer 5 (`progbuf5`) |
|0x26 |Program Buffer 6 (`progbuf6`) |
|0x27 |Program Buffer 7 (`progbuf7`) |
|0x28 |Program Buffer 8 (`progbuf8`) |
|0x29 |Program Buffer 9 (`progbuf9`) |
|0x2a |Program Buffer 10 (`progbuf10`) |
|0x2b |Program Buffer 11 (`progbuf11`) |
|0x2c |Program Buffer 12 (`progbuf12`) |
|0x2d |Program Buffer 13 (`progbuf13`) |
|0x2e |Program Buffer 14 (`progbuf14`) |
|0x2f |Program Buffer 15 (`progbuf15`) |
|0x30 |Authentication Data (`authdata`) |
|0x32 |Debug Module Control and Status 2 (`dmcs2`) |
|0x34 |Halt Summary 2 (`haltsum2`) |
|0x35 |Halt Summary 3 (`haltsum3`) |
|0x37 |System Bus Address 127:96 (`sbaddress3`) |
|0x38 |System Bus Access Control and Status (`sbcs`) |
|0x39 |System Bus Address 31:0 (`sbaddress0`) |
|0x3a |System Bus Address 63:32 (`sbaddress1`) |
|0x3b |System Bus Address 95:64 (`sbaddress2`) |
|0x3c |System Bus Data 31:0 (`sbdata0`) |
|0x3d |System Bus Data 63:32 (`sbdata1`) |
|0x3e |System Bus Data 95:64 (`sbdata2`) |
|0x3f |System Bus Data 127:96 (`sbdata3`) |
|0x40 |Halt Summary 0 (`haltsum0`) |
|0x70 |Custom Features 0 (`custom0`) |
|0x71 |Custom Features 1 (`custom1`) |
|0x72 |Custom Features 2 (`custom2`) |
|0x73 |Custom Features 3 (`custom3`) |
|0x74 |Custom Features 4 (`custom4`) |
|0x75 |Custom Features 5 (`custom5`) |
|0x76 |Custom Features 6 (`custom6`) |
|0x77 |Custom Features 7 (`custom7`) |
|0x78 |Custom Features 8 (`custom8`) |
|0x79 |Custom Features 9 (`custom9`) |
|0x7a |Custom Features 10 (`custom10`) |
|0x7b |Custom Features 11 (`custom11`) |
|0x7c |Custom Features 12 (`custom12`) |
|0x7d |Custom Features 13 (`custom13`) |
|0x7e |Custom Features 14 (`custom14`) |
|0x7f |Custom Features 15 (`custom15`) |
|===

== Debug Module Status (`dmstatus`, at 0x11)

[#dmDmstatus]## This register reports status for the overall Debug
Module as well as the currently selected harts, as defined in . Its
address will not change in the future, because it contains .

This entire register is read-only.

[cols="<,<,<,<,<,<,<,<,<,<,<,<",options="header",]
|===
|31 |25 |24 | |23 | |22 | |21 |20 |19 |
|latexmath:[$|0|$] | |latexmath:[$|ndmresetpending|$] |
|latexmath:[$|stickyunavail|$] | |latexmath:[$|impebreak|$] |
|latexmath:[$|0|$] | |latexmath:[$|allhavereset|$] |

|7 | |1 | |1 | |1 | |2 | |1 |
|===

[cols="<,<,<,<,<,<,<,<,<,<,<,<",options="header",]
|===
|18 | |17 | |16 | |15 | |14 | |13 |
|latexmath:[$|anyhavereset|$] | |latexmath:[$|allresumeack|$] |
|latexmath:[$|anyresumeack|$] | |latexmath:[$|allnonexistent|$] |
|latexmath:[$|anynonexistent|$] | |latexmath:[$|allunavail|$] |

|1 | |1 | |1 | |1 | |1 | |1 |
|===

[cols="<,<,<,<,<,<,<,<,<,<,<,<",options="header",]
|===
|12 | |11 | |10 | |9 | |8 | |7 |
|latexmath:[$|anyunavail|$] | |latexmath:[$|allrunning|$] |
|latexmath:[$|anyrunning|$] | |latexmath:[$|allhalted|$] |
|latexmath:[$|anyhalted|$] | |latexmath:[$|authenticated|$] |

|1 | |1 | |1 | |1 | |1 | |1 |
|===

[cols="<,<,<,<,<,<,<,<",options="header",]
|===
|6 | |5 | |4 | |3 |0
|latexmath:[$|authbusy|$] | |latexmath:[$|hasresethaltreq|$] |
|latexmath:[$|confstrptrvalid|$] | |latexmath:[$|version|$] |

|1 | |1 | |1 | |4 |
|===

[[dmDmstatusVersion]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

|[#dmDmstatusNdmresetpending]## |ndmresetpending| a|
0 (false): Unimplemented, or is zero and no ndmreset is currently in
progress.

1 (true): is currently nonzero, or there is an ndmreset in progress.

|R |-

|[#dmDmstatusStickyunavail]## |stickyunavail| a|
0 (current): The per-hart `unavail` bits reflect the current state of
the hart.

1 (sticky): The per-hart `unavail` bits are sticky. Once they are set,
they will not clear until the debugger acknowledges them using .

|R |Preset

|[#dmDmstatusImpebreak]## |impebreak| a|
If 1, then there is an implicit `ebreak` instruction at the non-existent
word immediately after the Program Buffer. This saves the debugger from
having to write the `ebreak` itself, and allows the Program Buffer to be
one word smaller.

This must be 1 when is 1.

|R |Preset

|[#dmDmstatusAllhavereset]## |allhavereset| |This field is 1 when all
currently selected harts have been reset and reset has not been
acknowledged for any of them. |R |-

|[#dmDmstatusAnyhavereset]## |anyhavereset| |This field is 1 when at
least one currently selected hart has been reset and reset has not been
acknowledged for that hart. |R |-

|[#dmDmstatusAllresumeack]## |allresumeack| |This field is 1 when all
currently selected harts have their resume ack bit set. |R |-

|[#dmDmstatusAnyresumeack]## |anyresumeack| |This field is 1 when any
currently selected hart has its resume ack bit set. |R |-

|[#dmDmstatusAllnonexistent]## |allnonexistent| |This field is 1 when
all currently selected harts do not exist in this hardware platform. |R
|-

|[#dmDmstatusAnynonexistent]## |anynonexistent| |This field is 1 when
any currently selected hart does not exist in this hardware platform. |R
|-

|[#dmDmstatusAllunavail]## |allunavail| |This field is 1 when all
currently selected harts are unavailable, or (if is 1) were unavailable
without that being acknowledged. |R |-

|[#dmDmstatusAnyunavail]## |anyunavail| |This field is 1 when any
currently selected hart is unavailable, or (if is 1) was unavailable
without that being acknowledged. |R |-

|[#dmDmstatusAllrunning]## |allrunning| |This field is 1 when all
currently selected harts are running. |R |-

|[#dmDmstatusAnyrunning]## |anyrunning| |This field is 1 when any
currently selected hart is running. |R |-

|[#dmDmstatusAllhalted]## |allhalted| |This field is 1 when all
currently selected harts are halted. |R |-

|[#dmDmstatusAnyhalted]## |anyhalted| |This field is 1 when any
currently selected hart is halted. |R |-

|[#dmDmstatusAuthenticated]## |authenticated| a|
0 (false): Authentication is required before using the DM.

1 (true): The authentication check has passed.

On components that don’t implement authentication, this bit must be
preset as 1.

|R |Preset

|[#dmDmstatusAuthbusy]## |authbusy| a|
0 (ready): The authentication module is ready to process the next
read/write to .

1 (busy): The authentication module is busy. Accessing results in
unspecified behavior.

only becomes set in immediate response to an access to .

|R |0

|[#dmDmstatusHasresethaltreq]## |hasresethaltreq| |1 if this Debug
Module supports halt-on-reset functionality controllable by the and
bits. 0 otherwise. |R |Preset

|[#dmDmstatusConfstrptrvalid]## |confstrptrvalid| a|
0 (invalid): –hold information which is not relevant to the
configuration structure.

1 (valid): –hold the address of the configuration structure.

|R |Preset

||version| a|
0 (none): There is no Debug Module present.

1 (0.11): There is a Debug Module and it conforms to version 0.11 of
this specification.

2 (0.13): There is a Debug Module and it conforms to version 0.13 of
this specification.

3 (1.0): There is a Debug Module and it conforms to version 1.0 of this
specification.

15 (custom): There is a Debug Module but it does not conform to any
available version of this spec.

|R |3
|===

== Debug Module Control (`dmcontrol`, at 0x10)

[#dmDmcontrol]## This register controls the overall Debug Module as well
as the currently selected harts, as defined in .

[#hartsel]## Throughout this document we refer to , which is combined
with . While the spec allows for 20 bits, an implementation may choose
to implement fewer than that. The actual width of is called
`HARTSELLEN`. It must be at least 0 and at most 20. A debugger should
discover `HARTSELLEN` by writing all ones to (assuming the maximum size)
and reading back the value to see which bits were actually set.
Debuggers must not change while an abstract command is executing.

There are separate and bits so that it is possible to write without
changing the halt-on-reset request bit for each selected hart, when not
all selected harts have the same configuration.

On any given write, a debugger may only write 1 to at most one of the
following bits: , , , , and . The others must be written 0.

[#resethaltreq]## is an optional internal bit of per-hart state that
cannot be read, but can be written with and .

[#keepalive]## is an optional internal bit of per-hart state. When it is
set, it suggests that the hardware should attempt to keep the hart
available for the debugger, e.g. by keeping it from entering a low-power
state once powered on. Even if the bit is implemented, hardware might
not be able to keep a hart available. The bit is written through and .

For forward compatibility, will always be readable when bit 1 () is 0
and bit 0 () is 1.

[cols="<,<,<,<,<,<,<,<,<,<",options="header",]
|===
|31 | |30 | |29 | |28 | |27 |
|latexmath:[$|haltreq|$] | |latexmath:[$|resumereq|$] |
|latexmath:[$|hartreset|$] | |latexmath:[$|ackhavereset|$] |
|latexmath:[$|ackunavail|$] |

|1 | |1 | |1 | |1 | |1 |
|===

[cols="<,<,<,<,<,<,<,<,<,<",options="header",]
|===
|26 | |25 |16 |15 |6 |5 | |4 |
|latexmath:[$|hasel|$] | |latexmath:[$|hartsello|$] |
|latexmath:[$|hartselhi|$] | |latexmath:[$|setkeepalive|$] |
|latexmath:[$|clrkeepalive|$] |

|1 | |10 | |10 | |1 | |1 |
|===

[cols="<,<,<,<,<,<,<,<",options="header",]
|===
|3 | |2 | |1 | |0 |
|latexmath:[$|setresethaltreq|$] | |latexmath:[$|clrresethaltreq|$] |
|latexmath:[$|ndmreset|$] | |latexmath:[$|dmactive|$] |

|1 | |1 | |1 | |1 |
|===

[[dmDmcontrolDmactive]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

|[#dmDmcontrolHaltreq]## |haltreq| a|
Writing 0 clears the halt request bit for all currently selected harts.
This may cancel outstanding halt requests for those harts.

Writing 1 sets the halt request bit for all currently selected harts.
Running harts will halt whenever their halt request bit is set.

Writes apply to the new value of and .

|WARZ |-

|[#dmDmcontrolResumereq]## |resumereq| a|
Writing 1 causes the currently selected harts to resume once, if they
are halted when the write occurs. It also clears the resume ack bit for
those harts.

is ignored if is set.

Writes apply to the new value of and .

|W1 |-

|[#dmDmcontrolHartreset]## |hartreset| a|
This optional field writes the reset bit for all the currently selected
harts. To perform a reset the debugger writes 1, and then writes 0 to
deassert the reset signal.

While this bit is 1, the debugger must not change which harts are
selected.

If this feature is not implemented, the bit always stays 0, so after
writing 1 the debugger can read the register back to see if the feature
is supported.

Writes apply to the new value of and .

|WARL |0

|[#dmDmcontrolAckhavereset]## |ackhavereset| a|
0 (nop): No effect.

1 (ack): Clears `havereset` for any selected harts.

Writes apply to the new value of and .

|W1 |-

|[#dmDmcontrolAckunavail]## |ackunavail| a|
0 (nop): No effect.

1 (ack): Clears `unavail` for any selected harts that are currently
available.

Writes apply to the new value of and .

|W1 |-

|[#dmDmcontrolHasel]## |hasel| a|
Selects the definition of currently selected harts.

0 (single): There is a single currently selected hart, that is selected
by .

1 (multiple): There may be multiple currently selected harts – the hart
selected by , plus those selected by the hart array mask register.

An implementation which does not implement the hart array mask register
must tie this field to 0. A debugger which wishes to use the hart array
mask register feature should set this bit and read back to see if the
functionality is supported.

|WARL |0

|[#dmDmcontrolHartsello]## |hartsello| |The low 10 bits of : the
DM-specific index of the hart to select. This hart is always part of the
currently selected harts. |WARL |0

|[#dmDmcontrolHartselhi]## |hartselhi| |The high 10 bits of : the
DM-specific index of the hart to select. This hart is always part of the
currently selected harts. |WARL |0

|[#dmDmcontrolSetkeepalive]## |setkeepalive| a|
This optional field sets for all currently selected harts, unless is
simultaneously set to 1.

Writes apply to the new value of and .

|W1 |-

|[#dmDmcontrolClrkeepalive]## |clrkeepalive| a|
This optional field clears for all currently selected harts.

Writes apply to the new value of and .

|W1 |-

|[#dmDmcontrolSetresethaltreq]## |setresethaltreq| a|
This optional field writes the halt-on-reset request bit for all
currently selected harts, unless is simultaneously set to 1. When set to
1, each selected hart will halt upon the next deassertion of its reset.
The halt-on-reset request bit is not automatically cleared. The debugger
must write to to clear it.

Writes apply to the new value of and .

If is 0, this field is not implemented.

|W1 |-

|[#dmDmcontrolClrresethaltreq]## |clrresethaltreq| a|
This optional field clears the halt-on-reset request bit for all
currently selected harts.

Writes apply to the new value of and .

|W1 |-

|[#dmDmcontrolNdmreset]## |ndmreset| |This bit controls the reset signal
from the DM to the rest of the hardware platform. The signal should
reset every part of the hardware platform, including every hart, except
for the DM and any logic required to access the DM. To perform a
hardware platform reset the debugger writes 1, and then writes 0 to
deassert the reset. |R/W |0

||dmactive| a|
This bit serves as a reset signal for the Debug Module itself. After
changing the value of this bit, the debugger must poll until has taken
the requested value before performing any action that assumes the
requested state change has completed. Hardware may take an arbitrarily
long time to complete activation or deactivation and will indicate
completion by setting to the requested value.

0 (inactive): The module’s state, including authentication mechanism,
takes its reset values (the bit is the only bit which can be written to
something other than its reset value). Any accesses to the module may
fail. Specifically, might not return correct data.

1 (active): The module functions normally.

No other mechanism should exist that may result in resetting the Debug
Module after power up.

To place the Debug Module into a known state, a debugger may write 0 to
, poll until is observed 0, write 1 to , and poll until is observed 1.

Implementations may pay attention to this bit to further aid debugging,
for example by preventing the Debug Module from being power gated while
debugging is active.

|R/W |0
|===

== Hart Info (`hartinfo`, at 0x12)

[#dmHartinfo]## This register gives information about the hart currently
selected by .

This register is optional. If it is not present it should read all-zero.

If this register is included, the debugger can do more with the Program
Buffer by writing programs which explicitly access the `data` and/or
`dscratch` registers.

This entire register is read-only.

[cols="<,<,<,<,<,<,<,<,<,<,<,<",options="header",]
|===
|31 |24 |23 |20 |19 |17 |16 | |15 |12 |11 |0
|latexmath:[$|0|$] | |latexmath:[$|nscratch|$] | |latexmath:[$|0|$] |
|latexmath:[$|dataaccess|$] | |latexmath:[$|datasize|$] |
|latexmath:[$|dataaddr|$] |

|8 | |4 | |3 | |1 | |4 | |12 |
|===

[[dmHartinfoDataaddr]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

|[#dmHartinfoNscratch]## |nscratch| |Number of `dscratch` registers
available for the debugger to use during program buffer execution,
starting from . The debugger can make no assumptions about the contents
of these registers between commands. |R |Preset

|[#dmHartinfoDataaccess]## |dataaccess| a|
0 (csr): The `data` registers are shadowed in the hart by CSRs. Each CSR
is DXLEN bits in size, and corresponds to a single argument, per
Table #tab:datareg[[tab:datareg]].

1 (memory): The `data` registers are shadowed in the hart’s memory map.
Each register takes up 4 bytes in the memory map.

|R |Preset

|[#dmHartinfoDatasize]## |datasize| a|
If is 0: Number of CSRs dedicated to shadowing the `data` registers.

If is 1: Number of 32-bit words in the memory map dedicated to shadowing
the `data` registers.

If this value is non-zero, then the tt data registers must be
traditional registers and not MRs.

Since there are at most 12 `data` registers, the value in this register
must be 12 or smaller.

|R |Preset

||dataaddr| a|
If is 0: The number of the first CSR dedicated to shadowing the `data`
registers.

If is 1: Address of RAM where the data registers are shadowed. This
address is sign extended giving a range of -2048 to 2047, easily
addressed with a load or store using as the address register.

|R |Preset
|===

== Hart Array Window Select (`hawindowsel`, at 0x14)

[#dmHawindowsel]## This register selects which of the 32-bit portion of
the hart array mask register (see
Section link:#hartarraymask[[hartarraymask]]) is accessible in .

[cols="<,<,<,<",options="header",]
|===
|31 |15 |14 |0
|latexmath:[$|0|$] | |latexmath:[$|hawindowsel|$] |
|17 | |15 |
|===

[[dmHawindowselHawindowsel]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

||hawindowsel| |The high bits of this field may be tied to 0, depending
on how large the array mask register is. E.g. on a hardware platform
with 48 harts only bit 0 of this field may actually be writable. |WARL
|0
|===

== Hart Array Window (`hawindow`, at 0x15)

[#dmHawindow]## This register provides R/W access to a 32-bit portion of
the hart array mask register (see
Section link:#hartarraymask[[hartarraymask]]). The position of the
window is determined by . I.e. bit 0 refers to hart
latexmath:[${dm-hawindowsel} * 32$], while bit 31 refers to hart
latexmath:[${dm-hawindowsel} * 32 + 31$].

Since some bits in the hart array mask register may be constant 0, some
bits in this register may be constant 0, depending on the current value
of .

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|maskdata|$] |
|32 |
|===

== Abstract Control and Status (`abstractcs`, at 0x16)

[#dmAbstractcs]## Writing this register while an abstract command is
executing causes to become 1 (busy) once the command completes (busy
becomes 0).

must be at least 1 to support RV32 harts, 2 to support RV64 harts, or 4
to support RV128 harts.

[cols="<,<,<,<,<,<,<,<",options="header",]
|===
|31 |29 |28 |24 |23 |13 |12 |
|latexmath:[$|0|$] | |latexmath:[$|progbufsize|$] | |latexmath:[$|0|$] |
|latexmath:[$|busy|$] |

|3 | |5 | |11 | |1 |
|===

[cols="<,<,<,<,<,<,<,<",options="header",]
|===
|11 | |10 |8 |7 |4 |3 |0
|latexmath:[$|relaxedpriv|$] | |latexmath:[$|cmderr|$] |
|latexmath:[$|0|$] | |latexmath:[$|datacount|$] |

|1 | |3 | |4 | |4 |
|===

[[dmAbstractcsDatacount]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

|[#dmAbstractcsProgbufsize]## |progbufsize| |Size of the Program Buffer,
in 32-bit words. Valid sizes are 0 - 16. |R |Preset

|[#dmAbstractcsBusy]## |busy| a|
0 (ready): There is no abstract command currently being executed.

1 (busy): An abstract command is currently being executed.

This bit is set as soon as is written, and is not cleared until that
command has completed.

|R |0

|[#dmAbstractcsRelaxedpriv]## |relaxedpriv| a|
This optional bit controls whether program buffer and abstract memory
accesses are performed with the exact and full set of permission checks
that apply based on the current architectural state of the hart
performing the access, or with a relaxed set of permission checks (e.g.
PMP restrictions are ignored). The details of the latter are
implementation-specific.

0 (full checks): Full permission checks apply.

1 (relaxed checks): Relaxed permission checks apply.

|WARL |Preset

|[#dmAbstractcsCmderr]## |cmderr| a|
Gets set if an abstract command fails. The bits in this field remain set
until they are cleared by writing 1 to them. No abstract command is
started until the value is reset to 0.

This field only contains a valid value if is 0.

0 (none): No error.

1 (busy): An abstract command was executing while , , or was written, or
when one of the `data` or `progbuf` registers was read or written. This
status is only written if contains 0.

2 (not supported): The command in is not supported. It may be supported
with different options set, but it will not be supported at a later time
when the hart or system state are different.

3 (exception): An exception occurred while executing the command
(e.g. while executing the Program Buffer).

4 (halt/resume): The abstract command couldn’t execute because the hart
wasn’t in the required state (running/halted), or unavailable.

5 (bus): The abstract command failed due to a bus error (e.g. alignment,
access size, or timeout).

6 (reserved): Reserved for future use.

7 (other): The command failed for another reason.

|R/W1C |0

||datacount| |Number of `data` registers that are implemented as part of
the abstract command interface. Valid sizes are 1 – 12. |R |Preset
|===

== Abstract Command (`command`, at 0x17)

[#dmCommand]## Writes to this register cause the corresponding abstract
command to be executed.

Writing this register while an abstract command is executing causes to
become 1 (busy) once the command completes (busy becomes 0).

If is non-zero, writes to this register are ignored.

inhibits starting a new command to accommodate debuggers that, for
performance reasons, send several commands to be executed in a row
without checking in between. They can safely do so and check at the end
without worrying that one command failed but then a later command (which
might have depended on the previous one succeeding) passed.

[cols="<,<,<,<",options="header",]
|===
|31 |24 |23 |0
|latexmath:[$|cmdtype|$] | |latexmath:[$|control|$] |
|8 | |24 |
|===

[[dmCommandControl]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

|[#dmCommandCmdtype]## |cmdtype| |The type determines the overall
functionality of this abstract command. |WARZ |0

||control| |This field is interpreted in a command-specific manner,
described for each abstract command. |WARZ |0
|===

== Abstract Command Autoexec (`abstractauto`, at 0x18)

[#dmAbstractauto]## This register is optional. Including it allows more
efficient burst accesses. A debugger can detect whether it is supported
by setting bits and reading them back.

If this register is implemented then bits corresponding to implemented
progbuf and data registers must be writable. Other bits must be
hard-wired to 0.

If this register is written while an abstract command is executing then
the write is ignored and becomes 1 (busy) once the command completes
(busy becomes 0).

[cols="<,<,<,<,<,<",options="header",]
|===
|31 |16 |15 |12 |11 |0
|latexmath:[$|autoexecprogbuf|$] | |latexmath:[$|0|$] |
|latexmath:[$|autoexecdata|$] |

|16 | |4 | |12 |
|===

[[dmAbstractautoAutoexecdata]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

|[#dmAbstractautoAutoexecprogbuf]## |autoexecprogbuf| |When a bit in
this field is 1, read or write accesses to the corresponding `progbuf`
word cause the DM to act as if the current value in was written there
again after the access to `progbuf` completes. |WARL |0

||autoexecdata| |When a bit in this field is 1, read or write accesses
to the corresponding `data` word cause the DM to act as if the current
value in was written there again after the access to `data` completes.
|WARL |0
|===

== Configuration Structure Pointer 0 (`confstrptr0`, at 0x19)

[#dmConfstrptrZero]## When is set, reading this register returns bits
31:0 of the configuration structure pointer. Reading the other
`confstrptr` registers returns the upper bits of the address.

When system bus access is implemented, this must be an address that can
be used with the System Bus Access module. Otherwise, this must be an
address that can be used to access the configuration structure from the
hart with ID 0.

If is 0, then the `confstrptr` registers hold identifier information
which is not further specified in this document.

The configuration structure itself is a data structure of the same
format as the data structure pointed to by mconfigptr as described in
the Privileged Spec.

This entire register is read-only.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|addr|$] |
|32 |
|===

== Configuration Structure Pointer 1 (`confstrptr1`, at 0x1a)

[#dmConfstrptrOne]## When is set, reading this register returns bits
63:32 of the configuration structure pointer. See for more details.

This entire register is read-only.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|addr|$] |
|32 |
|===

== Configuration Structure Pointer 2 (`confstrptr2`, at 0x1b)

[#dmConfstrptrTwo]## When is set, reading this register returns bits
95:64 of the configuration structure pointer. See for more details.

This entire register is read-only.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|addr|$] |
|32 |
|===

== Configuration Structure Pointer 3 (`confstrptr3`, at 0x1c)

[#dmConfstrptrThree]## When is set, reading this register returns bits
127:96 of the configuration structure pointer. See for more details.

This entire register is read-only.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|addr|$] |
|32 |
|===

== Next Debug Module (`nextdm`, at 0x1d)

[#dmNextdm]## If there is more than one DM accessible on this DMI, this
register contains the base address of the next one in the chain, or 0 if
this is the last one in the chain.

This entire register is read-only.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|addr|$] |
|32 |
|===

== Abstract Data 0 (`data0`, at 0x04)

[#dmDataZero]## through may be Message Registers, whose behavior is
described in Section #sec:mr[[sec:mr]]. These registers may be read or
changed by abstract commands. indicates how many of them are
implemented, starting at , counting up.
Table #tab:datareg[[tab:datareg]] shows how abstract commands use these
registers.

Accessing these registers while an abstract command is executing causes
to be set to 1 (busy) if it is 0.

Attempts to write them while is set does not change their value.

The values in these registers might not be preserved after an abstract
command is executed. The only guarantees on their contents are the ones
offered by the command in question. If the command fails, no assumptions
can be made about the contents of these registers.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|data|$] |
|32 |
|===

== Program Buffer 0 (`progbuf0`, at 0x20)

[#dmProgbufZero]## through must provide write access to the optional
program buffer. It may also be possible for the debugger to read from
the program buffer through these registers. If reading is not supported,
then all reads return 0.

indicates how many `progbuf` registers are implemented starting at ,
counting up.

Accessing these registers while an abstract command is executing causes
to be set to 1 (busy) if it is 0.

Attempts to write them while is set does not change their value.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|data|$] |
|32 |
|===

== Authentication Data (`authdata`, at 0x30)

[#dmAuthdata]## This register serves as a 32-bit serial port to/from the
authentication module.

When is clear, the debugger can communicate with the authentication
module by reading or writing this register. There is no separate
mechanism to signal overflow/underflow.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|data|$] |
|32 |
|===

== Debug Module Control and Status 2 (`dmcs2`, at 0x32)

[#dmDmcsTwo]## This register contains DM control and status bits that
didn’t easily fit in and . All are optional.

If halt groups are not implemented, then will always be 0 when is 0.

If resume groups are not implemented, then will remain 0 even after 1 is
written there.

The DM external triggers available to add to halt groups may be the same
as or distinct from the DM external triggers available to add to resume
groups.

[cols="<,<,<,<,<,<,<,<,<,<,<,<",options="header",]
|===
|31 |12 |11 | |10 |7 |6 |2 |1 | |0 |
|latexmath:[$|0|$] | |latexmath:[$|grouptype|$] |
|latexmath:[$|dmexttrigger|$] | |latexmath:[$|group|$] |
|latexmath:[$|hgwrite|$] | |latexmath:[$|hgselect|$] |

|20 | |1 | |4 | |5 | |1 | |1 |
|===

[[dmDmcsTwoHgselect]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

|[#dmDmcsTwoGrouptype]## |grouptype| a|
0 (halt): The remaining fields in this register configure halt groups.

1 (resume): The remaining fields in this register configure resume
groups.

|WARL |0

|[#dmDmcsTwoDmexttrigger]## |dmexttrigger| a|
This field contains the currently selected DM external trigger.

If a non-existent trigger value is written here, the hardware will
change it to a valid one or 0 if no DM external triggers exist.

|WARL |0

|[#dmDmcsTwoGroup]## |group| a|
When is 0, contains the group of the hart specified by .

When is 1, contains the group of the DM external trigger selected by .

The value written to this field is ignored unless is also written 1.

Group numbers are contiguous starting at 0, with the highest number
being implementation-dependent, and possibly different between different
group types. Debuggers should read back this field after writing to
confirm they are using a hart group that is supported.

If groups aren’t implemented, then this entire field is 0.

|WARL |preset

|[#dmDmcsTwoHgwrite]## |hgwrite| a|
When 1 is written and is 0, for every selected hart the DM will change
its group to the value written to , if the hardware supports that group
for that hart. Implementations may also change the group of a minimal
set of unselected harts in the same way, if that is necessary due to a
hardware limitation.

When 1 is written and is 1, the DM will change the group of the DM
external trigger selected by to the value written to , if the hardware
supports that group for that trigger.

Writing 0 has no effect.

|W1 |-

||hgselect| a|
0 (harts): Operate on harts.

1 (triggers): Operate on DM external triggers.

If there are no DM external triggers, this field must be tied to 0.

|WARL |0
|===

== Halt Summary 0 (`haltsum0`, at 0x40)

[#dmHaltsumZero]## Each bit in this read-only register indicates whether
one specific hart is halted or not. Unavailable/nonexistent harts are
not considered to be halted.

This register might not be present if fewer than 2 harts are connected
to this DM.

The LSB reflects the halt status of hart \{hartsel[19:5],5’h0}, and the
MSB reflects halt status of hart \{hartsel[19:5],5’h1f}.

This entire register is read-only.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|haltsum0|$] |
|32 |
|===

== Halt Summary 1 (`haltsum1`, at 0x13)

[#dmHaltsumOne]## Each bit in this read-only register indicates whether
any of a group of harts is halted or not. Unavailable/nonexistent harts
are not considered to be halted.

This register might not be present if fewer than 33 harts are connected
to this DM.

The LSB reflects the halt status of harts \{hartsel[19:10],10’h0}
through \{hartsel[19:10],10’h1f}. The MSB reflects the halt status of
harts \{hartsel[19:10],10’h3e0} through \{hartsel[19:10],10’h3ff}.

This entire register is read-only.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|haltsum1|$] |
|32 |
|===

== Halt Summary 2 (`haltsum2`, at 0x34)

[#dmHaltsumTwo]## Each bit in this read-only register indicates whether
any of a group of harts is halted or not. Unavailable/nonexistent harts
are not considered to be halted.

This register might not be present if fewer than 1025 harts are
connected to this DM.

The LSB reflects the halt status of harts \{hartsel[19:15],15’h0}
through \{hartsel[19:15],15’h3ff}. The MSB reflects the halt status of
harts \{hartsel[19:15],15’h7c00} through \{hartsel[19:15],15’h7fff}.

This entire register is read-only.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|haltsum2|$] |
|32 |
|===

== Halt Summary 3 (`haltsum3`, at 0x35)

[#dmHaltsumThree]## Each bit in this read-only register indicates
whether any of a group of harts is halted or not.
Unavailable/nonexistent harts are not considered to be halted.

This register might not be present if fewer than 32769 harts are
connected to this DM.

The LSB reflects the halt status of harts 20’h0 through 20’h7fff. The
MSB reflects the halt status of harts 20’hf8000 through 20’hfffff.

This entire register is read-only.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|haltsum3|$] |
|32 |
|===

== System Bus Access Control and Status (`sbcs`, at 0x38)

[#dmSbcs]##

[cols="<,<,<,<,<,<,<,<,<,<",options="header",]
|===
|31 |29 |28 |23 |22 | |21 | |20 |
|latexmath:[$|sbversion|$] | |latexmath:[$|0|$] |
|latexmath:[$|sbbusyerror|$] | |latexmath:[$|sbbusy|$] |
|latexmath:[$|sbreadonaddr|$] |

|3 | |6 | |1 | |1 | |1 |
|===

[cols="<,<,<,<,<,<,<,<,<,<",options="header",]
|===
|19 |17 |16 | |15 | |14 |12 |11 |5
|latexmath:[$|sbaccess|$] | |latexmath:[$|sbautoincrement|$] |
|latexmath:[$|sbreadondata|$] | |latexmath:[$|sberror|$] |
|latexmath:[$|sbasize|$] |

|3 | |1 | |1 | |3 | |7 |
|===

[cols="<,<,<,<,<,<,<,<,<,<",options="header",]
|===
|4 | |3 | |2 | |1 | |0 |
|latexmath:[$|sbaccess128|$] | |latexmath:[$|sbaccess64|$] |
|latexmath:[$|sbaccess32|$] | |latexmath:[$|sbaccess16|$] |
|latexmath:[$|sbaccess8|$] |

|1 | |1 | |1 | |1 | |1 |
|===

[[dmSbcsSbaccessEight]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

|[#dmSbcsSbversion]## |sbversion| a|
0 (legacy): The System Bus interface conforms to mainline drafts of this
spec older than 1 January, 2018.

1 (1.0): The System Bus interface conforms to this version of the spec.

Other values are reserved for future versions.

|R |1

|[#dmSbcsSbbusyerror]## |sbbusyerror| a|
Set when the debugger attempts to read data while a read is in progress,
or when the debugger initiates a new access while one is already in
progress (while is set). It remains set until it’s explicitly cleared by
the debugger.

While this field is set, no more system bus accesses can be initiated by
the Debug Module.

|R/W1C |0

|[#dmSbcsSbbusy]## |sbbusy| a|
When 1, indicates the system bus manager is busy. (Whether the system
bus itself is busy is related, but not the same thing.) This bit goes
high immediately when a read or write is requested for any reason, and
does not go low until the access is fully completed.

Writes to while is high result in undefined behavior. A debugger must
not write to until it reads as 0.

|R |0

|[#dmSbcsSbreadonaddr]## |sbreadonaddr| |When 1, every write to
automatically triggers a system bus read at the new address. |R/W |0

|[#dmSbcsSbaccess]## |sbaccess| a|
Select the access size to use for system bus accesses.

0 (8bit): 8-bit

1 (16bit): 16-bit

2 (32bit): 32-bit

3 (64bit): 64-bit

4 (128bit): 128-bit

If has an unsupported value when the DM starts a bus access, the access
is not performed and is set to 4.

|R/W |2

|[#dmSbcsSbautoincrement]## |sbautoincrement| |When 1, `sbaddress` is
incremented by the access size (in bytes) selected in after every system
bus access. |R/W |0

|[#dmSbcsSbreadondata]## |sbreadondata| |When 1, every read from
automatically triggers a system bus read at the (possibly
auto-incremented) address. |R/W |0

|[#dmSbcsSberror]## |sberror| a|
When the Debug Module’s system bus manager encounters an error, this
field gets set. The bits in this field remain set until they are cleared
by writing 1 to them. While this field is non-zero, no more system bus
accesses can be initiated by the Debug Module.

An implementation may report ``Other'' (7) for any error condition.

0 (none): There was no bus error.

1 (timeout): There was a timeout.

2 (address): A bad address was accessed.

3 (alignment): There was an alignment error.

4 (size): An access of unsupported size was requested.

7 (other): Other.

|R/W1C |0

|[#dmSbcsSbasize]## |sbasize| |Width of system bus addresses in bits. (0
indicates there is no bus access support.) |R |Preset

|[#dmSbcsSbaccessOneTwentyeight]## |sbaccess128| |1 when 128-bit system
bus accesses are supported. |R |Preset

|[#dmSbcsSbaccessSixtyfour]## |sbaccess64| |1 when 64-bit system bus
accesses are supported. |R |Preset

|[#dmSbcsSbaccessThirtytwo]## |sbaccess32| |1 when 32-bit system bus
accesses are supported. |R |Preset

|[#dmSbcsSbaccessSixteen]## |sbaccess16| |1 when 16-bit system bus
accesses are supported. |R |Preset

||sbaccess8| |1 when 8-bit system bus accesses are supported. |R |Preset
|===

== System Bus Address 31:0 (`sbaddress0`, at 0x39)

[#dmSbaddressZero]## If is 0, then this register is not present.

When the system bus manager is busy, writes to this register will set
and don’t do anything else.

If is 0, is 0, and is set then writes to this register start the
following:

Set .

Perform a bus read from the new value of `sbaddress`.

If the read succeeded and is set, increment `sbaddress`.

Clear .

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|address|$] |
|32 |
|===

[[dmSbaddressZeroAddress]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

||address| |Accesses bits 31:0 of the physical address in `sbaddress`.
|R/W |0
|===

== System Bus Address 63:32 (`sbaddress1`, at 0x3a)

[#dmSbaddressOne]## If is less than 33, then this register is not
present.

When the system bus manager is busy, writes to this register will set
and don’t do anything else.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|address|$] |
|32 |
|===

[[dmSbaddressOneAddress]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

||address| |Accesses bits 63:32 of the physical address in `sbaddress`
(if the system address bus is that wide). |R/W |0
|===

== System Bus Address 95:64 (`sbaddress2`, at 0x3b)

[#dmSbaddressTwo]## If is less than 65, then this register is not
present.

When the system bus manager is busy, writes to this register will set
and don’t do anything else.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|address|$] |
|32 |
|===

[[dmSbaddressTwoAddress]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

||address| |Accesses bits 95:64 of the physical address in `sbaddress`
(if the system address bus is that wide). |R/W |0
|===

== System Bus Address 127:96 (`sbaddress3`, at 0x37)

[#dmSbaddressThree]## If is less than 97, then this register is not
present.

When the system bus manager is busy, writes to this register will set
and don’t do anything else.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|address|$] |
|32 |
|===

[[dmSbaddressThreeAddress]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

||address| |Accesses bits 127:96 of the physical address in `sbaddress`
(if the system address bus is that wide). |R/W |0
|===

== System Bus Data 31:0 (`sbdata0`, at 0x3c)

[#dmSbdataZero]## If all of the `sbaccess` bits in are 0, then this
register is not present.

Any successful system bus read updates `sbdata`. If the width of the
read access is less than the width of `sbdata`, the contents of the
remaining high bits may take on any value.

If either or isn’t 0 then accesses do nothing.

If the bus manager is busy then accesses set , and don’t do anything
else.

Writes to this register start the following:

Set .

Perform a bus write of the new value of `sbdata` to `sbaddress`.

If the write succeeded and is set, increment `sbaddress`.

Clear .

Reads from this register start the following:

``Return'' the data.

Set .

If is set:

Perform a system bus read from the address contained in `sbaddress`,
placing the result in `sbdata`.

If is set and the read was successful, increment `sbaddress`.

Clear .

Only has this behavior. The other `sbdata` registers have no side
effects. On systems that have buses wider than 32 bits, a debugger
should access after accessing the other ` sbdata` registers.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|data|$] |
|32 |
|===

[[dmSbdataZeroData]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |
||data| |Accesses bits 31:0 of `sbdata`. |R/W |0
|===

== System Bus Data 63:32 (`sbdata1`, at 0x3d)

[#dmSbdataOne]## If and are 0, then this register is not present.

If the bus manager is busy then accesses set , and don’t do anything
else.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|data|$] |
|32 |
|===

[[dmSbdataOneData]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

||data| |Accesses bits 63:32 of `sbdata` (if the system bus is that
wide). |R/W |0
|===

== System Bus Data 95:64 (`sbdata2`, at 0x3e)

[#dmSbdataTwo]## This register only exists if is 1.

If the bus manager is busy then accesses set , and don’t do anything
else.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|data|$] |
|32 |
|===

[[dmSbdataTwoData]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

||data| |Accesses bits 95:64 of `sbdata` (if the system bus is that
wide). |R/W |0
|===

== System Bus Data 127:96 (`sbdata3`, at 0x3f)

[#dmSbdataThree]## This register only exists if is 1.

If the bus manager is busy then accesses set , and don’t do anything
else.

[cols="<,<",options="header",]
|===
|31 |0
|latexmath:[$|data|$] |
|32 |
|===

[[dmSbdataThreeData]]
[cols="<,<,^,<",options="header",]
|===
|Field |Description |Access |Reset
|_Continued on next page_ | | |

||data| |Accesses bits 127:96 of `sbdata` (if the system bus is that
wide). |R/W |0
|===

== Custom Features (`custom`, at 0x1f)

[#dmCustom]## This optional register may be used for non-standard
features. Future version of the debug spec will not use this address.

== Custom Features 0 (`custom0`, at 0x70)

[#dmCustomZero]## The optional through registers may be used for
non-standard features. Future versions of the debug spec will not use
these addresses.
