phdussud / pico-dirtyJtag

MIT License
276 stars 38 forks source link

does this work with openocd? #6

Closed laoshaw closed 1 year ago

laoshaw commented 1 year ago

how to talk to this JTAG adapter? will openocd work somehow and do I need write a service daemon on the host PC for pico-dirtyJtag? any doc on how to use this in practice? Thanks.

phdussud commented 1 year ago

You can use openocd. Please refer to https://github.com/jeanthom/DirtyJTAG. That's the original DirtyJTAG device. The read.me has all of the details you need to use a DirtyJTAG device. Please let me know if something is unclear.

laoshaw commented 1 year ago

the pico has 3 wires SWD for its own JTAG along with OpenOCD, which is separated from pico-DirtyJtag pins, how does openocd on my host PC knows it is talking to dirtyJtag instead of RP2040's own SWD-Jtag in this case?

For host PC openocd to talk with dirtyJtag, do I need wire anything other than the existing USB connection between RP2040-Pico and my host PC?

where is cfg file for openocd?

Thanks! new to this.

phdussud commented 1 year ago

In order to use the SWD pins, they need to be connected to a programmer supporting SWD. As long as they are not connected to anything, there is no confusion. The Host PC directly uses the USB interface of the RP2040. If your host PC is running Windows, you will need to use Zadig to install a libusb driver for the DirtyJTAG device. The OpenOCD docs for Windows may have more information.

laoshaw commented 1 year ago

Thanks a lot for the help!

jeanthom commented 1 year ago

Hi everyone, there has been attempts at implementing OpenOCD support for DirtyJTAG but I haven't been able to successfully program a Lattice ECP5 :/ https://github.com/jeanthom/openocd-dirtyjtag

Otherwise you can use UrJTAG or openFPGALoader if this suits your needs.

laoshaw commented 1 year ago

would be nice if openocd works as it is what we use for all other boards :)

phdussud commented 1 year ago

I can give you a better version of your file. It does program a lattice ECP5 but gets an error getting the status of the chip right before sending the bits. The chip is programmed correctly (the resulting firmware works).

If you want the file, be aware that I ported your code to the master branch of the openocd repo (on sourceforge). You may have to adjust it slightly to get it to compile on your version of openocd.

Here is the shell output: $openocd.exe -c "tcl_port disabled" --file tcl/interface/dirtyjtag.cfg --file ecp5.cfg Open On-Chip Debugger 0.11.0+dev-00873-g219cb9598-dirty (2022-09-14-13:58) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : only one transport option; autoselect 'jtag' DEPRECATED! use 'adapter speed' not 'adapter_khz' adapter speed: 6000 kHz

Info : clock speed 6000 kHz Info : JTAG tap: lfe5.tap tap/device found: 0x41113043 (mfg: 0x021 (Lattice Semi.), part: 0x1113, ver: 0x4) Warn : gdb services need one or more targets defined svf processing file: "bitstream.svf" 0% STATE RESET; 0% HDR 0; (Above Padding command skipped, as per -tap argument) 0% HIR 0; (Above Padding command skipped, as per -tap argument) 0% TDR 0; (Above Padding command skipped, as per -tap argument) 0% TIR 0; (Above Padding command skipped, as per -tap argument) 0% ENDDR DRPAUSE; 0% ENDIR IRPAUSE; 0% FREQUENCY 6.00e+006 HZ; adapter speed: 6000 kHz

0% STATE IDLE; 0% SIR 8 TDI (E0); 0% MASK (FFFFFFFF); 0% SIR 8 TDI (1C); 0% FFFFFFFFFFFFFFFFFFFFFFFFFFFF); 0% SIR 8 TDI (C6); 0% SDR 8 TDI (00); 0% RUNTEST IDLE 2 TCK 1.00E-002 SEC; 0% SIR 8 TDI (3C); 0% RUNTEST IDLE 2 TCK 1.00E-003 SEC; 0% MASK (00024040); 0% SIR 8 TDI (0E); 0% SDR 8 TDI (01); 0% RUNTEST IDLE 2 TCK 2.00E-000 SEC; 0% SIR 8 TDI (3C); 0% MASK (0000B000); 0% SIR 8 TDI (46); 0% SDR 8 TDI (01); 0% RUNTEST IDLE 2 TCK 1.00E-002 SEC; 0% SIR 8 TDI (7A); 0% RUNTEST IDLE 2 TCK 1.00E-002 SEC; 95% FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); 95% SIR 8 TDI (FF); 95% RUNTEST IDLE 100 TCK 1.00E-002 SEC; 95% SIR 8 TDI (C0); 95% RUNTEST IDLE 2 TCK 1.00E-003 SEC; 95% MASK (FFFFFFFF); 95% SIR 8 TDI (26); 95% RUNTEST IDLE 2 TCK 2.00E-001 SEC; 95% SIR 8 TDI (FF); 95% RUNTEST IDLE 2 TCK 1.00E-003 SEC; 95% SIR 8 TDI (3C); 95% MASK (00002100); 95% STATE RESET; Error: tdo check error at line 95 Error: READ = 0x0201f10 Error: WANT = 0x0000000 Error: MASK = 0x000b000 Time used: 0m7s14ms svf file programmed failed

phdussud commented 1 year ago

I spent more time on investigating the error. I am convinced that it is a bug in the SVF generation. The device reports it is busy and not ready after an erase instruction. If I add 1000 cycles to this line RUNTEST IDLE 1000 TCK 2.00E-001 SEC, then the programming does not generate an error. I modified the source code of dirtyjtag.c (openocd change) to wait a min of 1000 cycles in RUNTEST instructions to work around this problem.

phdussud commented 1 year ago

The changes are there: https://sourceforge.net/u/phdussud/openocd/ci/48ac6f3ebcf1a1d0281ed328cc8a52c746fb3560/

phdussud commented 1 year ago

Better look here: https://sourceforge.net/u/phdussud/openocd/ This will show all of my changes.

phdussud commented 1 year ago

About the SVF file... There was a bug in the JTAG_SLEEP implementation that didn't flush the instructions before the sleep. The effect was the sleep isn't affecting the right SVF instruction. It is fixed now and the SVF file does work as generated by the Lattice Diamond tool. If you guys (@laoshaw and @jeanthom) could try and let me know, I will appreciate it. Thanks.

zoobab commented 1 year ago

Will give it a shot! I was hoping for openocd support for dirtyjtag for quite a while :-)

jeanthom commented 1 year ago

Hi @phdussud, sorry for the while it took me to give it a try. My test setup is an STM32-based DirtyJTAG connected to a PortalPlayer PP5002-based media player, and I ran into the following assertion:

openocd: src/jtag/drivers/dirtyjtag.c:513: syncbb_scan: Assertion `read == sent_bytes' failed.
phdussud commented 1 year ago

Hello! The code is suspicious there... res = jtag_libusb_bulk_read(usb_handle, dirtyjtag_ep_read, (char *)xfer_rx, (sent_bytes > 255) ? sent_bytes : 32, DIRTYJTAG_USB_TIMEOUT, &read); assert(res == ERROR_OK); assert(read == sent_bytes); It should be (sent_bits > 255) not (sent_bytes > 255). This is confirmed by the code for openFPGALoader. Theh assert should be changed to assert(read >= sent_bytes); Can you try this change and see if it solves the problem? Thanks!

phdussud commented 1 year ago

After verifying that it does not regress my FPGA programming test, I pushed the change to my repo. Please test and keep me posted.

jeanthom commented 1 year ago

I tried that fix right after sending my message ^^ It did not fix the issue right away, I had to disable to disable the DJTAG version check. This is a bug I identified during my development of a DirtyJTAG driver for flashrom - the STM32 version of DirtyJTAG has a buggy identification function that breaks the firmware...

Now that I have commented out the "dirtyjtag_getversion" calls in my code, I'm having IR capture errors:

Open On-Chip Debugger 0.11.0+dev-00883-gec03ac6b5 (2022-11-05-14:09)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
Warn : Transport "jtag" was already selected
jtag
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Warn : An adapter speed is not selected in the init scripts. OpenOCD will try to run the adapter at the low speed (100 kHz)
Warn : To remove this warnings and achieve reasonable communication speed with the target, set "adapter speed" or "jtag_rclk" in the init scripts.
Info : clock speed 100 kHz
Warn : There are no enabled taps.  AUTO PROBING MIGHT NOT WORK!!
Error: JTAG scan chain interrogation failed: all zeroes
Error: Check JTAG interface, timings, target power, etc.
Error: Trying to use configured scan chain anyway...
Error: IR capture error at bit 0, saw 0x00 not 0x...3
Warn : Bypassing JTAG setup events due to errors
Warn : gdb services need one or more targets defined
phdussud commented 1 year ago

Ok, this is strange. I am not sure it matters, but I think we are not using the same version of tcl/interface/dirtyjtag.cfg. I checked one in my repo: It looks like this: adapter driver dirtyjtag adapter speed 1000

phdussud commented 1 year ago

I am wondering if there is a problem with the pinout of the probe, I know that it is different between V2 and V1 because of the SPI pinout constraints. I also believe that the doc you have for V2 may not be correct for all probes.

jeanthom commented 1 year ago

Here's the content of my openocd script:

adapter driver dirtyjtag
adapter speed 1000
transport select jtag

Pretty similar to yours. I'm quite sure the pinout is correct because everything seems to work well in UrJTAG (both ARM cores of the PP5002 are properly recognized).

phdussud commented 1 year ago

Right. I am a little stumped here. Here is what a blue pill V2 gives me: Open On-Chip Debugger 0.11.0+dev-00883-gec03ac6b5-dirty (2022-11-05-08:55) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : only one transport option; autoselect 'jtag' adapter speed: 1000 kHz

Info : dirtyjtag version 2 Info : clock speed 1000 kHz Info : JTAG tap: lfe5.tap tap/device found: 0x41113043 (mfg: 0x021 (Lattice Semi.), part: 0x1113, ver: 0x4) Warn : gdb services need one or more targets defined svf processing file: "bitstream.svf" adapter speed: 6000 kHz

shutdown command invoked

phdussud commented 1 year ago

my fpga.cfg looks like:

file: ecp5.ocd

tcl_port disabled telnet_port disabled gdb_port disabled

JTAG TAPs

jtag newtap lfe5 tap -irlen 8 -irmask 0x83 -ircapture 0x1 \ -expected-id 0x01111043 -expected-id 0x01112043 -expected-id 0x01113043 \ -expected-id 0x21111043 -expected-id 0x41111043 -expected-id 0x41112043 \ -expected-id 0x41113043 -expected-id 0x81111043 -expected-id 0x81112043 \ -expected-id 0x81113043 reset_config none

init

phdussud commented 1 year ago

If I don't use this ecp5.ocd, I get this:

Info : tcl server disabled Info : Listening on port 4444 for telnet connections Info : dirtyjtag version 2 Info : clock speed 1000 kHz Warn : There are no enabled taps. AUTO PROBING MIGHT NOT WORK!! Info : JTAG tap: auto0.tap tap/device found: 0x41113043 (mfg: 0x021 (Lattice Semi.), part: 0x1113, ver: 0x4) Warn : AUTO auto0.tap - use "jtag newtap auto0 tap -irlen 2 -expected-id 0x41113043" Error: IR capture error at bit 2, saw 0x3fffffffffffff05 not 0x...3 Warn : Bypassing JTAG setup events due to errors Warn : gdb services need one or more targets defined

As a consequence I don't think you can trust auto probing.

phdussud commented 1 year ago

I tried to debug a STM32F407 board using the blue pill DirtyJTAGV2. It does look promising. Here is the output: `$ ../src/openocd.exe -c "tcl_port disabled" --file interface/dirtyjtag.cfg --file target/stm32f4x.cfg Open On-Chip Debugger 0.11.0+dev-00883-gec03ac6b5-dirty (2022-11-05-08:55) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : only one transport option; autoselect 'jtag' adapter speed: 1000 kHz

Info : tcl server disabled Info : Listening on port 4444 for telnet connections Info : dirtyjtag version 2 Info : clock speed 2000 kHz Info : JTAG tap: stm32f4x.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4) Info : JTAG tap: stm32f4x.bs tap/device found: 0x06413041 (mfg: 0x020 (STMicroelectronics), part: 0x6413, ver: 0x0) Info : [stm32f4x.cpu] Cortex-M4 r0p1 processor detected Info : [stm32f4x.cpu] target has 6 breakpoints, 4 watchpoints Info : starting gdb server for stm32f4x.cpu on 3333 Info : Listening on port 3333 for gdb connections Info : [stm32f4x.cpu] external reset detected`

phdussud commented 1 year ago

After fixing a bug (inversion of logic for both the TRST and SRST pins) I can load a debug a program for a STM32F407 processor

(gdb) target extended-remote :3333 Remote debugging using :3333 0x00000000 in ?? () (gdb) monitor reset halt JTAG tap: stm32f4x.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4) JTAG tap: stm32f4x.bs tap/device found: 0x06413041 (mfg: 0x020 (STMicroelectronics), part: 0x6413, ver: 0x0) target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x080076ec msp: 0x2001c380 (gdb) load Loading section .isr_vector, size 0x188 lma 0x8000000 Loading section .text, size 0x3d2c lma 0x8000188 Loading section .data, size 0x28 lma 0x8003eb4 Start address 0x08003e5c, load size 16092 Transfer rate: 3 KB/sec, 5364 bytes/write. (gdb) br main Breakpoint 1 at 0x8000226: file ..\main.c, line 69. Note: automatically using hardware breakpoints for read-only addresses. (gdb) run The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: P:\eclispe-workspace-neon\STM32F4-freq-gen\Debug\STM32F4-freq-gen.elf

Breakpoint 1, main () at ..\main.c:69 69 if (SysTick_Config(SystemCoreClock / 1000)) { (gdb) n 76 TIM_Config(); (gdb) s TIM_Config () at ..\main.c:220 220 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE);

jeanthom commented 1 year ago

Good catch! I'm now able to properly recognize my JTAG tap :)

phdussud commented 1 year ago

Wonderful. I see your repo showing your progress. Let me know when you think dirtyjtag.c works end to end and I will submit a PR to the official OpenOCD repo

jeanthom commented 1 year ago

It seems to work quite well. I think we can start working on upstream that. Maybe we could leave the DJTAG2/DJTAG3 bits for a later pull request?

phdussud commented 1 year ago

I can totally remove the DJTAG3 references from the code. However, DJTAG2 is the only supported version on the pico platform. I was under the impression that DJTAG1 was obsolete so I have not tested it.

phdussud commented 1 year ago

@jeanthom I am in the process of working through the PR process for openocd. You should take a look at: https://review.openocd.org/c/openocd/+/7344 It is quite entertaining. So far I have submitted 15 patches to the PR and there have been discussions on the merit of DirtyJTAG which I responded to. It seems that one of the reviewer believes that sending more than 64bytes to a USB FS devices is faster than breaking the requests into 64bytes chunks. It isn't true of course since libusb will chop the requests into 64 bytes chunks. At some point one has to face the reality of the hardware

0xNoor commented 1 year ago

I tested out this patch, but I'm not able to debug my raspberry pi 4b using pico-dirtyJTAG. Whenever I launch openocd, the following shows up.

Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : dirtyjtag version 2
Info : clock speed 4000 kHz
Info : JTAG tap: bcm2711.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4)
Error: missing data from bitq interface

My command for openocd is sudo ./src/openocd -f tcl/interface/dirtyjtag.cfg -f tcl/target/bcm2711.cfg The reason why I'm not installing is because I regularly use openocd, dont want to mess things up.

phdussud commented 1 year ago

@0xNoor It may very well be a bug in this patch. Can you try a different implementation on https://sourceforge.net/u/phdussud/openocd ? Thanks! Patrick

0xNoor commented 1 year ago

So I tested that out and it worked! Thanks. But after that, (maybe?) new problem is present. Changing the adapter speed wont change the loading speed through GDB. At 1000KHz, the loading speed is around 14-15KBps and at 10000KHz, the speed is at 16-17KBps. So is this a bug or a limitation?

phdussud commented 1 year ago

I think this is may be a limitation, due to the overhead in the communication between the host and the probe. If there is a lot of send/receive on the USB channel, it does not scale.

ThomTrab commented 10 months ago

Hello,

I'm using a Pico running your version of dirtyJTAG. I tried the latest version of your clone of openOCD from SF, but I'm running in the following issue :

Open On-Chip Debugger 0.11.0+dev-00875-g92ec5f2f4 (2023-09-08-21:44)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
adapter speed: 1000 kHz

at91sam9g20_reset_init
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : dirtyjtag version 2
Info : clock speed 5 kHz
Error: libusb_bulk_read error: LIBUSB_ERROR_TIMEOUT
openocd: src/jtag/drivers/dirtyjtag.c:505: syncbb_scan: Assertion `res == ERROR_OK' failed.
Abandon (core dumped)

Any ideas from where this could come from ? Thank you

phdussud commented 10 months ago

I am not sure. The error means that OpenOCD is reading the USB connection and gets a timeout. I find the clock speed very low. It should be much higher than 5kHz. I would say greater than 100kHz. I can imagine that this could trigger a timeout. Try to find out the part of OpenOCD that sets the jtag clock too slow and try with a higher clock speed.


From: ThomTrab @.> Sent: Friday, September 8, 2023 12:56 PM To: phdussud/pico-dirtyJtag @.> Cc: phdussud @.>; Mention @.> Subject: Re: [phdussud/pico-dirtyJtag] does this work with openocd? (Issue #6)

Hello,

I'm using a Pico running your version of dirtyJTAG. I tried the latest version of your clone of openOCD from SF, but I'm running in the following issue :

Open On-Chip Debugger 0.11.0+dev-00875-g92ec5f2f4 (2023-09-08-21:44) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : only one transport option; autoselect 'jtag' adapter speed: 1000 kHz

at91sam9g20_reset_init Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections Info : dirtyjtag version 2 Info : clock speed 5 kHz Error: libusb_bulk_read error: LIBUSB_ERROR_TIMEOUT openocd: src/jtag/drivers/dirtyjtag.c:505: syncbb_scan: Assertion `res == ERROR_OK' failed. Abandon (core dumped)

Any ideas from where this could come from ? Thank you

— Reply to this email directly, view it on GitHubhttps://github.com/phdussud/pico-dirtyJtag/issues/6#issuecomment-1712157734, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ABVQKX45IYGSFRUQF4OIFJ3XZNZ6PANCNFSM6AAAAAAQLSMIUQ. You are receiving this because you were mentioned.Message ID: @.***>

ThomTrab commented 10 months ago

Indeed increasing the clock speed solved the issue. Thanks