-
-
Notifications
You must be signed in to change notification settings - Fork 842
Description
A method to generate N cycles of TCK with fixed values of TMS and TDI, jtagtap_cycles(), was added somewhat later than the other base methods to jtag_proc structure of function pointers. I have identified four places where this is used.
jtagtap_init()and equivalents, for emitting SWD LINERESET (50 cycles with TMS high), sometimes coded as a literal for-loop aroundjtagtap_next()or a prepared byte buffer.
blackmagic/src/platforms/common/jtagtap.c
Lines 54 to 59 in 54ddc35
/* Ensure we're in JTAG mode. Start by issuing a complete SWD reset of at least 50 reset cycles */ jtagtap_cycle(true, false, 51U); /* Having achieved reset, try the deprecated 16-bit SWD-to-JTAG sequence */ jtagtap_tms_seq(ADIV5_SWD_TO_JTAG_SELECT_SEQUENCE, 16U); /* Next, to complete that sequence, do a full 50+ cycle reset again */ jtagtap_cycle(true, false, 51U); - jtag_scan.c:
jtag_sanity_check(), called as early asjtag_scan()=>jtag_discover()=>jtag_sanity_check(). I have touched this recently in Fix JTAG sanity check in BYPASS device counting #2178.blackmagic/src/target/jtag_scan.c
Lines 306 to 307 in 54ddc35
/* Preload entire DR chain of BYPASS with known 0 value */ jtag_proc.jtagtap_cycle(false, false, jtag_dev_count); - adiv5_jtag.c:
adiv5_jtag_raw_access(), for 8 idle cycles but only for ADI v6 JTAG-DP targets. Never encountered with ADI v5.blackmagic/src/target/adiv5_jtag.c
Lines 166 to 170 in 54ddc35
/* ADIv6 needs 8 idle cycles run after we get done to ensure the state machine is idle */ if (dp->version > 2) jtag_proc.jtagtap_cycle(false, false, 8); return result; } - icepick.c:
icepick_router_handler(), for 10 idle cycles after reconfiguring type-D controller. Very target-specific.
blackmagic/src/target/icepick.c
Lines 135 to 140 in 54ddc35
/* Go to an idle state instruction and then run 10 idle cycles to complete reconfiguration */ icepick_write_ir(device, IR_IDCODE); jtag_proc.jtagtap_cycle(false, false, 10U); /* Now re-scan the bus to pick up all the new TAPs */ jtag_discover(); }
None of these places are particularly hot code (intensively called during debug). The problem is that BMDA backends for FTDI MPSSE, J-Link, CMSIS-DAP never set the pointer, so it stays NULL (in a calloc()'ed struct), allowing one to inadvertently segfault BMDA mid-scan.
The obvious solutions are a) null-check the pointer at all callsites and fall back to jtagtap_next(); b) code the wrappers which invoke corresponding methods bound to jtagtap_next(). Which can then evolve into proper functions optimized for bit-packing and buffering characteristic for the protocols of these low-level adapters.
I've started at it in #2179 just to fix it until other usable or optimized implementations arrive. The CMSIS-DAP protocol is too convoluted for me to do it properly. J-Link HW_JTAG3 and FTDI MPSSE are easier.