- {
- 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);
- 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);
- 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;
- }
- } /* switch (n->value) */
- } /* while (goi->argc) */
-
- /* default is enabled-after-reset */
- pTap->enabled = !pTap->disabled_after_reset;
-
- /* Did all the required option bits get cleared? */
- if (pTap->ir_length != 0)
- {
- jtag_tap_init(pTap);
- return ERROR_OK;
- }
-
- Jim_SetResult_sprintf(goi->interp,
- "newtap: %s missing IR length",
- pTap->dotted_name);
- jtag_tap_free(pTap);
- return JIM_ERR;
-}
-
-static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e)
-{
- struct jtag_tap_event_action * jteap;
-
- for (jteap = tap->event_action; jteap != NULL; jteap = jteap->next) {
- if (jteap->event == e) {
- LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
- tap->dotted_name,
- e,
- Jim_Nvp_value2name_simple(nvp_jtag_tap_event, e)->name,
- Jim_GetString(jteap->body, NULL));
- if (Jim_EvalObj(interp, jteap->body) != JIM_OK) {
- Jim_PrintErrorMessage(interp);
- } else switch (e) {
- case JTAG_TAP_EVENT_ENABLE:
- case JTAG_TAP_EVENT_DISABLE:
- /* NOTE: we currently assume the handlers
- * can't fail. Right here is where we should
- * really be verifying the scan chains ...
- */
- tap->enabled = (e == JTAG_TAP_EVENT_ENABLE);
- LOG_INFO("JTAG tap: %s %s", tap->dotted_name,
- tap->enabled ? "enabled" : "disabled");
- break;
- default:
- break;
- }
- }
- }
-}
-
-
-static int jim_jtag_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- 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);
-
- 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 */
- /* TCL code might need to know the exact type... */
- /* FUTURE: we allow this as a means to "set" the interface. */
- if (goi.argc != 0) {
- Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
- return JIM_ERR;
- }
- const char *name = jtag_interface ? jtag_interface->name : NULL;
- Jim_SetResultString(goi.interp, name ? : "undefined", -1);
- return JIM_OK;
- case JTAG_CMD_INIT:
- if (goi.argc != 0) {
- Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
- return JIM_ERR;
- }
- e = jtag_init_inner(context);
- if (e != ERROR_OK) {
- Jim_SetResult_sprintf(goi.interp, "error: %d", e);
- return JIM_ERR;
- }
- return JIM_OK;
- case JTAG_CMD_INIT_RESET:
- if (goi.argc != 0) {
- Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
- return JIM_ERR;
- }
- e = jtag_init_reset(context);
- if (e != ERROR_OK) {
- Jim_SetResult_sprintf(goi.interp, "error: %d", e);
- return JIM_ERR;
- }
- return JIM_OK;
- case JTAG_CMD_NEWTAP:
- return jim_newtap_cmd(&goi);
- break;
- case JTAG_CMD_TAPISENABLED:
- case JTAG_CMD_TAPENABLE:
- case JTAG_CMD_TAPDISABLE:
- if (goi.argc != 1) {
- Jim_SetResultString(goi.interp, "Too many parameters",-1);
- return JIM_ERR;
- }
-
- {
- struct jtag_tap *t;
-
- t = jtag_tap_by_jim_obj(goi.interp, goi.argv[0]);
- if (t == NULL)
- return JIM_ERR;
-
- switch (n->value) {
- case JTAG_CMD_TAPISENABLED:
- break;
- case JTAG_CMD_TAPENABLE:
- if (t->enabled)
- break;
- jtag_tap_handle_event(t, JTAG_TAP_EVENT_ENABLE);
- if (!t->enabled)
- break;
-
- /* 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);
- 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;