#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; /* deprecated! only used from jtag_set_check_value. used to validate scan results */
- u8* in_check_mask; /* deprecated! only used from jtag_set_check_value. check specified bits against check_value */
- in_handler_t in_handler; /* deprecated! SET TO NULL. DO NOT USE! process received buffer using this handler */
- void* in_handler_priv; /* deprecated! only used by obsolete in_handler implementations */
+
+ 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);
-/* same as jtag_add_dr_scan but the scan is executed immediately. sets jtag_error if there
- * was a failure.
+
+/* 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.
*/
-extern void jtag_add_dr_scan_now(int num_fields, scan_field_t* fields, tap_state_t endstate);
+
+#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.
*/
/* JTAG support functions */
struct invalidstruct
{
-
+
};
-extern void jtag_set_check_value(scan_field_t* field, u8* value, u8* mask, struct invalidstruct *obsolete);
/* 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);
#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);
+
+#endif
-/* jtag_add_dr_out() is a faster version of jtag_add_dr_scan()
+/* 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)
{