X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fjtag%2Ftcl.c;h=00b1038e250d5a54ffb550fca9a85094a73d3489;hb=2bc7446bb8caf751f7d6900af26384f6c64cc791;hp=bb86a325b0da2de65925e3efdf18671168b3bddb;hpb=7124be824792eee3f973eb2cf7e1c851cbd2a923;p=openocd diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index bb86a325..00b1038e 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -51,6 +51,17 @@ static const Jim_Nvp nvp_jtag_tap_event[] = { extern struct jtag_interface *jtag_interface; +struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o) +{ + const char *cp = Jim_GetString(o, NULL); + struct jtag_tap *t = cp ? jtag_tap_by_string(cp) : NULL; + if (NULL == cp) + cp = "(unknown)"; + if (NULL == t) + Jim_SetResult_sprintf(interp, "Tap '%s' could not be found", cp); + return t; +} + static bool scan_is_safe(tap_state_t state) { switch (state) @@ -341,8 +352,9 @@ static int jtag_tap_configure_event(Jim_GetOptInfo *goi, struct jtag_tap * tap) if (!found) jteap = calloc(1, sizeof(*jteap)); else if (NULL != jteap->body) - Jim_DecrRefCount(interp, jteap->body); + Jim_DecrRefCount(goi->interp, jteap->body); + jteap->interp = goi->interp; jteap->event = n->value; Jim_Obj *o; @@ -359,6 +371,7 @@ static int jtag_tap_configure_event(Jim_GetOptInfo *goi, struct jtag_tap * tap) } else if (found) { + jteap->interp = goi->interp; Jim_SetResult(goi->interp, Jim_DuplicateObj(goi->interp, jteap->body)); } @@ -406,27 +419,109 @@ static int is_bad_irval(int ir_length, jim_wide w) return (w & v) != 0; } +static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi, + struct jtag_tap *pTap) +{ + jim_wide w; + int e = Jim_GetOpt_Wide(goi, &w); + if (e != JIM_OK) { + Jim_SetResult_sprintf(goi->interp, "option: %s bad parameter", n->name); + return e; + } + + unsigned expected_len = sizeof(uint32_t) * pTap->expected_ids_cnt; + uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t)); + if (new_expected_ids == NULL) + { + Jim_SetResult_sprintf(goi->interp, "no memory"); + return JIM_ERR; + } + + memcpy(new_expected_ids, pTap->expected_ids, expected_len); + + new_expected_ids[pTap->expected_ids_cnt] = w; + + free(pTap->expected_ids); + pTap->expected_ids = new_expected_ids; + pTap->expected_ids_cnt++; + + return JIM_OK; +} + +#define NTAP_OPT_IRLEN 0 +#define NTAP_OPT_IRMASK 1 +#define NTAP_OPT_IRCAPTURE 2 +#define NTAP_OPT_ENABLED 3 +#define NTAP_OPT_DISABLED 4 +#define NTAP_OPT_EXPECTED_ID 5 +#define NTAP_OPT_VERSION 6 + +static int jim_newtap_ir_param(Jim_Nvp *n, Jim_GetOptInfo *goi, + struct jtag_tap *pTap) +{ + jim_wide w; + int e = Jim_GetOpt_Wide(goi, &w); + if (e != JIM_OK) + { + Jim_SetResult_sprintf(goi->interp, + "option: %s bad parameter", n->name); + free((void *)pTap->dotted_name); + return e; + } + switch (n->value) { + case NTAP_OPT_IRLEN: + if (w > (jim_wide) (8 * sizeof(pTap->ir_capture_value))) + { + LOG_WARNING("%s: huge IR length %d", + pTap->dotted_name, (int) w); + } + pTap->ir_length = w; + break; + case NTAP_OPT_IRMASK: + if (is_bad_irval(pTap->ir_length, w)) + { + LOG_ERROR("%s: IR mask %x too big", + pTap->dotted_name, + (int) w); + return JIM_ERR; + } + if ((w & 3) != 3) + LOG_WARNING("%s: nonstandard IR mask", pTap->dotted_name); + pTap->ir_capture_mask = w; + break; + case NTAP_OPT_IRCAPTURE: + if (is_bad_irval(pTap->ir_length, w)) + { + LOG_ERROR("%s: IR capture %x too big", + pTap->dotted_name, (int) w); + return JIM_ERR; + } + if ((w & 3) != 1) + LOG_WARNING("%s: nonstandard IR value", + pTap->dotted_name); + pTap->ir_capture_value = w; + break; + default: + return JIM_ERR; + } + return JIM_OK; +} + static int jim_newtap_cmd(Jim_GetOptInfo *goi) { struct jtag_tap *pTap; - jim_wide w; int x; int e; Jim_Nvp *n; char *cp; const Jim_Nvp opts[] = { -#define NTAP_OPT_IRLEN 0 { .name = "-irlen" , .value = NTAP_OPT_IRLEN }, -#define NTAP_OPT_IRMASK 1 { .name = "-irmask" , .value = NTAP_OPT_IRMASK }, -#define NTAP_OPT_IRCAPTURE 2 { .name = "-ircapture" , .value = NTAP_OPT_IRCAPTURE }, -#define NTAP_OPT_ENABLED 3 { .name = "-enable" , .value = NTAP_OPT_ENABLED }, -#define NTAP_OPT_DISABLED 4 { .name = "-disable" , .value = NTAP_OPT_DISABLED }, -#define NTAP_OPT_EXPECTED_ID 5 { .name = "-expected-id" , .value = NTAP_OPT_EXPECTED_ID }, + { .name = "-ignore-version" , .value = NTAP_OPT_VERSION }, { .name = NULL , .value = -1 }, }; @@ -483,81 +578,28 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi) pTap->disabled_after_reset = true; break; case NTAP_OPT_EXPECTED_ID: - { - uint32_t *new_expected_ids; - - e = Jim_GetOpt_Wide(goi, &w); - if (e != JIM_OK) { - Jim_SetResult_sprintf(goi->interp, "option: %s bad parameter", n->name); + e = jim_newtap_expected_id(n, goi, pTap); + if (JIM_OK != e) + { free((void *)pTap->dotted_name); free(pTap); return e; } - - new_expected_ids = malloc(sizeof(uint32_t) * (pTap->expected_ids_cnt + 1)); - if (new_expected_ids == NULL) { - Jim_SetResult_sprintf(goi->interp, "no memory"); - free((void *)pTap->dotted_name); - free(pTap); - return JIM_ERR; - } - - memcpy(new_expected_ids, pTap->expected_ids, sizeof(uint32_t) * pTap->expected_ids_cnt); - - new_expected_ids[pTap->expected_ids_cnt] = w; - - free(pTap->expected_ids); - pTap->expected_ids = new_expected_ids; - pTap->expected_ids_cnt++; break; - } case NTAP_OPT_IRLEN: case NTAP_OPT_IRMASK: case NTAP_OPT_IRCAPTURE: - e = Jim_GetOpt_Wide(goi, &w); - if (e != JIM_OK) { - Jim_SetResult_sprintf(goi->interp, "option: %s bad parameter", n->name); + e = jim_newtap_ir_param(n, goi, pTap); + if (JIM_OK != e) + { free((void *)pTap->dotted_name); free(pTap); return e; } - switch (n->value) { - case NTAP_OPT_IRLEN: - if (w > (jim_wide) (8 * sizeof(pTap->ir_capture_value))) - LOG_WARNING("%s: huge IR length %d", - pTap->dotted_name, - (int) w); - pTap->ir_length = w; - break; - case NTAP_OPT_IRMASK: - if (is_bad_irval(pTap->ir_length, w)) { - LOG_ERROR("%s: IR mask %x too big", - pTap->dotted_name, - (int) w); - free((void *)pTap->dotted_name); - free(pTap); - return ERROR_FAIL; - } - if ((w & 3) != 3) - LOG_WARNING("%s: nonstandard IR mask", - pTap->dotted_name); - pTap->ir_capture_mask = w; - break; - case NTAP_OPT_IRCAPTURE: - if (is_bad_irval(pTap->ir_length, w)) { - LOG_ERROR("%s: IR capture %x too big", - pTap->dotted_name, - (int) w); - free((void *)pTap->dotted_name); - free(pTap); - return ERROR_FAIL; - } - if ((w & 3) != 1) - LOG_WARNING("%s: nonstandard IR value", - pTap->dotted_name); - pTap->ir_capture_value = w; - break; - } + break; + case NTAP_OPT_VERSION: + pTap->ignore_version = true; + break; } /* switch (n->value) */ } /* while (goi->argc) */ @@ -592,9 +634,9 @@ static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e) tap->dotted_name, e, nvp->name, Jim_GetString(jteap->body, NULL)); - if (Jim_EvalObj(interp, jteap->body) != JIM_OK) + if (Jim_EvalObj(jteap->interp, jteap->body) != JIM_OK) { - Jim_PrintErrorMessage(interp); + Jim_PrintErrorMessage(jteap->interp); continue; } @@ -782,7 +824,30 @@ static int jim_jtag_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_OK; } +COMMAND_HANDLER(handle_jtag_init_command) +{ + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + static bool jtag_initialized = false; + if (jtag_initialized) + { + LOG_INFO("'jtag init' has already been called"); + return ERROR_OK; + } + jtag_initialized = true; + + LOG_DEBUG("Initializing jtag devices..."); + return jtag_init(CMD_CTX); +} + static const struct command_registration jtag_subcommand_handlers[] = { + { + .name = "init", + .mode = COMMAND_ANY, + .handler = &handle_jtag_init_command, + .help = "initialize jtag scan chain", + }, { .name = "interface", .mode = COMMAND_ANY, @@ -953,32 +1018,47 @@ COMMAND_HANDLER(handle_interface_command) COMMAND_HANDLER(handle_scan_chain_command) { struct jtag_tap *tap; + char expected_id[12]; tap = jtag_all_taps(); - command_print(CMD_CTX, " TapName | Enabled | IdCode Expected IrLen IrCap IrMask Instr "); - command_print(CMD_CTX, "---|--------------------|---------|------------|------------|------|------|------|---------"); + command_print(CMD_CTX, +" TapName Enabled IdCode Expected IrLen IrCap IrMask"); + command_print(CMD_CTX, +"-- ------------------- -------- ---------- ---------- ----- ----- ------"); while (tap) { - uint32_t expected, expected_mask, cur_instr, ii; + uint32_t expected, expected_mask, ii; + + snprintf(expected_id, sizeof expected_id, "0x%08x", + (unsigned)((tap->expected_ids_cnt > 0) + ? tap->expected_ids[0] + : 0)); + if (tap->ignore_version) + expected_id[2] = '*'; + expected = buf_get_u32(tap->expected, 0, tap->ir_length); expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length); - cur_instr = buf_get_u32(tap->cur_instr, 0, tap->ir_length); command_print(CMD_CTX, - "%2d | %-18s | %c | 0x%08x | 0x%08x | 0x%02x | 0x%02x | 0x%02x | 0x%02x", + "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x", tap->abs_chain_position, tap->dotted_name, tap->enabled ? 'Y' : 'n', (unsigned int)(tap->idcode), - (unsigned int)(tap->expected_ids_cnt > 0 ? tap->expected_ids[0] : 0), + expected_id, (unsigned int)(tap->ir_length), (unsigned int)(expected), - (unsigned int)(expected_mask), - (unsigned int)(cur_instr)); + (unsigned int)(expected_mask)); for (ii = 1; ii < tap->expected_ids_cnt; ii++) { - command_print(CMD_CTX, " | | | | 0x%08x | | | | ", - (unsigned int)(tap->expected_ids[ii])); + snprintf(expected_id, sizeof expected_id, "0x%08x", + (unsigned) tap->expected_ids[1]); + if (tap->ignore_version) + expected_id[2] = '*'; + + command_print(CMD_CTX, + " %s", + expected_id); } tap = tap->next_tap;