Skip to content

Commit f642f1f

Browse files
committed
adiv5_jtag: Restore lost JTAG-DP state across resets
* In some targets like AT32F403A, a nRST falling edge behaves like TRST. IR is loaded with IDCODE. Next transaction expects DPACC but gets a 8974008e:7. * Mangle internal JTAG IR cache to BYPASS state so that daisy-chaining works. For the active/attached target, BMD logic should run through Capture-IR. * Nothing is needed in SWD transport, so avoid calling a null pointer.
1 parent 31d30ad commit f642f1f

File tree

5 files changed

+22
-0
lines changed

5 files changed

+22
-0
lines changed

src/target/adiv5.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,5 +294,6 @@ uint32_t adiv5_jtag_read(adiv5_debug_port_s *dp, uint16_t addr);
294294
uint32_t adiv5_jtag_raw_access(adiv5_debug_port_s *dp, uint8_t rnw, uint16_t addr, uint32_t value);
295295
uint32_t adiv5_jtag_clear_error(adiv5_debug_port_s *dp, bool protocol_recovery);
296296
void adiv5_jtag_abort(adiv5_debug_port_s *dp, uint32_t abort);
297+
void adiv5_jtag_ensure_idle(adiv5_debug_port_s *dp);
297298

298299
#endif /* TARGET_ADIV5_H */

src/target/adiv5_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ struct adiv5_debug_port {
203203
uint32_t (*error)(adiv5_debug_port_s *dp, bool protocol_recovery);
204204
uint32_t (*low_access)(adiv5_debug_port_s *dp, uint8_t RnW, uint16_t addr, uint32_t value);
205205
void (*abort)(adiv5_debug_port_s *dp, uint32_t abort);
206+
void (*ensure_idle)(adiv5_debug_port_s *dp);
206207

207208
#if CONFIG_BMDA == 1
208209
void (*ap_regs_read)(adiv5_access_port_s *ap, void *data);

src/target/adiv5_jtag.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ void adiv5_jtag_dp_handler(const uint8_t dev_index)
5555
dp->low_access = adiv5_jtag_raw_access;
5656
dp->error = adiv5_jtag_clear_error;
5757
dp->abort = adiv5_jtag_abort;
58+
dp->ensure_idle = adiv5_jtag_ensure_idle;
5859
#if CONFIG_BMDA == 1
5960
bmda_jtag_dp_init(dp);
6061
#endif
@@ -175,3 +176,14 @@ void adiv5_jtag_abort(adiv5_debug_port_s *dp, uint32_t abort)
175176
jtag_dev_write_ir(dp->dev_index, IR_ABORT);
176177
jtag_dev_shift_dr(dp->dev_index, NULL, (const uint8_t *)&request, 35);
177178
}
179+
180+
void adiv5_jtag_ensure_idle(adiv5_debug_port_s *dp)
181+
{
182+
/*
183+
* On devices where nRST pulls TRST, the JTAG-DP's IR is reset
184+
* from DPACC/APACC to IDCODE. We want BYPASS in case of daisy-chaining.
185+
*/
186+
jtag_devs[dp->dev_index].current_ir = 0xffU;
187+
/* Go from TLR to RTI. */
188+
jtagtap_return_idle(1);
189+
}

src/target/adiv5_swd.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ bool adiv5_swd_scan(const uint32_t targetid)
172172
dp->low_access = adiv5_swd_raw_access;
173173
dp->error = adiv5_swd_clear_error;
174174
dp->abort = adiv5_swd_abort;
175+
dp->ensure_idle = NULL;
175176

176177
#if CONFIG_BMDA == 0
177178
swdptap_init();

src/target/cortexm.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,11 @@ static void cortexm_reset(target_s *const target)
784784
platform_delay(10);
785785
}
786786

787+
adiv5_access_port_s *ap = cortex_ap(target);
788+
adiv5_debug_port_s *dp = ap->dp;
789+
if (dp->ensure_idle)
790+
dp->ensure_idle(dp);
791+
787792
/* Check if the reset succeeded */
788793
const uint32_t status = target_mem32_read32(target, CORTEXM_DHCSR);
789794
if (!(status & CORTEXM_DHCSR_S_RESET_ST)) {
@@ -792,6 +797,8 @@ static void cortexm_reset(target_s *const target)
792797
* Trigger reset by AIRCR.
793798
*/
794799
target_mem32_write32(target, CORTEXM_AIRCR, CORTEXM_AIRCR_VECTKEY | CORTEXM_AIRCR_SYSRESETREQ);
800+
if (dp->ensure_idle)
801+
dp->ensure_idle(dp);
795802
}
796803

797804
/* If target needs to do something extra (see Atmel SAM4L for example) */

0 commit comments

Comments
 (0)