Skip to content

Commit a1ae913

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 a1ae913

File tree

3 files changed

+21
-0
lines changed

3 files changed

+21
-0
lines changed

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
@@ -41,6 +41,17 @@
4141
#define IR_DPACC 0xaU
4242
#define IR_APACC 0xbU
4343

44+
static void adiv5_jtag_ensure_idle(adiv5_debug_port_s *dp)
45+
{
46+
/*
47+
* On devices where nRST pulls TRST, the JTAG-DP's IR is reset
48+
* from DPACC/APACC to IDCODE. We want BYPASS in case of daisy-chaining.
49+
*/
50+
jtag_devs[dp->dev_index].current_ir = 0xffU;
51+
/* Go from TLR to RTI. */
52+
jtagtap_return_idle(1);
53+
}
54+
4455
void adiv5_jtag_dp_handler(const uint8_t dev_index)
4556
{
4657
adiv5_debug_port_s *dp = calloc(1, sizeof(*dp));
@@ -55,6 +66,7 @@ void adiv5_jtag_dp_handler(const uint8_t dev_index)
5566
dp->low_access = adiv5_jtag_raw_access;
5667
dp->error = adiv5_jtag_clear_error;
5768
dp->abort = adiv5_jtag_abort;
69+
dp->ensure_idle = adiv5_jtag_ensure_idle;
5870
#if CONFIG_BMDA == 1
5971
bmda_jtag_dp_init(dp);
6072
#endif

src/target/cortexm.c

Lines changed: 8 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,9 @@ 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+
platform_delay(10);
801+
if (dp->ensure_idle)
802+
dp->ensure_idle(dp);
795803
}
796804

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

0 commit comments

Comments
 (0)