begin moving JTAG jim handlers/helpers
Moves the tertiary jim handlers and required static helpers to the top of tcl.c, defining them in a new registration array that is chained in both the top-level context and under the jtag command. The top-level commands can be removed at some point in the future to reduce clutter.
This commit is contained in:
parent
c4992c6d86
commit
0377e5b54d
463
src/jtag/tcl.c
463
src/jtag/tcl.c
|
@ -51,6 +51,238 @@ static const Jim_Nvp nvp_jtag_tap_event[] = {
|
|||
|
||||
extern struct jtag_interface *jtag_interface;
|
||||
|
||||
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 Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args)
|
||||
{
|
||||
int retval;
|
||||
struct scan_field *fields;
|
||||
int num_fields;
|
||||
int field_count = 0;
|
||||
int i, e;
|
||||
struct jtag_tap *tap;
|
||||
tap_state_t endstate;
|
||||
|
||||
/* args[1] = device
|
||||
* args[2] = num_bits
|
||||
* args[3] = hex string
|
||||
* ... repeat num bits and hex string ...
|
||||
*
|
||||
* .. optionally:
|
||||
* args[N-2] = "-endstate"
|
||||
* args[N-1] = statename
|
||||
*/
|
||||
if ((argc < 4) || ((argc % 2) != 0))
|
||||
{
|
||||
Jim_WrongNumArgs(interp, 1, args, "wrong arguments");
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
endstate = TAP_IDLE;
|
||||
|
||||
script_debug(interp, "drscan", argc, args);
|
||||
|
||||
/* validate arguments as numbers */
|
||||
e = JIM_OK;
|
||||
for (i = 2; i < argc; i += 2)
|
||||
{
|
||||
long bits;
|
||||
const char *cp;
|
||||
|
||||
e = Jim_GetLong(interp, args[i], &bits);
|
||||
/* If valid - try next arg */
|
||||
if (e == JIM_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Not valid.. are we at the end? */
|
||||
if (((i + 2) != argc)) {
|
||||
/* nope, then error */
|
||||
return e;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
/* is it the magic? */
|
||||
if (0 == strcmp("-endstate", cp)) {
|
||||
/* is the statename valid? */
|
||||
cp = Jim_GetString(args[i + 1], NULL);
|
||||
|
||||
/* see if it is a valid state name */
|
||||
endstate = tap_state_by_name(cp);
|
||||
if (endstate < 0) {
|
||||
/* 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 */
|
||||
argc -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Still an error? */
|
||||
if (e != JIM_OK) {
|
||||
return e; /* too bad */
|
||||
}
|
||||
} /* validate args */
|
||||
|
||||
tap = jtag_tap_by_jim_obj(interp, args[1]);
|
||||
if (tap == NULL) {
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
num_fields = (argc-2)/2;
|
||||
fields = malloc(sizeof(struct scan_field) * num_fields);
|
||||
for (i = 2; i < argc; i += 2)
|
||||
{
|
||||
long bits;
|
||||
int len;
|
||||
const char *str;
|
||||
|
||||
Jim_GetLong(interp, args[i], &bits);
|
||||
str = Jim_GetString(args[i + 1], &len);
|
||||
|
||||
fields[field_count].tap = tap;
|
||||
fields[field_count].num_bits = bits;
|
||||
fields[field_count].out_value = malloc(DIV_ROUND_UP(bits, 8));
|
||||
str_to_buf(str, len, fields[field_count].out_value, bits, 0);
|
||||
fields[field_count].in_value = fields[field_count].out_value;
|
||||
field_count++;
|
||||
}
|
||||
|
||||
jtag_add_dr_scan(num_fields, fields, endstate);
|
||||
|
||||
retval = jtag_execute_queue();
|
||||
if (retval != ERROR_OK)
|
||||
{
|
||||
Jim_SetResultString(interp, "drscan: jtag execute failed",-1);
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
field_count = 0;
|
||||
Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);
|
||||
for (i = 2; i < argc; i += 2)
|
||||
{
|
||||
long bits;
|
||||
char *str;
|
||||
|
||||
Jim_GetLong(interp, args[i], &bits);
|
||||
str = buf_to_str(fields[field_count].in_value, bits, 16);
|
||||
free(fields[field_count].out_value);
|
||||
|
||||
Jim_ListAppendElement(interp, list, Jim_NewStringObj(interp, str, strlen(str)));
|
||||
free(str);
|
||||
field_count++;
|
||||
}
|
||||
|
||||
Jim_SetResult(interp, list);
|
||||
|
||||
free(fields);
|
||||
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
|
||||
static int Jim_Command_pathmove(Jim_Interp *interp, int argc, Jim_Obj *const *args)
|
||||
{
|
||||
tap_state_t states[8];
|
||||
|
||||
if ((argc < 2) || ((size_t)argc > (ARRAY_SIZE(states) + 1)))
|
||||
{
|
||||
Jim_WrongNumArgs(interp, 1, args, "wrong arguments");
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
script_debug(interp, "pathmove", argc, args);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < argc-1; i++)
|
||||
{
|
||||
const char *cp;
|
||||
cp = Jim_GetString(args[i + 1], NULL);
|
||||
states[i] = tap_state_by_name(cp);
|
||||
if (states[i] < 0)
|
||||
{
|
||||
/* update the error message */
|
||||
Jim_SetResult_sprintf(interp,"endstate: %s invalid", cp);
|
||||
return JIM_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if ((jtag_add_statemove(states[0]) != ERROR_OK) || (jtag_execute_queue()!= ERROR_OK))
|
||||
{
|
||||
Jim_SetResultString(interp, "pathmove: jtag execute failed",-1);
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
jtag_add_pathmove(argc-2, states + 1);
|
||||
|
||||
if (jtag_execute_queue()!= ERROR_OK)
|
||||
{
|
||||
Jim_SetResultString(interp, "pathmove: failed",-1);
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
|
||||
static int Jim_Command_flush_count(Jim_Interp *interp, int argc, Jim_Obj *const *args)
|
||||
{
|
||||
script_debug(interp, "flush_count", argc, args);
|
||||
|
||||
Jim_SetResult(interp, Jim_NewIntObj(interp, jtag_get_flush_queue_count()));
|
||||
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
static const struct command_registration jtag_command_handlers_to_move[] = {
|
||||
{
|
||||
.name = "drscan",
|
||||
.mode = COMMAND_EXEC,
|
||||
.jim_handler = &Jim_Command_drscan,
|
||||
.help = "execute DR scan <device> "
|
||||
"<num_bits> <value> <num_bits1> <value2> ...",
|
||||
},
|
||||
{
|
||||
.name = "flush_count",
|
||||
.mode = COMMAND_EXEC,
|
||||
.jim_handler = &Jim_Command_flush_count,
|
||||
.help = "returns number of times the JTAG queue has been flushed",
|
||||
},
|
||||
{
|
||||
.name = "pathmove",
|
||||
.mode = COMMAND_EXEC,
|
||||
.jim_handler = &Jim_Command_pathmove,
|
||||
.usage = "<state1>,<state2>,<state3>... ",
|
||||
.help = "move JTAG to state1 then to state2, state3, etc.",
|
||||
},
|
||||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
|
||||
|
||||
enum jtag_tap_cfg_param {
|
||||
JCFG_EVENT
|
||||
};
|
||||
|
@ -598,6 +830,9 @@ static const struct command_registration jtag_subcommand_handlers[] = {
|
|||
.jim_handler = &jim_jtag_names,
|
||||
.help = "Returns list of all JTAG tap names",
|
||||
},
|
||||
{
|
||||
.chain = jtag_command_handlers_to_move,
|
||||
},
|
||||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
|
||||
|
@ -1095,20 +1330,6 @@ COMMAND_HANDLER(handle_runtest_command)
|
|||
* 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)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case TAP_RESET:
|
||||
case TAP_IDLE:
|
||||
case TAP_DRPAUSE:
|
||||
case TAP_IRPAUSE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
COMMAND_HANDLER(handle_irscan_command)
|
||||
{
|
||||
|
@ -1191,199 +1412,6 @@ error_return:
|
|||
return retval;
|
||||
}
|
||||
|
||||
static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args)
|
||||
{
|
||||
int retval;
|
||||
struct scan_field *fields;
|
||||
int num_fields;
|
||||
int field_count = 0;
|
||||
int i, e;
|
||||
struct jtag_tap *tap;
|
||||
tap_state_t endstate;
|
||||
|
||||
/* args[1] = device
|
||||
* args[2] = num_bits
|
||||
* args[3] = hex string
|
||||
* ... repeat num bits and hex string ...
|
||||
*
|
||||
* .. optionally:
|
||||
* args[N-2] = "-endstate"
|
||||
* args[N-1] = statename
|
||||
*/
|
||||
if ((argc < 4) || ((argc % 2) != 0))
|
||||
{
|
||||
Jim_WrongNumArgs(interp, 1, args, "wrong arguments");
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
endstate = TAP_IDLE;
|
||||
|
||||
script_debug(interp, "drscan", argc, args);
|
||||
|
||||
/* validate arguments as numbers */
|
||||
e = JIM_OK;
|
||||
for (i = 2; i < argc; i += 2)
|
||||
{
|
||||
long bits;
|
||||
const char *cp;
|
||||
|
||||
e = Jim_GetLong(interp, args[i], &bits);
|
||||
/* If valid - try next arg */
|
||||
if (e == JIM_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Not valid.. are we at the end? */
|
||||
if (((i + 2) != argc)) {
|
||||
/* nope, then error */
|
||||
return e;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
/* is it the magic? */
|
||||
if (0 == strcmp("-endstate", cp)) {
|
||||
/* is the statename valid? */
|
||||
cp = Jim_GetString(args[i + 1], NULL);
|
||||
|
||||
/* see if it is a valid state name */
|
||||
endstate = tap_state_by_name(cp);
|
||||
if (endstate < 0) {
|
||||
/* 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 */
|
||||
argc -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Still an error? */
|
||||
if (e != JIM_OK) {
|
||||
return e; /* too bad */
|
||||
}
|
||||
} /* validate args */
|
||||
|
||||
tap = jtag_tap_by_jim_obj(interp, args[1]);
|
||||
if (tap == NULL) {
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
num_fields = (argc-2)/2;
|
||||
fields = malloc(sizeof(struct scan_field) * num_fields);
|
||||
for (i = 2; i < argc; i += 2)
|
||||
{
|
||||
long bits;
|
||||
int len;
|
||||
const char *str;
|
||||
|
||||
Jim_GetLong(interp, args[i], &bits);
|
||||
str = Jim_GetString(args[i + 1], &len);
|
||||
|
||||
fields[field_count].tap = tap;
|
||||
fields[field_count].num_bits = bits;
|
||||
fields[field_count].out_value = malloc(DIV_ROUND_UP(bits, 8));
|
||||
str_to_buf(str, len, fields[field_count].out_value, bits, 0);
|
||||
fields[field_count].in_value = fields[field_count].out_value;
|
||||
field_count++;
|
||||
}
|
||||
|
||||
jtag_add_dr_scan(num_fields, fields, endstate);
|
||||
|
||||
retval = jtag_execute_queue();
|
||||
if (retval != ERROR_OK)
|
||||
{
|
||||
Jim_SetResultString(interp, "drscan: jtag execute failed",-1);
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
field_count = 0;
|
||||
Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);
|
||||
for (i = 2; i < argc; i += 2)
|
||||
{
|
||||
long bits;
|
||||
char *str;
|
||||
|
||||
Jim_GetLong(interp, args[i], &bits);
|
||||
str = buf_to_str(fields[field_count].in_value, bits, 16);
|
||||
free(fields[field_count].out_value);
|
||||
|
||||
Jim_ListAppendElement(interp, list, Jim_NewStringObj(interp, str, strlen(str)));
|
||||
free(str);
|
||||
field_count++;
|
||||
}
|
||||
|
||||
Jim_SetResult(interp, list);
|
||||
|
||||
free(fields);
|
||||
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
|
||||
static int Jim_Command_pathmove(Jim_Interp *interp, int argc, Jim_Obj *const *args)
|
||||
{
|
||||
tap_state_t states[8];
|
||||
|
||||
if ((argc < 2) || ((size_t)argc > (ARRAY_SIZE(states) + 1)))
|
||||
{
|
||||
Jim_WrongNumArgs(interp, 1, args, "wrong arguments");
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
script_debug(interp, "pathmove", argc, args);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < argc-1; i++)
|
||||
{
|
||||
const char *cp;
|
||||
cp = Jim_GetString(args[i + 1], NULL);
|
||||
states[i] = tap_state_by_name(cp);
|
||||
if (states[i] < 0)
|
||||
{
|
||||
/* update the error message */
|
||||
Jim_SetResult_sprintf(interp,"endstate: %s invalid", cp);
|
||||
return JIM_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if ((jtag_add_statemove(states[0]) != ERROR_OK) || (jtag_execute_queue()!= ERROR_OK))
|
||||
{
|
||||
Jim_SetResultString(interp, "pathmove: jtag execute failed",-1);
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
jtag_add_pathmove(argc-2, states + 1);
|
||||
|
||||
if (jtag_execute_queue()!= ERROR_OK)
|
||||
{
|
||||
Jim_SetResultString(interp, "pathmove: failed",-1);
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
|
||||
static int Jim_Command_flush_count(Jim_Interp *interp, int argc, Jim_Obj *const *args)
|
||||
{
|
||||
script_debug(interp, "flush_count", argc, args);
|
||||
|
||||
Jim_SetResult(interp, Jim_NewIntObj(interp, jtag_get_flush_queue_count()));
|
||||
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
|
||||
COMMAND_HANDLER(handle_verify_ircapture_command)
|
||||
{
|
||||
|
@ -1560,7 +1588,6 @@ static const struct command_registration jtag_command_handlers[] = {
|
|||
.help = "choose short(default) or long tms_sequence",
|
||||
.usage = "<short | long>",
|
||||
},
|
||||
// jim commands
|
||||
{
|
||||
.name = "jtag",
|
||||
.mode = COMMAND_ANY,
|
||||
|
@ -1569,28 +1596,10 @@ static const struct command_registration jtag_command_handlers[] = {
|
|||
.chain = jtag_subcommand_handlers,
|
||||
},
|
||||
{
|
||||
.name = "drscan",
|
||||
.mode = COMMAND_EXEC,
|
||||
.jim_handler = &Jim_Command_drscan,
|
||||
.help = "execute DR scan <device> "
|
||||
"<num_bits> <value> <num_bits1> <value2> ...",
|
||||
},
|
||||
{
|
||||
.name = "flush_count",
|
||||
.mode = COMMAND_EXEC,
|
||||
.jim_handler = &Jim_Command_flush_count,
|
||||
.help = "returns number of times the JTAG queue has been flushed",
|
||||
},
|
||||
{
|
||||
.name = "pathmove",
|
||||
.mode = COMMAND_EXEC,
|
||||
.jim_handler = &Jim_Command_pathmove,
|
||||
.usage = "<state1>,<state2>,<state3>... ",
|
||||
.help = "move JTAG to state1 then to state2, state3, etc.",
|
||||
.chain = jtag_command_handlers_to_move,
|
||||
},
|
||||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
|
||||
int jtag_register_commands(struct command_context *cmd_ctx)
|
||||
{
|
||||
return register_commands(cmd_ctx, NULL, jtag_command_handlers);
|
||||
|
|
Loading…
Reference in New Issue