summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/openocd.texi28
-rw-r--r--src/jtag/jtag.h2
-rw-r--r--src/jtag/tcl.c107
-rw-r--r--src/target/arm7_9_common.c15
4 files changed, 128 insertions, 24 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 8156de4d..11267fc0 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -2099,7 +2099,7 @@ nTRST (active-low JTAG TAP reset) before starting new JTAG operations.
@end deffn
@deffn {Command} reset_config mode_flag ...
-This command tells OpenOCD the reset configuration
+This command displays or modifies the reset configuration
of your combination of JTAG board and target in target
configuration scripts.
@@ -2113,7 +2113,9 @@ from a particular combination of interface and board.
with a board that only wires up SRST.)
The @var{mode_flag} options can be specified in any order, but only one
-of each type -- @var{signals}, @var{combination}, @var{trst_type},
+of each type -- @var{signals}, @var{combination},
+@var{gates},
+@var{trst_type},
and @var{srst_type} -- may be specified at a time.
If you don't provide a new value for a given type, its previous
value (perhaps the default) is unchanged.
@@ -2121,6 +2123,8 @@ For example, this means that you don't need to say anything at all about
TRST just to declare that if the JTAG adapter should want to drive SRST,
it must explicitly be driven high (@option{srst_push_pull}).
+@itemize
+@item
@var{signals} can specify which of the reset signals are connected.
For example, If the JTAG interface provides SRST, but the board doesn't
connect that signal properly, then OpenOCD can't use it.
@@ -2128,10 +2132,11 @@ Possible values are @option{none} (the default), @option{trst_only},
@option{srst_only} and @option{trst_and_srst}.
@quotation Tip
-If your board provides SRST or TRST through the JTAG connector,
+If your board provides SRST and/or TRST through the JTAG connector,
you must declare that or else those signals will not be used.
@end quotation
+@item
The @var{combination} is an optional value specifying broken reset
signal implementations.
The default behaviour if no option given is @option{separate},
@@ -2144,26 +2149,37 @@ haven't seen hardware with such a bug, and can be worked around).
@option{combined} implies both @option{srst_pulls_trst} and
@option{trst_pulls_srst}.
-@option{srst_gates_jtag} indicates that asserting SRST gates the
+@item
+The @var{gates} tokens control flags that describe some cases where
+JTAG may be unvailable during reset.
+@option{srst_gates_jtag} (default)
+indicates that asserting SRST gates the
JTAG clock. This means that no communication can happen on JTAG
while SRST is asserted.
+Its converse is @option{srst_nogate}, indicating that JTAG commands
+can safely be issued while SRST is active.
+@end itemize
The optional @var{trst_type} and @var{srst_type} parameters allow the
driver mode of each reset line to be specified. These values only affect
JTAG interfaces with support for different driver modes, like the Amontec
-JTAGkey and JTAGAccelerator. Also, they are necessarily ignored if the
+JTAGkey and JTAG Accelerator. Also, they are necessarily ignored if the
relevant signal (TRST or SRST) is not connected.
+@itemize
+@item
Possible @var{trst_type} driver modes for the test reset signal (TRST)
-are @option{trst_push_pull} (default) and @option{trst_open_drain}.
+are the default @option{trst_push_pull}, and @option{trst_open_drain}.
Most boards connect this signal to a pulldown, so the JTAG TAPs
never leave reset unless they are hooked up to a JTAG adapter.
+@item
Possible @var{srst_type} driver modes for the system reset signal (SRST)
are the default @option{srst_open_drain}, and @option{srst_push_pull}.
Most boards connect this signal to a pullup, and allow the
signal to be pulled low by various events including system
powerup and pressing a reset button.
+@end itemize
@end deffn
diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h
index 786b2b83..60774589 100644
--- a/src/jtag/jtag.h
+++ b/src/jtag/jtag.h
@@ -286,7 +286,7 @@ enum reset_types {
RESET_TRST_PULLS_SRST = 0x8,
RESET_TRST_OPEN_DRAIN = 0x10,
RESET_SRST_PUSH_PULL = 0x20,
- RESET_SRST_GATES_JTAG = 0x40,
+ RESET_SRST_NO_GATING = 0x40,
};
enum reset_types jtag_get_reset_config(void);
diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index 9101d31e..e080279a 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -631,7 +631,12 @@ int jtag_register_commands(struct command_context_s *cmd_ctx)
COMMAND_CONFIG, "(DEPRECATED) jtag_device <ir_length> <ir_expected> <ir_mask>");
register_command(cmd_ctx, NULL, "reset_config", handle_reset_config_command,
COMMAND_ANY,
- "[none/trst_only/srst_only/trst_and_srst] [srst_pulls_trst/trst_pulls_srst] [combined/separate] [trst_push_pull/trst_open_drain] [srst_push_pull/srst_open_drain]");
+ "reset_config "
+ "[none|trst_only|srst_only|trst_and_srst] "
+ "[srst_pulls_trst|trst_pulls_srst|combined|separate] "
+ "[srst_gates_jtag|srst_nogate] "
+ "[trst_push_pull|trst_open_drain] "
+ "[srst_push_pull|srst_open_drain]");
register_command(cmd_ctx, NULL, "jtag_nsrst_delay", handle_jtag_nsrst_delay_command,
COMMAND_ANY, "jtag_nsrst_delay <ms> - delay after deasserting srst in ms");
register_command(cmd_ctx, NULL, "jtag_ntrst_delay", handle_jtag_ntrst_delay_command,
@@ -851,9 +856,6 @@ static int handle_reset_config_command(struct command_context_s *cmd_ctx, char *
int new_cfg = 0;
int mask = 0;
- if (argc < 1)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
/* Original versions cared about the order of these tokens:
* reset_config signals [combination [trst_type [srst_type]]]
* They also clobbered the previous configuration even on error.
@@ -865,13 +867,21 @@ static int handle_reset_config_command(struct command_context_s *cmd_ctx, char *
int tmp = 0;
int m;
- m = RESET_SRST_GATES_JTAG;
- tmp = 0;
+ /* gating */
+ m = RESET_SRST_NO_GATING;
if (strcmp(*args, "srst_gates_jtag") == 0)
- {
- tmp = RESET_SRST_GATES_JTAG;
- goto next;
+ /* default: don't use JTAG while SRST asserted */;
+ else if (strcmp(*args, "srst_nogate") == 0)
+ tmp = RESET_SRST_NO_GATING;
+ else
+ m = 0;
+ if (mask & m) {
+ LOG_ERROR("extra reset_config %s spec (%s)",
+ "gating", *args);
+ return ERROR_INVALID_ARGUMENTS;
}
+ if (m)
+ goto next;
/* signals */
m = RESET_HAS_TRST | RESET_HAS_SRST;
@@ -958,10 +968,81 @@ next:
}
/* clear previous values of those bits, save new values */
- enum reset_types old_cfg = jtag_get_reset_config();
- old_cfg &= ~mask;
- new_cfg |= old_cfg;
- jtag_set_reset_config(new_cfg);
+ if (mask) {
+ int old_cfg = jtag_get_reset_config();
+
+ old_cfg &= ~mask;
+ new_cfg |= old_cfg;
+ jtag_set_reset_config(new_cfg);
+ } else
+ new_cfg = jtag_get_reset_config();
+
+
+ /*
+ * Display the (now-)current reset mode
+ */
+ char *modes[5];
+
+ /* minimal JTAG has neither SRST nor TRST (so that's the default) */
+ switch (new_cfg & (RESET_HAS_TRST | RESET_HAS_SRST)) {
+ case RESET_HAS_SRST:
+ modes[0] = "srst_only";
+ break;
+ case RESET_HAS_TRST:
+ modes[0] = "trst_only";
+ break;
+ case RESET_TRST_AND_SRST:
+ modes[0] = "trst_and_srst";
+ break;
+ default:
+ modes[0] = "none";
+ break;
+ }
+
+ /* normally SRST and TRST are decoupled; but bugs happen ... */
+ switch (new_cfg & (RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST)) {
+ case RESET_SRST_PULLS_TRST:
+ modes[1] = "srst_pulls_trst";
+ break;
+ case RESET_TRST_PULLS_SRST:
+ modes[1] = "trst_pulls_srst";
+ break;
+ case RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST:
+ modes[1] = "combined";
+ break;
+ default:
+ modes[1] = "separate";
+ break;
+ }
+
+ /* TRST-less connectors include Altera, Xilinx, and minimal JTAG */
+ if (new_cfg & RESET_HAS_TRST) {
+ if (new_cfg & RESET_TRST_OPEN_DRAIN)
+ modes[3] = " trst_open_drain";
+ else
+ modes[3] = " trst_push_pull";
+ } else
+ modes[3] = "";
+
+ /* SRST-less connectors include TI-14, Xilinx, and minimal JTAG */
+ if (new_cfg & RESET_HAS_SRST) {
+ if (new_cfg & RESET_SRST_NO_GATING)
+ modes[2] = " srst_nogate";
+ else
+ modes[2] = " srst_gates_jtag";
+
+ if (new_cfg & RESET_SRST_PUSH_PULL)
+ modes[4] = " srst_push_pull";
+ else
+ modes[4] = " srst_open_drain";
+ } else {
+ modes[2] = "";
+ modes[4] = "";
+ }
+
+ command_print(cmd_ctx, "%s %s%s%s%s",
+ modes[0], modes[1],
+ modes[2], modes[3], modes[4]);
return ERROR_OK;
}
diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index 40dddda6..2b064f23 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -1021,12 +1021,19 @@ int arm7_9_assert_reset(target_t *target)
return ERROR_FAIL;
}
- /* at this point trst has been asserted/deasserted once. We want to
- * program embedded ice while SRST is asserted, but some CPUs gate
- * the JTAG clock while SRST is asserted
+ /* At this point trst has been asserted/deasserted once. We would
+ * like to program EmbeddedICE while SRST is asserted, instead of
+ * depending on SRST to leave that module alone. However, many CPUs
+ * gate the JTAG clock while SRST is asserted; or JTAG may need
+ * clock stability guarantees (adaptive clocking might help).
+ *
+ * So we assume JTAG access during SRST is off the menu unless it's
+ * been specifically enabled.
*/
bool srst_asserted = false;
- if (((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0) && ((jtag_reset_config & RESET_SRST_GATES_JTAG) == 0))
+
+ if (((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0)
+ && (jtag_reset_config & RESET_SRST_NO_GATING))
{
jtag_add_reset(0, 1);
srst_asserted = true;