Wrote up post processing JTAG API. Not used yet, but reference implementation will be used in subsequent explanations of new scheme + patches to use it.
git-svn-id: svn://svn.berlios.de/openocd/trunk@1692 b42882b7-edfa-0310-969c-e2dbd0fdcd60__archive__
parent
72acdac71a
commit
26526a80ea
|
@ -76,6 +76,24 @@ const Jim_Nvp nvp_jtag_tap_event[] = {
|
||||||
int jtag_trst = 0;
|
int jtag_trst = 0;
|
||||||
int jtag_srst = 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 *jtag_command_queue = NULL;
|
||||||
jtag_command_t **last_comand_pointer = &jtag_command_queue;
|
jtag_command_t **last_comand_pointer = &jtag_command_queue;
|
||||||
static jtag_tap_t *jtag_all_taps = NULL;
|
static jtag_tap_t *jtag_all_taps = NULL;
|
||||||
|
@ -1434,7 +1452,46 @@ enum scan_type jtag_scan_type(scan_command_t *cmd)
|
||||||
return type;
|
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;
|
int retval;
|
||||||
|
|
||||||
|
@ -1446,13 +1503,28 @@ int MINIDRIVER(interface_jtag_execute_queue)(void)
|
||||||
|
|
||||||
retval = jtag->execute_queue();
|
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();
|
cmd_queue_free();
|
||||||
|
|
||||||
|
jtag_callback_queue_head = NULL;
|
||||||
|
jtag_callback_queue_tail = NULL;
|
||||||
|
|
||||||
jtag_command_queue = NULL;
|
jtag_command_queue = NULL;
|
||||||
last_comand_pointer = &jtag_command_queue;
|
last_comand_pointer = &jtag_command_queue;
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void jtag_execute_queue_noclear(void)
|
void jtag_execute_queue_noclear(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -568,6 +568,70 @@ extern int interface_jtag_add_plain_ir_scan(int num_fields, scan_field_t* field
|
||||||
extern void jtag_add_plain_dr_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);
|
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_callback3 */
|
||||||
|
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 void *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);
|
||||||
|
|
||||||
|
|
||||||
|
/* 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_callback3(jtag_callback_t, u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2);
|
||||||
|
#else
|
||||||
|
/* implemented by minidriver */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* run a TAP_RESET reset. End state is TAP_RESET, regardless
|
/* run a TAP_RESET reset. End state is TAP_RESET, regardless
|
||||||
* of start state.
|
* of start state.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue