X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Ftcl.c;h=5056a5c5d58ac10acdd9438f65a72628979d94ae;hp=9101d31eec95f520750eddc9f9f102f73cb6fc31;hb=0b476c9f4c0235f52f1a6c522f4835b5ca7e05c5;hpb=39b57471bfd92ef0d9a3aceb69f40c1335f5b62f diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index 9101d31eec..5056a5c5d5 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -197,7 +197,6 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi) jim_wide w; int x; int e; - int reqbits; Jim_Nvp *n; char *cp; const Jim_Nvp opts[] = { @@ -252,9 +251,6 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi) pTap->ir_capture_mask = 0x03; pTap->ir_capture_value = 0x01; - /* clear flags for "required options" them as we find them */ - reqbits = 1; - while (goi->argc) { e = Jim_GetOpt_Nvp(goi, opts, &n); if (e != JIM_OK) { @@ -317,7 +313,6 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi) pTap->dotted_name, (int) w); pTap->ir_length = w; - reqbits = 0; break; case NTAP_OPT_IRMASK: if (is_bad_irval(pTap->ir_length, w)) { @@ -355,14 +350,14 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi) pTap->enabled = !pTap->disabled_after_reset; /* Did all the required option bits get cleared? */ - if (0 == reqbits) + if (pTap->ir_length != 0) { jtag_tap_init(pTap); return ERROR_OK; } Jim_SetResult_sprintf(goi->interp, - "newtap: %s missing required parameters", + "newtap: %s missing IR length", pTap->dotted_name); jtag_tap_free(pTap); return JIM_ERR; @@ -631,7 +626,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 +851,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 +862,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 +963,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; } @@ -1167,6 +1243,8 @@ static int handle_runtest_command(struct command_context_s *cmd_ctx, * For "irscan" or "drscan" commands, the "end" (really, "next") state * should be stable ... and *NOT* a shift state, otherwise free-running * jtag clocks could change the values latched by the update state. + * Not surprisingly, this is the same constraint as SVF; the "irscan" + * and "drscan" commands are a write-only subset of what SVF provides. */ static bool scan_is_safe(tap_state_t state) { @@ -1204,25 +1282,14 @@ static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, c if (argc >= 4) { /* have at least one pair of numbers. */ /* is last pair the magic text? */ - if (0 == strcmp("-endstate", args[ argc - 2 ])) { - const char *cpA; - const char *cpS; - cpA = args[ argc-1 ]; - for (endstate = 0 ; endstate < TAP_NUM_STATES ; endstate++) { - cpS = tap_state_name(endstate); - if (0 == strcmp(cpA, cpS)) { - break; - } - } - if (endstate >= TAP_NUM_STATES) { + if (strcmp("-endstate", args[argc - 2]) == 0) { + endstate = tap_state_by_name(args[argc - 1]); + if (endstate == TAP_INVALID) return ERROR_COMMAND_SYNTAX_ERROR; - } else { - if (!scan_is_safe(endstate)) - LOG_WARNING("irscan with unsafe " - "endstate \"%s\"", cpA); - /* found - remove the last 2 args */ - argc -= 2; - } + if (!scan_is_safe(endstate)) + LOG_WARNING("unstable irscan endstate \"%s\"", + args[argc - 1]); + argc -= 2; } }