split jim_jtag_command into multiple handlers
Explodes the 'jtag' into separate command handlers, which are easier to understand and extend. Makes the code much easier to understand, though further simplifications are possible. This patch tries to minimize the noise when viewed with 'git diff -w'. Gives these commands improved built-in help and usage information.
This commit is contained in:
parent
2da2864632
commit
c4992c6d86
286
src/jtag/tcl.c
286
src/jtag/tcl.c
|
@ -366,55 +366,11 @@ static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int jim_jtag_interface(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||||
static int jim_jtag_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
|
||||||
{
|
{
|
||||||
Jim_GetOptInfo goi;
|
Jim_GetOptInfo goi;
|
||||||
int e;
|
|
||||||
Jim_Nvp *n;
|
|
||||||
Jim_Obj *o;
|
|
||||||
struct command_context *context;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
JTAG_CMD_INTERFACE,
|
|
||||||
JTAG_CMD_INIT,
|
|
||||||
JTAG_CMD_INIT_RESET,
|
|
||||||
JTAG_CMD_NEWTAP,
|
|
||||||
JTAG_CMD_TAPENABLE,
|
|
||||||
JTAG_CMD_TAPDISABLE,
|
|
||||||
JTAG_CMD_TAPISENABLED,
|
|
||||||
JTAG_CMD_CONFIGURE,
|
|
||||||
JTAG_CMD_CGET,
|
|
||||||
JTAG_CMD_NAMES,
|
|
||||||
};
|
|
||||||
|
|
||||||
const Jim_Nvp jtag_cmds[] = {
|
|
||||||
{ .name = "interface" , .value = JTAG_CMD_INTERFACE },
|
|
||||||
{ .name = "arp_init" , .value = JTAG_CMD_INIT },
|
|
||||||
{ .name = "arp_init-reset", .value = JTAG_CMD_INIT_RESET },
|
|
||||||
{ .name = "newtap" , .value = JTAG_CMD_NEWTAP },
|
|
||||||
{ .name = "tapisenabled" , .value = JTAG_CMD_TAPISENABLED },
|
|
||||||
{ .name = "tapenable" , .value = JTAG_CMD_TAPENABLE },
|
|
||||||
{ .name = "tapdisable" , .value = JTAG_CMD_TAPDISABLE },
|
|
||||||
{ .name = "configure" , .value = JTAG_CMD_CONFIGURE },
|
|
||||||
{ .name = "cget" , .value = JTAG_CMD_CGET },
|
|
||||||
{ .name = "names" , .value = JTAG_CMD_NAMES },
|
|
||||||
|
|
||||||
{ .name = NULL, .value = -1 },
|
|
||||||
};
|
|
||||||
|
|
||||||
context = Jim_GetAssocData(interp, "context");
|
|
||||||
/* go past the command */
|
|
||||||
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
||||||
|
|
||||||
e = Jim_GetOpt_Nvp(&goi, jtag_cmds, &n);
|
|
||||||
if (e != JIM_OK) {
|
|
||||||
Jim_GetOpt_NvpUnknown(&goi, jtag_cmds, 0);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
Jim_SetEmptyResult(goi.interp);
|
|
||||||
switch (n->value) {
|
|
||||||
case JTAG_CMD_INTERFACE:
|
|
||||||
/* return the name of the interface */
|
/* return the name of the interface */
|
||||||
/* TCL code might need to know the exact type... */
|
/* TCL code might need to know the exact type... */
|
||||||
/* FUTURE: we allow this as a means to "set" the interface. */
|
/* FUTURE: we allow this as a means to "set" the interface. */
|
||||||
|
@ -425,133 +381,146 @@ static int jim_jtag_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||||
const char *name = jtag_interface ? jtag_interface->name : NULL;
|
const char *name = jtag_interface ? jtag_interface->name : NULL;
|
||||||
Jim_SetResultString(goi.interp, name ? : "undefined", -1);
|
Jim_SetResultString(goi.interp, name ? : "undefined", -1);
|
||||||
return JIM_OK;
|
return JIM_OK;
|
||||||
case JTAG_CMD_INIT:
|
}
|
||||||
|
|
||||||
|
static int jim_jtag_arp_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||||
|
{
|
||||||
|
Jim_GetOptInfo goi;
|
||||||
|
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
||||||
if (goi.argc != 0) {
|
if (goi.argc != 0) {
|
||||||
Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
|
Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
}
|
}
|
||||||
e = jtag_init_inner(context);
|
struct command_context *context = Jim_GetAssocData(interp, "context");
|
||||||
|
int e = jtag_init_inner(context);
|
||||||
if (e != ERROR_OK) {
|
if (e != ERROR_OK) {
|
||||||
Jim_SetResult_sprintf(goi.interp, "error: %d", e);
|
Jim_SetResult_sprintf(goi.interp, "error: %d", e);
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
}
|
}
|
||||||
return JIM_OK;
|
return JIM_OK;
|
||||||
case JTAG_CMD_INIT_RESET:
|
}
|
||||||
|
|
||||||
|
static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||||
|
{
|
||||||
|
Jim_GetOptInfo goi;
|
||||||
|
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
||||||
if (goi.argc != 0) {
|
if (goi.argc != 0) {
|
||||||
Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
|
Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
}
|
}
|
||||||
e = jtag_init_reset(context);
|
struct command_context *context = Jim_GetAssocData(interp, "context");
|
||||||
|
int e = jtag_init_reset(context);
|
||||||
if (e != ERROR_OK) {
|
if (e != ERROR_OK) {
|
||||||
Jim_SetResult_sprintf(goi.interp, "error: %d", e);
|
Jim_SetResult_sprintf(goi.interp, "error: %d", e);
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
}
|
}
|
||||||
return JIM_OK;
|
return JIM_OK;
|
||||||
case JTAG_CMD_NEWTAP:
|
}
|
||||||
|
|
||||||
|
static int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||||
|
{
|
||||||
|
Jim_GetOptInfo goi;
|
||||||
|
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
||||||
return jim_newtap_cmd(&goi);
|
return jim_newtap_cmd(&goi);
|
||||||
break;
|
}
|
||||||
case JTAG_CMD_TAPISENABLED:
|
|
||||||
case JTAG_CMD_TAPENABLE:
|
static bool jtag_tap_enable(struct jtag_tap *t)
|
||||||
case JTAG_CMD_TAPDISABLE:
|
{
|
||||||
|
if (t->enabled)
|
||||||
|
return false;
|
||||||
|
jtag_tap_handle_event(t, JTAG_TAP_EVENT_ENABLE);
|
||||||
|
if (!t->enabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* FIXME add JTAG sanity checks, w/o TLR
|
||||||
|
* - scan chain length grew by one (this)
|
||||||
|
* - IDs and IR lengths are as expected
|
||||||
|
*/
|
||||||
|
jtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
static bool jtag_tap_disable(struct jtag_tap *t)
|
||||||
|
{
|
||||||
|
if (!t->enabled)
|
||||||
|
return false;
|
||||||
|
jtag_tap_handle_event(t, JTAG_TAP_EVENT_DISABLE);
|
||||||
|
if (t->enabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* FIXME add JTAG sanity checks, w/o TLR
|
||||||
|
* - scan chain length shrank by one (this)
|
||||||
|
* - IDs and IR lengths are as expected
|
||||||
|
*/
|
||||||
|
jtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jim_jtag_tap_enabler(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||||
|
{
|
||||||
|
const char *cmd_name = Jim_GetString(argv[0], NULL);
|
||||||
|
Jim_GetOptInfo goi;
|
||||||
|
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
||||||
if (goi.argc != 1) {
|
if (goi.argc != 1) {
|
||||||
Jim_SetResultString(goi.interp, "Too many parameters",-1);
|
Jim_SetResult_sprintf(goi.interp, "usage: %s <name>", cmd_name);
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
struct jtag_tap *t;
|
struct jtag_tap *t;
|
||||||
|
|
||||||
t = jtag_tap_by_jim_obj(goi.interp, goi.argv[0]);
|
t = jtag_tap_by_jim_obj(goi.interp, goi.argv[0]);
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
|
|
||||||
switch (n->value) {
|
if (strcasecmp(cmd_name, "tapisenabled") == 0) {
|
||||||
case JTAG_CMD_TAPISENABLED:
|
// do nothing, just return the value
|
||||||
break;
|
} else if (strcasecmp(cmd_name, "tapenable") == 0) {
|
||||||
case JTAG_CMD_TAPENABLE:
|
if (!jtag_tap_enable(t))
|
||||||
if (t->enabled)
|
LOG_WARNING("failed to disable tap");
|
||||||
break;
|
} else if (strcasecmp(cmd_name, "tapdisable") == 0) {
|
||||||
jtag_tap_handle_event(t, JTAG_TAP_EVENT_ENABLE);
|
if (!jtag_tap_disable(t))
|
||||||
if (!t->enabled)
|
LOG_WARNING("failed to disable tap");
|
||||||
break;
|
} else {
|
||||||
|
LOG_ERROR("command '%s' unknown", cmd_name);
|
||||||
/* FIXME add JTAG sanity checks, w/o TLR
|
return JIM_ERR;
|
||||||
* - scan chain length grew by one (this)
|
|
||||||
* - IDs and IR lengths are as expected
|
|
||||||
*/
|
|
||||||
|
|
||||||
jtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE);
|
|
||||||
break;
|
|
||||||
case JTAG_CMD_TAPDISABLE:
|
|
||||||
if (!t->enabled)
|
|
||||||
break;
|
|
||||||
jtag_tap_handle_event(t, JTAG_TAP_EVENT_DISABLE);
|
|
||||||
if (t->enabled)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* FIXME add JTAG sanity checks, w/o TLR
|
|
||||||
* - scan chain length shrank by one (this)
|
|
||||||
* - IDs and IR lengths are as expected
|
|
||||||
*/
|
|
||||||
|
|
||||||
jtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
e = t->enabled;
|
bool e = t->enabled;
|
||||||
Jim_SetResult(goi.interp, Jim_NewIntObj(goi.interp, e));
|
Jim_SetResult(goi.interp, Jim_NewIntObj(goi.interp, e));
|
||||||
return JIM_OK;
|
return JIM_OK;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case JTAG_CMD_CGET:
|
static int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||||
if (goi.argc < 2) {
|
{
|
||||||
|
const char *cmd_name = Jim_GetString(argv[0], NULL);
|
||||||
|
Jim_GetOptInfo goi;
|
||||||
|
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
||||||
|
goi.isconfigure = !strcmp(cmd_name, "configure");
|
||||||
|
if (goi.argc < 2 + goi.isconfigure) {
|
||||||
Jim_WrongNumArgs(goi.interp, 0, NULL,
|
Jim_WrongNumArgs(goi.interp, 0, NULL,
|
||||||
"cget tap_name queryparm");
|
"<tap_name> <attribute> ...");
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
struct jtag_tap *t;
|
struct jtag_tap *t;
|
||||||
|
|
||||||
|
Jim_Obj *o;
|
||||||
Jim_GetOpt_Obj(&goi, &o);
|
Jim_GetOpt_Obj(&goi, &o);
|
||||||
t = jtag_tap_by_jim_obj(goi.interp, o);
|
t = jtag_tap_by_jim_obj(goi.interp, o);
|
||||||
if (t == NULL) {
|
if (t == NULL) {
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
goi.isconfigure = 0;
|
|
||||||
return jtag_tap_configure_cmd(&goi, t);
|
return jtag_tap_configure_cmd(&goi, t);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case JTAG_CMD_CONFIGURE:
|
static int jim_jtag_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||||
if (goi.argc < 3) {
|
{
|
||||||
Jim_WrongNumArgs(goi.interp, 0, NULL,
|
Jim_GetOptInfo goi;
|
||||||
"configure tap_name attribute value ...");
|
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
|
||||||
return JIM_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
struct jtag_tap *t;
|
|
||||||
|
|
||||||
Jim_GetOpt_Obj(&goi, &o);
|
|
||||||
t = jtag_tap_by_jim_obj(goi.interp, o);
|
|
||||||
if (t == NULL) {
|
|
||||||
return JIM_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
goi.isconfigure = 1;
|
|
||||||
return jtag_tap_configure_cmd(&goi, t);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JTAG_CMD_NAMES:
|
|
||||||
if (goi.argc != 0) {
|
if (goi.argc != 0) {
|
||||||
Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters");
|
Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters");
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
}
|
}
|
||||||
Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0));
|
Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0));
|
||||||
{
|
|
||||||
struct jtag_tap *tap;
|
struct jtag_tap *tap;
|
||||||
|
|
||||||
for (tap = jtag_all_taps(); tap; tap = tap->next_tap) {
|
for (tap = jtag_all_taps(); tap; tap = tap->next_tap) {
|
||||||
|
@ -561,14 +530,76 @@ static int jim_jtag_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||||
tap->dotted_name, -1));
|
tap->dotted_name, -1));
|
||||||
}
|
}
|
||||||
return JIM_OK;
|
return JIM_OK;
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return JIM_ERR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct command_registration jtag_subcommand_handlers[] = {
|
||||||
|
{
|
||||||
|
.name = "interface",
|
||||||
|
.mode = COMMAND_ANY,
|
||||||
|
.jim_handler = &jim_jtag_interface,
|
||||||
|
.help = "Returns the selected interface",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "arp_init",
|
||||||
|
.mode = COMMAND_ANY,
|
||||||
|
.jim_handler = &jim_jtag_arp_init,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "arp_init-reset",
|
||||||
|
.mode = COMMAND_ANY,
|
||||||
|
.jim_handler = &jim_jtag_arp_init_reset,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "newtap",
|
||||||
|
.mode = COMMAND_CONFIG,
|
||||||
|
.jim_handler = &jim_jtag_newtap,
|
||||||
|
.help = "Create a new TAP instance",
|
||||||
|
.usage = "<name> <type> -irlen <count> [-ircapture <count>] "
|
||||||
|
"[-irmask <count>] [-enable|-disable]",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "tapisenabled",
|
||||||
|
.mode = COMMAND_EXEC,
|
||||||
|
.jim_handler = &jim_jtag_tap_enabler,
|
||||||
|
.help = "Returns a integer indicating TAP state (0/1)",
|
||||||
|
.usage = "<name>",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "tapenable",
|
||||||
|
.mode = COMMAND_EXEC,
|
||||||
|
.jim_handler = &jim_jtag_tap_enabler,
|
||||||
|
.help = "Enable the specified TAP",
|
||||||
|
.usage = "<name>",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "tapdisable",
|
||||||
|
.mode = COMMAND_EXEC,
|
||||||
|
.jim_handler = &jim_jtag_tap_enabler,
|
||||||
|
.help = "Enable the specified TAP",
|
||||||
|
.usage = "<name>",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "configure",
|
||||||
|
.mode = COMMAND_EXEC,
|
||||||
|
.jim_handler = &jim_jtag_configure,
|
||||||
|
.help = "Enable the specified TAP",
|
||||||
|
.usage = "<name> [<key> <value> ...]",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "cget",
|
||||||
|
.mode = COMMAND_EXEC,
|
||||||
|
.jim_handler = &jim_jtag_configure,
|
||||||
|
.help = "Enable the specified TAP",
|
||||||
|
.usage = "<name> [<key> <value> ...]",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "names",
|
||||||
|
.mode = COMMAND_ANY,
|
||||||
|
.jim_handler = &jim_jtag_names,
|
||||||
|
.help = "Returns list of all JTAG tap names",
|
||||||
|
},
|
||||||
|
COMMAND_REGISTRATION_DONE
|
||||||
|
};
|
||||||
|
|
||||||
void jtag_notify_event(enum jtag_event event)
|
void jtag_notify_event(enum jtag_event event)
|
||||||
{
|
{
|
||||||
|
@ -1533,8 +1564,9 @@ static const struct command_registration jtag_command_handlers[] = {
|
||||||
{
|
{
|
||||||
.name = "jtag",
|
.name = "jtag",
|
||||||
.mode = COMMAND_ANY,
|
.mode = COMMAND_ANY,
|
||||||
.jim_handler = &jim_jtag_command,
|
|
||||||
.help = "perform jtag tap actions",
|
.help = "perform jtag tap actions",
|
||||||
|
|
||||||
|
.chain = jtag_subcommand_handlers,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "drscan",
|
.name = "drscan",
|
||||||
|
|
Loading…
Reference in New Issue