Continue clean-up of JTAG driver interface:
authorzwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Tue, 2 Jun 2009 07:05:54 +0000 (07:05 +0000)
committerzwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Tue, 2 Jun 2009 07:05:54 +0000 (07:05 +0000)
- Move all interface_jtag_* functions to jtag_driver.c.
- Extern command queue routines in jtag.h (with INCLUDE_JTAG_INTERFACE_H).
- Add new source file to automake inputs.

git-svn-id: svn://svn.berlios.de/openocd/trunk@1996 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/jtag/Makefile.am
src/jtag/jtag.c
src/jtag/jtag.h
src/jtag/jtag_driver.c [new file with mode: 0644]

index 3163b245e692e731d2ba08fe00728083cb469bcb..58110ff4166e5221a6c17628c8addd08f011210e 100644 (file)
@@ -109,7 +109,9 @@ else
 ARMJTAGEWFILES =
 endif
 
-libjtag_la_SOURCES = jtag.c \
+libjtag_la_SOURCES = \
+       jtag.c \
+       jtag_driver.c \
        $(BITBANGFILES) \
        $(PARPORTFILES) \
        $(DUMMYFILES) \
index 682c1b33098685b3ef40082dc82cbc180882e685..af07e78a2b177884fe8f356bcf904e37da9fd792 100644 (file)
@@ -72,30 +72,6 @@ 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;
-
-static void jtag_callback_queue_reset(void)
-{
-       jtag_callback_queue_head = NULL;
-       jtag_callback_queue_tail = NULL;
-}
-#endif
-
-
 jtag_command_t *jtag_command_queue = NULL;
 static jtag_command_t **next_command_pointer = &jtag_command_queue;
 static jtag_tap_t *jtag_all_taps = NULL;
@@ -235,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;
@@ -527,20 +503,6 @@ void jtag_command_queue_reset(void)
        next_command_pointer = &jtag_command_queue;
 }
 
-/**
- * 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)
@@ -606,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
  *
@@ -698,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);
 
@@ -825,174 +685,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 +704,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 +715,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 +753,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 +766,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 +892,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 +901,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,67 +1094,6 @@ 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)
-{
-       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 = default_interface_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;
-               }
-       }
-
-       jtag_command_queue_reset();
-       jtag_callback_queue_reset();
-
-       return retval;
-}
-#endif
-
 int default_interface_jtag_execute_queue(void)
 {
        if (NULL == jtag)
@@ -3718,13 +3225,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)
index 668486332f134e011e04089a63244ba81e36a8c7..9298e896d7b258121b7ae7fac885bdacfc5d1764 100644 (file)
@@ -365,6 +365,12 @@ typedef struct jtag_command_s
 
 extern jtag_command_t* jtag_command_queue;
 
+extern void* cmd_queue_alloc(size_t size);
+extern void cmd_queue_free(void);
+
+extern void jtag_queue_command(jtag_command_t *cmd);
+extern void jtag_command_queue_reset(void);
+
 #endif // INCLUDE_JTAG_INTERFACE_H
 
 /* forward declaration */
diff --git a/src/jtag/jtag_driver.c b/src/jtag/jtag_driver.c
new file mode 100644 (file)
index 0000000..d532359
--- /dev/null
@@ -0,0 +1,525 @@
+/***************************************************************************
+ *   Copyright (C) 2005 by Dominic Rath                                    *
+ *   Dominic.Rath@gmx.de                                                   *
+ *                                                                         *
+ *   Copyright (C) 2007,2008 Ã˜yvind Harboe                                 *
+ *   oyvind.harboe@zylin.com                                               *
+ *                                                                         *
+ *   Copyright (C) 2009 SoftPLC Corporation                                *
+ *       http://softplc.com                                                *
+ *   dick@softplc.com                                                      *
+ *                                                                         *
+ *   Copyright (C) 2009 Zachary T Welch                                    *
+ *   zw@superlucidity.net                                                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define INCLUDE_JTAG_MINIDRIVER_H
+#define INCLUDE_JTAG_INTERFACE_H
+#include "jtag.h"
+#include "command.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;
+
+static void jtag_callback_queue_reset(void)
+{
+       jtag_callback_queue_head = NULL;
+       jtag_callback_queue_tail = 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;
+}
+
+/**
+ * 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;
+}
+
+/**
+ * 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;
+}
+
+
+
+/**
+ * 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 */
+}
+
+/**
+ * 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;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+/* 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)
+{
+       jtag_add_callback4(jtag_convert_to_callback4, in, (jtag_callback_data_t)callback, 0, 0);
+}
+
+int interface_jtag_execute_queue(void)
+{
+       int retval = default_interface_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;
+               }
+       }
+
+       jtag_command_queue_reset();
+       jtag_callback_queue_reset();
+
+       return retval;
+}
+
+void jtag_alloc_in_value32(scan_field_t *field)
+{
+       field->in_value=(u8 *)cmd_queue_alloc(4);
+}

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)