aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Borneo <borneo.antonio@gmail.com>2023-01-02 22:16:46 +0100
committerAntonio Borneo <borneo.antonio@gmail.com>2023-05-13 08:53:06 +0000
commit4bf994fc9c810a996e31f9cd21ffc7d58ad3917d (patch)
treecbae982c217791bb27f3cc6637bb4fa9cab3a3ff
parent599f1cf763448f043e97702ca8a611f0ab87b849 (diff)
downloadriscv-openocd-4bf994fc9c810a996e31f9cd21ffc7d58ad3917d.zip
riscv-openocd-4bf994fc9c810a996e31f9cd21ffc7d58ad3917d.tar.gz
riscv-openocd-4bf994fc9c810a996e31f9cd21ffc7d58ad3917d.tar.bz2
jtag: rewrite command 'drscan' as COMMAND_HANDLER
Reorganize the code to parse the command line only once. Add check for successful memory allocation. Change-Id: Ibf6068e177c09e93150d11aecfcf079348c47c21 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: https://review.openocd.org/c/openocd/+/7555 Tested-by: jenkins
-rw-r--r--src/jtag/tcl.c179
1 files changed, 65 insertions, 114 deletions
diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index b3cbc48..ea50102 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -72,147 +72,98 @@ static bool scan_is_safe(tap_state_t state)
}
}
-static int jim_command_drscan(Jim_Interp *interp, int argc, Jim_Obj * const *args)
+static COMMAND_HELPER(handle_jtag_command_drscan_fields, struct scan_field *fields)
{
- int retval;
- struct scan_field *fields;
- int num_fields;
- int field_count = 0;
- int i, e;
- struct jtag_tap *tap;
- tap_state_t endstate;
+ unsigned int field_count = 0;
+ for (unsigned int i = 1; i < CMD_ARGC; i += 2) {
+ unsigned int bits;
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[i], bits);
+ fields[field_count].num_bits = bits;
- /* 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;
+ void *t = malloc(DIV_ROUND_UP(bits, 8));
+ if (!t) {
+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
+ }
+ fields[field_count].out_value = t;
+ str_to_buf(CMD_ARGV[i + 1], strlen(CMD_ARGV[i + 1]), t, bits, 0);
+ fields[field_count].in_value = t;
+ field_count++;
}
- endstate = TAP_IDLE;
-
- /* validate arguments as numbers */
- e = JIM_OK;
- for (i = 2; i < argc; i += 2) {
- long bits;
- const char *cp;
+ return ERROR_OK;
+}
- e = Jim_GetLong(interp, args[i], &bits);
- /* If valid - try next arg */
- if (e == JIM_OK)
- continue;
+COMMAND_HANDLER(handle_jtag_command_drscan)
+{
+ /*
+ * CMD_ARGV[0] = device
+ * CMD_ARGV[1] = num_bits
+ * CMD_ARGV[2] = hex string
+ * ... repeat num bits and hex string ...
+ *
+ * ... optionally:
+ * CMD_ARGV[CMD_ARGC-2] = "-endstate"
+ * CMD_ARGV[CMD_ARGC-1] = statename
+ */
- /* Not valid.. are we at the end? */
- if (((i + 2) != argc)) {
- /* nope, then error */
- return e;
- }
+ if (CMD_ARGC < 3 || (CMD_ARGC % 2) != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
- /* it could be: "-endstate FOO"
- * e.g. DRPAUSE so we can issue more instructions
- * before entering RUN/IDLE and executing them.
- */
+ struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[0]);
+ if (!tap) {
+ command_print(CMD, "Tap '%s' could not be found", CMD_ARGV[0]);
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
- /* get arg as a string. */
- cp = Jim_GetString(args[i], NULL);
- /* is it the magic? */
- if (strcmp("-endstate", cp) == 0) {
- /* 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_SetResultFormatted(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;
- }
+ tap_state_t endstate = TAP_IDLE;
+ if (CMD_ARGC > 3 && !strcmp("-endstate", CMD_ARGV[CMD_ARGC - 2])) {
+ const char *state_name = CMD_ARGV[CMD_ARGC - 1];
+ endstate = tap_state_by_name(state_name);
+ if (endstate < 0) {
+ command_print(CMD, "endstate: %s invalid", state_name);
+ return ERROR_COMMAND_ARGUMENT_INVALID;
}
- /* Still an error? */
- if (e != JIM_OK)
- return e; /* too bad */
- } /* validate args */
-
- assert(e == JIM_OK);
-
- tap = jtag_tap_by_jim_obj(interp, args[1]);
- if (!tap)
- return JIM_ERR;
+ if (!scan_is_safe(endstate))
+ LOG_WARNING("drscan with unsafe endstate \"%s\"", state_name);
- num_fields = (argc-2)/2;
- if (num_fields <= 0) {
- Jim_SetResultString(interp, "drscan: no scan fields supplied", -1);
- return JIM_ERR;
+ CMD_ARGC -= 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].num_bits = bits;
- void *t = malloc(DIV_ROUND_UP(bits, 8));
- fields[field_count].out_value = t;
- str_to_buf(str, len, t, bits, 0);
- fields[field_count].in_value = t;
- field_count++;
+ unsigned int num_fields = (CMD_ARGC - 1) / 2;
+ struct scan_field *fields = calloc(num_fields, sizeof(struct scan_field));
+ if (!fields) {
+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
}
+ int retval = CALL_COMMAND_HANDLER(handle_jtag_command_drscan_fields, fields);
+ if (retval != ERROR_OK)
+ goto fail;
+
jtag_add_dr_scan(tap, num_fields, fields, endstate);
retval = jtag_execute_queue();
if (retval != ERROR_OK) {
- Jim_SetResultString(interp, "drscan: jtag execute failed", -1);
-
- for (i = 0; i < field_count; i++)
- free(fields[i].in_value);
- free(fields);
-
- return JIM_ERR;
+ command_print(CMD, "drscan: jtag execute failed");
+ goto fail;
}
- 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_hex_str(fields[field_count].in_value, bits);
- free(fields[field_count].in_value);
-
- Jim_ListAppendElement(interp, list, Jim_NewStringObj(interp, str, strlen(str)));
+ for (unsigned int i = 0; i < num_fields; i++) {
+ char *str = buf_to_hex_str(fields[i].in_value, fields[i].num_bits);
+ command_print(CMD, "%s", str);
free(str);
- field_count++;
}
- Jim_SetResult(interp, list);
-
+fail:
+ for (unsigned int i = 0; i < num_fields; i++)
+ free(fields[i].in_value);
free(fields);
- return JIM_OK;
+ return retval;
}
-
static int jim_command_pathmove(Jim_Interp *interp, int argc, Jim_Obj * const *args)
{
tap_state_t states[8];
@@ -274,7 +225,7 @@ static const struct command_registration jtag_command_handlers_to_move[] = {
{
.name = "drscan",
.mode = COMMAND_EXEC,
- .jim_handler = jim_command_drscan,
+ .handler = handle_jtag_command_drscan,
.help = "Execute Data Register (DR) scan for one TAP. "
"Other TAPs must be in BYPASS mode.",
.usage = "tap_name [num_bits value]* ['-endstate' state_name]",