X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fjtag.c;h=d66a779d13f818fdd749f38b049d7b64c448c161;hp=649ead4654b6e56353d7d13194b248be65702b31;hb=591a23ec8d803c34f4168001202a736d643d2b20;hpb=49e286509b30e8e1283a7e4bcf2a82b9a6efaffb diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index 649ead4654..d66a779d13 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -28,23 +28,18 @@ #include "config.h" #endif -#include "replacements.h" - #include "jtag.h" -#include "command.h" -#include "log.h" - -#include -#include -#include #ifdef HAVE_STRINGS_H #include #endif -#include + int jtag_flush_queue_count; /* count # of flushes for profiling / debugging purposes */ +static void jtag_add_scan_check(void (*jtag_add_scan)(int num_fields, scan_field_t *fields, tap_state_t state), + int num_fields, scan_field_t *fields, tap_state_t state); + /* note that this is not marked as static as it must be available from outside jtag.c for those that implement the jtag_xxx() minidriver layer */ @@ -75,6 +70,24 @@ const Jim_Nvp nvp_jtag_tap_event[] = { int jtag_trst = 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; + jtag_callback_data_t data3; +}; + + +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 **last_comand_pointer = &jtag_command_queue; static jtag_tap_t *jtag_all_taps = NULL; @@ -538,51 +551,22 @@ void jtag_add_ir_scan_noverify(int num_fields, scan_field_t *fields, tap_state_t void jtag_add_ir_scan(int num_fields, scan_field_t *fields, tap_state_t state) { /* 8 x 32 bit id's is enough for all invoations */ - u32 id[8]; - int modified[8]; - - - /* if we are to run a verification of the ir scan, we need to get the input back. - * We may have to allocate space if the caller didn't ask for the input back. - * - */ - if (jtag_verify_capture_ir) - { - int j; - for (j = 0; j < num_fields; j++) - { - modified[j]=0; - if ((fields[j].in_value==NULL)&&(fields[j].num_bits<=32)) - { - if (j<8) - { - modified[j]=1; - fields[j].in_value=(u8 *)(id+j); - } else - { - LOG_DEBUG("caller must provide in_value space for verify_capture_ir to work"); - } - } - } - } - - jtag_add_ir_scan_noverify(num_fields, fields, state); - - if (jtag_verify_capture_ir) + int j; + for (j = 0; j < num_fields; j++) { - int j; - for (j = 0; j < num_fields; j++) + fields[j].check_value=NULL; + fields[j].check_mask=NULL; + /* if we are to run a verification of the ir scan, we need to get the input back. + * We may have to allocate space if the caller didn't ask for the input back. + */ + if (jtag_verify_capture_ir) { - jtag_tap_t *tap=fields[j].tap; - jtag_check_value_mask(fields+j, tap->expected, tap->expected_mask); - - if (modified[j]) - { - fields[j].in_value=NULL; - } + fields[j].check_value=fields[j].tap->expected; + fields[j].check_mask=fields[j].tap->expected_mask; } } + jtag_add_scan_check(jtag_add_ir_scan_noverify, num_fields, fields, state); } int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, tap_state_t state) @@ -621,10 +605,13 @@ int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, break; } nth_tap++; + + assert(nth_tap < x ); + scan_size = tap->ir_length; (*last_cmd)->cmd.scan->fields[nth_tap].tap = tap; (*last_cmd)->cmd.scan->fields[nth_tap].num_bits = scan_size; - (*last_cmd)->cmd.scan->fields[nth_tap].in_value = fields[nth_tap].in_value; + (*last_cmd)->cmd.scan->fields[nth_tap].in_value = NULL; /* do not collect input for tap's in bypass */ /* search the list */ for (j = 0; j < num_fields; j++) @@ -632,6 +619,7 @@ int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, if (tap == fields[j].tap) { found = 1; + (*last_cmd)->cmd.scan->fields[nth_tap].in_value = fields[j].in_value; (*last_cmd)->cmd.scan->fields[nth_tap].out_value = buf_cpy(fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); tap->bypass = 0; @@ -649,6 +637,7 @@ int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, /* update device information */ buf_cpy((*last_cmd)->cmd.scan->fields[nth_tap].out_value, tap->cur_instr, scan_size); } + assert(nth_tap == (x-1)); return ERROR_OK; } @@ -706,12 +695,69 @@ void jtag_add_dr_scan(int num_fields, scan_field_t *fields, tap_state_t state) jtag_error=retval; } -void jtag_add_dr_scan_now(int num_fields, scan_field_t *fields, tap_state_t state) + +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) { - jtag_add_dr_scan(num_fields, fields, state); - jtag_execute_queue_noclear(); + return jtag_check_value_inner(in, (u8 *)data1, (u8 *)data2, (int)data3); } +static void jtag_add_scan_check(void (*jtag_add_scan)(int num_fields, scan_field_t *fields, tap_state_t state), + int num_fields, scan_field_t *fields, tap_state_t state) +{ + for (int i=0; idotted_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; @@ -1360,8 +1405,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); @@ -1403,7 +1450,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); } @@ -1425,7 +1472,47 @@ enum scan_type jtag_scan_type(scan_command_t *cmd) return type; } -int MINIDRIVER(interface_jtag_execute_queue)(void) + +#ifndef HAVE_JTAG_MINIDRIVER_H +/* add callback to end of queue */ +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)); + + entry->next=NULL; + entry->callback=callback; + entry->in=in; + entry->data1=data1; + entry->data2=data2; + entry->data3=data3; + + 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_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; +} + +void jtag_add_callback(jtag_callback1_t callback, u8 *in) +{ + jtag_add_callback4(jtag_convert_to_callback4, in, (jtag_callback_data_t)callback, 0, 0); +} +#endif + +#ifndef HAVE_JTAG_MINIDRIVER_H + +int interface_jtag_execute_queue(void) { int retval; @@ -1437,20 +1524,35 @@ int MINIDRIVER(interface_jtag_execute_queue)(void) 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, entry->data3); + if (retval!=ERROR_OK) + break; + } + } + cmd_queue_free(); + jtag_callback_queue_head = NULL; + jtag_callback_queue_tail = NULL; + jtag_command_queue = NULL; last_comand_pointer = &jtag_command_queue; return retval; } +#endif void jtag_execute_queue_noclear(void) { /* each flush can take as much as 1-2ms on high bandwidth low latency interfaces. * E.g. a JTAG over TCP/IP or USB.... */ - jtag_flush_queue_count++; + jtag_flush_queue_count++; int retval=interface_jtag_execute_queue(); /* we keep the first error */ @@ -2787,9 +2889,11 @@ static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, c } } - fields = malloc(sizeof(scan_field_t) * argc / 2); + int num_fields= num_fields; - for (i = 0; i < argc / 2; i++) + fields = malloc(sizeof(scan_field_t) * num_fields); + + for (i = 0; i < num_fields; i++) { tap = jtag_TapByString( args[i*2] ); if (tap==NULL) @@ -2799,19 +2903,20 @@ static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, c } int field_size = tap->ir_length; fields[i].tap = tap; + fields[i].num_bits = field_size; fields[i].out_value = malloc(CEIL(field_size, 8)); buf_set_u32(fields[i].out_value, 0, field_size, strtoul(args[i*2+1], NULL, 0)); fields[i].in_value = NULL; } - jtag_add_ir_scan(argc / 2, fields, TAP_INVALID); + jtag_add_ir_scan(num_fields, fields, TAP_INVALID); /* did we have an endstate? */ if (endstate != TAP_INVALID) jtag_add_end_state(endstate); jtag_execute_queue(); - for (i = 0; i < argc / 2; i++) + for (i = 0; i < num_fields; i++) free(fields[i].out_value); free (fields); @@ -3457,4 +3562,12 @@ tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf, } #endif // _DEBUG_JTAG_IO_ +#ifndef HAVE_JTAG_MINIDRIVER_H +void jtag_alloc_in_value32(scan_field_t *field) +{ + field->in_value=(u8 *)cmd_queue_alloc(4); +} +#endif + + /*-------------------------------------------*/