- add support for cortino jtag interface
[openocd.git] / src / jtag / jtag.c
index baff66c3b2690e6365a801cb62a256ebc28ef56a..56a8075b155b9ab06f0731f5089bb145fa067414 100644 (file)
@@ -37,7 +37,7 @@
 
 int jtag_flush_queue_count; /* count # of flushes for profiling / debugging purposes */
 
-static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, scan_field_t *in_fields, tap_state_t state),
+static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state),
                int in_num_fields, scan_field_t *in_fields, tap_state_t state);
 
 /* note that this is not marked as static as it must be available from outside jtag.c for those
@@ -531,6 +531,20 @@ void cmd_queue_free(void)
        cmd_queue_pages = NULL;
 }
 
+/**
+ * Copy a scan_field_t for insertion into the queue.
+ *
+ * This allocates a new copy of out_value using cmd_queue_alloc.
+ */
+static void cmd_queue_scan_field_clone(scan_field_t * dst, const scan_field_t * src)
+{
+       dst->tap                = src->tap;
+       dst->num_bits   = src->num_bits;
+       dst->out_value  = buf_cpy(src->out_value, cmd_queue_alloc(CEIL(src->num_bits, 8)), src->num_bits);
+       dst->in_value   = src->in_value;
+}
+
+
 static void jtag_prelude1(void)
 {
        if (jtag_trst == 1)
@@ -554,7 +568,7 @@ static void jtag_prelude(tap_state_t state)
        cmd_queue_cur_state = cmd_queue_end_state;
 }
 
-void jtag_add_ir_scan_noverify(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
+void jtag_add_ir_scan_noverify(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
 {
        int retval;
        jtag_prelude(state);
@@ -566,6 +580,15 @@ void jtag_add_ir_scan_noverify(int in_num_fields, scan_field_t *in_fields, tap_s
 }
 
 
+/**
+ * Generate an IR SCAN with a list of scan fields with one entry for each enabled TAP.
+ *
+ * If the input field list contains an instruction value for a TAP then that is used
+ * otherwise the TAP is set to bypass.
+ *
+ * TAPs for which no fields are passed are marked as bypassed for subsequent DR SCANs.
+ *
+ */
 void jtag_add_ir_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
 {
        if (jtag_verify&&jtag_verify_capture_ir)
@@ -590,21 +613,16 @@ void jtag_add_ir_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t st
 }
 
 /**
- * Generate a list of scan fields with one entry for each TAP.
- *
- * If the input field list contains an instruction value for a TAP then that is used
- * otherwise the TAP is set to bypass.
+ * see jtag_add_ir_scan()
  *
  */
-int MINIDRIVER(interface_jtag_add_ir_scan)(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
+int MINIDRIVER(interface_jtag_add_ir_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
 {
-       jtag_tap_t *tap;
-       int nth_tap;
+       size_t num_taps = jtag_NumEnabledTaps();
 
-       int num_taps = jtag_NumEnabledTaps();
-
-       jtag_command_t * cmd    = cmd_queue_alloc(sizeof(jtag_command_t));
-       scan_command_t * scan   = cmd_queue_alloc(sizeof(scan_command_t));
+       jtag_command_t * cmd            = cmd_queue_alloc(sizeof(jtag_command_t));
+       scan_command_t * scan           = cmd_queue_alloc(sizeof(scan_command_t));
+       scan_field_t * out_fields       = cmd_queue_alloc(num_taps  * sizeof(scan_field_t));
 
        jtag_queue_command(cmd);
 
@@ -613,59 +631,68 @@ int MINIDRIVER(interface_jtag_add_ir_scan)(int in_num_fields, scan_field_t *in_f
 
        scan->ir_scan                   = true;
        scan->num_fields                = num_taps;     /* one field per device */
-       scan->fields                    = cmd_queue_alloc(num_taps  * sizeof(scan_field_t));
+       scan->fields                    = out_fields;
        scan->end_state                 = state;
 
-       nth_tap = -1;
-       tap = NULL;
-       for(;;){
-               int found = 0;
 
-               /* do this here so it is not forgotten */
-               tap = jtag_NextEnabledTap(tap);
-               if( tap == NULL ){
-                       break;
-               }
-               nth_tap++;
+       scan_field_t * field = out_fields;      /* keep track where we insert data */
+
+       /* loop over all enabled TAPs */
 
-               assert(nth_tap < num_taps);
+       for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap))
+       {
+               /* search the input field list for fields for the current TAP */
 
-               size_t scan_size                                = tap->ir_length;
-               scan->fields[nth_tap].tap               = tap;
-               scan->fields[nth_tap].num_bits  = scan_size;
-               scan->fields[nth_tap].in_value  = NULL; /* do not collect input for tap's in bypass */
+               bool found = false;
 
-               /* search the list */
                for (int j = 0; j < in_num_fields; j++)
                {
-                       if (tap == in_fields[j].tap)
-                       {
-                               found = 1;
-                               scan->fields[nth_tap].in_value  = in_fields[j].in_value;
-                               scan->fields[nth_tap].out_value = buf_cpy(in_fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
+                       if (tap != in_fields[j].tap)
+                               continue;
 
-                               tap->bypass = 0;
-                               break;
-                       }
+                       /* if TAP is listed in input fields, copy the value */
+
+                       found = true;
+
+                       tap->bypass = 0;
+
+                       assert(in_fields[j].num_bits == tap->ir_length); /* input fields must have the same length as the TAP's IR */
+
+                       cmd_queue_scan_field_clone(field, in_fields + j);
+
+                       break;
                }
 
                if (!found)
                {
-                       /* if a tap isn't listed, set it to BYPASS */
-                       scan->fields[nth_tap].out_value = buf_set_ones(cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
+                       /* if a TAP isn't listed in input fields, set it to BYPASS */
+
                        tap->bypass = 1;
+
+                       field->tap                      = tap;
+                       field->num_bits         = tap->ir_length;
+                       field->out_value        = buf_set_ones(cmd_queue_alloc(CEIL(tap->ir_length, 8)), tap->ir_length);
+                       field->in_value         = NULL; /* do not collect input for tap's in bypass */
                }
 
                /* update device information */
-               buf_cpy(scan->fields[nth_tap].out_value, tap->cur_instr, scan_size);
+               buf_cpy(field->out_value, tap->cur_instr, tap->ir_length);
+
+               field++;
        }
 
-       assert(nth_tap == (num_taps - 1));
+       assert(field == out_fields + num_taps); /* paranoia: jtag_NumEnabledTaps() and jtag_NextEnabledTap() not in sync */
 
        return ERROR_OK;
 }
 
-void jtag_add_plain_ir_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
+/**
+ * Duplicate the scan fields passed into the function into an IR SCAN command
+ *
+ * This function assumes that the caller handles extra fields for bypassed TAPs
+ *
+ */
+void jtag_add_plain_ir_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
 {
        int retval;
 
@@ -676,11 +703,17 @@ void jtag_add_plain_ir_scan(int in_num_fields, scan_field_t *in_fields, tap_stat
                jtag_error=retval;
 }
 
-int MINIDRIVER(interface_jtag_add_plain_ir_scan)(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
+
+/**
+ * see jtag_add_plain_ir_scan()
+ *
+ */
+int MINIDRIVER(interface_jtag_add_plain_ir_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
 {
 
-       jtag_command_t * cmd    = cmd_queue_alloc(sizeof(jtag_command_t));
-       scan_command_t * scan   = cmd_queue_alloc(sizeof(scan_command_t));
+       jtag_command_t * cmd            = cmd_queue_alloc(sizeof(jtag_command_t));
+       scan_command_t * scan           = cmd_queue_alloc(sizeof(scan_command_t));
+       scan_field_t * out_fields       = cmd_queue_alloc(in_num_fields * sizeof(scan_field_t));
        
        jtag_queue_command(cmd);
 
@@ -689,32 +722,15 @@ int MINIDRIVER(interface_jtag_add_plain_ir_scan)(int in_num_fields, scan_field_t
 
        scan->ir_scan                   = true;
        scan->num_fields                = in_num_fields;
-       scan->fields                    = cmd_queue_alloc(in_num_fields * sizeof(scan_field_t));
+       scan->fields                    = out_fields;
        scan->end_state                 = state;
 
        for (int i = 0; i < in_num_fields; i++)
-       {
-               int num_bits = in_fields[i].num_bits;
-               int num_bytes = CEIL(in_fields[i].num_bits, 8);
-               scan->fields[i].tap = in_fields[i].tap;
-               scan->fields[i].num_bits = num_bits;
-               scan->fields[i].out_value = buf_cpy(in_fields[i].out_value, cmd_queue_alloc(num_bytes), num_bits);
-               scan->fields[i].in_value = in_fields[i].in_value;
-       }
+               cmd_queue_scan_field_clone(out_fields + i, in_fields + i);
 
        return ERROR_OK;
 }
 
-void jtag_add_dr_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
-{
-       int retval;
-
-       jtag_prelude(state);
-
-       retval=interface_jtag_add_dr_scan(in_num_fields, in_fields, cmd_queue_end_state);
-       if (retval!=ERROR_OK)
-               jtag_error=retval;
-}
 
 
 int jtag_check_value_inner(u8 *captured, u8 *in_check_value, u8 *in_check_mask, int num_bits);
@@ -724,7 +740,7 @@ static int jtag_check_value_mask_callback(u8 *in, jtag_callback_data_t data1, jt
        return jtag_check_value_inner(in, (u8 *)data1, (u8 *)data2, (int)data3);
 }
 
-static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, scan_field_t *in_fields, tap_state_t state),
+static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state),
                int in_num_fields, scan_field_t *in_fields, tap_state_t state)
 {
        for (int i = 0; i < in_num_fields; i++)
@@ -785,30 +801,47 @@ void jtag_add_dr_scan_check(int in_num_fields, scan_field_t *in_fields, tap_stat
        }
 }
 
-int MINIDRIVER(interface_jtag_add_dr_scan)(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
+
+/**
+ * Generate a DR SCAN using the fields passed to the function
+ *
+ * For not bypassed TAPs the function checks in_fields and uses fields specified there.
+ * For bypassed TAPs the function generates a dummy 1bit field.
+ *
+ * The bypass status of TAPs is set by jtag_add_ir_scan().
+ *
+ */
+void jtag_add_dr_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
 {
-       int j;
-       int nth_tap;
-       int bypass_devices = 0;
-       int field_count = 0;
+       int retval;
 
-       jtag_tap_t *tap;
+       jtag_prelude(state);
 
+       retval=interface_jtag_add_dr_scan(in_num_fields, in_fields, cmd_queue_end_state);
+       if (retval!=ERROR_OK)
+               jtag_error=retval;
+}
+
+
+/**
+ * see jtag_add_dr_scan()
+ *
+ */
+int MINIDRIVER(interface_jtag_add_dr_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
+{
        /* count devices in bypass */
-       tap = NULL;
-       bypass_devices = 0;
-       for(;;){
-               tap = jtag_NextEnabledTap(tap);
-               if( tap == NULL ){
-                       break;
-               }
-               if( tap->bypass ){
+
+       size_t bypass_devices = 0;
+
+       for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap))
+       {
+               if (tap->bypass)
                        bypass_devices++;
-               }
        }
 
-       jtag_command_t * cmd    = cmd_queue_alloc(sizeof(jtag_command_t));
-       scan_command_t * scan   = cmd_queue_alloc(sizeof(scan_command_t));
+       jtag_command_t * cmd            = cmd_queue_alloc(sizeof(jtag_command_t));
+       scan_command_t * scan           = cmd_queue_alloc(sizeof(scan_command_t));
+       scan_field_t * out_fields       = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t));
        
        jtag_queue_command(cmd);
        
@@ -817,93 +850,88 @@ int MINIDRIVER(interface_jtag_add_dr_scan)(int in_num_fields, scan_field_t *in_f
 
        scan->ir_scan                   = false;
        scan->num_fields                = in_num_fields + bypass_devices;
-       scan->fields                    = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t));
+       scan->fields                    = out_fields;
        scan->end_state                 = state;
 
-       tap = NULL;
-       nth_tap = -1;
-       for(;;){
-               nth_tap++;
-               tap = jtag_NextEnabledTap(tap);
-               if( tap == NULL ){
-                       break;
-               }
-               int found = 0;
-               scan->fields[field_count].tap = tap;
 
-               for (j = 0; j < in_num_fields; j++)
-               {
-                       if (tap == in_fields[j].tap)
-                       {
-                               found = 1;
-                               size_t scan_size = in_fields[j].num_bits;
-                               scan->fields[field_count].num_bits      = scan_size;
-                               scan->fields[field_count].out_value     = buf_cpy(in_fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
-                               scan->fields[field_count].in_value      = in_fields[j].in_value;
-                               field_count++;
-                       }
-               }
-               if (!found)
+       scan_field_t * field = out_fields;      /* keep track where we insert data */
+
+       /* loop over all enabled TAPs */
+
+       for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap))
+       {
+               /* if TAP is not bypassed insert matching input fields */
+
+               if (!tap->bypass)
                {
-#ifdef _DEBUG_JTAG_IO_
-                       /* if a device isn't listed, the BYPASS register should be selected */
-                       if (! tap->bypass)
+                       scan_field_t * start_field = field;     /* keep initial position for assert() */
+
+                       for (int j = 0; j < in_num_fields; j++)
                        {
-                               LOG_ERROR("BUG: no scan data for a device not in BYPASS");
-                               exit(-1);
+                               if (tap != in_fields[j].tap)
+                                       continue;
+
+                               cmd_queue_scan_field_clone(field, in_fields + j);
+
+                               field++;
                        }
-#endif
-                       /* program the scan field to 1 bit length, and ignore it's value */
-                       scan->fields[field_count].num_bits              = 1;
-                       scan->fields[field_count].out_value             = NULL;
-                       scan->fields[field_count].in_value              = NULL;
-                       field_count++;
+
+                       assert(field > start_field);    /* must have at least one input field per not bypassed TAP */
                }
+               
+               /* if a TAP is bypassed, generated a dummy bit*/
                else
                {
-#ifdef _DEBUG_JTAG_IO_
-                       /* if a device is listed, the BYPASS register must not be selected */
-                       if (tap->bypass)
-                       {
-                               LOG_ERROR("BUG: scan data for a device in BYPASS");
-                               exit(-1);
-                       }
-#endif
+                       field->tap                      = tap;
+                       field->num_bits         = 1;
+                       field->out_value        = NULL;
+                       field->in_value         = NULL;
+
+                       field++;
                }
        }
 
-       /* field_count represents the true number of fields setup*/
-       scan->num_fields = field_count;
+       assert(field == out_fields + scan->num_fields); /* no superfluous input fields permitted */
+
        return ERROR_OK;
 }
 
+
+
+/**
+ * Generate a DR SCAN using the array of output values passed to the function
+ *
+ * This function assumes that the parameter target_tap specifies the one TAP
+ * that is not bypassed. All other TAPs must be bypassed and the function will
+ * generate a dummy 1bit field for them.
+ *
+ * For the target_tap a sequence of output-only fields will be generated where
+ * each field has the size num_bits and the field's values are taken from
+ * the array value.
+ *
+ * The bypass status of TAPs is set by jtag_add_ir_scan().
+ *
+ */
 void MINIDRIVER(interface_jtag_add_dr_out)(jtag_tap_t *target_tap,
                int in_num_fields,
                const int *num_bits,
                const u32 *value,
                tap_state_t end_state)
 {
-       int nth_tap;
-       int field_count = 0;
-       int bypass_devices = 0;
+       /* count devices in bypass */
 
-       jtag_tap_t *tap;
+       size_t bypass_devices = 0;
 
-       /* count devices in bypass */
-       tap = NULL;
-       bypass_devices = 0;
-       for(;;){
-               tap = jtag_NextEnabledTap(tap);
-               if( tap == NULL ){
-                       break;
-               }
-               if( tap->bypass ){
+       for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap))
+       {
+               if (tap->bypass)
                        bypass_devices++;
-               }
        }
 
-       jtag_command_t * cmd    = cmd_queue_alloc(sizeof(jtag_command_t));
-       scan_command_t * scan   = cmd_queue_alloc(sizeof(scan_command_t));
+
+       jtag_command_t * cmd            = cmd_queue_alloc(sizeof(jtag_command_t));
+       scan_command_t * scan           = cmd_queue_alloc(sizeof(scan_command_t));
+       scan_field_t * out_fields       = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t));
 
        jtag_queue_command(cmd);
 
@@ -912,59 +940,65 @@ void MINIDRIVER(interface_jtag_add_dr_out)(jtag_tap_t *target_tap,
 
        scan->ir_scan                   = false;
        scan->num_fields                = in_num_fields + bypass_devices;
-       scan->fields                    = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t));
+       scan->fields                    = out_fields;
        scan->end_state                 = end_state;
 
-       tap = NULL;
-       nth_tap = -1;
-       for(;;){
-               tap = jtag_NextEnabledTap(tap);
-               if( tap == NULL ){
-                       break;
-               }
-               nth_tap++;
-               scan->fields[field_count].tap = tap;
 
-               if (tap == target_tap)
+       bool target_tap_match   = false;
+
+       scan_field_t * field = out_fields;      /* keep track where we insert data */
+
+       /* loop over all enabled TAPs */
+
+       for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap))
+       {
+               /* if TAP is not bypassed insert matching input fields */
+
+               if (!tap->bypass)
                {
-#ifdef _DEBUG_JTAG_IO_
-                       /* if a device is listed, the BYPASS register must not be selected */
-                       if (tap->bypass)
-                       {
-                               LOG_ERROR("BUG: scan data for a device in BYPASS");
-                               exit(-1);
-                       }
-#endif
+                       assert(tap == target_tap); /* target_tap must match the one not bypassed TAP */
+
+                       target_tap_match = true;
+
                        for (int j = 0; j < in_num_fields; j++)
                        {
                                u8 out_value[4];
                                size_t scan_size = num_bits[j];
                                buf_set_u32(out_value, 0, scan_size, value[j]);
-                               scan->fields[field_count].num_bits              = scan_size;
-                               scan->fields[field_count].out_value             = buf_cpy(out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
-                               scan->fields[field_count].in_value              = NULL;
-                               field_count++;
+
+                               field->tap                      = tap;
+                               field->num_bits         = scan_size;
+                               field->out_value        = buf_cpy(out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
+                               field->in_value         = NULL;
+
+                               field++;
                        }
-               } else
+               }
+
+               /* if a TAP is bypassed, generated a dummy bit*/
+               else
                {
-#ifdef _DEBUG_JTAG_IO_
-                       /* if a device isn't listed, the BYPASS register should be selected */
-                       if (! tap->bypass)
-                       {
-                               LOG_ERROR("BUG: no scan data for a device not in BYPASS");
-                               exit(-1);
-                       }
-#endif
-                       /* program the scan field to 1 bit length, and ignore it's value */
-                       scan->fields[field_count].num_bits                      = 1;
-                       scan->fields[field_count].out_value                     = NULL;
-                       scan->fields[field_count].in_value                      = NULL;
-                       field_count++;
+
+                       field->tap                              = tap;
+                       field->num_bits                 = 1;
+                       field->out_value                = NULL;
+                       field->in_value                 = NULL;
+
+                       field++;
                }
        }
+
+       assert(target_tap_match);       /* target_tap should be enabled and not bypassed */
 }
 
-void jtag_add_plain_dr_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
+
+/**
+ * Duplicate the scan fields passed into the function into a DR SCAN command
+ *
+ * This function assumes that the caller handles extra fields for bypassed TAPs
+ *
+ */
+void jtag_add_plain_dr_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
 {
        int retval;
 
@@ -975,35 +1009,34 @@ void jtag_add_plain_dr_scan(int in_num_fields, scan_field_t *in_fields, tap_stat
                jtag_error=retval;
 }
 
-int MINIDRIVER(interface_jtag_add_plain_dr_scan)(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
+
+/**
+ * see jtag_add_plain_dr_scan()
+ *
+ */
+int MINIDRIVER(interface_jtag_add_plain_dr_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
 {
-       /* allocate memory for a new list member */
-       jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
+       jtag_command_t * cmd            = cmd_queue_alloc(sizeof(jtag_command_t));
+       scan_command_t * scan           = cmd_queue_alloc(sizeof(scan_command_t));
+       scan_field_t * out_fields       = cmd_queue_alloc(in_num_fields * sizeof(scan_field_t));
 
        jtag_queue_command(cmd);
 
-       cmd->type = JTAG_SCAN;
+       cmd->type                               = JTAG_SCAN;
+       cmd->cmd.scan                   = scan;
 
-       /* allocate memory for scan command */
-       cmd->cmd.scan = cmd_queue_alloc(sizeof(scan_command_t));
-       cmd->cmd.scan->ir_scan = false;
-       cmd->cmd.scan->num_fields = in_num_fields;
-       cmd->cmd.scan->fields = cmd_queue_alloc(in_num_fields * sizeof(scan_field_t));
-       cmd->cmd.scan->end_state = state;
+       scan->ir_scan                   = false;
+       scan->num_fields                = in_num_fields;
+       scan->fields                    = out_fields;
+       scan->end_state                 = state;
 
        for (int i = 0; i < in_num_fields; i++)
-       {
-               int num_bits = in_fields[i].num_bits;
-               int num_bytes = CEIL(in_fields[i].num_bits, 8);
-               cmd->cmd.scan->fields[i].tap = in_fields[i].tap;
-               cmd->cmd.scan->fields[i].num_bits = num_bits;
-               cmd->cmd.scan->fields[i].out_value = buf_cpy(in_fields[i].out_value, cmd_queue_alloc(num_bytes), num_bits);
-               cmd->cmd.scan->fields[i].in_value = in_fields[i].in_value;
-       }
+               cmd_queue_scan_field_clone(out_fields + i, in_fields + i);
 
        return ERROR_OK;
 }
 
+
 void jtag_add_tlr(void)
 {
        jtag_prelude(TAP_RESET);
@@ -1031,7 +1064,7 @@ int MINIDRIVER(interface_jtag_add_tlr)(void)
        return ERROR_OK;
 }
 
-void jtag_add_pathmove(int num_states, tap_state_t *path)
+void jtag_add_pathmove(int num_states, const tap_state_t *path)
 {
        tap_state_t cur_state = cmd_queue_cur_state;
        int i;
@@ -1069,7 +1102,7 @@ void jtag_add_pathmove(int num_states, tap_state_t *path)
                jtag_error=retval;
 }
 
-int MINIDRIVER(interface_jtag_add_pathmove)(int num_states, tap_state_t *path)
+int MINIDRIVER(interface_jtag_add_pathmove)(int num_states, const tap_state_t *path)
 {
        /* allocate memory for a new list member */
        jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
@@ -1220,6 +1253,7 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst)
                jtag_error=retval;
                return;
        }
+       jtag_execute_queue();
 
        if (jtag_srst)
        {
@@ -1247,7 +1281,7 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst)
                 * and inform possible listeners about this
                 */
                LOG_DEBUG("TRST line asserted");
-               cmd_queue_cur_state = TAP_RESET;
+               tap_set_state(TAP_RESET);
                jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
        }
        else
@@ -1306,7 +1340,7 @@ void jtag_add_sleep(u32 us)
        return;
 }
 
-int jtag_scan_size(scan_command_t *cmd)
+int jtag_scan_size(const scan_command_t *cmd)
 {
        int bit_count = 0;
        int i;
@@ -1320,7 +1354,7 @@ int jtag_scan_size(scan_command_t *cmd)
        return bit_count;
 }
 
-int jtag_build_buffer(scan_command_t *cmd, u8 **buffer)
+int jtag_build_buffer(const scan_command_t *cmd, u8 **buffer)
 {
        int bit_count = 0;
        int i;
@@ -1364,7 +1398,7 @@ int jtag_build_buffer(scan_command_t *cmd, u8 **buffer)
        return bit_count;
 }
 
-int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
+int jtag_read_buffer(u8 *buffer, const scan_command_t *cmd)
 {
        int i;
        int bit_count = 0;
@@ -1402,7 +1436,7 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
        return retval;
 }
 
-static const char *jtag_tap_name(jtag_tap_t *tap)
+static const char *jtag_tap_name(const jtag_tap_t *tap)
 {
        return (tap == NULL) ? "(unknown)" : tap->dotted_name;
 }
@@ -1474,7 +1508,7 @@ void jtag_check_value_mask(scan_field_t *field, u8 *value, u8 *mask)
 
 
 
-enum scan_type jtag_scan_type(scan_command_t *cmd)
+enum scan_type jtag_scan_type(const scan_command_t *cmd)
 {
        int i;
        int type = 0;
@@ -2281,9 +2315,10 @@ int jtag_register_commands(struct command_context_s *cmd_ctx)
        register_command(cmd_ctx, NULL, "interface", handle_interface_command,
                COMMAND_CONFIG, "try to configure interface");
        register_command(cmd_ctx, NULL, "jtag_speed", handle_jtag_speed_command,
-               COMMAND_ANY, "set jtag speed (if supported)");
+               COMMAND_ANY, "(DEPRECATED) set jtag speed (if supported)");
        register_command(cmd_ctx, NULL, "jtag_khz", handle_jtag_khz_command,
-               COMMAND_ANY, "same as jtag_speed, except it takes maximum khz as arguments. 0 KHz = RTCK.");
+               COMMAND_ANY, "set maximum jtag speed (if supported); "
+               "parameter is maximum khz, or 0 for adaptive clocking (RTCK).");
        register_command(cmd_ctx, NULL, "jtag_device", handle_jtag_device_command,
                COMMAND_CONFIG, "jtag_device <ir_length> <ir_expected> <ir_mask>");
        register_command(cmd_ctx, NULL, "reset_config", handle_reset_config_command,
@@ -3329,10 +3364,10 @@ static const struct tms_sequences short_tms_seqs[6][6] =                /*  [from_state_ndx][t
 
        /* to state: */
        /*      RESET                   IDLE                            DRSHIFT                 DRPAUSE                 IRSHIFT                 IRPAUSE */                      /* from state: */
-       {       B8(1111111,7),  B8(0000000,7),  B8(00101,5),            B8(01010,5),    B8(001101,6),   B8(010110,6) },         /* RESET */
+       {       B8(1111111,7),  B8(0000000,7),  B8(0010111,7),          B8(0001010,7),  B8(0011011,7),  B8(0010110,7) },        /* RESET */
        {       B8(1111111,7),  B8(0000000,7),  B8(001,3),                      B8(0101,4),             B8(0011,4),     B8(01011,5) },          /* IDLE */
-       {       B8(1111111,7),  B8(011,3),              B8(00111,5),            B8(01,2),               B8(001111,6),   B8(0101111,7) },                /* DRSHIFT */
-       {       B8(1111111,7),  B8(011,3),              B8(01,2),               B8(0,1),                B8(001111,6),   B8(0101111,7) },                /* DRPAUSE */
+       {       B8(1111111,7),  B8(011,3),              B8(00111,5),            B8(01,2),               B8(001111,6),   B8(0101111,7) },        /* DRSHIFT */
+       {       B8(1111111,7),  B8(011,3),              B8(01,2),               B8(0,1),                B8(001111,6),   B8(0101111,7) },        /* DRPAUSE */
        {       B8(1111111,7),  B8(011,3),              B8(00111,5),            B8(010111,6),   B8(001111,6),   B8(01,2) },                     /* IRSHIFT */
        {       B8(1111111,7),  B8(011,3),              B8(00111,5),            B8(010111,6),   B8(01,2),               B8(0,1) }                       /* IRPAUSE */
 

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)