Partially fix USBprog and JLink adapters on XScale target
[openocd.git] / src / jtag / jtag.c
index ae51ebc16ce0114dfddb07800baff3ed56d7605a..a9a4b30cbb21c090adaffa6da235b4665627f2cb 100644 (file)
@@ -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)
        }
 }
 
-
 /*-----<Cable Helper API>---------------------------------------*/
 
 /*  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;
+}
+
 /*-----</Cable Helper API>--------------------------------------*/

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)