X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fjtag.c;h=a9a4b30cbb21c090adaffa6da235b4665627f2cb;hb=7989000e0969c1ccf69acbc3ce649a020bc1ee66;hp=ae51ebc16ce0114dfddb07800baff3ed56d7605a;hpb=e77ae9096a40707d3b878b46969a60a06656dc06;p=openocd.git diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index ae51ebc16c..a9a4b30cbb 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -4,10 +4,10 @@ * * * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * - * - * Copyright (C) 2009 SoftPLC Corporation - * http://softplc.com - * dick@softplc.com + * * + * Copyright (C) 2009 SoftPLC Corporation * + * http://softplc.com * + * dick@softplc.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -44,7 +44,6 @@ */ int jtag_error=ERROR_OK; - typedef struct cmd_queue_page_s { void *address; @@ -155,6 +154,10 @@ static int hasKHz = 0; extern jtag_interface_t rlink_interface; #endif +#if BUILD_ARMJTAGEW == 1 + extern jtag_interface_t armjtagew_interface; +#endif + jtag_interface_t *jtag_interfaces[] = { #if BUILD_ECOSBOARD == 1 &zy1000_interface, @@ -197,6 +200,9 @@ jtag_interface_t *jtag_interfaces[] = { #endif #if BUILD_RLINK == 1 &rlink_interface, +#endif +#if BUILD_ARMJTAGEW == 1 + &armjtagew_interface, #endif NULL, }; @@ -213,7 +219,7 @@ void jtag_add_runtest(int num_cycles, tap_state_t endstate); void jtag_add_end_state(tap_state_t endstate); void jtag_add_sleep(u32 us); int jtag_execute_queue(void); - +tap_state_t tap_state_by_name(const char *name); /* jtag commands */ int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); @@ -269,14 +275,13 @@ int jtag_NumEnabledTaps(void) return n; } - jtag_tap_t *jtag_TapByString( const char *s ) { jtag_tap_t *t; char *cp; t = jtag_AllTaps(); - // try name first + /* try name first */ while(t){ if( 0 == strcmp( t->dotted_name, s ) ){ break; @@ -284,7 +289,7 @@ jtag_tap_t *jtag_TapByString( const char *s ) t = t->next_tap; } } - // backup plan is by number + /* backup plan is by number */ if( t == NULL ){ /* ok - is "s" a number? */ int n; @@ -505,7 +510,7 @@ static void jtag_prelude(tap_state_t state) { jtag_prelude1(); - if (state != -1) + if (state != TAP_INVALID) jtag_add_end_state(state); cmd_queue_cur_state = cmd_queue_end_state; @@ -531,7 +536,6 @@ int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, int nth_tap; int scan_size = 0; - last_cmd = jtag_get_last_command_p(); /* allocate memory for a new list member */ @@ -553,7 +557,7 @@ int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, for(;;){ int found = 0; - // do this here so it is not forgotten + /* do this here so it is not forgotten */ tap = jtag_NextEnabledTap(tap); if( tap == NULL ){ break; @@ -1503,7 +1507,7 @@ int jtag_examine_chain(void) return ERROR_JTAG_INIT_FAILED; } - // point at the 1st tap + /* point at the 1st tap */ tap = jtag_NextEnabledTap(NULL); if( tap == NULL ){ LOG_ERROR("JTAG: No taps enabled?"); @@ -1707,9 +1711,7 @@ static Jim_Nvp nvp_config_opts[] = { { .name = NULL, .value = -1 } }; -static int -jtag_tap_configure_cmd( Jim_GetOptInfo *goi, - jtag_tap_t * tap) +static int jtag_tap_configure_cmd( Jim_GetOptInfo *goi, jtag_tap_t * tap) { Jim_Nvp *n; Jim_Obj *o; @@ -2389,9 +2391,9 @@ int handle_jtag_device_command(struct command_context_s *cmd_ctx, char *cmd, cha args[0], args[1], args[2] ); - command_print( cmd_ctx, "Example: STM32 has 2 taps, the cortexM3(len4) + boundryscan(len5)"); - command_print( cmd_ctx, "jtag newtap stm32 cortexm3 ....., thus creating the tap: \"stm32.cortexm3\""); - command_print( cmd_ctx, "jtag newtap stm32 boundry ....., and the tap: \"stm32.boundery\""); + command_print( cmd_ctx, "Example: STM32 has 2 taps, the cortexM3(len4) + boundaryscan(len5)"); + command_print( cmd_ctx, "jtag newtap stm32 cortexm3 ....., thus creating the tap: \"stm32.cortexm3\""); + command_print( cmd_ctx, "jtag newtap stm32 boundary ....., and the tap: \"stm32.boundary\""); command_print( cmd_ctx, "And then refer to the taps by the dotted name."); newargs[0] = Jim_NewStringObj( interp, "jtag", -1 ); @@ -2658,14 +2660,13 @@ int handle_endstate_command(struct command_context_s *cmd_ctx, char *cmd, char * } else { - for (state = 0; state < 16; state++) - { - if (strcmp(args[0], tap_state_name(state)) == 0) - { - jtag_add_end_state(state); - jtag_execute_queue(); - } + state = tap_state_by_name( args[0] ); + if( state < 0 ){ + command_print( cmd_ctx, "Invalid state name: %s\n", args[0] ); + return ERROR_COMMAND_SYNTAX_ERROR; } + jtag_add_end_state(state); + jtag_execute_queue(); } command_print(cmd_ctx, "current endstate: %s", tap_state_name(cmd_queue_end_state)); @@ -2716,7 +2717,7 @@ int handle_runtest_command(struct command_context_s *cmd_ctx, char *cmd, char ** return ERROR_COMMAND_SYNTAX_ERROR; } - jtag_add_runtest(strtol(args[0], NULL, 0), -1); + jtag_add_runtest(strtol(args[0], NULL, 0), TAP_INVALID); jtag_execute_queue(); return ERROR_OK; @@ -2728,12 +2729,40 @@ int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **a int i; scan_field_t *fields; jtag_tap_t *tap; + tap_state_t endstate; if ((argc < 2) || (argc % 2)) { return ERROR_COMMAND_SYNTAX_ERROR; } + /* optional "-endstate" */ + /* "statename" */ + /* at the end of the arguments. */ + /* assume none. */ + endstate = TAP_INVALID; + if( argc >= 4 ){ + /* have at least one pair of numbers. */ + /* is last pair the magic text? */ + if( 0 == strcmp( "-endstate", args[ argc - 2 ] ) ){ + const char *cpA; + const char *cpS; + cpA = args[ argc-1 ]; + for( endstate = 0 ; endstate < TAP_NUM_STATES ; endstate++ ){ + cpS = tap_state_name( endstate ); + if( 0 == strcmp( cpA, cpS ) ){ + break; + } + } + if( endstate >= TAP_NUM_STATES ){ + return ERROR_COMMAND_SYNTAX_ERROR; + } else { + /* found - remove the last 2 args */ + argc -= 2; + } + } + } + fields = malloc(sizeof(scan_field_t) * argc / 2); for (i = 0; i < argc / 2; i++) @@ -2755,7 +2784,11 @@ int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **a fields[i].in_handler_priv = NULL; } - jtag_add_ir_scan(argc / 2, fields, -1); + jtag_add_ir_scan(argc / 2, fields, TAP_INVALID); + /* did we have an endstate? */ + if (endstate != TAP_INVALID) + jtag_add_end_state(endstate); + jtag_execute_queue(); for (i = 0; i < argc / 2; i++) @@ -2774,11 +2807,16 @@ int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args) int field_count = 0; int i, e; jtag_tap_t *tap; + tap_state_t endstate; /* 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)) { @@ -2786,14 +2824,54 @@ int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args) return JIM_ERR; } + /* assume no endstate */ + endstate = TAP_INVALID; + /* validate arguments as numbers */ + e = JIM_OK; for (i = 2; i < argc; i+=2) { long bits; + const char *cp; e = Jim_GetLong(interp, args[i], &bits); - if (e != JIM_OK) + /* If valid - try next arg */ + if( e == JIM_OK ){ + continue; + } + + /* Not valid.. are we at the end? */ + if ( ((i+2) != argc) ){ + /* nope, then error */ return e; - } + } + + /* it could be: "-endstate FOO" */ + + /* get arg as a string. */ + cp = Jim_GetString( args[i], NULL ); + /* is it the magic? */ + if( 0 == strcmp( "-endstate", cp ) ){ + /* 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_SetResult_sprintf(interp,"endstate: %s invalid", cp ); + } else { + /* valid - so clear the error */ + e = JIM_OK; + /* and remove the last 2 args */ + argc -= 2; + } + } + + /* Still an error? */ + if( e != JIM_OK ){ + return e; /* too bad */ + } + } /* validate args */ tap = jtag_TapByJimObj( interp, args[1] ); if( tap == NULL ){ @@ -2823,7 +2901,11 @@ int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args) fields[field_count++].in_handler_priv = NULL; } - jtag_add_dr_scan(num_fields, fields, -1); + jtag_add_dr_scan(num_fields, fields, TAP_INVALID); + /* did we get an end state? */ + if (endstate != TAP_INVALID) + jtag_add_end_state(endstate); + retval = jtag_execute_queue(); if (retval != ERROR_OK) { @@ -2920,7 +3002,6 @@ void jtag_tap_handle_event( jtag_tap_t * tap, enum jtag_tap_event e) } } - /*--------------------------------------------*/ /* these Cable Helper API functions are all documented in the jtag.h header file, @@ -2996,7 +3077,6 @@ int tap_move_ndx( tap_state_t astate ) return ndx; } - int tap_get_tms_path( tap_state_t from, tap_state_t to ) { /* tap_move[i][j]: tap movement command to go from state i to state j @@ -3009,7 +3089,7 @@ int tap_get_tms_path( tap_state_t from, tap_state_t to ) * * DRSHIFT->DRSHIFT and IRSHIFT->IRSHIFT have to be caught in interface specific code */ - const static u8 tms_seqs[6][6] = + static const u8 tms_seqs[6][6] = { /* value clocked to TMS to move from one of six stable states to another */ @@ -3189,4 +3269,18 @@ const char* tap_state_name(tap_state_t state) return ret; } +tap_state_t tap_state_by_name( const char *name ) +{ + tap_state_t x; + + for( x = 0 ; x < TAP_NUM_STATES ; x++ ){ + /* be nice to the human */ + if( 0 == strcasecmp( name, tap_state_name(x) ) ){ + return x; + } + } + /* not found */ + return TAP_INVALID; +} + /*-------------------------------------------*/