summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2009-06-01 23:30:58 +0000
committerzwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2009-06-01 23:30:58 +0000
commita8f3ba8f5f66180fb293d0f65b6520ecce9cfe73 (patch)
treea5c3fcf6c8c6103d37159576eec0695a49bd43cb /src
parent5120d1263bf22c5f426333fd28f27216dacf2b56 (diff)
downloadopenocd+libswd-a8f3ba8f5f66180fb293d0f65b6520ecce9cfe73.tar.gz
openocd+libswd-a8f3ba8f5f66180fb293d0f65b6520ecce9cfe73.tar.bz2
openocd+libswd-a8f3ba8f5f66180fb293d0f65b6520ecce9cfe73.tar.xz
openocd+libswd-a8f3ba8f5f66180fb293d0f65b6520ecce9cfe73.zip
David Brownell <david-b@pacbell.net>:
Make the TCL "drscan" and "irscan" commands finish in RUN/IDLE unless the user specifies otherwise ... usually they'd choose something like DRPAUSE or IRPAUSE, avoiding RUN/IDLE. The current "end" state is whatever the preceding commands left in "cmd_queue_end_state", which to TCL scripts isn't knowable. This change should forestall various surprises/bugs. Also check that any "end" state specified is safe in case this adapter's JTAG clock is free-running. For now, just issue a warning; eventually a hard failure is probably correct. git-svn-id: svn://svn.berlios.de/openocd/trunk@1988 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src')
-rw-r--r--src/jtag/jtag.c47
1 files changed, 39 insertions, 8 deletions
diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c
index fb7429f2..ec233086 100644
--- a/src/jtag/jtag.c
+++ b/src/jtag/jtag.c
@@ -2955,6 +2955,26 @@ static int handle_runtest_command(struct command_context_s *cmd_ctx, char *cmd,
}
+/*
+ * 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.
+ */
+static bool scan_is_safe(tap_state_t state)
+{
+ switch (state)
+ {
+ case TAP_RESET:
+ case TAP_IDLE:
+ case TAP_DRPAUSE:
+ case TAP_IRPAUSE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+
static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
int i;
@@ -2967,11 +2987,12 @@ static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, c
return ERROR_COMMAND_SYNTAX_ERROR;
}
- /* optional "-endstate" */
- /* "statename" */
- /* at the end of the arguments. */
- /* assume none. */
- endstate = cmd_queue_end_state;
+ /* optional "-endstate" "statename" at the end of the arguments,
+ * so that e.g. IRPAUSE can let us load the data register before
+ * entering RUN/IDLE to execute the instruction we load here.
+ */
+ endstate = TAP_IDLE;
+
if( argc >= 4 ){
/* have at least one pair of numbers. */
/* is last pair the magic text? */
@@ -2988,6 +3009,9 @@ static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, c
if( endstate >= TAP_NUM_STATES ){
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;
}
@@ -3052,8 +3076,8 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args
return JIM_ERR;
}
- /* assume no endstate */
- endstate = cmd_queue_end_state;
+ endstate = TAP_IDLE;
+
/* validate arguments as numbers */
e = JIM_OK;
for (i = 2; i < argc; i+=2)
@@ -3073,7 +3097,10 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args
return e;
}
- /* it could be: "-endstate FOO" */
+ /* it could be: "-endstate FOO"
+ * e.g. DRPAUSE so we can issue more instructions
+ * before entering RUN/IDLE and executing them.
+ */
/* get arg as a string. */
cp = Jim_GetString( args[i], NULL );
@@ -3088,6 +3115,10 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args
/* update the error message */
Jim_SetResult_sprintf(interp,"endstate: %s invalid", cp );
} else {
+ if (!scan_is_safe(endstate))
+ LOG_WARNING("drscan with unsafe "
+ "endstate \"%s\"", cp);
+
/* valid - so clear the error */
e = JIM_OK;
/* and remove the last 2 args */