From b83d79a42f908d3860f06910fdec8fb4fc670e6c Mon Sep 17 00:00:00 2001 From: dbrownell Date: Wed, 7 Oct 2009 15:31:33 +0000 Subject: [PATCH] Updates for "reset_config": - revert to previous default: don't talk JTAG during SRST - add "srst_nogates" flag, the converse of "srst_gates_jtag" - with no args, display the current configuration And update the User's Guide text with bullet lists to be a bit more clear. git-svn-id: svn://svn.berlios.de/openocd/trunk@2818 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- doc/openocd.texi | 28 +++++++--- src/jtag/jtag.h | 2 +- src/jtag/tcl.c | 107 ++++++++++++++++++++++++++++++++----- src/target/arm7_9_common.c | 15 ++++-- 4 files changed, 128 insertions(+), 24 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 8156de4d1..11267fc08 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 786b2b839..607745891 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 9101d31ee..e080279a0 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 "); 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 - 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 40dddda6c..2b064f231 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;