(Addition to what I posted, to avoid unclarity)

  *
Jan: (...) All other processing should go to the underlying transport-specific 
layers.

In other words, I meant that the RISC-V code should be clearly separated into:


  *
A generic, transport-independent part.
  *
Transport-specific parts (JTAG DTM, ARM ADI, ...).


The API between those two should be DMI reads & writes (including the 
possibility to create batches), as ImproperCatGirl suggests.

Jan


________________________________
From: Jan Matyáš <[email protected]>
Sent: Friday, July 17, 2026 7:55 AM
To: Improper CatGirl <[email protected]>; Antonio Borneo 
<[email protected]>; [email protected] 
<[email protected]>
Subject: Re: [RFC] riscv: decouple Debug Module logic from the JTAG DMI 
transport

Hello,


  *
ImproperCatGirl: "My fork takes a different direction. (...) 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."


I haven't yet had opportunity to take a look at the code of the "RP2350" or 
"ImproperCatGirl/openocd" forks, mentioned in this thread.

However, I fully agree with the statement above and the rationale that 
ImproperCatGirl provided. IMO, this proposal is an architecturally correct 
approach. The RISC-V transport-independent code should end with DMI read and 
DMI write requests (singular requests or batches). All other processing should 
go to the underlying transport-specific layers.

Regards,
Jan



________________________________
From: Improper CatGirl <[email protected]>
Sent: Thursday, July 16, 2026 6:46 PM
To: Antonio Borneo <[email protected]>; Jan Matyáš 
<[email protected]>; [email protected] 
<[email protected]>
Cc: [email protected] <[email protected]>
Subject: Re: [RFC] riscv: decouple Debug Module logic from the JTAG DMI 
transport

You don't often get email from [email protected]. Learn why this is 
important<https://aka.ms/LearnAboutSenderIdentification>
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.





Reply via email to