X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Ftcl.c;h=ad4d886aceb4feda014c71d8347c8e4580ce3631;hb=c18947b947064e7eceed8047c42d4c8dfd8ae964;hp=ed24498b87e10e2847aa224bdbc7dac730afb384;hpb=cd7f89f6bcc954da3ffa5b9b9eca49c32e152e7d;p=openocd.git diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index ed24498b87..ad4d886ace 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -39,14 +39,17 @@ #include #endif -extern bool hasKHz; +static const Jim_Nvp nvp_jtag_tap_event[] = { + { .value = JTAG_TAP_EVENT_ENABLE, .name = "tap-enable" }, + { .value = JTAG_TAP_EVENT_DISABLE, .name = "tap-disable" }, -extern const Jim_Nvp nvp_jtag_tap_event[]; + { .name = NULL, .value = -1 } +}; /* jtag interfaces (parport, FTDI-USB, TI-USB, ...) */ -#if BUILD_ECOSBOARD == 1 +#if BUILD_ZY1000 == 1 extern jtag_interface_t zy1000_interface; #elif defined(BUILD_MINIDRIVER_DUMMY) extern jtag_interface_t minidummy_interface; @@ -116,7 +119,7 @@ extern const Jim_Nvp nvp_jtag_tap_event[]; * or some number of standard driver interfaces, never both. */ jtag_interface_t *jtag_interfaces[] = { -#if BUILD_ECOSBOARD == 1 +#if BUILD_ZY1000 == 1 &zy1000_interface, #elif defined(BUILD_MINIDRIVER_DUMMY) &minidummy_interface, @@ -167,7 +170,6 @@ jtag_interface_t *jtag_interfaces[] = { NULL, }; -extern struct jtag_interface_s *jtag; extern jtag_interface_t *jtag_interface; /* jtag commands */ @@ -187,6 +189,7 @@ static int handle_jtag_reset_command(struct command_context_s *cmd_ctx, char *cm static int handle_runtest_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *argv); +static int Jim_Command_pathmove(Jim_Interp *interp, int argc, Jim_Obj *const *argv); static int Jim_Command_flush_count(Jim_Interp *interp, int argc, Jim_Obj *const *args); static int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); @@ -253,7 +256,7 @@ static int jtag_tap_configure_cmd( Jim_GetOptInfo *goi, jtag_tap_t * tap) jteap = tap->event_action; /* replace existing? */ while (jteap) { - if (jteap->event == (enum jtag_tap_event)n->value) { + if (jteap->event == (enum jtag_event)n->value) { break; } jteap = jteap->next; @@ -293,9 +296,15 @@ static int jtag_tap_configure_cmd( Jim_GetOptInfo *goi, jtag_tap_t * tap) return JIM_OK; } +static int is_bad_irval(int ir_length, jim_wide w) +{ + jim_wide v = 1; -extern void jtag_tap_init(jtag_tap_t *tap); -extern void jtag_tap_free(jtag_tap_t *tap); + v <<= ir_length; + v -= 1; + v = ~v; + return (w & v) != 0; +} static int jim_newtap_cmd( Jim_GetOptInfo *goi ) { @@ -322,12 +331,12 @@ static int jim_newtap_cmd( Jim_GetOptInfo *goi ) { .name = NULL , .value = -1 }, }; - pTap = malloc( sizeof(jtag_tap_t) ); - memset( pTap, 0, sizeof(*pTap) ); - if( !pTap ){ - Jim_SetResult_sprintf( goi->interp, "no memory"); + pTap = calloc(1, sizeof(jtag_tap_t)); + if (!pTap) { + Jim_SetResult_sprintf(goi->interp, "no memory"); return JIM_ERR; } + /* * we expect CHIP + TAP + OPTIONS * */ @@ -350,9 +359,6 @@ static int jim_newtap_cmd( Jim_GetOptInfo *goi ) LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params", pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc); - /* default is enabled */ - pTap->enabled = 1; - /* deal with options */ #define NTREQ_IRLEN 1 #define NTREQ_IRCAPTURE 2 @@ -370,10 +376,10 @@ static int jim_newtap_cmd( Jim_GetOptInfo *goi ) LOG_DEBUG("Processing option: %s", n->name ); switch( n->value ){ case NTAP_OPT_ENABLED: - pTap->enabled = 1; + pTap->disabled_after_reset = false; break; case NTAP_OPT_DISABLED: - pTap->enabled = 0; + pTap->disabled_after_reset = true; break; case NTAP_OPT_EXPECTED_ID: { @@ -408,22 +414,28 @@ static int jim_newtap_cmd( Jim_GetOptInfo *goi ) Jim_SetResult_sprintf( goi->interp, "option: %s bad parameter", n->name ); return e; } - if( (w < 0) || (w > 0xffff) ){ - /* wacky value */ - Jim_SetResult_sprintf( goi->interp, "option: %s - wacky value: %d (0x%x)", - n->name, (int)(w), (int)(w)); - return JIM_ERR; - } switch(n->value){ case NTAP_OPT_IRLEN: + if (w > (jim_wide) (8 * sizeof(pTap->ir_capture_value))) + LOG_WARNING("huge IR length %d", (int) w); pTap->ir_length = w; reqbits &= (~(NTREQ_IRLEN)); break; case NTAP_OPT_IRMASK: + if (is_bad_irval(pTap->ir_length, w)) { + LOG_ERROR("IR mask %x too big", + (int) w); + return ERROR_FAIL; + } pTap->ir_capture_mask = w; reqbits &= (~(NTREQ_IRMASK)); break; case NTAP_OPT_IRCAPTURE: + if (is_bad_irval(pTap->ir_length, w)) { + LOG_ERROR("IR capture %x too big", + (int) w); + return ERROR_FAIL; + } pTap->ir_capture_value = w; reqbits &= (~(NTREQ_IRCAPTURE)); break; @@ -431,6 +443,9 @@ static int jim_newtap_cmd( Jim_GetOptInfo *goi ) } /* 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 (0 == reqbits) { @@ -445,6 +460,44 @@ static int jim_newtap_cmd( Jim_GetOptInfo *goi ) return JIM_ERR; } +static void jtag_tap_handle_event(jtag_tap_t *tap, enum jtag_event e) +{ + jtag_tap_event_action_t * jteap; + int done; + + jteap = tap->event_action; + + done = 0; + while (jteap) { + if (jteap->event == e) { + done = 1; + LOG_DEBUG( "JTAG tap: %s event: %d (%s) action: %s\n", + 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 { + /* NOTE: we currently assume the handlers + * can't fail. That presumes later code + * will be verifying the scan chains ... + */ + tap->enabled = (e == JTAG_TAP_EVENT_ENABLE); + } + } + + jteap = jteap->next; + } + + if (!done) { + LOG_DEBUG( "event %d %s - no action", + e, + Jim_Nvp_value2name_simple( nvp_jtag_tap_event, e)->name); + } +} + + static int jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) { Jim_GetOptInfo goi; @@ -522,26 +575,45 @@ static int jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv { jtag_tap_t *t; - t = jtag_tap_by_jim_obj( goi.interp, goi.argv[0] ); - if( t == NULL ){ + + t = jtag_tap_by_jim_obj(goi.interp, goi.argv[0]); + if (t == NULL) return JIM_ERR; - } - switch( n->value ){ + + switch (n->value) { case JTAG_CMD_TAPISENABLED: - e = t->enabled; break; case JTAG_CMD_TAPENABLE: - jtag_tap_handle_event( t, JTAG_TAP_EVENT_ENABLE); - e = 1; - t->enabled = e; + 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: - jtag_tap_handle_event( t, JTAG_TAP_EVENT_DISABLE); - e = 0; - t->enabled = e; + 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; } - Jim_SetResult( goi.interp, Jim_NewIntObj( goi.interp, e ) ); + e = t->enabled; + Jim_SetResult(goi.interp, Jim_NewIntObj(goi.interp, e)); return JIM_OK; } break; @@ -624,6 +696,7 @@ int jtag_register_commands(struct command_context_s *cmd_ctx) COMMAND_EXEC, "execute IR scan [dev2] [instr2] ..."); register_jim(cmd_ctx, "drscan", Jim_Command_drscan, "execute DR scan ..."); register_jim(cmd_ctx, "flush_count", Jim_Command_flush_count, "returns number of times the JTAG queue has been flushed"); + register_jim(cmd_ctx, "pathmove", Jim_Command_pathmove, "move JTAG to state1 then to state2, state3, etc. ,,..."); register_command(cmd_ctx, NULL, "verify_ircapture", handle_verify_ircapture_command, COMMAND_ANY, "verify value captured during Capture-IR "); @@ -921,8 +994,10 @@ next: } /* clear previous values of those bits, save new values */ - jtag_reset_config &= ~mask; - jtag_reset_config |= new_cfg; + enum reset_types old_cfg = jtag_get_reset_config(); + old_cfg &= ~mask; + new_cfg |= old_cfg; + jtag_set_reset_config(new_cfg); return ERROR_OK; } @@ -933,7 +1008,13 @@ static int handle_jtag_nsrst_delay_command(struct command_context_s *cmd_ctx, if (argc > 1) return ERROR_COMMAND_SYNTAX_ERROR; if (argc == 1) - jtag_set_nsrst_delay(strtoul(args[0], NULL, 0)); + { + unsigned delay; + int retval = parse_uint(args[0], &delay); + if (ERROR_OK != retval) + return retval; + jtag_set_nsrst_delay(delay); + } command_print(cmd_ctx, "jtag_nsrst_delay: %u", jtag_get_nsrst_delay()); return ERROR_OK; } @@ -944,7 +1025,13 @@ static int handle_jtag_ntrst_delay_command(struct command_context_s *cmd_ctx, if (argc > 1) return ERROR_COMMAND_SYNTAX_ERROR; if (argc == 1) - jtag_set_ntrst_delay(strtoul(args[0], NULL, 0)); + { + unsigned delay; + int retval = parse_uint(args[0], &delay); + if (ERROR_OK != retval) + return retval; + jtag_set_ntrst_delay(delay); + } command_print(cmd_ctx, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay()); return ERROR_OK; } @@ -959,8 +1046,10 @@ static int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cm { LOG_DEBUG("handle jtag speed"); - int cur_speed = 0; - cur_speed = strtoul(args[0], NULL, 0); + unsigned cur_speed = 0; + int retval = parse_uint(args[0], &cur_speed); + if (ERROR_OK != retval) + return retval; retval = jtag_set_speed(cur_speed); } @@ -975,44 +1064,28 @@ static int handle_jtag_khz_command(struct command_context_s *cmd_ctx, char *cmd, return ERROR_COMMAND_SYNTAX_ERROR; int retval = ERROR_OK; - int cur_speed = 0; if (argc == 1) { - LOG_DEBUG("handle jtag khz"); - - jtag_set_speed_khz(strtoul(args[0], NULL, 0)); - if (jtag != NULL) - { - LOG_DEBUG("have interface set up"); - int speed_div1; - retval = jtag->khz(jtag_get_speed_khz(), &speed_div1); - if (ERROR_OK != retval) - { - jtag_set_speed_khz(0); - return retval; - } - cur_speed = speed_div1; - - retval = jtag_set_speed(cur_speed); - } - else - hasKHz = true; - } - - cur_speed = jtag_get_speed_khz(); - if (jtag != NULL) - { - retval = jtag->speed_div(jtag_get_speed(), &cur_speed); + unsigned khz = 0; + int retval = parse_uint(args[0], &khz); + if (ERROR_OK != retval) + return retval; + retval = jtag_config_khz(khz); if (ERROR_OK != retval) return retval; } + int cur_speed = jtag_get_speed_khz(); + retval = jtag_get_speed_readable(&cur_speed); + if (ERROR_OK != retval) + return retval; + if (cur_speed) command_print(cmd_ctx, "%d kHz", cur_speed); else command_print(cmd_ctx, "RCLK - adaptive"); - return retval; + return retval; } static int handle_jtag_reset_command(struct command_context_s *cmd_ctx, @@ -1052,7 +1125,12 @@ static int handle_runtest_command(struct command_context_s *cmd_ctx, if (argc != 1) return ERROR_COMMAND_SYNTAX_ERROR; - jtag_add_runtest(strtol(args[0], NULL, 0), jtag_get_end_state()); + unsigned num_clocks; + int retval = parse_uint(args[0], &num_clocks); + if (ERROR_OK != retval) + return retval; + + jtag_add_runtest(num_clocks, TAP_IDLE); jtag_execute_queue(); return ERROR_OK; @@ -1122,9 +1200,11 @@ static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, c } int num_fields = argc / 2; + size_t fields_len = sizeof(scan_field_t) * num_fields; + fields = malloc(fields_len); + memset(fields, 0, fields_len); - fields = malloc(sizeof(scan_field_t) * num_fields); - + int retval; for (i = 0; i < num_fields; i++) { tap = jtag_tap_by_string( args[i*2] ); @@ -1137,17 +1217,26 @@ static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, c fields[i].tap = tap; fields[i].num_bits = field_size; fields[i].out_value = malloc(CEIL(field_size, 8)); - buf_set_u32(fields[i].out_value, 0, field_size, strtoul(args[i*2+1], NULL, 0)); + + u32 value; + retval = parse_u32(args[i * 2 + 1], &value); + if (ERROR_OK != retval) + goto error_return; + buf_set_u32(fields[i].out_value, 0, field_size, value); fields[i].in_value = NULL; } /* did we have an endstate? */ jtag_add_ir_scan(num_fields, fields, endstate); - int retval=jtag_execute_queue(); + retval = jtag_execute_queue(); +error_return: for (i = 0; i < num_fields; i++) - free(fields[i].out_value); + { + if (NULL != fields[i].out_value) + free(fields[i].out_value); + } free (fields); @@ -1181,6 +1270,8 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args endstate = TAP_IDLE; + script_debug(interp, "drscan", argc, args); + /* validate arguments as numbers */ e = JIM_OK; for (i = 2; i < argc; i+=2) @@ -1292,8 +1383,54 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args } +static int Jim_Command_pathmove(Jim_Interp *interp, int argc, Jim_Obj *const *args) +{ + tap_state_t states[8]; + + if ((argc < 2) || ((size_t)argc > (sizeof(states)/sizeof(*states)+1))) + { + Jim_WrongNumArgs(interp, 1, args, "wrong arguments"); + return JIM_ERR; + } + + script_debug(interp, "pathmove", argc, args); + + int i; + for (i=0; i 1) + return ERROR_COMMAND_SYNTAX_ERROR; + if (argc == 1) { if (strcmp(args[0], "enable") == 0) - { - jtag_verify_capture_ir = 1; - } + jtag_set_verify_capture_ir(true); else if (strcmp(args[0], "disable") == 0) - { - jtag_verify_capture_ir = 0; - } else - { + jtag_set_verify_capture_ir(false); + else return ERROR_COMMAND_SYNTAX_ERROR; - } - } else if (argc != 0) - { - return ERROR_COMMAND_SYNTAX_ERROR; } - command_print(cmd_ctx, "verify Capture-IR is %s", (jtag_verify_capture_ir) ? "enabled": "disabled"); + const char *status = jtag_will_verify_capture_ir() ? "enabled": "disabled"; + command_print(cmd_ctx, "verify Capture-IR is %s", status); return ERROR_OK; }