#endif
#include <assert.h>
+int jtag_flush_queue_count; /* count # of flushes for profiling / debugging purposes */
/* note that this is not marked as static as it must be available from outside jtag.c for those
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;
+
+};
+
+
+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_comand_pointer = &jtag_command_queue;
static jtag_tap_t *jtag_all_taps = NULL;
static int handle_runtest_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
+static int Jim_Command_flush_count(Jim_Interp *interp, int argc, Jim_Obj *const *args);
static int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
u32 id[8];
int modified[8];
-
/* 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.
*
for (j = 0; j < num_fields; j++)
{
jtag_tap_t *tap=fields[j].tap;
- jtag_check_value_mask(fields+j, tap->expected, tap->expected_mask);
+ if (fields[j].in_value!=NULL)
+ {
+ /* we verify max 32 bit long irlens. */
+ jtag_check_value_mask(fields+j, tap->expected, tap->expected_mask);
+ }
if (modified[j])
{
break;
}
nth_tap++;
+
+ assert(nth_tap < x );
+
scan_size = tap->ir_length;
(*last_cmd)->cmd.scan->fields[nth_tap].tap = tap;
(*last_cmd)->cmd.scan->fields[nth_tap].num_bits = scan_size;
- (*last_cmd)->cmd.scan->fields[nth_tap].in_value = fields[nth_tap].in_value;
+ (*last_cmd)->cmd.scan->fields[nth_tap].in_value = NULL; /* do not collect input for tap's in bypass */
/* search the list */
for (j = 0; j < num_fields; j++)
if (tap == fields[j].tap)
{
found = 1;
+ (*last_cmd)->cmd.scan->fields[nth_tap].in_value = fields[j].in_value;
(*last_cmd)->cmd.scan->fields[nth_tap].out_value = buf_cpy(fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
tap->bypass = 0;
/* update device information */
buf_cpy((*last_cmd)->cmd.scan->fields[nth_tap].out_value, tap->cur_instr, scan_size);
}
+ assert(nth_tap == (x-1));
return ERROR_OK;
}
return type;
}
-int MINIDRIVER(interface_jtag_execute_queue)(void)
+
+#ifndef HAVE_JTAG_MINIDRIVER_H
+/* add callback to end of queue */
+void jtag_add_callback3(jtag_callback_t callback, u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2)
+{
+ 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;
+
+ 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_callback3(u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2)
+{
+ ((jtag_callback1_t)data1)(in);
+ return ERROR_OK;
+}
+
+void jtag_add_callback(jtag_callback1_t callback, u8 *in)
+{
+ jtag_add_callback3(jtag_convert_to_callback3, in, (jtag_callback_data_t)callback, 0);
+}
+#endif
+
+#ifndef HAVE_JTAG_MINIDRIVER_H
+
+int interface_jtag_execute_queue(void)
{
int retval;
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);
+ if (retval!=ERROR_OK)
+ break;
+ }
+ }
+
cmd_queue_free();
+ jtag_callback_queue_head = NULL;
+ jtag_callback_queue_tail = NULL;
+
jtag_command_queue = NULL;
last_comand_pointer = &jtag_command_queue;
return retval;
}
+#endif
void jtag_execute_queue_noclear(void)
{
+ /* each flush can take as much as 1-2ms on high bandwidth low latency interfaces.
+ * E.g. a JTAG over TCP/IP or USB....
+ */
+ jtag_flush_queue_count++;
+
int retval=interface_jtag_execute_queue();
/* we keep the first error */
if ((jtag_error==ERROR_OK)&&(retval!=ERROR_OK))
register_command(cmd_ctx, NULL, "irscan", handle_irscan_command,
COMMAND_EXEC, "execute IR scan <device> <instr> [dev2] [instr2] ...");
register_jim(cmd_ctx, "drscan", Jim_Command_drscan, "execute DR scan <device> <num_bits> <value> <num_bits1> <value2> ...");
+ register_jim(cmd_ctx, "flush_count", Jim_Command_flush_count, "returns number of times the JTAG queue has been flushed");
register_command(cmd_ctx, NULL, "verify_ircapture", handle_verify_ircapture_command,
COMMAND_ANY, "verify value captured during Capture-IR <enable|disable>");
return JIM_OK;
}
+
+static int Jim_Command_flush_count(Jim_Interp *interp, int argc, Jim_Obj *const *args)
+{
+ Jim_SetResult(interp, Jim_NewIntObj(interp, jtag_flush_queue_count));
+
+ return JIM_OK;
+}
+
+
static int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
if (argc == 1)