Skip to main content

1 Introduction

When a design progresses from simulation to hardware implementation, a user’s control and understanding of the system’s current state drops dramatically. To help bring up and debug low level software and hardware, it is critical to have good debugging support built into the hardware. When a robust OS is running on a core, software can handle many debugging tasks. However, in many scenarios, hardware support is essential.

This document outlines a standard architecture for debug support on RISC-V hardware platforms. This architecture allows a variety of implementations and tradeoffs, which is complementary to the wide range of RISC-V implementations. At the same time, this specification defines common interfaces to allow debugging tools and components to target a variety of hardware platforms based on the RISC-V ISA.

System designers may choose to add additional hardware debug support, but this specification defines a standard interface for common functionality.

1.1 Terminology

advanced feature An advanced feature for advanced users. Most users will not be able to take advantage of it.

AMO Atomic Memory Operation.

BYPASS JTAG instruction that selects a single bit data register, also called BYPASS.

component A RISC-V core, or other part of a hardware platform. Typically all components will be connected to a single system bus.

CSR Control and Status Register.

DM Debug Module (see Section 3).

DMI Debug Module Interface (see Section 3.1).

DR JTAG Data Register.

DTM Debug Transport Module (see Section 6).

DXLEN Debug XLEN, which is the widest XLEN a hart supports, ignoring the current value of mxl in misa.

ELP Expected landing pad state, define by the Zicfilp extension.

essential feature An essential feature must be present in order for debug to work correctly.

GPR General Purpose Register.

hardware platform A single system consisting of one or more components.

hart A hardware thread in a RISC-V core.

IDCODE 32-bit Identification CODE, and a JTAG instruction that returns the IDCODE value.

IR JTAG Instruction Register.

JTAG Refers to work done by IEEE’s Joint Test Action Group, described in IEEE 1149.1.

legacy feature A legacy feature should only be implemented to support legacy hardware that is present in a system.

Minimal RISC-V Debug Specification A subset of the full Debug Specification that allows for very small implementations. See Section 3.

NAPOT Naturally Aligned Power-Of-Two.

NMI Non-Maskable Interrupt.

physical address address that is directly usable on the system bus.

recommended feature A recommended feature is not required for debug to work correctly, but it is so useful that it should not be omitted without good reason.

SBA System Bus Access (see Section 3.10).

specialized feature A specialized feature, that only makes sense in the context of some specific hardware.

TAP Test Access Port, defined in IEEE 1149.1.

TM Trigger Module (see Section 5).

virtual address An address as a hart sees it. If the hart is using address translation this may be different from the physical address. If there is no translation then it will be the same.

xepc The exception program counter CSR (e.g. mepc) that is appropriate for the mode being trapped to.

1.2 Context

This specification attempts to support all RISC-V ISA extensions that have, roughly, been ratified through the first half of 2023. In particular, though, this specification specifically addresses features in the following extensions:

  1. A
  2. C
  3. D
  4. F
  5. H
  6. Sm1p13
  7. Smstateen
  8. Ss1p13
  9. V
  10. Zawrs
  11. Zcmp
  12. Zicbom
  13. Zicbop
  14. Zicboz
  15. Zicsr

1.2.1 Versions

Version 0.13 of this document was ratified by the RISC-V Foundation’s board. Versions 0.13.xx are bug fix releases to that ratified specification.

Version 0.14 was a working version that was never officially ratified.

Version 1.0 is almost entirely forwards and backwards compatible with Version 0.13.

1.2.1.1 Bugfixes from 0.13 to 1.0

Changes that fix a bug in the spec:

  1. Fix order of operations described in sbdata0. #392
  2. Resume ack is set after resume, in Section 3.5. #400
  3. sselect applies to svalue . #402
  4. mte only applies when action=0. #411
  5. aamsize does not affect Argument Width. #420
  6. Clarify that harts halt out of reset if haltreq =1. #419

1.2.1.2 Incompatible Changes from 0.13 to 1.0

Changes that are not backwards-compatible. Debuggers or hardware implementations that implement 0.13 will have to change something in order to implement 1.0:

  1. Make haltsum0 optional if there is only one hart. #505
  2. System bus autoincrement only happens if an access actually takes place. (sbdata0) #507
  3. Bump version to 3. #512
  4. Require debugger to poll dmactive after lowering it. #566
  5. Add pending to icount . #574
  6. When a selected trigger is disabled, tdata2 and tdata3 can be written with any value supported by any of the types this trigger supports. #721
  7. tcontrol fields only apply to breakpoint traps, not any trap. #723
  8. If version is greater than 0, then hit0 (previously called mcontrol6.hit) now contains 0 when a trigger fires more than one instruction after the instruction that matched. (This information is now reflected in hit1.) #795
  9. If version is greater than 0, then bit 20 of mcontrol6 is no longer used for timing information. (Previously the bit was called mcontrol6.timing.) #807
  10. If version is greater than 0, then the encodings of size for sizes greater than 64 bit have changed. #807

1.2.1.3 Minor Changes from 0.13 to 1.0

Changes that slightly modify defined behavior. Technically backwards incompatible, but unlikely to be noticeable:

  1. stopcount only applies to hart-local counters. #405
  2. version may be invalid when dmactive=0. #414
  3. Address triggers (mcontrol) may fire on any accessed address. #421
  4. All Trigger Module registers (Table 14) are optional. #431
  5. When extending IR, bypass still is all ones. #437
  6. ebreaks and ebreaku are WARL. #458
  7. NMIs are disabled by stepie. #465
  8. R/W1C fields should be cleared by writing every bit high. #472
  9. Specify trigger priorities in Table 13 relative to exceptions. #478
  10. Time may pass before dmactive becomes high. #500
  11. Clear MPRV when resuming into lower privilege mode. #503
  12. Halt state may not be preserved across reset. #504
  13. Hardware should clear trigger action when dmode is cleared and action is 1. #501
  14. Change quick access exceptions to halt the target in Section 3.7.1.2. #585
  15. Writing 0 to tdata1 forces a state where tdata2 and tdata3 are writable. #598
  16. Solutions to deal with reentrancy in Section 5.4 prevent triggers from matching, not merely firing. This primarily affects icount behavior. #722
  17. Attempts to access an unimplemented CSR raise an illegal instruction exception. #791

1.2.1.4 New Features from 0.13 to 1.0

New backwards-compatible feature that did not exist before:

  1. Add halt groups and external triggers in Section 3.6. #404
  2. Reserve some DMI space for non-standard use. See custom, and custom0 through custom15. #406
  3. Reserve trigger type values for non-standard use. #417
  4. Add nmi bit to itrigger. #408 and #709
  5. Recommend matching on every accessed address. #449
  6. Add resume groups in Section 3.6. #506
  7. Add relaxedpriv . #536
  8. Move scontext, renaming original to mscontext, and create hcontext. #535
  9. Add mcontrol6, deprecating mcontrol. #538
  10. Add hypervisor support: ebreakvs, ebreakvu, v, hcontext, mcontrol, mcontrol6, and priv. #549
  11. Optionally make anyunavail and allunavail sticky, controlled by stickyunavail. #520
  12. Add tmexttrigger to support trigger module external trigger inputs. #543
  13. Describe mcontrol and mcontrol6 behavior with atomic instructions. #561
  14. Trigger hit bits must be set on fire, may be set on match. #593
  15. Add sbytemask and sbytemask to textra32 and textra64. #588
  16. Allow debugger to request harts stay alive with keepalive bit in setkeepalive. #592
  17. Add ndmresetpending to allow a debugger to determine when ndmreset is complete. #594
  18. Add intctl to support triggers from an interrupt controller. #599

1.2.1.5 Incompatible Changes During 1.0 Stable

Backwards-incompatible changes between two versions that are both called 1.0 stable.

  1. nmi was moved from etrigger to itrigger, and is now subject to the mode bits in that trigger.
  2. #728 introduced Message Registers, which were later removed in #878.
  3. It may not be possible to read the contents of the Program Buffer using the progbuf registers. #731
  4. tcontrol fields apply to all traps, not just breakpoint traps. This reverts #723. #880

1.2.1.6 Incompatible Changes Between 1.0.0-rc1 and 1.0.0-rc2

Backwards-incompatible changes between 1.0.0-rc1 and 1.0.0-rc2.

  1. #981 made scontext.data, mcontext.hcontext, sbytemask, and textra64.svalue narrower. This avoids confusion about the contents of scontext and mcontext when XLEN is reduced and increased again.

1.3 About This Document

1.3.1 Structure

This document contains two parts. The main part of the document is the specification, which is given in the numbered chapters. The second part of the document is a set of appendices. The information in the appendices is intended to clarify and provide examples, but is not part of the actual specification.

1.3.2 ISA vs. non-ISA

This specification contains both ISA and non-ISA parts. The ISA parts define self-contained ISA extensions. The other parts of the document describe the non-ISA external debug extension. Chapters whose contents are solely one or the other are labeled as such in their title. Chapters without such a label apply to both ISA and non-ISA.

1.3.3 Register Definition Format

All register definitions in this document follow the format shown below. A simple graphic shows which fields are in the register. The upper and lower bit indices are shown to the top left and top right of each field. The total number of bits in the field are shown below it.

After the graphic follows a table which for each field lists its name, description, allowed accesses, and reset value. The allowed accesses are listed in Table 1. The reset value is either a constant or "Preset." The latter means it is an implementation-specific legal value.

Parts of the register which are currently unused are labeled with the number 0. Software must only write 0 to those fields, and ignore their value while reading. Hardware must return 0 when those fields are read, and ignore the value written to them.

note

This behavior enables us to use those fields later without having to increase the values in the version fields.

Names of registers and their fields are hyperlinks to their definition, and are also listed in the Index.

1.3.3.1 Long Name (, at 0x123)

8d17d6a98d8dd19b9e6c774dcbd20c8c

FieldDescriptionAccessReset
``Description of what this field is used for.R/W15

Table 1. Register Access Abbreviations

| R | Read-only. | | R/W | Read/Write. | | R/W1C | Read/Write Ones to Clear. Writing 0 to every bit has no effect. Writing 1 to every bit clears the field. The result of other writes is undefined. | | WARZ | Write any, read zero. A debugger may write any value. When read this field returns 0. | | W1 | Write-only. Only writing 1 has an effect. When read the returned value should be 0. | | WARL | Write any, read legal. A debugger may write any value. If a value is unsupported, the implementation converts the value to one that is supported. |

1.4 Background

There are several use cases for dedicated debugging hardware, both in native debug and external debug. Native debug (sometimes called self-hosted debug) refers to debug software running on a RISC-V platform which debugs the same platform. The optional Trigger Module provides features that are useful for native debug. External debug refers to debug software running somewhere else, debugging the RISC-V platform via a debug transport like JTAG. The entire document provides features that are useful for external debug.

This specification addresses the use cases listed below. Implementations can choose not to implement every feature, which means some use cases might not be supported.

  • Accessing hardware on a hardware platform without a working CPU. (External debug.)
  • Bootstrapping a hardware platform to test, configure, and program components before there is any executable code path in the hardware platform. (External debug.)
  • Debugging low-level software in the absence of an OS or other software. (External debug.)
  • Debugging issues in the OS itself. (External or native debug.)
  • Debugging processes running on an OS. (Native or external debug.)

1.5 Supported Features

The debug interface described in this specification supports the following features:

  1. All hart registers (including CSRs) can be read/written.
  2. Memory can be accessed either from the hart’s point of view, through the system bus directly, or both.
  3. RV32, RV64, and future RV128 are all supported.
  4. Any hart in the hardware platform can be independently debugged.
  5. A debugger can discover almost everything it needs to know itself, without user configuration.
  6. Each hart can be debugged from the very first instruction executed.
  7. A RISC-V hart can be halted when a software breakpoint instruction is executed.
  8. Hardware single-step can execute one instruction at a time.
  9. Debug functionality is independent of the debug transport used.
  10. The debugger does not need to know anything about the microarchitecture of the harts it is debugging.
  11. Arbitrary subsets of harts can be halted and resumed simultaneously. (Optional)
  12. Arbitrary instructions can be executed on a halted hart. That means no new debug functionality is needed when a core has additional or custom instructions or state, as long as there exist programs that can move that state into GPRs. (Optional)
  13. Registers can be accessed without halting. (Optional)
  14. A running hart can be directed to execute a short sequence of instructions, with little overhead. (Optional)
  15. A system bus manager allows memory access without involving any hart. (Optional)
  16. A RISC-V hart can be halted when a trigger matches the PC, read/write address/data, or an instruction opcode. (Optional)
  17. Harts can be grouped, and harts in the same group will all halt when any of them halts. These groups can also react to or notify external triggers. (Optional)

This document does not suggest a strategy or implementation for hardware test, debugging or error detection techniques. Scan, built-in self test (BIST), etc. are out of scope of this specification, but this specification does not intend to limit their use in RISC-V systems.

It is possible to debug code that uses software threads, but there is no special debug support for it.