X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fjtag.h;h=e2b613615f04ca25931634099cc12ceb44491f47;hb=ff2737b429f563c57ab255fa2479725c9f057028;hp=604692cddd0ed84f7d714e68b61e84403c8606dc;hpb=e86dee32004d750e8654fe449bfcdffaed7339fa;p=openocd.git diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 604692cddd..e2b613615f 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 { @@ -286,7 +287,7 @@ enum scan_type { typedef struct scan_command_s { - int ir_scan; /* instruction/not data scan */ + bool ir_scan; /* instruction/not data scan */ int num_fields; /* number of fields in *fields array */ scan_field_t* fields; /* pointer to an array of data scan fields */ tap_state_t end_state; /* TAP state in which JTAG commands should finish */ @@ -559,13 +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); -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); -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); +/* same as jtag_add_ir_scan except no verify is performed */ +extern void jtag_add_ir_scan_noverify(int num_fields, const scan_field_t *fields, tap_state_t state); +extern int interface_jtag_add_ir_scan(int num_fields, const scan_field_t* fields, tap_state_t endstate); +extern void jtag_add_dr_scan(int num_fields, const 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, const scan_field_t* fields, tap_state_t endstate); +extern void jtag_add_plain_ir_scan(int num_fields, const scan_field_t* fields, tap_state_t endstate); +extern int interface_jtag_add_plain_ir_scan(int num_fields, const scan_field_t* fields, tap_state_t endstate); +extern void jtag_add_plain_dr_scan(int num_fields, const scan_field_t* fields, tap_state_t endstate); +extern int interface_jtag_add_plain_dr_scan(int num_fields, const 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. @@ -614,8 +705,8 @@ extern int interface_jtag_add_tlr(void); * a partial implementation of pathmove would have little practical * application. */ -extern void jtag_add_pathmove(int num_states, tap_state_t* path); -extern int interface_jtag_add_pathmove(int num_states, tap_state_t* path); +extern void jtag_add_pathmove(int num_states, const tap_state_t* path); +extern int interface_jtag_add_pathmove(int num_states, const tap_state_t* path); /* go to TAP_IDLE, if we're not already there and cycle * precisely num_cycles in the TAP_IDLE after which move @@ -696,17 +787,47 @@ 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); -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); -extern int jtag_build_buffer(scan_command_t* cmd, u8** buffer); +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(const scan_command_t* cmd); +extern int jtag_scan_size(const scan_command_t* cmd); +extern int jtag_read_buffer(u8* buffer, const scan_command_t* cmd); +extern int jtag_build_buffer(const scan_command_t* cmd, u8** buffer); extern void jtag_sleep(u32 us); extern int jtag_call_event_callbacks(enum jtag_event event); @@ -735,8 +856,15 @@ void jtag_tap_handle_event(jtag_tap_t* tap, enum jtag_tap_event e); #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 * @@ -751,13 +879,13 @@ void jtag_tap_handle_event(jtag_tap_t* tap, enum jtag_tap_event e); * 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) {