jtag: rewrite jim_jtag_configure() as COMMAND_HANDLER

The function is used for commands:
- jtag configure
- jtag cget

While there, add the missing .usage field.

Change-Id: I97ddc4898259ddb7fd2d057a997f33a6f4b0e2a8
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8058
Tested-by: jenkins
This commit is contained in:
Antonio Borneo 2023-08-06 23:14:15 +02:00
parent b9f5262d42
commit ea2e26f7d5
4 changed files with 82 additions and 124 deletions

View File

@ -127,7 +127,8 @@ static const struct command_registration hl_transport_jtag_subcommand_handlers[]
{ {
.name = "cget", .name = "cget",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.jim_handler = jim_jtag_configure, .handler = handle_jtag_configure,
.usage = "",
}, },
{ {
.name = "names", .name = "names",

View File

@ -41,7 +41,7 @@
* Holds support for accessing JTAG-specific mechanisms from TCl scripts. * Holds support for accessing JTAG-specific mechanisms from TCl scripts.
*/ */
static const struct jim_nvp nvp_jtag_tap_event[] = { static const struct nvp nvp_jtag_tap_event[] = {
{ .value = JTAG_TRST_ASSERTED, .name = "post-reset" }, { .value = JTAG_TRST_ASSERTED, .name = "post-reset" },
{ .value = JTAG_TAP_EVENT_SETUP, .name = "setup" }, { .value = JTAG_TAP_EVENT_SETUP, .name = "setup" },
{ .value = JTAG_TAP_EVENT_ENABLE, .name = "tap-enable" }, { .value = JTAG_TAP_EVENT_ENABLE, .name = "tap-enable" },
@ -259,123 +259,104 @@ enum jtag_tap_cfg_param {
JCFG_IDCODE, JCFG_IDCODE,
}; };
static struct jim_nvp nvp_config_opts[] = { static struct nvp nvp_config_opts[] = {
{ .name = "-event", .value = JCFG_EVENT }, { .name = "-event", .value = JCFG_EVENT },
{ .name = "-idcode", .value = JCFG_IDCODE }, { .name = "-idcode", .value = JCFG_IDCODE },
{ .name = NULL, .value = -1 } { .name = NULL, .value = -1 }
}; };
static int jtag_tap_configure_event(struct jim_getopt_info *goi, struct jtag_tap *tap) static int jtag_tap_set_event(struct command_context *cmd_ctx, struct jtag_tap *tap,
const struct nvp *event, Jim_Obj *body)
{ {
if (goi->argc == 0) { struct jtag_tap_event_action *jteap = tap->event_action;
Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event <event-name> ...");
return JIM_ERR;
}
struct jim_nvp *n;
int e = jim_getopt_nvp(goi, nvp_jtag_tap_event, &n);
if (e != JIM_OK) {
jim_getopt_nvp_unknown(goi, nvp_jtag_tap_event, 1);
return e;
}
if (goi->isconfigure) {
if (goi->argc != 1) {
Jim_WrongNumArgs(goi->interp,
goi->argc,
goi->argv,
"-event <event-name> <event-body>");
return JIM_ERR;
}
} else {
if (goi->argc != 0) {
Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event <event-name>");
return JIM_ERR;
}
}
struct jtag_tap_event_action *jteap = tap->event_action;
/* replace existing event body */
bool found = false;
while (jteap) { while (jteap) {
if (jteap->event == (enum jtag_event)n->value) { if (jteap->event == (enum jtag_event)event->value)
found = true;
break; break;
}
jteap = jteap->next; jteap = jteap->next;
} }
Jim_SetEmptyResult(goi->interp); if (!jteap) {
jteap = calloc(1, sizeof(*jteap));
if (goi->isconfigure) { if (!jteap) {
if (!found) LOG_ERROR("Out of memory");
jteap = calloc(1, sizeof(*jteap)); return ERROR_FAIL;
else if (jteap->body)
Jim_DecrRefCount(goi->interp, jteap->body);
jteap->interp = goi->interp;
jteap->event = n->value;
Jim_Obj *o;
jim_getopt_obj(goi, &o);
jteap->body = Jim_DuplicateObj(goi->interp, o);
Jim_IncrRefCount(jteap->body);
if (!found) {
/* add to head of event list */
jteap->next = tap->event_action;
tap->event_action = jteap;
} }
} else if (found) {
jteap->interp = goi->interp; /* add to head of event list */
Jim_SetResult(goi->interp, jteap->next = tap->event_action;
Jim_DuplicateObj(goi->interp, jteap->body)); tap->event_action = jteap;
} else {
Jim_DecrRefCount(cmd_ctx->interp, jteap->body);
} }
return JIM_OK;
jteap->interp = cmd_ctx->interp;
jteap->event = (enum jtag_event)event->value;
jteap->body = Jim_DuplicateObj(cmd_ctx->interp, body);
Jim_IncrRefCount(jteap->body);
return ERROR_OK;
} }
static int jtag_tap_configure_cmd(struct jim_getopt_info *goi, struct jtag_tap *tap) __COMMAND_HANDLER(handle_jtag_configure)
{ {
/* parse config or cget options */ bool is_configure = !strcmp(CMD_NAME, "configure");
while (goi->argc > 0) {
Jim_SetEmptyResult(goi->interp);
struct jim_nvp *n; if (CMD_ARGC < (is_configure ? 3 : 2))
int e = jim_getopt_nvp(goi, nvp_config_opts, &n); return ERROR_COMMAND_SYNTAX_ERROR;
if (e != JIM_OK) {
jim_getopt_nvp_unknown(goi, nvp_config_opts, 0);
return e;
}
/* FIXME: rework jtag_tap_by_jim_obj */
struct jtag_tap *tap = jtag_tap_by_jim_obj(CMD_CTX->interp, CMD_JIMTCL_ARGV[0]);
if (!tap)
return ERROR_FAIL;
for (unsigned int i = 1; i < CMD_ARGC; i++) {
const struct nvp *n = nvp_name2value(nvp_config_opts, CMD_ARGV[i]);
switch (n->value) { switch (n->value) {
case JCFG_EVENT: case JCFG_EVENT:
e = jtag_tap_configure_event(goi, tap); if (i + (is_configure ? 3 : 2) >= CMD_ARGC) {
if (e != JIM_OK) command_print(CMD, "wrong # args: should be \"-event <event-name>%s\"",
return e; is_configure ? " <event-body>" : "");
break; return ERROR_COMMAND_ARGUMENT_INVALID;
case JCFG_IDCODE: }
if (goi->isconfigure) {
Jim_SetResultFormatted(goi->interp, const struct nvp *event = nvp_name2value(nvp_jtag_tap_event, CMD_ARGV[i + 1]);
"not settable: %s", n->name); if (!event->name) {
return JIM_ERR; nvp_unknown_command_print(CMD, nvp_jtag_tap_event, CMD_ARGV[i], CMD_ARGV[i + 1]);
} else { return ERROR_COMMAND_ARGUMENT_INVALID;
if (goi->argc != 0) { }
Jim_WrongNumArgs(goi->interp,
goi->argc, goi->argv, if (is_configure) {
"NO PARAMS"); int retval = jtag_tap_set_event(CMD_CTX, tap, event, CMD_JIMTCL_ARGV[i + 2]);
return JIM_ERR; if (retval != ERROR_OK)
return retval;
} else {
struct jtag_tap_event_action *jteap = tap->event_action;
while (jteap) {
if (jteap->event == (enum jtag_event)event->value) {
command_print(CMD, "%s", Jim_GetString(jteap->body, NULL));
break;
} }
jteap = jteap->next;
} }
Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, tap->idcode)); }
break;
default: i += is_configure ? 2 : 1;
Jim_SetResultFormatted(goi->interp, "unknown value: %s", n->name); break;
return JIM_ERR; case JCFG_IDCODE:
if (is_configure) {
command_print(CMD, "not settable: %s", n->name);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
command_print(CMD, "0x%08x", tap->idcode);
break;
default:
nvp_unknown_command_print(CMD, nvp_config_opts, NULL, CMD_ARGV[i]);
return ERROR_COMMAND_ARGUMENT_INVALID;
} }
} }
return ERROR_OK;
return JIM_OK;
} }
#define NTAP_OPT_IRLEN 0 #define NTAP_OPT_IRLEN 0
@ -558,7 +539,7 @@ static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e)
if (jteap->event != e) if (jteap->event != e)
continue; continue;
struct jim_nvp *nvp = jim_nvp_value2name_simple(nvp_jtag_tap_event, e); const struct nvp *nvp = nvp_value2name(nvp_jtag_tap_event, e);
LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s", LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
tap->dotted_name, e, nvp->name, tap->dotted_name, e, nvp->name,
Jim_GetString(jteap->body, NULL)); Jim_GetString(jteap->body, NULL));
@ -675,30 +656,6 @@ __COMMAND_HANDLER(handle_jtag_tap_enabler)
return ERROR_OK; return ERROR_OK;
} }
int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
struct command *c = jim_to_command(interp);
const char *cmd_name = c->name;
struct jim_getopt_info 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,
"<tap_name> <attribute> ...");
return JIM_ERR;
}
struct jtag_tap *t;
Jim_Obj *o;
jim_getopt_obj(&goi, &o);
t = jtag_tap_by_jim_obj(goi.interp, o);
if (!t)
return JIM_ERR;
return jtag_tap_configure_cmd(&goi, t);
}
COMMAND_HANDLER(handle_jtag_names) COMMAND_HANDLER(handle_jtag_names)
{ {
if (CMD_ARGC != 0) if (CMD_ARGC != 0)
@ -793,7 +750,7 @@ static const struct command_registration jtag_subcommand_handlers[] = {
{ {
.name = "configure", .name = "configure",
.mode = COMMAND_ANY, .mode = COMMAND_ANY,
.jim_handler = jim_jtag_configure, .handler = handle_jtag_configure,
.help = "Provide a Tcl handler for the specified " .help = "Provide a Tcl handler for the specified "
"TAP event.", "TAP event.",
.usage = "tap_name '-event' event_name handler", .usage = "tap_name '-event' event_name handler",
@ -801,7 +758,7 @@ static const struct command_registration jtag_subcommand_handlers[] = {
{ {
.name = "cget", .name = "cget",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.jim_handler = jim_jtag_configure, .handler = handle_jtag_configure,
.help = "Return any Tcl handler for the specified " .help = "Return any Tcl handler for the specified "
"TAP event.", "TAP event.",
.usage = "tap_name '-event' event_name", .usage = "tap_name '-event' event_name",

View File

@ -20,8 +20,7 @@
#include <helper/command.h> #include <helper/command.h>
int jim_jtag_configure(Jim_Interp *interp, int argc, __COMMAND_HANDLER(handle_jtag_configure);
Jim_Obj * const *argv);
__COMMAND_HANDLER(handle_jtag_tap_enabler); __COMMAND_HANDLER(handle_jtag_tap_enabler);
#endif /* OPENOCD_JTAG_TCL_H */ #endif /* OPENOCD_JTAG_TCL_H */

View File

@ -118,7 +118,8 @@ static const struct command_registration dapdirect_jtag_subcommand_handlers[] =
{ {
.name = "cget", .name = "cget",
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.jim_handler = jim_jtag_configure, .handler = handle_jtag_configure,
.usage = "",
}, },
{ {
.name = "names", .name = "names",