Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Restore lost JTAG-DP state across resets #2072

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

ALTracer
Copy link
Contributor

@ALTracer ALTracer commented Feb 9, 2025

Detailed description

  • This is a minor new feature, akin to OpenOCD reset_config srst_pulls_trst.
  • The existing problem is AT32F403A in JTAG transport disappearing during load/reset, as if nRST falling edge asserts TRST. Thus it's impossible to flash it, SWD is required (and it does protocol recovery).
  • The PR solves it by adding intermediate JTAG-DP related sequences every time Cortex-M targets are reset.

35-bit DPACC/APACC of 8974008e:7 (<<3, + 7) is 0x44ba00477, and 0x4ba00477 is JTAG-DP v0 IDCODE. So I assume IR gets loaded with IDCODE as if TAP is reset.
BMD has internal IR cache for all JTAG devices. If this device is selected, its IR should be changed to DPACC/APACC/ABORT for next access. If another device is selected but this target was reset by a shared nRST network, then IR should be changed to BYPASS for daisy-chain operation to continue.
A new function, adiv5_jtag_ensure_idle(), is added to struct debug_port, and NULL-checked to not break SWD transport.

This is tested on BMDA+blackpill-f411ce and at32f403acgu7 to fix flash loading.
TODO: BMDA CMSIS-DAP backend for JTAG sequences?

Your checklist for this pull request

Closing issues

@@ -172,6 +172,7 @@ bool adiv5_swd_scan(const uint32_t targetid)
dp->low_access = adiv5_swd_raw_access;
dp->error = adiv5_swd_clear_error;
dp->abort = adiv5_swd_abort;
dp->ensure_idle = NULL;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to assign here - calloc() ensures the struct is 0'd out anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted. I thought it'd be important to always fill this field in case protocols are switched, but indeed it is freshly calloc'ed.

@@ -294,5 +294,6 @@ uint32_t adiv5_jtag_read(adiv5_debug_port_s *dp, uint16_t addr);
uint32_t adiv5_jtag_raw_access(adiv5_debug_port_s *dp, uint8_t rnw, uint16_t addr, uint32_t value);
uint32_t adiv5_jtag_clear_error(adiv5_debug_port_s *dp, bool protocol_recovery);
void adiv5_jtag_abort(adiv5_debug_port_s *dp, uint32_t abort);
void adiv5_jtag_ensure_idle(adiv5_debug_port_s *dp);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given this is only used in adiv5_jtag.c, you can put this at the top of that file and mark it static.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted. Implementation moved.

* 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.
@ALTracer ALTracer force-pushed the feature/srst-pulls-trst branch from f642f1f to a1ae913 Compare February 9, 2025 19:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants