Reorder the two JTAG reset events (C/internal, Tcl/external) so
they can be used properly to enable TAPs with ICEpick. Make them
kick in the same way on *both* paths (TCK/TMS or TRST).
Tweak TCL reset script ... mostly improving comments about what
the steps do, but also call [target names] only once.
Plus some minor cleanups (whitespace, strings, better messaging
during debug) to reset-related code.
---
I think only that first change could be controversial; if nobody
comes up with a reason it could cause trouble, I'll commit this
later today.
src/helper/startup.tcl | 39 +++++++++++++++++++++++++++------------
src/jtag/core.c | 26 ++++++++++++--------------
src/target/target.c | 3 ++-
3 files changed, 41 insertions(+), 27 deletions(-)
--- a/src/helper/startup.tcl
+++ b/src/helper/startup.tcl
@@ -157,6 +157,7 @@ proc ocd_process_reset { MODE } {
}
proc ocd_process_reset_inner { MODE } {
+ set targets [target names]
# If this target must be halted...
set halt -1
@@ -175,26 +176,38 @@ proc ocd_process_reset_inner { MODE } {
# Target event handlers *might* change which TAPs are enabled
# or disabled, so we fire all of them. But don't issue any
- # of the "arp_*" commands, which may issue JTAG transactions,
+ # target "arp_*" commands, which may issue JTAG transactions,
# unless we know the underlying TAP is active.
+ #
+ # NOTE: ARP == "Advanced Reset Process" ... "advanced" is
+ # relative to a previous restrictive scheme
- foreach t [ target names ] {
+ foreach t $targets {
# New event script.
$t invoke-event reset-start
}
- # Init the tap controller.
+ # Use TRST or TMS/TCK operations to reset all the tap controllers.
+ # TAP reset events get reported; they might enable some taps.
+ #
+ # REVISIT arp_init-reset pulses SRST (if it can) with TRST active;
+ # but SRST events aren't reported (unlike "jtag arp_reset", below)
jtag arp_init-reset
# Examine all targets on enabled taps.
- foreach t [ target names ] {
+ foreach t $targets {
if {[jtag tapisenabled [$t cget -chain-position]]} {
$t arp_examine
}
}
- # Let the C code know we are asserting reset.
- foreach t [ target names ] {
+ # Assert SRST, and report the pre/post events.
+ #
+ # REVISIT this presumes a single-target config, since SRST
+ # applies to the whole device-under-test. When two targets
+ # both need special setup before SRST, it's only done for
+ # the first one...
+ foreach t $targets {
$t invoke-event reset-assert-pre
# C code needs to know if we expect to 'halt'
if {[jtag tapisenabled [$t cget -chain-position]]} {
@@ -203,8 +216,8 @@ proc ocd_process_reset_inner { MODE } {
$t invoke-event reset-assert-post
}
- # Now de-assert reset.
- foreach t [ target names ] {
+ # Now de-assert SRST, and report the pre/post events.
+ foreach t $targets {
$t invoke-event reset-deassert-pre
# Again, de-assert code needs to know..
if {[jtag tapisenabled [$t cget -chain-position]]} {
@@ -213,9 +226,11 @@ proc ocd_process_reset_inner { MODE } {
$t invoke-event reset-deassert-post
}
- # Pass 1 - Now try to halt.
+ # Pass 1 - Now wait for any halt (requested as part of reset
+ # assert/deassert) to happen. Ideally it takes effect without
+ # first executing any instructions.
if { $halt } {
- foreach t [target names] {
+ foreach t $targets {
if {[jtag tapisenabled [$t cget -chain-position]] == 0}
{
continue
}
@@ -239,7 +254,7 @@ proc ocd_process_reset_inner { MODE } {
#Pass 2 - if needed "init"
if { 0 == [string compare init $MODE] } {
- foreach t [target names] {
+ foreach t $targets {
if {[jtag tapisenabled [$t cget -chain-position]] == 0}
{
continue
}
@@ -252,7 +267,7 @@ proc ocd_process_reset_inner { MODE } {
}
}
- foreach t [ target names ] {
+ foreach t $targets {
$t invoke-event reset-end
}
}
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -446,7 +446,7 @@ void jtag_add_dr_scan(int in_num_fields,
tap_state_t state)
{
assert(state != TAP_RESET);
-
+
jtag_prelude(state);
int retval;
@@ -458,7 +458,7 @@ void jtag_add_plain_dr_scan(int in_num_f
tap_state_t state)
{
assert(state != TAP_RESET);
-
+
jtag_prelude(state);
int retval;
@@ -471,7 +471,6 @@ void jtag_add_dr_out(jtag_tap_t* tap,
tap_state_t end_state)
{
assert(end_state != TAP_RESET);
-
assert(end_state != TAP_INVALID);
cmd_queue_cur_state = end_state;
@@ -486,9 +485,9 @@ void jtag_add_tlr(void)
jtag_prelude(TAP_RESET);
jtag_set_error(interface_jtag_add_tlr());
- jtag_notify_reset();
-
+ /* NOTE: order here matches TRST path in jtag_add_reset() */
jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
+ jtag_notify_reset();
}
void jtag_add_pathmove(int num_states, const tap_state_t *path)
@@ -684,21 +683,19 @@ void jtag_add_reset(int req_tlr_or_trst,
} else if (jtag_trst != new_trst) {
jtag_trst = new_trst;
if (jtag_trst) {
- /* we just asserted nTRST, so we're now in TAP_RESET;
- * inform possible listeners about this
- *
- * REVISIT asserting TRST is less significant than
- * being in TAP_RESET ... both entries (TRST, TLR)
- * should trigger a callback.
- */
LOG_DEBUG("TRST line asserted");
tap_set_state(TAP_RESET);
- jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
} else {
LOG_DEBUG("TRST line released");
if (jtag_ntrst_delay)
jtag_add_sleep(jtag_ntrst_delay * 1000);
+ /* We just asserted nTRST, so we're now in TAP_RESET.
+ * Inform possible listeners about this, now that
+ * JTAG instructions and data can be shifted. This
+ * sequence must match jtag_add_tlr().
+ */
+ jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
jtag_notify_reset();
}
}
@@ -823,7 +820,8 @@ static int jtag_reset_callback(enum jtag
{
jtag_tap_t *tap = priv;
- LOG_DEBUG("-");
+ LOG_DEBUG("TAP %s event %s", tap->dotted_name,
+ jtag_event_strings[event]);
if (event == JTAG_TRST_ASSERTED)
{
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -4028,7 +4028,8 @@ static int tcl_target_func(Jim_Interp *i
break;
case TS_CMD_RESET:
if (goi.argc != 2) {
- Jim_WrongNumArgs(interp, 2, argv, "t | f|assert |
deassert BOOL");
+ Jim_WrongNumArgs(interp, 2, argv,
+ "([tT]|[fF]|assert|deassert) BOOL");
return JIM_ERR;
}
e = Jim_GetOpt_Nvp(&goi, nvp_assert, &n);
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development