change jtag_add_callback API to be able to support check_value/mask

git-svn-id: svn://svn.berlios.de/openocd/trunk@1735 b42882b7-edfa-0310-969c-e2dbd0fdcd60
__archive__
oharboe 2009-05-11 08:39:49 +00:00
parent 265b0a9fca
commit 8c77f7c69c
4 changed files with 85 additions and 15 deletions

View File

@ -77,7 +77,7 @@ struct jtag_callback_entry
u8 *in;
jtag_callback_data_t data1;
jtag_callback_data_t data2;
jtag_callback_data_t data3;
};
@ -725,6 +725,62 @@ void jtag_add_dr_scan(int num_fields, scan_field_t *fields, tap_state_t state)
jtag_error=retval;
}
int jtag_check_value_inner(u8 *captured, u8 *in_check_value, u8 *in_check_mask, int num_bits);
static int jtag_check_value_mask_callback(u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
{
return jtag_check_value_inner(in, (u8 *)data1, (u8 *)data2, (int)data3);
}
void jtag_add_dr_scan_check(int num_fields, scan_field_t *fields, tap_state_t state)
{
for (int i=0; i<num_fields; i++)
{
fields[i].allocated=0;
fields[i].modified=0;
if ((fields[i].check_value!=NULL)&&(fields[i].in_value==NULL))
{
fields[i].modified=1;
/* we need storage space... */
#ifdef HAVE_JTAG_MINIDRIVER_H
if (fields[i].num_bits<=32)
{
/* This is enough space and we're executing this synchronously */
fields[i].in_value=(u8 *)&fields[i].intmp;
} else
{
fields[i].in_value=(u8 *)malloc(CEIL(fields[i].num_bits, 8));
fields[i].allocated=1;
}
#else
fields[i].in_value=(u8 *)cmd_queue_alloc(CEIL(fields[i].num_bits, 8));
#endif
}
}
jtag_add_dr_scan(num_fields, fields, state);
for (int i=0; i<num_fields; i++)
{
if ((fields[i].check_value!=NULL)&&(fields[i].in_value!=NULL))
{
/* this is synchronous for a minidriver */
jtag_add_callback4(jtag_check_value_mask_callback, fields[i].in_value, fields[i].check_value, fields[i].check_mask, (jtag_callback_data_t)fields[i].num_bits);
}
if (fields[i].allocated)
{
free(fields[i].in_value);
}
if (fields[i].modified)
{
fields[i].in_value=NULL;
}
}
}
void jtag_add_dr_scan_now(int num_fields, scan_field_t *fields, tap_state_t state)
{
jtag_add_dr_scan(num_fields, fields, state);
@ -1362,10 +1418,9 @@ static const char *jtag_tap_name(jtag_tap_t *tap)
return (tap == NULL) ? "(unknown)" : tap->dotted_name;
}
int jtag_check_value_inner(u8 *captured, scan_field_t *field, u8 *in_check_value, u8 *in_check_mask)
int jtag_check_value_inner(u8 *captured, u8 *in_check_value, u8 *in_check_mask, int num_bits)
{
int retval = ERROR_OK;
int num_bits = field->num_bits;
int compare_failed = 0;
@ -1379,8 +1434,10 @@ int jtag_check_value_inner(u8 *captured, scan_field_t *field, u8 *in_check_value
* only report a problem when there wasn't a handler, or if the handler
* acknowledged the error
*/
/*
LOG_WARNING("TAP %s:",
jtag_tap_name(field->tap));
*/
if (compare_failed)
{
char *captured_char = buf_to_str(captured, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits, 16);
@ -1422,7 +1479,7 @@ void jtag_check_value_mask(scan_field_t *field, u8 *value, u8 *mask)
jtag_execute_queue_noclear();
int retval=jtag_check_value_inner(field->in_value, field, value, mask);
int retval=jtag_check_value_inner(field->in_value, value, mask, field->num_bits);
jtag_set_error(retval);
}
@ -1447,7 +1504,7 @@ enum scan_type jtag_scan_type(scan_command_t *cmd)
#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)
void jtag_add_callback4(jtag_callback_t callback, u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
{
struct jtag_callback_entry *entry=cmd_queue_alloc(sizeof(struct jtag_callback_entry));
@ -1456,6 +1513,7 @@ void jtag_add_callback3(jtag_callback_t callback, u8 *in, jtag_callback_data_t d
entry->in=in;
entry->data1=data1;
entry->data2=data2;
entry->data3=data3;
if (jtag_callback_queue_head==NULL)
{
@ -1469,7 +1527,7 @@ void jtag_add_callback3(jtag_callback_t callback, u8 *in, jtag_callback_data_t d
}
static int jtag_convert_to_callback3(u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2)
static int jtag_convert_to_callback4(u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
{
((jtag_callback1_t)data1)(in);
return ERROR_OK;
@ -1477,7 +1535,7 @@ static int jtag_convert_to_callback3(u8 *in, jtag_callback_data_t data1, jtag_ca
void jtag_add_callback(jtag_callback1_t callback, u8 *in)
{
jtag_add_callback3(jtag_convert_to_callback3, in, (jtag_callback_data_t)callback, 0);
jtag_add_callback4(jtag_convert_to_callback4, in, (jtag_callback_data_t)callback, 0, 0);
}
#endif
@ -1500,7 +1558,7 @@ int interface_jtag_execute_queue(void)
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);
retval=entry->callback(entry->in, entry->data1, entry->data2, entry->data3);
if (retval!=ERROR_OK)
break;
}

View File

@ -269,6 +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 */
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? */
u32 intmp; /* temporary storage for checking synchronously */
} scan_field_t;
enum scan_type {
@ -555,6 +564,9 @@ extern void jtag_add_ir_scan(int num_fields, scan_field_t* fields, tap_state_t e
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);
/* 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);
/* same as jtag_add_dr_scan but the scan is executed immediately. sets jtag_error if there
* was a failure.
*/
@ -573,7 +585,7 @@ extern int interface_jtag_add_plain_dr_scan(int num_fields, scan_field_t* field
typedef void (*jtag_callback1_t)(u8 *in);
#ifndef HAVE_JTAG_MINIDRIVER_H
/* A simpler version of jtag_add_callback3 */
/* A simpler version of jtag_add_callback4 */
extern void jtag_add_callback(jtag_callback1_t, u8 *in);
#else
/* implemented by minidriver */
@ -588,7 +600,7 @@ typedef void *jtag_callback_data_t;
* 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);
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
@ -623,7 +635,7 @@ typedef int (*jtag_callback_t)(u8 *in, jtag_callback_data_t data1, jtag_callback
* 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);
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

View File

@ -244,7 +244,7 @@ void arm_endianness(u8 *tmp, void *in, int size, int be, int flip)
}
}
static int arm7endianness(u8 *in, jtag_callback_data_t size, jtag_callback_data_t be)
static int arm7endianness(u8 *in, jtag_callback_data_t size, jtag_callback_data_t be, jtag_callback_data_t dummy)
{
arm_endianness(in, in, (int)size, (int)be, 1);
return ERROR_OK;
@ -278,7 +278,7 @@ int arm7tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size,
jtag_add_dr_scan(2, fields, TAP_INVALID);
jtag_add_callback3(arm7endianness, in, (jtag_callback_data_t)size, (jtag_callback_data_t)be);
jtag_add_callback4(arm7endianness, in, (jtag_callback_data_t)size, (jtag_callback_data_t)be, NULL);
jtag_add_runtest(0, TAP_INVALID);

View File

@ -291,7 +291,7 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
extern void arm_endianness(u8 *tmp, void *in, int size, int be, int flip);
static int arm9endianness(u8 *in, jtag_callback_data_t size, jtag_callback_data_t be)
static int arm9endianness(u8 *in, jtag_callback_data_t size, jtag_callback_data_t be, jtag_callback_data_t dummy)
{
arm_endianness(in, in, (int)size, (int)be, 0);
return ERROR_OK;
@ -331,7 +331,7 @@ int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size,
jtag_add_dr_scan(3, fields, TAP_INVALID);
jtag_add_callback3(arm9endianness, in, (jtag_callback_data_t)size, (jtag_callback_data_t)be);
jtag_add_callback4(arm9endianness, in, (jtag_callback_data_t)size, (jtag_callback_data_t)be, 0);
jtag_add_runtest(0, TAP_INVALID);