X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fjtag.h;h=84290ca7e189c0fc7288b4fb60618b209116d4db;hb=71d76b0a74bee78bd9aade2957e92c6b420372b9;hp=604692cddd0ed84f7d714e68b61e84403c8606dc;hpb=e86dee32004d750e8654fe449bfcdffaed7339fa;p=openocd.git diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 604692cddd..84290ca7e1 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -23,12 +23,9 @@ #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) @@ -272,11 +269,15 @@ typedef struct scan_field_s 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 { @@ -559,14 +560,103 @@ extern int jtag_register_commands(struct command_context_s* cmd_ctx); * */ 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. */ @@ -696,13 +786,43 @@ int interface_jtag_add_clocks(int num_cycles); */ 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);