Move interface_jtag_add_scan_check_alloc implementations to their
[openocd.git] / src / jtag / jtag.c
index d0cb43321396cdd4e849a462ba21f7b0b747a11c..593200ee8b0b805ce359142622f8a31da69575c5 100644 (file)
@@ -6,7 +6,7 @@
  *   oyvind.harboe@zylin.com                                               *
  *                                                                         *
  *   Copyright (C) 2009 SoftPLC Corporation                                *
- *      http://softplc.com                                                    *
+ *       http://softplc.com                                                *
  *   dick@softplc.com                                                      *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -72,26 +72,8 @@ const Jim_Nvp nvp_jtag_tap_event[] = {
 int jtag_trst = 0;
 int jtag_srst = 0;
 
-#ifndef HAVE_JTAG_MINIDRIVER_H
-struct jtag_callback_entry
-{
-       struct jtag_callback_entry *next;
-
-       jtag_callback_t callback;
-       u8 *in;
-       jtag_callback_data_t data1;
-       jtag_callback_data_t data2;
-       jtag_callback_data_t data3;
-};
-
-
-static struct jtag_callback_entry *jtag_callback_queue_head = NULL;
-static struct jtag_callback_entry *jtag_callback_queue_tail = NULL;
-#endif
-
-
 jtag_command_t *jtag_command_queue = NULL;
-jtag_command_t **last_command_pointer = &jtag_command_queue;
+static jtag_command_t **next_command_pointer = &jtag_command_queue;
 static jtag_tap_t *jtag_all_taps = NULL;
 
 enum reset_types jtag_reset_config = RESET_NONE;
@@ -229,7 +211,7 @@ jtag_interface_t *jtag_interfaces[] = {
        NULL,
 };
 
-static jtag_interface_t *jtag = NULL;
+struct jtag_interface_s *jtag = NULL;
 
 /* configuration */
 static jtag_interface_t *jtag_interface = NULL;
@@ -423,40 +405,20 @@ int jtag_call_event_callbacks(enum jtag_event event)
        return ERROR_OK;
 }
 
-/* returns a pointer to the pointer of the last command in queue
- * this may be a pointer to the root pointer (jtag_command_queue)
- * or to the next member of the last but one command
- */
-jtag_command_t** jtag_get_last_command_p(void)
-{
-/*     jtag_command_t *cmd = jtag_command_queue;
-
-       if (cmd)
-               while (cmd->next)
-                       cmd = cmd->next;
-       else
-               return &jtag_command_queue;
-
-       return &cmd->next;*/
-
-       return last_command_pointer;
-}
-
-
 void jtag_queue_command(jtag_command_t * cmd)
 {
-       jtag_command_t **last_cmd;
-
-       last_cmd = jtag_get_last_command_p();
+       // this command goes on the end, so ensure the queue terminates
+       cmd->next = NULL;
 
+       jtag_command_t **last_cmd = next_command_pointer;
+       assert(NULL != last_cmd);
+       assert(NULL == *last_cmd);
        *last_cmd = cmd;
 
-       (*last_cmd)->next = NULL;
-
-       last_command_pointer = &((*last_cmd)->next);
+       // store location where the next command pointer will be stored
+       next_command_pointer = &cmd->next;
 }
 
-
 void* cmd_queue_alloc(size_t size)
 {
        cmd_queue_page_t **p_page = &cmd_queue_pages;
@@ -533,19 +495,13 @@ 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)
+void jtag_command_queue_reset(void)
 {
-       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;
-}
+       cmd_queue_free();
 
+       jtag_command_queue = NULL;
+       next_command_pointer = &jtag_command_queue;
+}
 
 static void jtag_prelude1(void)
 {
@@ -595,12 +551,10 @@ void jtag_add_ir_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t st
 {
        if (jtag_verify&&jtag_verify_capture_ir)
        {
-               /* 8 x 32 bit id's is enough for all invoations */
+               /* 8 x 32 bit id's is enough for all invocations */
 
                for (int j = 0; j < in_num_fields; j++)
                {
-                       in_fields[j].check_value=NULL;
-                       in_fields[j].check_mask=NULL;
                        /* if we are to run a verification of the ir scan, we need to get the input back.
                         * We may have to allocate space if the caller didn't ask for the input back.
                         */
@@ -614,80 +568,6 @@ void jtag_add_ir_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t st
        }
 }
 
-/**
- * see jtag_add_ir_scan()
- *
- */
-int MINIDRIVER(interface_jtag_add_ir_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
-{
-       size_t 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));
-       scan_field_t * out_fields       = cmd_queue_alloc(num_taps  * sizeof(scan_field_t));
-
-       jtag_queue_command(cmd);
-
-       cmd->type                               = JTAG_SCAN;
-       cmd->cmd.scan                   = scan;
-
-       scan->ir_scan                   = true;
-       scan->num_fields                = num_taps;     /* one field per device */
-       scan->fields                    = out_fields;
-       scan->end_state                 = state;
-
-
-       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))
-       {
-               /* search the input field list for fields for the current TAP */
-
-               bool found = false;
-
-               for (int j = 0; j < in_num_fields; j++)
-               {
-                       if (tap != in_fields[j].tap)
-                               continue;
-
-                       /* 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 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(field->out_value, tap->cur_instr, tap->ir_length);
-
-               field++;
-       }
-
-       assert(field == out_fields + num_taps); /* paranoia: jtag_NumEnabledTaps() and jtag_NextEnabledTap() not in sync */
-
-       return ERROR_OK;
-}
-
 /**
  * Duplicate the scan fields passed into the function into an IR SCAN command
  *
@@ -706,34 +586,6 @@ void jtag_add_plain_ir_scan(int in_num_fields, const scan_field_t *in_fields, ta
 }
 
 
-/**
- * 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));
-       scan_field_t * out_fields       = cmd_queue_alloc(in_num_fields * sizeof(scan_field_t));
-       
-       jtag_queue_command(cmd);
-
-       cmd->type                               = JTAG_SCAN;
-       cmd->cmd.scan                   = scan;
-
-       scan->ir_scan                   = true;
-       scan->num_fields                = in_num_fields;
-       scan->fields                    = out_fields;
-       scan->end_state                 = state;
-
-       for (int i = 0; i < in_num_fields; i++)
-               cmd_queue_scan_field_clone(out_fields + i, in_fields + i);
-
-       return ERROR_OK;
-}
-
-
 
 int jtag_check_value_inner(u8 *captured, u8 *in_check_value, u8 *in_check_mask, int num_bits);
 
@@ -747,26 +599,13 @@ static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const s
 {
        for (int i = 0; i < in_num_fields; i++)
        {
-               in_fields[i].allocated = 0;
-               in_fields[i].modified = 0;
-               if ((in_fields[i].check_value != NULL) && (in_fields[i].in_value == NULL))
-               {
-                       in_fields[i].modified = 1;
-                       /* we need storage space... */
-#ifdef HAVE_JTAG_MINIDRIVER_H
-                       if (in_fields[i].num_bits <= 32)
-                       {
-                               /* This is enough space and we're executing this synchronously */
-                               in_fields[i].in_value = in_fields[i].intmp;
-                       } else
-                       {
-                               in_fields[i].in_value = (u8 *)malloc(CEIL(in_fields[i].num_bits, 8));
-                               in_fields[i].allocated = 1;
-                       }
-#else
-                       in_fields[i].in_value = (u8 *)cmd_queue_alloc(CEIL(in_fields[i].num_bits, 8));
-#endif
-               }
+               struct scan_field_s *field = &in_fields[i];
+               field->allocated = 0;
+               field->modified = 0;
+               if (field->check_value || field->in_value)
+                       continue;
+               interface_jtag_add_scan_check_alloc(field);
+               field->modified = 1;
        }
 
        jtag_add_scan(in_num_fields, in_fields, state);
@@ -825,174 +664,6 @@ void jtag_add_dr_scan(int in_num_fields, const scan_field_t *in_fields, tap_stat
 }
 
 
-/**
- * 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 */
-
-       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));
-       scan_field_t * out_fields       = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t));
-       
-       jtag_queue_command(cmd);
-       
-       cmd->type                               = JTAG_SCAN;
-       cmd->cmd.scan                   = scan;
-
-       scan->ir_scan                   = false;
-       scan->num_fields                = in_num_fields + bypass_devices;
-       scan->fields                    = out_fields;
-       scan->end_state                 = state;
-
-
-       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)
-               {
-                       scan_field_t * start_field = field;     /* keep initial position for assert() */
-
-                       for (int j = 0; j < in_num_fields; j++)
-                       {
-                               if (tap != in_fields[j].tap)
-                                       continue;
-
-                               cmd_queue_scan_field_clone(field, in_fields + j);
-
-                               field++;
-                       }
-
-                       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
-               {
-                       field->tap                      = tap;
-                       field->num_bits         = 1;
-                       field->out_value        = NULL;
-                       field->in_value         = NULL;
-
-                       field++;
-               }
-       }
-
-       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)
-{
-       /* count devices in 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));
-       scan_field_t * out_fields       = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t));
-
-       jtag_queue_command(cmd);
-
-       cmd->type                               = JTAG_SCAN;
-       cmd->cmd.scan                   = scan;
-
-       scan->ir_scan                   = false;
-       scan->num_fields                = in_num_fields + bypass_devices;
-       scan->fields                    = out_fields;
-       scan->end_state                 = end_state;
-
-
-       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)
-               {
-                       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]);
-
-                               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++;
-                       }
-               }
-
-               /* if a TAP is bypassed, generated a dummy bit*/
-               else
-               {
-
-                       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 */
-}
-
 
 /**
  * Duplicate the scan fields passed into the function into a DR SCAN command
@@ -1012,32 +683,6 @@ void jtag_add_plain_dr_scan(int in_num_fields, const scan_field_t *in_fields, ta
 }
 
 
-/**
- * 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)
-{
-       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->cmd.scan                   = scan;
-
-       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++)
-               cmd_queue_scan_field_clone(out_fields + i, in_fields + i);
-
-       return ERROR_OK;
-}
-
 
 void jtag_add_tlr(void)
 {
@@ -1049,23 +694,6 @@ void jtag_add_tlr(void)
                jtag_error=retval;
 }
 
-int MINIDRIVER(interface_jtag_add_tlr)(void)
-{
-       tap_state_t state = TAP_RESET;
-
-       /* allocate memory for a new list member */
-       jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
-
-       jtag_queue_command(cmd);
-
-       cmd->type = JTAG_STATEMOVE;
-
-       cmd->cmd.statemove = cmd_queue_alloc(sizeof(statemove_command_t));
-       cmd->cmd.statemove->end_state = state;
-
-       return ERROR_OK;
-}
-
 void jtag_add_pathmove(int num_states, const tap_state_t *path)
 {
        tap_state_t cur_state = cmd_queue_cur_state;
@@ -1104,41 +732,6 @@ void jtag_add_pathmove(int num_states, const tap_state_t *path)
                jtag_error=retval;
 }
 
-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));
-
-       jtag_queue_command(cmd);
-
-       cmd->type = JTAG_PATHMOVE;
-
-       cmd->cmd.pathmove = cmd_queue_alloc(sizeof(pathmove_command_t));
-       cmd->cmd.pathmove->num_states = num_states;
-       cmd->cmd.pathmove->path = cmd_queue_alloc(sizeof(tap_state_t) * num_states);
-
-       for (int i = 0; i < num_states; i++)
-               cmd->cmd.pathmove->path[i] = path[i];
-
-       return ERROR_OK;
-}
-
-int MINIDRIVER(interface_jtag_add_runtest)(int num_cycles, tap_state_t state)
-{
-       /* allocate memory for a new list member */
-       jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
-
-       jtag_queue_command(cmd);
-
-       cmd->type = JTAG_RUNTEST;
-
-       cmd->cmd.runtest = cmd_queue_alloc(sizeof(runtest_command_t));
-       cmd->cmd.runtest->num_cycles = num_cycles;
-       cmd->cmd.runtest->end_state = state;
-
-       return ERROR_OK;
-}
-
 void jtag_add_runtest(int num_cycles, tap_state_t state)
 {
        int retval;
@@ -1152,21 +745,6 @@ void jtag_add_runtest(int num_cycles, tap_state_t state)
 }
 
 
-int MINIDRIVER(interface_jtag_add_clocks)( int num_cycles )
-{
-       /* allocate memory for a new list member */
-       jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
-
-       jtag_queue_command(cmd);
-
-       cmd->type = JTAG_STABLECLOCKS;
-
-       cmd->cmd.stableclocks = cmd_queue_alloc(sizeof(stableclocks_command_t));
-       cmd->cmd.stableclocks->num_cycles = num_cycles;
-
-       return ERROR_OK;
-}
-
 void jtag_add_clocks( int num_cycles )
 {
        int retval;
@@ -1293,22 +871,6 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst)
        }
 }
 
-int MINIDRIVER(interface_jtag_add_reset)(int req_trst, int req_srst)
-{
-       /* allocate memory for a new list member */
-       jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
-
-       jtag_queue_command(cmd);
-
-       cmd->type = JTAG_RESET;
-
-       cmd->cmd.reset = cmd_queue_alloc(sizeof(reset_command_t));
-       cmd->cmd.reset->trst = req_trst;
-       cmd->cmd.reset->srst = req_srst;
-
-       return ERROR_OK;
-}
-
 void jtag_add_end_state(tap_state_t state)
 {
        cmd_queue_end_state = state;
@@ -1318,21 +880,6 @@ void jtag_add_end_state(tap_state_t state)
        }
 }
 
-int MINIDRIVER(interface_jtag_add_sleep)(u32 us)
-{
-       /* allocate memory for a new list member */
-       jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t));
-
-       jtag_queue_command(cmd);
-
-       cmd->type = JTAG_SLEEP;
-
-       cmd->cmd.sleep = cmd_queue_alloc(sizeof(sleep_command_t));
-       cmd->cmd.sleep->us = us;
-
-       return ERROR_OK;
-}
-
 void jtag_add_sleep(u32 us)
 {
        keep_alive(); /* we might be running on a very slow JTAG clk */
@@ -1526,80 +1073,18 @@ enum scan_type jtag_scan_type(const scan_command_t *cmd)
        return type;
 }
 
-
-#ifndef HAVE_JTAG_MINIDRIVER_H
-/* add callback to end of queue */
-void jtag_add_callback4(jtag_callback_t callback, u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
-{
-       struct jtag_callback_entry *entry=cmd_queue_alloc(sizeof(struct jtag_callback_entry));
-
-       entry->next=NULL;
-       entry->callback=callback;
-       entry->in=in;
-       entry->data1=data1;
-       entry->data2=data2;
-       entry->data3=data3;
-
-       if (jtag_callback_queue_head==NULL)
-       {
-               jtag_callback_queue_head=entry;
-               jtag_callback_queue_tail=entry;
-       } else
-       {
-               jtag_callback_queue_tail->next=entry;
-               jtag_callback_queue_tail=entry;
-       }
-}
-
-
-static int jtag_convert_to_callback4(u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
-{
-       ((jtag_callback1_t)data1)(in);
-       return ERROR_OK;
-}
-
-void jtag_add_callback(jtag_callback1_t callback, u8 *in)
+int default_interface_jtag_execute_queue(void)
 {
-       jtag_add_callback4(jtag_convert_to_callback4, in, (jtag_callback_data_t)callback, 0, 0);
-}
-#endif
-
-#ifndef HAVE_JTAG_MINIDRIVER_H
-
-int interface_jtag_execute_queue(void)
-{
-       int retval;
-
-       if (jtag==NULL)
+       if (NULL == jtag)
        {
-               LOG_ERROR("No JTAG interface configured yet. Issue 'init' command in startup scripts before communicating with targets.");
+               LOG_ERROR("No JTAG interface configured yet.  "
+                       "Issue 'init' command in startup scripts "
+                       "before communicating with targets.");
                return ERROR_FAIL;
        }
 
-       retval = jtag->execute_queue();
-
-       if (retval == ERROR_OK)
-       {
-               struct jtag_callback_entry *entry;
-               for (entry=jtag_callback_queue_head; entry!=NULL; entry=entry->next)
-               {
-                       retval=entry->callback(entry->in, entry->data1, entry->data2, entry->data3);
-                       if (retval!=ERROR_OK)
-                               break;
-               }
-       }
-
-       cmd_queue_free();
-
-       jtag_callback_queue_head = NULL;
-       jtag_callback_queue_tail = NULL;
-
-       jtag_command_queue = NULL;
-       last_command_pointer = &jtag_command_queue;
-
-       return retval;
+       return jtag->execute_queue();
 }
-#endif
 
 void jtag_execute_queue_noclear(void)
 {
@@ -2322,7 +1807,7 @@ int jtag_register_commands(struct command_context_s *cmd_ctx)
                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>");
+               COMMAND_CONFIG, "(DEPRECATED) jtag_device <ir_length> <ir_expected> <ir_mask>");
        register_command(cmd_ctx, NULL, "reset_config", handle_reset_config_command,
                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]");
@@ -2957,6 +2442,26 @@ static int handle_runtest_command(struct command_context_s *cmd_ctx, char *cmd,
 
 }
 
+/*
+ * For "irscan" or "drscan" commands, the "end" (really, "next") state
+ * should be stable ... and *NOT* a shift state, otherwise free-running
+ * jtag clocks could change the values latched by the update state.
+ */
+static bool scan_is_safe(tap_state_t state)
+{
+       switch (state)
+       {
+       case TAP_RESET:
+       case TAP_IDLE:
+       case TAP_DRPAUSE:
+       case TAP_IRPAUSE:
+               return true;
+       default:
+               return false;
+       }
+}
+
+
 static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        int i;
@@ -2969,11 +2474,12 @@ static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, c
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       /* optional "-endstate" */
-       /*          "statename" */
-       /* at the end of the arguments. */
-       /* assume none. */
-       endstate = cmd_queue_end_state;
+       /* optional "-endstate" "statename" at the end of the arguments,
+        * so that e.g. IRPAUSE can let us load the data register before
+        * entering RUN/IDLE to execute the instruction we load here.
+        */
+       endstate = TAP_IDLE;
+
        if( argc >= 4 ){
                /* have at least one pair of numbers. */
                /* is last pair the magic text? */
@@ -2990,6 +2496,9 @@ static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, c
                        if( endstate >= TAP_NUM_STATES ){
                                return ERROR_COMMAND_SYNTAX_ERROR;
                        } else {
+                               if (!scan_is_safe(endstate))
+                                       LOG_WARNING("irscan with unsafe "
+                                                       "endstate \"%s\"", cpA);
                                /* found - remove the last 2 args */
                                argc -= 2;
                        }
@@ -3054,8 +2563,8 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args
                return JIM_ERR;
        }
 
-       /* assume no endstate */
-       endstate = cmd_queue_end_state;
+       endstate = TAP_IDLE;
+
        /* validate arguments as numbers */
        e = JIM_OK;
        for (i = 2; i < argc; i+=2)
@@ -3075,7 +2584,10 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args
                        return e;
                }
 
-               /* it could be: "-endstate FOO" */
+               /* it could be: "-endstate FOO"
+                * e.g. DRPAUSE so we can issue more instructions
+                * before entering RUN/IDLE and executing them.
+                */
 
                /* get arg as a string. */
                cp = Jim_GetString( args[i], NULL );
@@ -3090,6 +2602,10 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args
                                /* update the error message */
                                Jim_SetResult_sprintf(interp,"endstate: %s invalid", cp );
                        } else {
+                               if (!scan_is_safe(endstate))
+                                       LOG_WARNING("drscan with unsafe "
+                                                       "endstate \"%s\"", cp);
+
                                /* valid - so clear the error */
                                e = JIM_OK;
                                /* and remove the last 2 args */
@@ -3369,7 +2885,7 @@ static const struct tms_sequences old_tms_seqs[6][6] =            /*  [from_state_ndx][to_
         * N.B. OOCD clocks TMS from LSB first, so read these right-to-left.
         * N.B. These values are tightly bound to the table in tap_get_tms_path_len().
         * N.B. Reset only needs to be 0b11111, but in JLink an even byte of 1's is more stable.
-        *              These extra ones cause no TAP state problem, because we go into reset and stay in reset.
+        * These extra ones cause no TAP state problem, because we go into reset and stay in reset.
         */
 
 
@@ -3388,7 +2904,7 @@ static const struct tms_sequences old_tms_seqs[6][6] =            /*  [from_state_ndx][to_
 
 static const struct tms_sequences short_tms_seqs[6][6] =               /*  [from_state_ndx][to_state_ndx] */
 {
-       /*      this is the table submitted by Jeff Williams on 3/30/2009 with this comment:
+       /* this is the table submitted by Jeff Williams on 3/30/2009 with this comment:
 
                OK, I added Peter's version of the state table, and it works OK for
                me on MC1322x. I've recreated the jlink portion of patch with this
@@ -3443,7 +2959,7 @@ bool tap_is_state_stable(tap_state_t astate)
 {
        bool is_stable;
 
-       /*      A switch() is used because it is symbol dependent
+       /*      A switch() is used because it is symbol dependent
                (not value dependent like an array), and can also check bounds.
        */
        switch( astate )
@@ -3467,7 +2983,7 @@ tap_state_t tap_state_transition(tap_state_t cur_state, bool tms)
 {
        tap_state_t new_state;
 
-       /*      A switch is used because it is symbol dependent and not value dependent
+       /*      A switch is used because it is symbol dependent and not value dependent
                like an array.  Also it can check for out of range conditions.
        */
 
@@ -3688,13 +3204,6 @@ tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf,
 }
 #endif // _DEBUG_JTAG_IO_
 
-#ifndef HAVE_JTAG_MINIDRIVER_H
-void jtag_alloc_in_value32(scan_field_t *field)
-{
-       field->in_value=(u8 *)cmd_queue_alloc(4);
-}
-#endif
-
 static int handle_tms_sequence_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        if (argc == 1)

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)