#ifndef JTAG_H
#define JTAG_H
-#include "types.h"
#include "binarybuffer.h"
#include "log.h"
-#include "command.h"
-
#ifdef _DEBUG_JTAG_IO_
#define DEBUG_JTAG_IO(expr ...) LOG_DEBUG(expr)
int num_bits; /* number of bits this field specifies (up to 32) */
u8* out_value; /* value to be scanned into the device */
u8* in_value; /* pointer to a 32-bit memory location to take data scanned out */
- /* in_check_value/mask, in_handler_error_handler, in_handler_priv can be used by the in handler, otherwise they contain garbage */
- u8* in_check_value; /* used to validate scan results */
- u8* in_check_mask; /* check specified bits against check_value */
- in_handler_t in_handler; /* process received buffer using this handler */
- void* in_handler_priv; /* additional information for the in_handler */
+
+ u8* check_value; /* Used together with jtag_add_dr_scan_check() to check data clocked
+ in */
+ u8* check_mask; /* mask to go with check_value */
+
+ /* internal work space */
+ int allocated; /* in_value has been allocated for the queue */
+ int modified; /* did we modify the in_value? */
+ u8 intmp[4]; /* temporary storage for checking synchronously */
} scan_field_t;
enum scan_type {
*
*/
extern void jtag_add_ir_scan(int num_fields, scan_field_t* fields, tap_state_t endstate);
+/* same as jtag_add_ir_scan except no verify is performed */
+extern void jtag_add_ir_scan_noverify(int num_fields, scan_field_t *fields, tap_state_t state);
extern int interface_jtag_add_ir_scan(int num_fields, scan_field_t* fields, tap_state_t endstate);
extern void jtag_add_dr_scan(int num_fields, scan_field_t* fields, tap_state_t endstate);
+
+/* set in_value to point to 32 bits of memory to scan into. This function
+ * is a way to handle the case of synchronous and asynchronous
+ * JTAG queues.
+ *
+ * In the event of an asynchronous queue execution the queue buffer
+ * allocation method is used, for the synchronous case the temporary 32 bits come
+ * from the input field itself.
+ */
+
+#ifndef HAVE_JTAG_MINIDRIVER_H
+extern void jtag_alloc_in_value32(scan_field_t *field);
+#else
+static __inline__ void jtag_alloc_in_value32(scan_field_t *field)
+{
+ field->in_value=field->intmp;
+}
+#endif
+
+
+
+/* This version of jtag_add_dr_scan() uses the check_value/mask fields */
+extern void jtag_add_dr_scan_check(int num_fields, scan_field_t* fields, tap_state_t endstate);
extern int interface_jtag_add_dr_scan(int num_fields, scan_field_t* fields, tap_state_t endstate);
extern void jtag_add_plain_ir_scan(int num_fields, scan_field_t* fields, tap_state_t endstate);
extern int interface_jtag_add_plain_ir_scan(int num_fields, scan_field_t* fields, tap_state_t endstate);
extern void jtag_add_plain_dr_scan(int num_fields, scan_field_t* fields, tap_state_t endstate);
extern int interface_jtag_add_plain_dr_scan(int num_fields, scan_field_t* fields, tap_state_t endstate);
+
+/* Simplest/typical callback - do some conversion on the data clocked in.
+ * This callback is for such conversion that can not fail.
+ * For conversion types or checks that can
+ * fail, use the jtag_callback_t variant */
+typedef void (*jtag_callback1_t)(u8 *in);
+
+#ifndef HAVE_JTAG_MINIDRIVER_H
+/* A simpler version of jtag_add_callback4 */
+extern void jtag_add_callback(jtag_callback1_t, u8 *in);
+#else
+/* implemented by minidriver */
+#endif
+
+
+/* This type can store an integer safely by a normal cast on 64 and
+ * 32 bit systems. */
+typedef intptr_t jtag_callback_data_t;
+
+/* The generic callback mechanism.
+ *
+ * The callback is invoked with three arguments. The first argument is
+ * the pointer to the data clocked in.
+ */
+typedef int (*jtag_callback_t)(u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3);
+
+
+/* This callback can be executed immediately the queue has been flushed. Note that
+ * the JTAG queue can either be executed synchronously or asynchronously. Typically
+ * for USB the queue is executed asynchronously. For low latency interfaces, the
+ * queue may be executed synchronously.
+ *
+ * These callbacks are typically executed *after* the *entire* JTAG queue has been
+ * executed for e.g. USB interfaces.
+ *
+ * The callbacks are guaranteeed to be invoked in the order that they were queued.
+ *
+ * The strange name is due to C's lack of overloading using function arguments
+ *
+ * The callback mechansim is very general and does not really make any assumptions
+ * about what the callback does and what the arguments are.
+ *
+ * in - typically used to point to the data to operate on. More often than not
+ * this will be the data clocked in during a shift operation
+ *
+ * data1 - an integer that is big enough to be used either as an 'int' or
+ * cast to/from a pointer
+ *
+ * data2 - an integer that is big enough to be used either as an 'int' or
+ * cast to/from a pointer
+ *
+ * Why stop at 'data2' for arguments? Somewhat historical reasons. This is
+ * sufficient to implement the jtag_check_value_mask(), besides the
+ * line is best drawn somewhere...
+ *
+ * If the execution of the queue fails before the callbacks, then the
+ * callbacks may or may not be invoked depending on driver implementation.
+ */
+#ifndef HAVE_JTAG_MINIDRIVER_H
+extern void jtag_add_callback4(jtag_callback_t, u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3);
+#else
+/* implemented by minidriver */
+#endif
+
+
/* run a TAP_RESET reset. End state is TAP_RESET, regardless
* of start state.
*/
* of the same interface over time. Even if the OpenOCD code
* is unchanged, the actual path taken may vary over time
* and versions of interface firmware or PCB revisions.
- *
+ *
* Use jtag_add_pathmove() when specific transition sequences
* are required.
- *
+ *
* Do not use jtag_add_pathmove() unless you need to, but do use it
* if you have to.
*
*/
extern int jtag_execute_queue(void);
+/* same as jtag_execute_queue() but does not clear the error flag */
+extern void jtag_execute_queue_noclear(void);
+
+/* this flag is set when an error occurs while executing the queue. cleared
+ * by jtag_execute_queue()
+ *
+ * this flag can also be set from application code if some error happens
+ * during processing that should be reported during jtag_execute_queue().
+ */
+extern int jtag_error;
+
+static __inline__ void jtag_set_error(int error)
+{
+ if ((error==ERROR_OK)||(jtag_error!=ERROR_OK))
+ {
+ /* keep first error */
+ return;
+ }
+ jtag_error=error;
+}
+
+
+
/* can be implemented by hw+sw */
extern int interface_jtag_execute_queue(void);
extern int jtag_power_dropout(int* dropout);
extern int jtag_srst_asserted(int* srst_asserted);
/* JTAG support functions */
-extern void jtag_set_check_value(scan_field_t* field, u8* value, u8* mask, error_handler_t* in_error_handler);
+struct invalidstruct
+{
+
+};
+
+/* execute jtag queue and check value and use mask if mask is != NULL. invokes
+ * jtag_set_error() with any error. */
+extern void jtag_check_value_mask(scan_field_t *field, u8 *value, u8 *mask);
extern enum scan_type jtag_scan_type(scan_command_t* cmd);
extern int jtag_scan_size(scan_command_t* cmd);
extern int jtag_read_buffer(u8* buffer, scan_command_t* cmd);
#define MINIDRIVER(a) notused ## a
#else
#define MINIDRIVER(a) a
+extern void interface_jtag_add_dr_out(jtag_tap_t* tap, int num_fields, const int* num_bits, const u32* value,
+ tap_state_t end_state);
-/* jtag_add_dr_out() is a faster version of jtag_add_dr_scan()
+#endif
+
+/* jtag_add_dr_out() is a version of jtag_add_dr_scan() which
+ * only scans data out. It operates on 32 bit integers instead
+ * of 8 bit, which makes it a better impedance match with
+ * the calling code which often operate on 32 bit integers.
*
* Current or end_state can not be TAP_RESET. end_state can be TAP_INVALID
*
* return an error. There is no way to determine if there was a failure
* during this function call.
*
- * Note that this jtag_add_dr_out can be defined as an inline function.
+ * This is an inline fn to speed up embedded hosts. Also note that
+ * interface_jtag_add_dr_out() can be a *small* inline function for
+ * embedded hosts.
+ *
+ * There is no jtag_add_dr_outin() version of this fn that also allows
+ * clocking data back in. Patches gladly accepted!
*/
-extern void interface_jtag_add_dr_out(jtag_tap_t* tap, int num_fields, const int* num_bits, const u32* value,
- tap_state_t end_state);
-
-#endif
-
static __inline__ void jtag_add_dr_out(jtag_tap_t* tap, int num_fields, const int* num_bits, const u32* value,
tap_state_t end_state)
{