X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fjtag.c;h=80707b15b28832a013c3135de623e43d4c2aa542;hb=6fda8707668c413a78f44ae4f58a79f5765376c2;hp=0b70c0f14bfce3aaadd3fb01f28cdf1e792bccac;hpb=bcde5b3830147c131afacf836cb24698039b9f84;p=openocd.git diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index 0b70c0f14b..80707b15b2 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -40,15 +40,6 @@ */ int jtag_error=ERROR_OK; - -char* tap_state_strings[16] = -{ - "tlr", - "sds", "cd", "sd", "e1d", "pd", "e2d", "ud", - "rti", - "sis", "ci", "si", "e1i", "pi", "e2i", "ui" -}; - typedef struct cmd_queue_page_s { void *address; @@ -87,22 +78,22 @@ int tap_move_map[16] = { tap_transition_t tap_transitions[16] = { - {TAP_RESET, TAP_IDLE}, /* RESET */ - {TAP_IRSELECT, TAP_DRCAPTURE}, /* DRSELECT */ - {TAP_DREXIT1, TAP_DRSHIFT}, /* DRCAPTURE */ - {TAP_DREXIT1, TAP_DRSHIFT}, /* DRSHIFT */ + {TAP_RESET, TAP_IDLE}, /* RESET */ + {TAP_IRSELECT, TAP_DRCAPTURE}, /* DRSELECT */ + {TAP_DREXIT1, TAP_DRSHIFT}, /* DRCAPTURE */ + {TAP_DREXIT1, TAP_DRSHIFT}, /* DRSHIFT */ {TAP_DRUPDATE, TAP_DRPAUSE}, /* DREXIT1 */ - {TAP_DREXIT2, TAP_DRPAUSE}, /* DRPAUSE */ + {TAP_DREXIT2, TAP_DRPAUSE}, /* DRPAUSE */ {TAP_DRUPDATE, TAP_DRSHIFT}, /* DREXIT2 */ - {TAP_DRSELECT, TAP_IDLE}, /* DRUPDATE */ - {TAP_DRSELECT, TAP_IDLE}, /* IDLE */ - {TAP_RESET, TAP_IRCAPTURE}, /* IRSELECT */ - {TAP_IREXIT1, TAP_IRSHIFT}, /* IRCAPTURE */ - {TAP_IREXIT1, TAP_IRSHIFT}, /* IRSHIFT */ + {TAP_DRSELECT, TAP_IDLE}, /* DRUPDATE */ + {TAP_DRSELECT, TAP_IDLE}, /* IDLE */ + {TAP_RESET, TAP_IRCAPTURE}, /* IRSELECT */ + {TAP_IREXIT1, TAP_IRSHIFT}, /* IRCAPTURE */ + {TAP_IREXIT1, TAP_IRSHIFT}, /* IRSHIFT */ {TAP_IRUPDATE, TAP_IRPAUSE}, /* IREXIT1 */ - {TAP_IREXIT2, TAP_IRPAUSE}, /* IRPAUSE */ + {TAP_IREXIT2, TAP_IRPAUSE}, /* IRPAUSE */ {TAP_IRUPDATE, TAP_IRSHIFT}, /* IREXIT2 */ - {TAP_DRSELECT, TAP_IDLE} /* IRUPDATE */ + {TAP_DRSELECT, TAP_IDLE} /* IRUPDATE */ }; char* jtag_event_strings[] = @@ -110,6 +101,13 @@ char* jtag_event_strings[] = "JTAG controller reset (RESET or TRST)" }; +const Jim_Nvp nvp_jtag_tap_event[] = { + { .value = JTAG_TAP_EVENT_ENABLE, .name = "tap-enable" }, + { .value = JTAG_TAP_EVENT_DISABLE, .name = "tap-disable" }, + + { .name = NULL, .value = -1 } +}; + /* kludge!!!! these are just global variables that the * interface use internally. They really belong * inside the drivers, but we don't want to break @@ -197,6 +195,14 @@ static int hasKHz = 0; extern jtag_interface_t jlink_interface; #endif +#if BUILD_VSLLINK == 1 + extern jtag_interface_t vsllink_interface; +#endif + +#if BUILD_RLINK == 1 + extern jtag_interface_t rlink_interface; +#endif + jtag_interface_t *jtag_interfaces[] = { #if BUILD_ECOSBOARD == 1 &zy1000_interface, @@ -233,6 +239,12 @@ jtag_interface_t *jtag_interfaces[] = { #endif #if BUILD_JLINK == 1 &jlink_interface, +#endif +#if BUILD_VSLLINK == 1 + &vsllink_interface, +#endif +#if BUILD_RLINK == 1 + &rlink_interface, #endif NULL, }; @@ -243,8 +255,6 @@ jtag_interface_t *jtag = NULL; jtag_interface_t *jtag_interface = NULL; int jtag_speed = 0; - - /* forward declarations */ void jtag_add_pathmove(int num_states, enum tap_state *path); void jtag_add_runtest(int num_cycles, enum tap_state endstate); @@ -272,14 +282,12 @@ int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *argv); int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); - jtag_tap_t *jtag_AllTaps(void) { - return jtag_all_taps; + return jtag_all_taps; }; -int -jtag_NumTotalTaps(void) +int jtag_NumTotalTaps(void) { jtag_tap_t *t; int n; @@ -293,8 +301,7 @@ jtag_NumTotalTaps(void) return n; } -int -jtag_NumEnabledTaps(void) +int jtag_NumEnabledTaps(void) { jtag_tap_t *t; int n; @@ -338,8 +345,7 @@ jtag_tap_t *jtag_TapByString( const char *s ) return t; } -jtag_tap_t * -jtag_TapByJimObj( Jim_Interp *interp, Jim_Obj *o ) +jtag_tap_t * jtag_TapByJimObj( Jim_Interp *interp, Jim_Obj *o ) { jtag_tap_t *t; const char *cp; @@ -358,8 +364,7 @@ jtag_TapByJimObj( Jim_Interp *interp, Jim_Obj *o ) } /* returns a pointer to the n-th device in the scan chain */ -jtag_tap_t * -jtag_TapByAbsPosition( int n ) +jtag_tap_t * jtag_TapByAbsPosition( int n ) { int orig_n; jtag_tap_t *t; @@ -370,11 +375,10 @@ jtag_TapByAbsPosition( int n ) while( t && (n > 0)) { n--; t = t->next_tap; - } + } return t; } - int jtag_register_event_callback(int (*callback)(enum jtag_event event, void *priv), void *priv) { jtag_event_callback_t **callbacks_p = &jtag_event_callbacks; @@ -456,7 +460,6 @@ jtag_command_t** jtag_get_last_command_p(void) return last_comand_pointer; } - void* cmd_queue_alloc(size_t size) { cmd_queue_page_t **p_page = &cmd_queue_pages; @@ -484,17 +487,16 @@ void* cmd_queue_alloc(size_t size) * */ union worse_case_align { - int i; - long l; - float f; - void *v; + int i; + long l; + float f; + void *v; }; #define ALIGN_SIZE (sizeof(union worse_case_align)) - // The alignment process. + /* The alignment process. */ size = (size + ALIGN_SIZE -1) & (~(ALIGN_SIZE-1)); - // Done... - + /* Done... */ if (*p_page) { @@ -645,7 +647,6 @@ int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, (*last_cmd)->cmd.scan->fields[nth_tap].out_value = buf_set_ones(cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); (*last_cmd)->cmd.scan->fields[nth_tap].out_mask = NULL; tap->bypass = 1; - } /* update device information */ @@ -967,7 +968,7 @@ void jtag_add_tlr(void) jtag_error=retval; } -int MINIDRIVER(interface_jtag_add_tlr)() +int MINIDRIVER(interface_jtag_add_tlr)(void) { enum tap_state state = TAP_RESET; jtag_command_t **last_cmd = jtag_get_last_command_p(); @@ -981,7 +982,6 @@ int MINIDRIVER(interface_jtag_add_tlr)() (*last_cmd)->cmd.statemove = cmd_queue_alloc(sizeof(statemove_command_t)); (*last_cmd)->cmd.statemove->end_state = state; - return ERROR_OK; } @@ -1008,7 +1008,7 @@ void jtag_add_pathmove(int num_states, enum tap_state *path) if ((tap_transitions[cur_state].low != path[i])&& (tap_transitions[cur_state].high != path[i])) { - LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[path[i]]); + LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", jtag_state_name(cur_state), jtag_state_name(path[i])); exit(-1); } cur_state = path[i]; @@ -1016,7 +1016,6 @@ void jtag_add_pathmove(int num_states, enum tap_state *path) jtag_prelude1(); - retval=interface_jtag_add_pathmove(num_states, path); cmd_queue_cur_state = path[num_states - 1]; if (retval!=ERROR_OK) @@ -1073,6 +1072,33 @@ void jtag_add_runtest(int num_cycles, enum tap_state state) jtag_error=retval; } + +int MINIDRIVER(interface_jtag_add_clocks)( int num_cycles ) +{ + jtag_command_t **last_cmd = jtag_get_last_command_p(); + + /* allocate memory for a new list member */ + *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + (*last_cmd)->next = NULL; + last_comand_pointer = &((*last_cmd)->next); + (*last_cmd)->type = JTAG_STABLECLOCKS; + + (*last_cmd)->cmd.stableclocks = cmd_queue_alloc(sizeof(stableclocks_command_t)); + (*last_cmd)->cmd.stableclocks->num_cycles = num_cycles; + return ERROR_OK; +} + +void jtag_add_clocks( int num_cycles ) +{ + int retval; + + jtag_prelude1(); + + retval=interface_jtag_add_clocks(num_cycles); + if (retval!=ERROR_OK) + jtag_error=retval; +} + void jtag_add_reset(int req_tlr_or_trst, int req_srst) { int trst_with_tlr = 0; @@ -1251,6 +1277,10 @@ int jtag_build_buffer(scan_command_t *cmd, u8 **buffer) bit_count = 0; +#ifdef _DEBUG_JTAG_IO_ + LOG_DEBUG("num_fields: %i",cmd->num_fields); +#endif + for (i = 0; i < cmd->num_fields; i++) { if (cmd->fields[i].out_value) @@ -1260,12 +1290,15 @@ int jtag_build_buffer(scan_command_t *cmd, u8 **buffer) #endif buf_set_buf(cmd->fields[i].out_value, 0, *buffer, bit_count, cmd->fields[i].num_bits); #ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("fields[%i].out_value: 0x%s", i, char_buf); + LOG_DEBUG("fields[%i].out_value[%i]: 0x%s", i, cmd->fields[i].num_bits, char_buf); free(char_buf); #endif } bit_count += cmd->fields[i].num_bits; +#ifdef _DEBUG_JTAG_IO_ + LOG_DEBUG("bit_count totalling: %i", bit_count ); +#endif } return bit_count; @@ -1291,10 +1324,8 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) u8 *captured = buf_set_buf(buffer, bit_count, malloc(CEIL(num_bits, 8)), 0, num_bits); #ifdef _DEBUG_JTAG_IO_ - char *char_buf; - - char_buf = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16); - LOG_DEBUG("fields[%i].in_value: 0x%s", i, char_buf); + char *char_buf = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16); + LOG_DEBUG("fields[%i].in_value[%i]: 0x%s", i, num_bits, char_buf); free(char_buf); #endif @@ -1306,7 +1337,7 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) { if (cmd->fields[i].in_handler(cmd->fields[i].in_value, cmd->fields[i].in_handler_priv, cmd->fields+i) != ERROR_OK) { - LOG_WARNING("in_handler reported a failed check"); + LOG_WARNING("in_handler: with \"in_value\", mismatch in %s", cmd->ir_scan ? "SIR" : "SDR" ); retval = ERROR_JTAG_QUEUE_FAILED; } } @@ -1320,7 +1351,7 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) /* We're going to call the error:handler later, but if the in_handler * reported an error we report this failure upstream */ - LOG_WARNING("in_handler reported a failed check"); + LOG_WARNING("in_handler: w/o \"in_value\", mismatch in %s", cmd->ir_scan ? "SIR" : "SDR" ); retval = ERROR_JTAG_QUEUE_FAILED; } } @@ -1699,9 +1730,106 @@ int jtag_validate_chain(void) return ERROR_OK; } +enum jtag_tap_cfg_param { + JCFG_EVENT +}; + +static Jim_Nvp nvp_config_opts[] = { + { .name = "-event", .value = JCFG_EVENT }, + + { .name = NULL, .value = -1 } +}; static int -jim_newtap_cmd( Jim_GetOptInfo *goi ) +jtag_tap_configure_cmd( Jim_GetOptInfo *goi, + jtag_tap_t * tap) +{ + Jim_Nvp *n; + Jim_Obj *o; + int e; + + /* parse config or cget options */ + while (goi->argc > 0) { + Jim_SetEmptyResult (goi->interp); + + e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n); + if (e != JIM_OK) { + Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0); + return e; + } + + switch (n->value) { + case JCFG_EVENT: + if (goi->argc == 0) { + Jim_WrongNumArgs( goi->interp, goi->argc, goi->argv, "-event ?event-name? ..." ); + return JIM_ERR; + } + + e = Jim_GetOpt_Nvp( goi, nvp_jtag_tap_event, &n ); + if (e != JIM_OK) { + Jim_GetOpt_NvpUnknown(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; + } + } + + { + jtag_tap_event_action_t *jteap; + + jteap = tap->event_action; + /* replace existing? */ + while (jteap) { + if (jteap->event == n->value) { + break; + } + jteap = jteap->next; + } + + if (goi->isconfigure) { + if (jteap == NULL) { + /* create new */ + jteap = calloc(1, sizeof (*jteap)); + } + jteap->event = n->value; + Jim_GetOpt_Obj( goi, &o); + if (jteap->body) { + Jim_DecrRefCount(interp, jteap->body); + } + jteap->body = Jim_DuplicateObj(goi->interp, o); + Jim_IncrRefCount(jteap->body); + + /* add to head of event list */ + jteap->next = tap->event_action; + tap->event_action = jteap; + Jim_SetEmptyResult(goi->interp); + } else { + /* get */ + if (jteap == NULL) { + Jim_SetEmptyResult(goi->interp); + } else { + Jim_SetResult(goi->interp, Jim_DuplicateObj(goi->interp, jteap->body)); + } + } + } + /* loop for more */ + break; + } + } /* while (goi->argc) */ + + return JIM_OK; +} + +static int jim_newtap_cmd( Jim_GetOptInfo *goi ) { jtag_tap_t *pTap; jtag_tap_t **ppTap; @@ -1719,24 +1847,23 @@ jim_newtap_cmd( Jim_GetOptInfo *goi ) #define NTAP_OPT_IRCAPTURE 2 { .name = "-ircapture" , .value = NTAP_OPT_IRCAPTURE }, #define NTAP_OPT_ENABLED 3 - { .name = "-enable" , .value = NTAP_OPT_ENABLED }, + { .name = "-enable" , .value = NTAP_OPT_ENABLED }, #define NTAP_OPT_DISABLED 4 - { .name = "-disable" , .value = NTAP_OPT_DISABLED }, + { .name = "-disable" , .value = NTAP_OPT_DISABLED }, #define NTAP_OPT_EXPECTED_ID 5 - { .name = "-expected-id" , .value = NTAP_OPT_EXPECTED_ID }, - { .name = NULL , .value = -1 }, + { .name = "-expected-id" , .value = NTAP_OPT_EXPECTED_ID }, + { .name = NULL , .value = -1 }, }; - pTap = malloc( sizeof(jtag_tap_t) ); memset( pTap, 0, sizeof(*pTap) ); if( !pTap ){ Jim_SetResult_sprintf( goi->interp, "no memory"); return JIM_ERR; } - // - // we expect CHIP + TAP + OPTIONS - // + /* + * we expect CHIP + TAP + OPTIONS + * */ if( goi->argc < 3 ){ Jim_SetResult_sprintf(goi->interp, "Missing CHIP TAP OPTIONS ...."); return JIM_ERR; @@ -1747,7 +1874,7 @@ jim_newtap_cmd( Jim_GetOptInfo *goi ) Jim_GetOpt_String( goi, &cp, NULL ); pTap->tapname = strdup(cp); - // name + dot + name + null + /* name + dot + name + null */ x = strlen(pTap->chip) + 1 + strlen(pTap->tapname) + 1; cp = malloc( x ); sprintf( cp, "%s.%s", pTap->chip, pTap->tapname ); @@ -1756,16 +1883,15 @@ 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 + /* default is enabled */ pTap->enabled = 1; - // deal with options + /* deal with options */ #define NTREQ_IRLEN 1 #define NTREQ_IRCAPTURE 2 #define NTREQ_IRMASK 4 - // clear them as we find them + /* clear them as we find them */ reqbits = (NTREQ_IRLEN | NTREQ_IRCAPTURE | NTREQ_IRMASK); while( goi->argc ){ @@ -1816,7 +1942,7 @@ jim_newtap_cmd( Jim_GetOptInfo *goi ) return e; } if( (w < 0) || (w > 0xffff) ){ - // wacky value + /* wacky value */ Jim_SetResult_sprintf( goi->interp, "option: %s - wacky value: %d (0x%x)", n->name, (int)(w), (int)(w)); return JIM_ERR; @@ -1835,17 +1961,17 @@ jim_newtap_cmd( Jim_GetOptInfo *goi ) reqbits &= (~(NTREQ_IRCAPTURE)); break; } - } // switch(n->value) - } // while( goi->argc ) + } /* switch(n->value) */ + } /* while( goi->argc ) */ - // Did we get all the options? + /* Did we get all the options? */ if( reqbits ){ // no Jim_SetResult_sprintf( goi->interp, "newtap: %s missing required parameters", pTap->dotted_name); - // fixme: Tell user what is missing :-( - // no memory leaks pelase + /* TODO: Tell user what is missing :-( */ + /* no memory leaks pelase */ free(((void *)(pTap->expected_ids))); free(((void *)(pTap->chip))); free(((void *)(pTap->tapname))); @@ -1871,7 +1997,6 @@ jim_newtap_cmd( Jim_GetOptInfo *goi ) pTap->bypass = 1; - jtag_register_event_callback(jtag_reset_callback, pTap ); ppTap = &(jtag_all_taps); @@ -1884,23 +2009,21 @@ jim_newtap_cmd( Jim_GetOptInfo *goi ) pTap->abs_chain_position = n_taps++; } LOG_DEBUG( "Created Tap: %s @ abs position %d, irlen %d, capture: 0x%x mask: 0x%x", - (*ppTap)->dotted_name, - (*ppTap)->abs_chain_position, - (*ppTap)->ir_length, - (*ppTap)->ir_capture_value, - (*ppTap)->ir_capture_mask ); - + (*ppTap)->dotted_name, + (*ppTap)->abs_chain_position, + (*ppTap)->ir_length, + (*ppTap)->ir_capture_value, + (*ppTap)->ir_capture_mask ); return ERROR_OK; } - -static int -jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) +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_s *context; enum { @@ -1909,7 +2032,9 @@ jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) JTAG_CMD_NEWTAP, JTAG_CMD_TAPENABLE, JTAG_CMD_TAPDISABLE, - JTAG_CMD_TAPISENABLED + JTAG_CMD_TAPISENABLED, + JTAG_CMD_CONFIGURE, + JTAG_CMD_CGET }; const Jim_Nvp jtag_cmds[] = { @@ -1919,12 +2044,14 @@ jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) { .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 = NULL, .value = -1 }, }; context = Jim_GetAssocData(interp, "context"); - // go past the command + /* go past the command */ Jim_GetOpt_Setup( &goi, interp, argc-1, argv+1 ); e = Jim_GetOpt_Nvp( &goi, jtag_cmds, &n ); @@ -1935,9 +2062,9 @@ jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) 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. + /* 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; @@ -1974,13 +2101,15 @@ jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) } switch( n->value ){ case JTAG_CMD_TAPISENABLED: - // below + e = t->enabled; break; case JTAG_CMD_TAPENABLE: + jtag_tap_handle_event( t, JTAG_TAP_EVENT_ENABLE); e = 1; t->enabled = e; break; case JTAG_CMD_TAPDISABLE: + jtag_tap_handle_event( t, JTAG_TAP_EVENT_DISABLE); e = 0; t->enabled = e; break; @@ -1988,8 +2117,47 @@ jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) Jim_SetResult( goi.interp, Jim_NewIntObj( goi.interp, e ) ); return JIM_OK; } - } + break; + + case JTAG_CMD_CGET: + if( goi.argc < 2 ){ + Jim_WrongNumArgs( goi.interp, 0, NULL, "?tap-name? -option ..."); + return JIM_ERR; + } + + { + jtag_tap_t *t; + + Jim_GetOpt_Obj(&goi, &o); + t = jtag_TapByJimObj( goi.interp, o ); + if( t == NULL ){ + return JIM_ERR; + } + + goi.isconfigure = 0; + return jtag_tap_configure_cmd( &goi, t); + } + break; + + case JTAG_CMD_CONFIGURE: + if( goi.argc < 3 ){ + Jim_WrongNumArgs( goi.interp, 0, NULL, "?tap-name? -option ?VALUE? ..."); + return JIM_ERR; + } + + { + jtag_tap_t *t; + Jim_GetOpt_Obj(&goi, &o); + t = jtag_TapByJimObj( goi.interp, o ); + if( t == NULL ){ + return JIM_ERR; + } + + goi.isconfigure = 1; + return jtag_tap_configure_cmd( &goi, t); + } + } return JIM_ERR; } @@ -2007,7 +2175,8 @@ int jtag_register_commands(struct command_context_s *cmd_ctx) register_command(cmd_ctx, NULL, "jtag_device", handle_jtag_device_command, COMMAND_CONFIG, "jtag_device "); register_command(cmd_ctx, NULL, "reset_config", handle_reset_config_command, - COMMAND_CONFIG, NULL); + COMMAND_ANY, + "[none/trst_only/srst_only/trst_and_srst] [srst_pulls_trst/trst_pulls_srst] [combined/separate] [trst_push_pull/trst_open_drain] [srst_push_pull/srst_open_drain]"); register_command(cmd_ctx, NULL, "jtag_nsrst_delay", handle_jtag_nsrst_delay_command, COMMAND_ANY, "jtag_nsrst_delay - delay after deasserting srst in ms"); register_command(cmd_ctx, NULL, "jtag_ntrst_delay", handle_jtag_ntrst_delay_command, @@ -2051,8 +2220,6 @@ int jtag_interface_init(struct command_context_s *cmd_ctx) if (jtag_interface->init() != ERROR_OK) return ERROR_JTAG_INIT_FAILED; - - jtag = jtag_interface; return ERROR_OK; } @@ -2064,7 +2231,6 @@ static int jtag_init_inner(struct command_context_s *cmd_ctx) LOG_DEBUG("Init JTAG chain"); - tap = jtag_NextEnabledTap(NULL); if( tap == NULL ){ LOG_ERROR("There are no enabled taps?"); @@ -2238,14 +2404,14 @@ int handle_jtag_device_command(struct command_context_s *cmd_ctx, char *cmd, cha int e; char buf[1024]; Jim_Obj *newargs[ 10 ]; - // - // CONVERT SYNTAX - // - // argv[-1] = command - // argv[ 0] = ir length - // argv[ 1] = ir capture - // argv[ 2] = ir mask - // argv[ 3] = not actually used by anything but in the docs + /* + * CONVERT SYNTAX + * argv[-1] = command + * argv[ 0] = ir length + * argv[ 1] = ir capture + * argv[ 2] = ir mask + * argv[ 3] = not actually used by anything but in the docs + */ if( argc < 4 ){ command_print( cmd_ctx, "OLD DEPRECATED SYNTAX: Please use the NEW syntax"); @@ -2261,8 +2427,6 @@ int handle_jtag_device_command(struct command_context_s *cmd_ctx, char *cmd, cha command_print( cmd_ctx, "jtag newtap stm32 boundry ....., and the tap: \"stm32.boundery\""); command_print( cmd_ctx, "And then refer to the taps by the dotted name."); - - newargs[0] = Jim_NewStringObj( interp, "jtag", -1 ); newargs[1] = Jim_NewStringObj( interp, "newtap", -1 ); sprintf( buf, "chip%d", jtag_NumTotalTaps() ); @@ -2289,8 +2453,6 @@ int handle_jtag_device_command(struct command_context_s *cmd_ctx, char *cmd, cha Jim_GetString( newargs[8], NULL ), Jim_GetString( newargs[9], NULL ) ); - - e = jim_jtag_command( interp, 10, newargs ); if( e != JIM_OK ){ command_print( cmd_ctx, "%s", Jim_GetString( Jim_GetResult(interp), NULL ) ); @@ -2298,7 +2460,6 @@ int handle_jtag_device_command(struct command_context_s *cmd_ctx, char *cmd, cha return e; } - int handle_scan_chain_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { jtag_tap_t *tap; @@ -2532,14 +2693,14 @@ int handle_endstate_command(struct command_context_s *cmd_ctx, char *cmd, char * { for (state = 0; state < 16; state++) { - if (strcmp(args[0], tap_state_strings[state]) == 0) + if (strcmp(args[0], jtag_state_name(state)) == 0) { jtag_add_end_state(state); jtag_execute_queue(); } } } - command_print(cmd_ctx, "current endstate: %s", tap_state_strings[cmd_queue_end_state]); + command_print(cmd_ctx, "current endstate: %s", jtag_state_name(cmd_queue_end_state)); return ERROR_OK; } @@ -2683,7 +2844,6 @@ int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args) Jim_GetLong(interp, args[i], &bits); str = Jim_GetString(args[i+1], &len); - fields[field_count].tap = tap; fields[field_count].num_bits = bits; fields[field_count].out_value = malloc(CEIL(bits, 8)); @@ -2752,7 +2912,6 @@ int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd return ERROR_OK; } - int jtag_power_dropout(int *dropout) { return jtag->power_dropout(dropout); @@ -2763,3 +2922,62 @@ int jtag_srst_asserted(int *srst_asserted) return jtag->srst_asserted(srst_asserted); } +void jtag_tap_handle_event( jtag_tap_t * tap, enum jtag_tap_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); + } + } + + jteap = jteap->next; + } + + if (!done) { + LOG_DEBUG( "event %d %s - no action", + e, + Jim_Nvp_value2name_simple( nvp_jtag_tap_event, e)->name); + } +} + +/* map state number to SVF state string */ +const char* jtag_state_name(enum tap_state state) +{ + const char* ret; + + switch( state ) + { + case TAP_RESET: ret = "RESET"; break; + case TAP_IDLE: ret = "IDLE"; break; + case TAP_DRSELECT: ret = "DRSELECT"; break; + case TAP_DRCAPTURE: ret = "DRCAPTURE"; break; + case TAP_DRSHIFT: ret = "DRSHIFT"; break; + case TAP_DREXIT1: ret = "DREXIT1"; break; + case TAP_DRPAUSE: ret = "DRPAUSE"; break; + case TAP_DREXIT2: ret = "DREXIT2"; break; + case TAP_DRUPDATE: ret = "DRUPDATE"; break; + case TAP_IRSELECT: ret = "IRSELECT"; break; + case TAP_IRCAPTURE: ret = "IRCAPTURE"; break; + case TAP_IRSHIFT: ret = "IRSHIFT"; break; + case TAP_IREXIT1: ret = "IREXIT1"; break; + case TAP_IRPAUSE: ret = "IRPAUSE"; break; + case TAP_IREXIT2: ret = "IREXIT2"; break; + case TAP_IRUPDATE: ret = "IRUPDATE"; break; + default: ret = "???"; + } + + return ret; +}