Hello:
The Raspberry Pi OpenOCD fork proves the RP2350 path is practical. It allows a
RISC-V target to be configured with an ADIv5/ADIv6 DAP/AP:
target create rp2350.rv0 riscv -dap rp2350.dap -ap-num 0xa000 -coreid 0
Internally, however, that fork keeps the transport decision inside the RISC-V
target implementation. The generic RISC-V code learns about ADIv5 state, sets
an "alternative_dmi" flag, and then several code paths branch on that flag. The
normal DMI scan path remains JTAG-oriented, while AP-backed access is handled
as a special case in places such as batch execution, DTMCS handling, and
riscv-013 DMI operations. In other words, their fork gets RP2350 working, but
the RISC-V target still has to know whether it is using JTAG or AP-backed DMI
access.
My fork takes a different direction. Inspired (or let's say based on) by the
patch Jan Matyáš mentioned, I modeled DTM as an object, rather than a hardcoded
assumption (JTAG or MEM-AP) on actual the RISC-V debug logic.
Currently there's 3 DTM backend in my fork to demonstrate the usefulness of
such a refactor:
- jtag: the existing JTAG DTM path, including IR/DR scans, DTMCS, DMI nops,
idle cycles, and bscan tunnel handling.
- ddmi/direct: a wrapper for probes that expose high-level DMI read/write,
such as the one I made for WCH chips.
- ap: an ADIv5/ADIv6 AP-backed DMI backend, used for RP2350.
The important interface boundary is that the RISC-V higher-level debug code
only asks for DMI read/write/batch operations. It does not need to know whether
those DMI operations are implemented by JTAG scans, a debugger API that exposes
DMI directly, or an AP memory window. JTAG-specific concepts such as IR values,
DR scan layout, DTMCS scanning, DMI NOP scans, bscan tunnel selection, and idle
cycle insertion are backend details of the JTAG DTM backend.
This has a few advantages:
1. It matches the RISC-V debug architecture more closely. The RISC-V Debug
Module is accessed through DMI. JTAG is one standard DTM implementation, but it
is not the only possible transport. Keeping DMI as the abstraction boundary
avoids baking JTAG assumptions into the target layer.
2. RP2350 support becomes an instance of a generic transport mechanism, not a
target-local exception. The RP2350 config can still use the familiar OpenOCD
form:
target create rp2350.rv0 riscv -dap rp2350.dap -ap-num 0xa000 -coreid 0
but that configuration now creates or selects an AP-backed DTM object rather
than enabling an "alternative_dmi" mode inside the RISC-V target.
3. Future non-JTAG support does not require more transport checks in the RISC-V
target. A new probe or SoC transport can provide a DTM backend that exposes DMI
read/write/batch operations. The target code above that layer should not grow
additional "if this transport" branches. This is demonstrated by WCH support
with my custom probe.
4. Existing JTAG behavior remains isolated. Moving JTAG scan construction and
DTMCS/DMI scan mechanics into the JTAG backend keeps the legacy path intact
while making the boundary explicit. This should make review easier because the
core RISC-V logic and the JTAG transport mechanics are no longer mixed as
deeply.
The RP fork is therefore a useful tool for RP2350, but only for RP2350, not for
the growing amount of RISC-V chips that are using diverse debug transportation
methods, just as RISC-V spec said. I think the named-DTM/backend model is the
better way forward. It keeps JTAG-specific code in the JTAG backend, and gives
OpenOCD a reusable path for high-level DMI adapters and non-JTAG RISC-V chips
beyond RP2350, such as the WCH CH32V2/3 series, which just exposed raw DMI R/W
on the naked SWD-ish wire.
________________________________
From: Antonio Borneo <[email protected]>
Sent: Thursday, July 16, 2026 7:59 PM
To: Jan Matyáš <[email protected]>
Cc: Improper CatGirl <[email protected]>;
[email protected] <[email protected]>
Subject: Re: [RFC] riscv: decouple Debug Module logic from the JTAG DMI
transport
Hello,
the RaspberryPi chip RP2350 has Risc-V behind ARM DAP, no DTM as far as I
understand.
There is a fork of OpenOCD that already addresses RP2350. I hope to see it
upstream soon.
See the thread in
https://sourceforge.net/p/openocd/mailman/openocd-devel/thread/CAAj6DX2tjx5893gJYK_LhWFAOt_J6XTG32DRkie4Wvw14h-_3A%40mail.gmail.com/#msg59241351
Said that, any contribution to OpenOCD is welcome!
Feel free to propose your work by following the hints in the file HACKING.
Regards
Antonio
On Thu, Jul 16, 2026 at 8:23 AM Jan Matyáš
<[email protected]<mailto:[email protected]>> wrote:
Hello Improper CatGirl,
Your proposal to separate the RISC-V transport specific code (DTM-specific
logic) from the rest of the RISC-V code sounds perfectly fine to me. I support
that direction.
Nevertheless, I am afraid that I won't have enough time to review your current
implementation in near term.
As a hint: You may also want to check the patch [1] (or an attempted split of
that patch [2]) which aims to introduce a DTM as a separate entity in OpenOCD's
Tcl configuration files. It sounds like that effort is at least somewhat
related to your work.
Regards,
Jan
[1] https://review.openocd.org/c/openocd/+/9695
[2] https://review.openocd.org/c/openocd/+/9760 + related series of patches
________________________________
From: Improper CatGirl
<[email protected]<mailto:[email protected]>>
Sent: Wednesday, July 15, 2026 2:12 PM
To:
[email protected]<mailto:[email protected]>
<[email protected]<mailto:[email protected]>>
Subject: [RFC] riscv: decouple Debug Module logic from the JTAG DMI transport
Some people who received this message don't often get email from
[email protected]<mailto:[email protected]>. Learn why
this is important<https://aka.ms/LearnAboutSenderIdentification>
Hello,
I have been working on support for a non-JTAG RISC-V debug transport and
would like feedback on decoupling OpenOCD's RISC-V Debug Module logic from its
current JTAG DTM implementation.
Background
The RISC-V debug architecture separates the Debug Module Interface (DMI) and
Debug Module from the transport used to access them. The specification defines
a standard JTAG DTM, but the spec specifically said implementations may provide
access to DMI through any other transport.
OpenOCD's current RISC-V implementation hard coded the assumption of JTAG. The
riscv-013 code directly uses JTAG TAPs, IR and DR scans, DTMCS operations, idle
cycles, and JTAG-oriented DMI batches. Consequently, a target that provides
standard RISC-V DMI semantics over a non-JTAG transport cannot reuse the
existing RISC-V Debug Module implementation.
Proposed direction
I propose introducing a transport-neutral DMI operations layer between the
RISC-V Debug Module implementation and the transport-specific code.
A transport backend would provide operations for initialization, DMI reads
and writes, DMI reset, and preferably batched DMI transactions. Details
that are specific to the JTAG DTM, such as IR selection, DTMCS scans,
run-test/idle cycles and BSCAN tunneling, would remain in the JTAG backend.
Use case and proof of concept
I have a working proof of concept for WCH RISC-V devices. These devices use
WCH's non-JTAG debug connection, therefore, cannot be supported by OpenOCD in
its current form.
The proof of concept includes:
an adapter driver for the proof-of-concept probe;
a demonstration abstraction for non-JTAG DMI transactions;
support for WCH devices as the initial test targets; and
working debug access through the existing RISC-V Debug Module operations.
Repo: https://github.com/ImproperCatGirl/openocd
https://github.com/ImproperCatGirl/RVSWD_pico
This is intended solely as a dirty architectural demonstration. I am not
assuming that the current interface or patch organization is suitable for
upstream in its present form.