sharpend JTAG docs w.r.t. hw fifo implementations and retired jtag_cancel_queue(...
[openocd.git] / src / jtag / jtag.c
index 09cffef799e601cdc59a8acb02262c72c29d6534..974328c52833d7b651dd542897287a053a6bf333 100644 (file)
@@ -209,10 +209,6 @@ int jtag_speed = -1;
 
 
 /* forward declarations */
-int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
-int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
-int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
-int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
 int jtag_add_statemove(enum tap_state endstate);
 int jtag_add_pathmove(int num_states, enum tap_state *path);
 int jtag_add_runtest(int num_cycles, enum tap_state endstate);
@@ -335,8 +331,9 @@ jtag_device_t* jtag_get_device(int num)
                device = device->next;
                i++;
        }
-
-       return NULL;
+       
+       ERROR("jtag device number %d not defined", num);
+       exit(-1);
 }
 
 void* cmd_queue_alloc(size_t size)
@@ -363,7 +360,8 @@ void* cmd_queue_alloc(size_t size)
        offset = (*p_page)->used;
        (*p_page)->used += size;
        
-       return ((*p_page)->address) + offset;
+       u8 *t=(u8 *)((*p_page)->address);
+       return t + offset;
 }
 
 void cmd_queue_free()
@@ -381,7 +379,7 @@ void cmd_queue_free()
        cmd_queue_pages = NULL;
 }
 
-int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
+int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, void *dummy_anachronism)
 {
        jtag_command_t **last_cmd;
        jtag_device_t *device;
@@ -408,15 +406,6 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state,
        (*last_cmd)->cmd.scan->num_fields = jtag_num_devices;   /* one field per device */
        (*last_cmd)->cmd.scan->fields = cmd_queue_alloc(jtag_num_devices * sizeof(scan_field_t));
        (*last_cmd)->cmd.scan->end_state = state;
-       if (error_handler)
-       {
-               (*last_cmd)->cmd.scan->error_handler = cmd_queue_alloc(sizeof(error_handler_t));
-               *(*last_cmd)->cmd.scan->error_handler = *error_handler;
-       }
-       else
-       {
-               (*last_cmd)->cmd.scan->error_handler = NULL;
-       }
                
        if (state != -1)
                cmd_queue_end_state = state;
@@ -429,7 +418,7 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state,
        
        cmd_queue_cur_state = cmd_queue_end_state;
                
-       for (i=0; i < jtag_num_devices; i++)
+       for (i = 0; i < jtag_num_devices; i++)
        {
                int found = 0;
                device = jtag_get_device(i);
@@ -437,27 +426,30 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state,
                (*last_cmd)->cmd.scan->fields[i].device = i;
                (*last_cmd)->cmd.scan->fields[i].num_bits = scan_size;
                (*last_cmd)->cmd.scan->fields[i].in_value = NULL;
-               if (jtag_verify_capture_ir)
-               {
-                       (*last_cmd)->cmd.scan->fields[i].in_check_value = buf_cpy(device->expected, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
-                       (*last_cmd)->cmd.scan->fields[i].in_check_mask = buf_cpy(device->expected_mask, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
-               }
-               else
-               {
-                       (*last_cmd)->cmd.scan->fields[i].in_check_value = NULL;
-                       (*last_cmd)->cmd.scan->fields[i].in_check_mask = NULL;
-               }
-               (*last_cmd)->cmd.scan->fields[i].in_handler = NULL;
-               (*last_cmd)->cmd.scan->fields[i].in_handler_priv = NULL;
+               (*last_cmd)->cmd.scan->fields[i].in_handler = NULL;     /* disable verification by default */
 
                /* search the list */
-               for (j=0; j < num_fields; j++)
+               for (j = 0; j < num_fields; j++)
                {
                        if (i == fields[j].device)
                        {
                                found = 1;
                                (*last_cmd)->cmd.scan->fields[i].out_value = buf_cpy(fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
                                (*last_cmd)->cmd.scan->fields[i].out_mask = buf_cpy(fields[j].out_mask, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
+                       
+                               if (jtag_verify_capture_ir)
+                               {
+                                       if (fields[j].in_handler==NULL)
+                                       {
+                                               jtag_set_check_value((*last_cmd)->cmd.scan->fields+i, device->expected, device->expected_mask, NULL);
+                                       } else
+                                       {
+                                               (*last_cmd)->cmd.scan->fields[i].in_handler = fields[j].in_handler;
+                                               (*last_cmd)->cmd.scan->fields[i].in_handler_priv = fields[j].in_handler_priv;
+                                               (*last_cmd)->cmd.scan->fields[i].in_check_value = device->expected; 
+                                               (*last_cmd)->cmd.scan->fields[i].in_check_mask = device->expected_mask;
+                                       }
+                               }
                                
                                device->bypass = 0;
                                break;
@@ -480,7 +472,7 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state,
        return ERROR_OK;
 }
 
-int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
+int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, void *dummy_anachronism)
 {
        jtag_command_t **last_cmd;
        int i;
@@ -505,15 +497,6 @@ int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state
        (*last_cmd)->cmd.scan->num_fields = num_fields;
        (*last_cmd)->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t));
        (*last_cmd)->cmd.scan->end_state = state;
-       if (error_handler)
-       {
-               (*last_cmd)->cmd.scan->error_handler = cmd_queue_alloc(sizeof(error_handler_t));
-               *(*last_cmd)->cmd.scan->error_handler = *error_handler;
-       }
-       else
-       {
-               (*last_cmd)->cmd.scan->error_handler = NULL;
-       }
 
        if (state != -1)
                cmd_queue_end_state = state;
@@ -535,15 +518,15 @@ int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state
                (*last_cmd)->cmd.scan->fields[i].out_value = buf_cpy(fields[i].out_value, cmd_queue_alloc(num_bytes), num_bits);
                (*last_cmd)->cmd.scan->fields[i].out_mask = buf_cpy(fields[i].out_mask, cmd_queue_alloc(num_bytes), num_bits);
                (*last_cmd)->cmd.scan->fields[i].in_value = fields[i].in_value;
-               (*last_cmd)->cmd.scan->fields[i].in_check_value = buf_cpy(fields[i].in_check_value, cmd_queue_alloc(num_bytes), num_bits);
-               (*last_cmd)->cmd.scan->fields[i].in_check_mask = buf_cpy(fields[i].in_check_mask, cmd_queue_alloc(num_bytes), num_bits);
+               (*last_cmd)->cmd.scan->fields[i].in_check_value = fields[i].in_check_value;
+               (*last_cmd)->cmd.scan->fields[i].in_check_mask = fields[i].in_check_mask;
                (*last_cmd)->cmd.scan->fields[i].in_handler = NULL;
                (*last_cmd)->cmd.scan->fields[i].in_handler_priv = NULL;
        }
        return ERROR_OK;
 }
 
-int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
+int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, void *dummy_anachronism)
 {
        int i, j;
        int bypass_devices = 0;
@@ -578,15 +561,6 @@ int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state,
        (*last_cmd)->cmd.scan->num_fields = num_fields + bypass_devices;
        (*last_cmd)->cmd.scan->fields = cmd_queue_alloc((num_fields + bypass_devices) * sizeof(scan_field_t));
        (*last_cmd)->cmd.scan->end_state = state;
-       if (error_handler)
-       {
-               (*last_cmd)->cmd.scan->error_handler = cmd_queue_alloc(sizeof(error_handler_t));
-               *(*last_cmd)->cmd.scan->error_handler = *error_handler;
-       }
-       else
-       {
-               (*last_cmd)->cmd.scan->error_handler = NULL;
-       }
        
        if (state != -1)
                cmd_queue_end_state = state;
@@ -599,12 +573,12 @@ int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state,
                        
        cmd_queue_cur_state = cmd_queue_end_state;
        
-       for (i=0; i < jtag_num_devices; i++)
+       for (i = 0; i < jtag_num_devices; i++)
        {
                int found = 0;
                (*last_cmd)->cmd.scan->fields[field_count].device = i;
        
-               for (j=0; j < num_fields; j++)
+               for (j = 0; j < num_fields; j++)
                {
                        if (i == fields[j].device)
                        {
@@ -614,8 +588,8 @@ int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state,
                                (*last_cmd)->cmd.scan->fields[field_count].out_value = buf_cpy(fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
                                (*last_cmd)->cmd.scan->fields[field_count].out_mask = buf_cpy(fields[j].out_mask, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
                                (*last_cmd)->cmd.scan->fields[field_count].in_value = fields[j].in_value;
-                               (*last_cmd)->cmd.scan->fields[field_count].in_check_value = buf_cpy(fields[j].in_check_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
-                               (*last_cmd)->cmd.scan->fields[field_count].in_check_mask = buf_cpy(fields[j].in_check_mask, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
+                               (*last_cmd)->cmd.scan->fields[field_count].in_check_value = fields[j].in_check_value;
+                               (*last_cmd)->cmd.scan->fields[field_count].in_check_mask = fields[j].in_check_mask;
                                (*last_cmd)->cmd.scan->fields[field_count].in_handler = fields[j].in_handler;
                                (*last_cmd)->cmd.scan->fields[field_count++].in_handler_priv = fields[j].in_handler_priv;
                        }
@@ -651,7 +625,7 @@ int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state,
        return ERROR_OK;
 }
 
-int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
+int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, void *dummy_anachronism)
 {
        int i;
        jtag_command_t **last_cmd = jtag_get_last_command_p();
@@ -674,15 +648,6 @@ int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state
        (*last_cmd)->cmd.scan->num_fields = num_fields;
        (*last_cmd)->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t));
        (*last_cmd)->cmd.scan->end_state = state;
-       if (error_handler)
-       {
-               (*last_cmd)->cmd.scan->error_handler = cmd_queue_alloc(sizeof(error_handler_t));
-               *(*last_cmd)->cmd.scan->error_handler = *error_handler;
-       }
-       else
-       {
-               (*last_cmd)->cmd.scan->error_handler = NULL;
-       }
                
        if (state != -1)
                cmd_queue_end_state = state;
@@ -704,8 +669,8 @@ int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state
                (*last_cmd)->cmd.scan->fields[i].out_value = buf_cpy(fields[i].out_value, cmd_queue_alloc(num_bytes), num_bits);
                (*last_cmd)->cmd.scan->fields[i].out_mask = buf_cpy(fields[i].out_mask, cmd_queue_alloc(num_bytes), num_bits);
                (*last_cmd)->cmd.scan->fields[i].in_value = fields[i].in_value;
-               (*last_cmd)->cmd.scan->fields[i].in_check_value = buf_cpy(fields[i].in_check_value, cmd_queue_alloc(num_bytes), num_bits);
-               (*last_cmd)->cmd.scan->fields[i].in_check_mask = buf_cpy(fields[i].in_check_mask, cmd_queue_alloc(num_bytes), num_bits);
+               (*last_cmd)->cmd.scan->fields[i].in_check_value = fields[i].in_check_value;
+               (*last_cmd)->cmd.scan->fields[i].in_check_mask = fields[i].in_check_mask;
                (*last_cmd)->cmd.scan->fields[i].in_handler = fields[i].in_handler;
                (*last_cmd)->cmd.scan->fields[i].in_handler_priv = fields[i].in_handler_priv;
        }
@@ -763,52 +728,18 @@ int jtag_add_pathmove(int num_states, enum tap_state *path)
                return ERROR_JTAG_NOT_IMPLEMENTED;
        }
        
-       if (jtag->support_pathmove)
-       {
-               /* allocate memory for a new list member */
-               *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
-               last_comand_pointer = &((*last_cmd)->next);
-               (*last_cmd)->next = NULL;
-               (*last_cmd)->type = JTAG_PATHMOVE;
+       /* allocate memory for a new list member */
+       *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
+       last_comand_pointer = &((*last_cmd)->next);
+       (*last_cmd)->next = NULL;
+       (*last_cmd)->type = JTAG_PATHMOVE;
+
+       (*last_cmd)->cmd.pathmove = cmd_queue_alloc(sizeof(pathmove_command_t));
+       (*last_cmd)->cmd.pathmove->num_states = num_states;
+       (*last_cmd)->cmd.pathmove->path = cmd_queue_alloc(sizeof(enum tap_state) * num_states);
        
-               (*last_cmd)->cmd.pathmove = cmd_queue_alloc(sizeof(pathmove_command_t));
-               (*last_cmd)->cmd.pathmove->num_states = num_states;
-               (*last_cmd)->cmd.pathmove->path = cmd_queue_alloc(sizeof(enum tap_state) * num_states);
-               
-               for (i = 0; i < num_states; i++)
-                       (*last_cmd)->cmd.pathmove->path[i] = path[i];
-       }
-       else
-       {
-               /* validate the desired path, and see if it fits a default path */
-               int begin = 0;
-               int end = 0;
-               int j;
-               
-               for (i = 0; i < num_states; i++)
-               {
-                       for (j = i; j < num_states; j++)
-                       {
-                               if (tap_move_map[path[j]] != -1)
-                               {       
-                                       end = j;
-                                       break;
-                               }
-                       }
-                       
-                       if (begin - end <= 7)   /* a default path spans no more than 7 states */
-                       {
-                               jtag_add_statemove(path[end]);
-                       }
-                       else
-                       {
-                               ERROR("encountered a TAP path that can't be fulfilled by default paths");       
-                               return ERROR_JTAG_NOT_IMPLEMENTED;
-                       }
-                       
-                       i = end;
-               }
-       }
+       for (i = 0; i < num_states; i++)
+               (*last_cmd)->cmd.pathmove->path[i] = path[i];
 
        if (cmd_queue_cur_state == TAP_TLR && cmd_queue_end_state != TAP_TLR)
                jtag_call_event_callbacks(JTAG_TRST_RELEASED);
@@ -998,7 +929,7 @@ int jtag_scan_size(scan_command_t *cmd)
        int i;
 
        /* count bits in scan command */
-       for (i=0; i<cmd->num_fields; i++)
+       for (i = 0; i < cmd->num_fields; i++)
        {
                bit_count += cmd->fields[i].num_bits;
        }
@@ -1046,23 +977,23 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
        /* we return ERROR_OK, unless a check fails, or a handler reports a problem */
        retval = ERROR_OK;
        
-       for (i=0; i < cmd->num_fields; i++)
+       for (i = 0; i < cmd->num_fields; i++)
        {
-               /* if neither in_value, in_check_value nor in_handler
+               /* if neither in_value nor in_handler
                 * are specified we don't have to examine this field
                 */
-               if (cmd->fields[i].in_value || cmd->fields[i].in_check_value || cmd->fields[i].in_handler)
+               if (cmd->fields[i].in_value || cmd->fields[i].in_handler)
                {
                        int num_bits = cmd->fields[i].num_bits;
                        u8 *captured = buf_set_buf(buffer, bit_count, malloc(CEIL(num_bits, 8)), 0, num_bits);
                        
-                       #ifdef _DEBUG_JTAG_IO_
-                               char *char_buf;
+#ifdef _DEBUG_JTAG_IO_
+                       char *char_buf;
 
-                               char_buf = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16);
-                               DEBUG("fields[%i].in_value: 0x%s", i, char_buf);
-                               free(char_buf);
-                       #endif
+                       char_buf = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16);
+                       DEBUG("fields[%i].in_value: 0x%s", i, char_buf);
+                       free(char_buf);
+#endif
                        
                        if (cmd->fields[i].in_value)
                        {
@@ -1070,7 +1001,7 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
                                
                                if (cmd->fields[i].in_handler)
                                {
-                                       if (cmd->fields[i].in_handler(cmd->fields[i].in_value, cmd->fields[i].in_handler_priv) != ERROR_OK)
+                                       if (cmd->fields[i].in_handler(cmd->fields[i].in_value, cmd->fields[i].in_handler_priv, cmd->fields+i) != ERROR_OK)
                                        {
                                                WARNING("in_handler reported a failed check");
                                                retval = ERROR_JTAG_QUEUE_FAILED;
@@ -1081,7 +1012,7 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
                        /* no in_value specified, but a handler takes care of the scanned data */
                        if (cmd->fields[i].in_handler && (!cmd->fields[i].in_value))
                        {
-                               if (cmd->fields[i].in_handler(captured, cmd->fields[i].in_handler_priv) != ERROR_OK)
+                               if (cmd->fields[i].in_handler(captured, cmd->fields[i].in_handler_priv, cmd->fields+i) != ERROR_OK)
                                {
                                        /* We're going to call the error:handler later, but if the in_handler
                                         * reported an error we report this failure upstream
@@ -1091,58 +1022,6 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
                                }
                        }
 
-                       if (cmd->fields[i].in_check_value)
-                       {
-                               int compare_failed = 0;
-                               
-                               if (cmd->fields[i].in_check_mask)
-                                       compare_failed = buf_cmp_mask(captured, cmd->fields[i].in_check_value, cmd->fields[i].in_check_mask, num_bits);
-                               else
-                                       compare_failed = buf_cmp(captured, cmd->fields[i].in_check_value, num_bits);
-                               
-                               if (compare_failed)
-                               {
-                                       if (cmd->error_handler)
-                                       {
-                                               /* ask the error handler if once has been specified if this is a real problem */ 
-                                               if (cmd->error_handler->error_handler(captured, cmd->error_handler->error_handler_priv) != ERROR_OK)
-                                                       retval = ERROR_JTAG_QUEUE_FAILED;
-                                               else
-                                                       compare_failed = 0;
-                                       }
-                                       else
-                                       {
-                                               /* if there wasn't a handler specified, we report a failure */
-                                               retval = ERROR_JTAG_QUEUE_FAILED;
-                                       }
-                                       
-                                       /* An error handler could have caught the failing check
-                                        * only report a problem when there wasn't a handler, or if the handler
-                                        * acknowledged the error
-                                        */ 
-                                       if (compare_failed)
-                                       {
-                                               char *captured_char = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16);
-                                               char *in_check_value_char = buf_to_str(cmd->fields[i].in_check_value, (num_bits > 64) ? 64 : num_bits, 16);
-
-                                               if (cmd->fields[i].in_check_mask)
-                                               {
-                                                       char *in_check_mask_char;
-                                                       in_check_mask_char = buf_to_str(cmd->fields[i].in_check_mask, (num_bits > 64) ? 64 : num_bits, 16);
-                                                       WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s check_mask: 0x%s", captured_char, in_check_value_char, in_check_mask_char);
-                                                       free(in_check_mask_char);
-                                               }
-                                               else
-                                               {
-                                                       WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s", captured_char, in_check_value_char);
-                                               }
-
-                                               free(captured_char);
-                                               free(in_check_value_char);
-                                       }
-                                       
-                               }
-                       }
                        free(captured);
                }
                bit_count += cmd->fields[i].num_bits;
@@ -1151,14 +1030,74 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
        return retval;
 }
 
+int jtag_check_value(u8 *captured, void *priv, scan_field_t *field)
+{
+       int retval = ERROR_OK;
+       int num_bits = field->num_bits;
+       
+       int compare_failed = 0;
+       
+       if (field->in_check_mask)
+               compare_failed = buf_cmp_mask(captured, field->in_check_value, field->in_check_mask, num_bits);
+       else
+               compare_failed = buf_cmp(captured, field->in_check_value, num_bits);
+       
+       if (compare_failed)
+               {
+               /* An error handler could have caught the failing check
+                * only report a problem when there wasn't a handler, or if the handler
+                * acknowledged the error
+                */ 
+               if (compare_failed)
+               {
+                       char *captured_char = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16);
+                       char *in_check_value_char = buf_to_str(field->in_check_value, (num_bits > 64) ? 64 : num_bits, 16);
+
+                       if (field->in_check_mask)
+                       {
+                               char *in_check_mask_char;
+                               in_check_mask_char = buf_to_str(field->in_check_mask, (num_bits > 64) ? 64 : num_bits, 16);
+                               WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s check_mask: 0x%s", captured_char, in_check_value_char, in_check_mask_char);
+                               free(in_check_mask_char);
+                       }
+                       else
+                       {
+                               WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s", captured_char, in_check_value_char);
+                       }
+
+                       free(captured_char);
+                       free(in_check_value_char);
+                       
+                       retval = ERROR_JTAG_QUEUE_FAILED;
+               }
+               
+       }
+       return retval;
+}
+
+/* 
+  set up checking of this field using the in_handler. The values passed in must be valid until
+  after jtag_execute() has completed.
+ */
+void jtag_set_check_value(scan_field_t *field, u8 *value, u8 *mask, error_handler_t *in_error_handler)
+{
+       if (value)
+               field->in_handler = jtag_check_value;
+       else
+               field->in_handler = NULL;       /* No check, e.g. embeddedice uses value==NULL to indicate no check */
+       field->in_handler_priv = NULL;  /* this will be filled in at the invocation site to point to the field duplicate */ 
+       field->in_check_value = value;
+       field->in_check_mask = mask;
+}
+
 enum scan_type jtag_scan_type(scan_command_t *cmd)
 {
        int i;
        int type = 0;
        
-       for (i=0; i < cmd->num_fields; i++)
+       for (i = 0; i < cmd->num_fields; i++)
        {
-               if (cmd->fields[i].in_check_value || cmd->fields[i].in_value || cmd->fields[i].in_handler)
+               if (cmd->fields[i].in_value || cmd->fields[i].in_handler)
                        type |= SCAN_IN;
                if (cmd->fields[i].out_value)
                        type |= SCAN_OUT;
@@ -1181,15 +1120,6 @@ int jtag_execute_queue(void)
        return retval;
 }
 
-int jtag_cancel_queue(void)
-{
-       cmd_queue_free();
-       jtag_command_queue = NULL;
-       last_comand_pointer = &jtag_command_queue;
-
-       return ERROR_OK;
-}
-
 int jtag_reset_callback(enum jtag_event event, void *priv)
 {
        jtag_device_t *device = priv;
@@ -1345,6 +1275,7 @@ int jtag_validate_chain()
                        char *cbuf = buf_to_str(ir_test, total_ir_length, 16);
                        ERROR("Error validating JTAG scan chain, IR mismatch, scan returned 0x%s", cbuf);
                        free(cbuf);
+                       free(ir_test);
                        return ERROR_JTAG_INIT_FAILED;
                }
                chain_pos += device->ir_length;
@@ -1356,6 +1287,7 @@ int jtag_validate_chain()
                char *cbuf = buf_to_str(ir_test, total_ir_length, 16);
                ERROR("Error validating JTAG scan chain, IR mismatch, scan returned 0x%s", cbuf);
                free(cbuf);
+               free(ir_test);
                return ERROR_JTAG_INIT_FAILED;
        }
        
@@ -1371,7 +1303,7 @@ int jtag_register_commands(struct command_context_s *cmd_ctx)
        register_command(cmd_ctx, NULL, "jtag_speed", handle_jtag_speed_command,
                COMMAND_ANY, "set jtag speed (if supported) <speed>");
        register_command(cmd_ctx, NULL, "jtag_device", handle_jtag_device_command,
-               COMMAND_CONFIG, NULL);
+               COMMAND_CONFIG, "jtag_device <ir_length> <ir_expected> <ir_mask>");
        register_command(cmd_ctx, NULL, "reset_config", handle_reset_config_command,
                COMMAND_CONFIG, NULL);
        register_command(cmd_ctx, NULL, "jtag_nsrst_delay", handle_jtag_nsrst_delay_command,
@@ -1446,7 +1378,8 @@ int jtag_init(struct command_context_s *cmd_ctx)
                                        if (validate_tries > 5)
                                        {
                                                ERROR("Could not validate JTAG chain, exit");
-                                               exit(-1);
+                                               jtag = NULL;
+                                               return ERROR_JTAG_INVALID_INTERFACE;
                                        }
                                        usleep(10000);
                                }
@@ -1568,8 +1501,9 @@ int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, ch
                        jtag_reset_config = RESET_TRST_AND_SRST;
                else
                {
-                       ERROR("invalid reset_config argument");
-                       exit(-1);
+                       ERROR("invalid reset_config argument, defaulting to none");
+                       jtag_reset_config = RESET_NONE;
+                       return ERROR_INVALID_ARGUMENTS;
                }
        }
        
@@ -1585,8 +1519,9 @@ int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, ch
                        jtag_reset_config &= ~(RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST);
                else
                {
-                       ERROR("invalid reset_config argument");
-                       exit(-1);
+                       ERROR("invalid reset_config argument, defaulting to none");
+                       jtag_reset_config = RESET_NONE;
+                       return ERROR_INVALID_ARGUMENTS;
                }
        }
        
@@ -1598,8 +1533,9 @@ int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, ch
                        jtag_reset_config &= ~RESET_TRST_OPEN_DRAIN;
                else
                {
-                       ERROR("invalid reset_config argument");
-                       exit(-1);
+                       ERROR("invalid reset_config argument, defaulting to none");
+                       jtag_reset_config = RESET_NONE;
+                       return ERROR_INVALID_ARGUMENTS;
                }
        }
 
@@ -1611,8 +1547,9 @@ int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, ch
                        jtag_reset_config &= ~RESET_SRST_PUSH_PULL;
                else
                {
-                       ERROR("invalid reset_config argument");
-                       exit(-1);
+                       ERROR("invalid reset_config argument, defaulting to none");
+                       jtag_reset_config = RESET_NONE;
+                       return ERROR_INVALID_ARGUMENTS;
                }
        }
        

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)