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__
oharboe 2009-05-10 19:48:09 +00:00
parent 72acdac71a
commit 26526a80ea
2 changed files with 137 additions and 1 deletions

View File

@ -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)
{ {

View File

@ -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.
*/ */