X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fjtag.c;h=9ae4cff638c5747e895678cce0205717a6041681;hb=d14b6ca01593e52a296db7f9f8134aa2a9f5d14b;hp=de02eaf5d112d1f1c2855a2c86dfd5e5ff81ecc8;hpb=48838d51937d3a62e508f25b68a1dfa4e0384982;p=openocd.git diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index de02eaf5d1..9ae4cff638 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -37,8 +37,8 @@ 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); +static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, scan_field_t *in_fields, tap_state_t state), + int in_num_fields, scan_field_t *in_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 @@ -89,7 +89,7 @@ static struct jtag_callback_entry *jtag_callback_queue_tail = NULL; jtag_command_t *jtag_command_queue = NULL; -jtag_command_t **last_comand_pointer = &jtag_command_queue; +jtag_command_t **last_command_pointer = &jtag_command_queue; static jtag_tap_t *jtag_all_taps = NULL; enum reset_types jtag_reset_config = RESET_NONE; @@ -261,6 +261,7 @@ static int Jim_Command_flush_count(Jim_Interp *interp, int argc, Jim_Obj *const static int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); static int handle_verify_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +static int handle_tms_sequence_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); jtag_tap_t *jtag_AllTaps(void) { @@ -436,7 +437,7 @@ jtag_command_t** jtag_get_last_command_p(void) return &cmd->next;*/ - return last_comand_pointer; + return last_command_pointer; } @@ -450,7 +451,7 @@ void jtag_queue_command(jtag_command_t * cmd) (*last_cmd)->next = NULL; - last_comand_pointer = &((*last_cmd)->next); + last_command_pointer = &((*last_cmd)->next); } @@ -553,63 +554,73 @@ static void jtag_prelude(tap_state_t state) cmd_queue_cur_state = cmd_queue_end_state; } -void jtag_add_ir_scan_noverify(int num_fields, scan_field_t *fields, tap_state_t state) +void jtag_add_ir_scan_noverify(int in_num_fields, scan_field_t *in_fields, tap_state_t state) { int retval; jtag_prelude(state); - retval=interface_jtag_add_ir_scan(num_fields, fields, cmd_queue_end_state); + retval=interface_jtag_add_ir_scan(in_num_fields, in_fields, cmd_queue_end_state); if (retval!=ERROR_OK) jtag_error=retval; } -void jtag_add_ir_scan(int num_fields, scan_field_t *fields, tap_state_t state) +/** + * Generate an IR SCAN with a list of scan fields with one entry for each enabled TAP. + * + * If the input field list contains an instruction value for a TAP then that is used + * otherwise the TAP is set to bypass. + * + * TAPs for which no fields are passed are marked as bypassed for subsequent DR SCANs. + * + */ +void jtag_add_ir_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t state) { if (jtag_verify&&jtag_verify_capture_ir) { /* 8 x 32 bit id's is enough for all invoations */ - int j; - for (j = 0; j < num_fields; j++) + + for (int j = 0; j < in_num_fields; j++) { - fields[j].check_value=NULL; - fields[j].check_mask=NULL; + in_fields[j].check_value=NULL; + in_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. */ - fields[j].check_value=fields[j].tap->expected; - fields[j].check_mask=fields[j].tap->expected_mask; + in_fields[j].check_value=in_fields[j].tap->expected; + in_fields[j].check_mask=in_fields[j].tap->expected_mask; } - jtag_add_scan_check(jtag_add_ir_scan_noverify, num_fields, fields, state); + jtag_add_scan_check(jtag_add_ir_scan_noverify, in_num_fields, in_fields, state); } else { - jtag_add_ir_scan_noverify(num_fields, fields, state); + jtag_add_ir_scan_noverify(in_num_fields, in_fields, state); } } -int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, tap_state_t state) +/** + * see jtag_add_ir_scan() + * + */ +int MINIDRIVER(interface_jtag_add_ir_scan)(int in_num_fields, scan_field_t *in_fields, tap_state_t state) { jtag_tap_t *tap; - int j; - int x; int nth_tap; - int scan_size = 0; - /* allocate memory for a new list member */ - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - + int num_taps = jtag_NumEnabledTaps(); + + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t)); + jtag_queue_command(cmd); - - cmd->type = JTAG_SCAN; - /* allocate memory for ir scan command */ - cmd->cmd.scan = cmd_queue_alloc(sizeof(scan_command_t)); - cmd->cmd.scan->ir_scan = true; - x = jtag_NumEnabledTaps(); - cmd->cmd.scan->num_fields = x; /* one field per device */ - cmd->cmd.scan->fields = cmd_queue_alloc(x * sizeof(scan_field_t)); - cmd->cmd.scan->end_state = state; + cmd->type = JTAG_SCAN; + cmd->cmd.scan = scan; + + scan->ir_scan = true; + scan->num_fields = num_taps; /* one field per device */ + scan->fields = cmd_queue_alloc(num_taps * sizeof(scan_field_t)); + scan->end_state = state; nth_tap = -1; tap = NULL; @@ -623,21 +634,21 @@ int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, } nth_tap++; - assert(nth_tap < x ); + assert(nth_tap < num_taps); - scan_size = tap->ir_length; - cmd->cmd.scan->fields[nth_tap].tap = tap; - cmd->cmd.scan->fields[nth_tap].num_bits = scan_size; - cmd->cmd.scan->fields[nth_tap].in_value = NULL; /* do not collect input for tap's in bypass */ + size_t scan_size = tap->ir_length; + scan->fields[nth_tap].tap = tap; + scan->fields[nth_tap].num_bits = scan_size; + 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++) + for (int j = 0; j < in_num_fields; j++) { - if (tap == fields[j].tap) + if (tap == in_fields[j].tap) { found = 1; - cmd->cmd.scan->fields[nth_tap].in_value = fields[j].in_value; - cmd->cmd.scan->fields[nth_tap].out_value = buf_cpy(fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); + scan->fields[nth_tap].in_value = in_fields[j].in_value; + scan->fields[nth_tap].out_value = buf_cpy(in_fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); tap->bypass = 0; break; @@ -647,69 +658,70 @@ int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, if (!found) { /* if a tap isn't listed, set it to BYPASS */ - cmd->cmd.scan->fields[nth_tap].out_value = buf_set_ones(cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); + scan->fields[nth_tap].out_value = buf_set_ones(cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); tap->bypass = 1; } /* update device information */ - buf_cpy(cmd->cmd.scan->fields[nth_tap].out_value, tap->cur_instr, scan_size); + buf_cpy(scan->fields[nth_tap].out_value, tap->cur_instr, scan_size); } - assert(nth_tap == (x-1)); + + assert(nth_tap == (num_taps - 1)); return ERROR_OK; } -void jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, tap_state_t state) +/** + * Duplicate the scan fields passed into the function into an IR SCAN command + * + * This function assumes that the caller handles extra fields for bypassed TAPs + * + */ +void jtag_add_plain_ir_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t state) { int retval; jtag_prelude(state); - retval=interface_jtag_add_plain_ir_scan(num_fields, fields, cmd_queue_end_state); + retval=interface_jtag_add_plain_ir_scan(in_num_fields, in_fields, cmd_queue_end_state); if (retval!=ERROR_OK) jtag_error=retval; } -int MINIDRIVER(interface_jtag_add_plain_ir_scan)(int num_fields, scan_field_t *fields, tap_state_t state) + +/** + * see jtag_add_plain_ir_scan() + * + */ +int MINIDRIVER(interface_jtag_add_plain_ir_scan)(int in_num_fields, scan_field_t *in_fields, tap_state_t state) { - /* allocate memory for a new list member */ - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t)); jtag_queue_command(cmd); - cmd->type = JTAG_SCAN; + cmd->type = JTAG_SCAN; + cmd->cmd.scan = scan; - /* allocate memory for ir scan command */ - cmd->cmd.scan = cmd_queue_alloc(sizeof(scan_command_t)); - cmd->cmd.scan->ir_scan = true; - cmd->cmd.scan->num_fields = num_fields; - cmd->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t)); - cmd->cmd.scan->end_state = state; + scan->ir_scan = true; + scan->num_fields = in_num_fields; + scan->fields = cmd_queue_alloc(in_num_fields * sizeof(scan_field_t)); + scan->end_state = state; - for (int i = 0; i < num_fields; i++) + for (int i = 0; i < in_num_fields; i++) { - int num_bits = fields[i].num_bits; - int num_bytes = CEIL(fields[i].num_bits, 8); - cmd->cmd.scan->fields[i].tap = fields[i].tap; - cmd->cmd.scan->fields[i].num_bits = num_bits; - cmd->cmd.scan->fields[i].out_value = buf_cpy(fields[i].out_value, cmd_queue_alloc(num_bytes), num_bits); - cmd->cmd.scan->fields[i].in_value = fields[i].in_value; + int num_bits = in_fields[i].num_bits; + int num_bytes = CEIL(in_fields[i].num_bits, 8); + scan->fields[i].tap = in_fields[i].tap; + scan->fields[i].num_bits = num_bits; + scan->fields[i].out_value = buf_cpy(in_fields[i].out_value, cmd_queue_alloc(num_bytes), num_bits); + scan->fields[i].in_value = in_fields[i].in_value; } return ERROR_OK; } -void jtag_add_dr_scan(int num_fields, scan_field_t *fields, tap_state_t state) -{ - int retval; - - jtag_prelude(state); - - retval=interface_jtag_add_dr_scan(num_fields, fields, cmd_queue_end_state); - if (retval!=ERROR_OK) - jtag_error=retval; -} int jtag_check_value_inner(u8 *captured, u8 *in_check_value, u8 *in_check_mask, int num_bits); @@ -719,71 +731,99 @@ static int jtag_check_value_mask_callback(u8 *in, jtag_callback_data_t data1, jt 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) +static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, scan_field_t *in_fields, tap_state_t state), + int in_num_fields, scan_field_t *in_fields, tap_state_t state) { - for (int i=0; itype = JTAG_SCAN; + cmd->type = JTAG_SCAN; + cmd->cmd.scan = scan; - /* allocate memory for dr scan command */ - cmd->cmd.scan = cmd_queue_alloc(sizeof(scan_command_t)); - cmd->cmd.scan->ir_scan = false; - cmd->cmd.scan->num_fields = num_fields + bypass_devices; - cmd->cmd.scan->fields = cmd_queue_alloc((num_fields + bypass_devices) * sizeof(scan_field_t)); - cmd->cmd.scan->end_state = state; + scan->ir_scan = false; + scan->num_fields = in_num_fields + bypass_devices; + scan->fields = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t)); + scan->end_state = state; tap = NULL; nth_tap = -1; @@ -824,17 +862,17 @@ int MINIDRIVER(interface_jtag_add_dr_scan)(int num_fields, scan_field_t *fields, break; } int found = 0; - cmd->cmd.scan->fields[field_count].tap = tap; + scan->fields[field_count].tap = tap; - for (j = 0; j < num_fields; j++) + for (j = 0; j < in_num_fields; j++) { - if (tap == fields[j].tap) + if (tap == in_fields[j].tap) { found = 1; - scan_size = fields[j].num_bits; - cmd->cmd.scan->fields[field_count].num_bits = scan_size; - cmd->cmd.scan->fields[field_count].out_value = buf_cpy(fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); - cmd->cmd.scan->fields[field_count].in_value = fields[j].in_value; + size_t scan_size = in_fields[j].num_bits; + scan->fields[field_count].num_bits = scan_size; + scan->fields[field_count].out_value = buf_cpy(in_fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); + scan->fields[field_count].in_value = in_fields[j].in_value; field_count++; } } @@ -849,9 +887,9 @@ int MINIDRIVER(interface_jtag_add_dr_scan)(int num_fields, scan_field_t *fields, } #endif /* program the scan field to 1 bit length, and ignore it's value */ - cmd->cmd.scan->fields[field_count].num_bits = 1; - cmd->cmd.scan->fields[field_count].out_value = NULL; - cmd->cmd.scan->fields[field_count].in_value = NULL; + scan->fields[field_count].num_bits = 1; + scan->fields[field_count].out_value = NULL; + scan->fields[field_count].in_value = NULL; field_count++; } else @@ -868,19 +906,34 @@ int MINIDRIVER(interface_jtag_add_dr_scan)(int num_fields, scan_field_t *fields, } /* field_count represents the true number of fields setup*/ - (*last_cmd)->cmd.scan->num_fields = field_count; + scan->num_fields = field_count; return ERROR_OK; } + + +/** + * Generate a DR SCAN using the array of output values passed to the function + * + * This function assumes that the parameter target_tap specifies the one TAP + * that is not bypassed. All other TAPs must be bypassed and the function will + * generate a dummy 1bit field for them. + * + * For the target_tap a sequence of output-only fields will be generated where + * each field has the size num_bits and the field's values are taken from + * the array value. + * + * The bypass status of TAPs is set by jtag_add_ir_scan(). + * + */ void MINIDRIVER(interface_jtag_add_dr_out)(jtag_tap_t *target_tap, - int num_fields, + int in_num_fields, const int *num_bits, const u32 *value, tap_state_t end_state) { int nth_tap; int field_count = 0; - int scan_size; int bypass_devices = 0; jtag_tap_t *tap; @@ -898,19 +951,18 @@ void MINIDRIVER(interface_jtag_add_dr_out)(jtag_tap_t *target_tap, } } - /* allocate memory for a new list member */ - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t)); jtag_queue_command(cmd); - cmd->type = JTAG_SCAN; + cmd->type = JTAG_SCAN; + cmd->cmd.scan = scan; - /* allocate memory for dr scan command */ - cmd->cmd.scan = cmd_queue_alloc(sizeof(scan_command_t)); - cmd->cmd.scan->ir_scan = false; - cmd->cmd.scan->num_fields = num_fields + bypass_devices; - cmd->cmd.scan->fields = cmd_queue_alloc((num_fields + bypass_devices) * sizeof(scan_field_t)); - cmd->cmd.scan->end_state = end_state; + scan->ir_scan = false; + scan->num_fields = in_num_fields + bypass_devices; + scan->fields = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t)); + scan->end_state = end_state; tap = NULL; nth_tap = -1; @@ -920,11 +972,10 @@ void MINIDRIVER(interface_jtag_add_dr_out)(jtag_tap_t *target_tap, break; } nth_tap++; - cmd->cmd.scan->fields[field_count].tap = tap; + scan->fields[field_count].tap = tap; if (tap == target_tap) { - int j; #ifdef _DEBUG_JTAG_IO_ /* if a device is listed, the BYPASS register must not be selected */ if (tap->bypass) @@ -933,14 +984,14 @@ void MINIDRIVER(interface_jtag_add_dr_out)(jtag_tap_t *target_tap, exit(-1); } #endif - for (j = 0; j < num_fields; j++) + for (int j = 0; j < in_num_fields; j++) { u8 out_value[4]; - scan_size = num_bits[j]; + size_t scan_size = num_bits[j]; buf_set_u32(out_value, 0, scan_size, value[j]); - cmd->cmd.scan->fields[field_count].num_bits = scan_size; - cmd->cmd.scan->fields[field_count].out_value = buf_cpy(out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); - cmd->cmd.scan->fields[field_count].in_value = NULL; + scan->fields[field_count].num_bits = scan_size; + scan->fields[field_count].out_value = buf_cpy(out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); + scan->fields[field_count].in_value = NULL; field_count++; } } else @@ -954,54 +1005,66 @@ void MINIDRIVER(interface_jtag_add_dr_out)(jtag_tap_t *target_tap, } #endif /* program the scan field to 1 bit length, and ignore it's value */ - cmd->cmd.scan->fields[field_count].num_bits = 1; - cmd->cmd.scan->fields[field_count].out_value = NULL; - cmd->cmd.scan->fields[field_count].in_value = NULL; + scan->fields[field_count].num_bits = 1; + scan->fields[field_count].out_value = NULL; + scan->fields[field_count].in_value = NULL; field_count++; } } } -void jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, tap_state_t state) + +/** + * Duplicate the scan fields passed into the function into a DR SCAN command + * + * This function assumes that the caller handles extra fields for bypassed TAPs + * + */ +void jtag_add_plain_dr_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t state) { int retval; jtag_prelude(state); - retval=interface_jtag_add_plain_dr_scan(num_fields, fields, cmd_queue_end_state); + retval=interface_jtag_add_plain_dr_scan(in_num_fields, in_fields, cmd_queue_end_state); if (retval!=ERROR_OK) jtag_error=retval; } -int MINIDRIVER(interface_jtag_add_plain_dr_scan)(int num_fields, scan_field_t *fields, tap_state_t state) + +/** + * see jtag_add_plain_dr_scan() + * + */ +int MINIDRIVER(interface_jtag_add_plain_dr_scan)(int in_num_fields, scan_field_t *in_fields, tap_state_t state) { - /* allocate memory for a new list member */ - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + scan_command_t * scan = cmd_queue_alloc(sizeof(scan_command_t)); jtag_queue_command(cmd); - cmd->type = JTAG_SCAN; + cmd->type = JTAG_SCAN; + cmd->cmd.scan = scan; - /* allocate memory for scan command */ - cmd->cmd.scan = cmd_queue_alloc(sizeof(scan_command_t)); - cmd->cmd.scan->ir_scan = false; - cmd->cmd.scan->num_fields = num_fields; - cmd->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t)); - cmd->cmd.scan->end_state = state; + scan->ir_scan = false; + scan->num_fields = in_num_fields; + scan->fields = cmd_queue_alloc(in_num_fields * sizeof(scan_field_t)); + scan->end_state = state; - for (int i = 0; i < num_fields; i++) + for (int i = 0; i < in_num_fields; i++) { - int num_bits = fields[i].num_bits; - int num_bytes = CEIL(fields[i].num_bits, 8); - cmd->cmd.scan->fields[i].tap = fields[i].tap; - cmd->cmd.scan->fields[i].num_bits = num_bits; - cmd->cmd.scan->fields[i].out_value = buf_cpy(fields[i].out_value, cmd_queue_alloc(num_bytes), num_bits); - cmd->cmd.scan->fields[i].in_value = fields[i].in_value; + int num_bits = in_fields[i].num_bits; + int num_bytes = CEIL(in_fields[i].num_bits, 8); + scan->fields[i].tap = in_fields[i].tap; + scan->fields[i].num_bits = num_bits; + scan->fields[i].out_value = buf_cpy(in_fields[i].out_value, cmd_queue_alloc(num_bytes), num_bits); + scan->fields[i].in_value = in_fields[i].in_value; } return ERROR_OK; } + void jtag_add_tlr(void) { jtag_prelude(TAP_RESET); @@ -1015,16 +1078,16 @@ void jtag_add_tlr(void) int MINIDRIVER(interface_jtag_add_tlr)(void) { tap_state_t state = TAP_RESET; - jtag_command_t **last_cmd = jtag_get_last_command_p(); /* allocate memory for a new list member */ - *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - last_comand_pointer = &((*last_cmd)->next); - (*last_cmd)->next = NULL; - (*last_cmd)->type = JTAG_STATEMOVE; + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + + jtag_queue_command(cmd); + + cmd->type = JTAG_STATEMOVE; - (*last_cmd)->cmd.statemove = cmd_queue_alloc(sizeof(statemove_command_t)); - (*last_cmd)->cmd.statemove->end_state = state; + cmd->cmd.statemove = cmd_queue_alloc(sizeof(statemove_command_t)); + cmd->cmd.statemove->end_state = state; return ERROR_OK; } @@ -1069,38 +1132,35 @@ void jtag_add_pathmove(int num_states, tap_state_t *path) int MINIDRIVER(interface_jtag_add_pathmove)(int num_states, tap_state_t *path) { - jtag_command_t **last_cmd = jtag_get_last_command_p(); - int i; - /* allocate memory for a new list member */ - *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - last_comand_pointer = &((*last_cmd)->next); - (*last_cmd)->next = NULL; - (*last_cmd)->type = JTAG_PATHMOVE; + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + + jtag_queue_command(cmd); + + cmd->type = JTAG_PATHMOVE; - (*last_cmd)->cmd.pathmove = cmd_queue_alloc(sizeof(pathmove_command_t)); - (*last_cmd)->cmd.pathmove->num_states = num_states; - (*last_cmd)->cmd.pathmove->path = cmd_queue_alloc(sizeof(tap_state_t) * num_states); + cmd->cmd.pathmove = cmd_queue_alloc(sizeof(pathmove_command_t)); + cmd->cmd.pathmove->num_states = num_states; + cmd->cmd.pathmove->path = cmd_queue_alloc(sizeof(tap_state_t) * num_states); - for (i = 0; i < num_states; i++) - (*last_cmd)->cmd.pathmove->path[i] = path[i]; + for (int i = 0; i < num_states; i++) + cmd->cmd.pathmove->path[i] = path[i]; return ERROR_OK; } int MINIDRIVER(interface_jtag_add_runtest)(int num_cycles, tap_state_t state) { - jtag_command_t **last_cmd = jtag_get_last_command_p(); - /* allocate memory for a new list member */ - *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - (*last_cmd)->next = NULL; - last_comand_pointer = &((*last_cmd)->next); - (*last_cmd)->type = JTAG_RUNTEST; + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + + jtag_queue_command(cmd); + + cmd->type = JTAG_RUNTEST; - (*last_cmd)->cmd.runtest = cmd_queue_alloc(sizeof(runtest_command_t)); - (*last_cmd)->cmd.runtest->num_cycles = num_cycles; - (*last_cmd)->cmd.runtest->end_state = state; + cmd->cmd.runtest = cmd_queue_alloc(sizeof(runtest_command_t)); + cmd->cmd.runtest->num_cycles = num_cycles; + cmd->cmd.runtest->end_state = state; return ERROR_OK; } @@ -1120,16 +1180,16 @@ void jtag_add_runtest(int num_cycles, tap_state_t state) int MINIDRIVER(interface_jtag_add_clocks)( int num_cycles ) { - jtag_command_t **last_cmd = jtag_get_last_command_p(); - /* allocate memory for a new list member */ - *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - (*last_cmd)->next = NULL; - last_comand_pointer = &((*last_cmd)->next); - (*last_cmd)->type = JTAG_STABLECLOCKS; + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + + jtag_queue_command(cmd); + + cmd->type = JTAG_STABLECLOCKS; + + cmd->cmd.stableclocks = cmd_queue_alloc(sizeof(stableclocks_command_t)); + cmd->cmd.stableclocks->num_cycles = num_cycles; - (*last_cmd)->cmd.stableclocks = cmd_queue_alloc(sizeof(stableclocks_command_t)); - (*last_cmd)->cmd.stableclocks->num_cycles = num_cycles; return ERROR_OK; } @@ -1260,17 +1320,16 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst) int MINIDRIVER(interface_jtag_add_reset)(int req_trst, int req_srst) { - jtag_command_t **last_cmd = jtag_get_last_command_p(); - /* allocate memory for a new list member */ - *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - (*last_cmd)->next = NULL; - last_comand_pointer = &((*last_cmd)->next); - (*last_cmd)->type = JTAG_RESET; + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - (*last_cmd)->cmd.reset = cmd_queue_alloc(sizeof(reset_command_t)); - (*last_cmd)->cmd.reset->trst = req_trst; - (*last_cmd)->cmd.reset->srst = req_srst; + jtag_queue_command(cmd); + + cmd->type = JTAG_RESET; + + cmd->cmd.reset = cmd_queue_alloc(sizeof(reset_command_t)); + cmd->cmd.reset->trst = req_trst; + cmd->cmd.reset->srst = req_srst; return ERROR_OK; } @@ -1286,16 +1345,15 @@ void jtag_add_end_state(tap_state_t state) int MINIDRIVER(interface_jtag_add_sleep)(u32 us) { - jtag_command_t **last_cmd = jtag_get_last_command_p(); - /* allocate memory for a new list member */ - *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - (*last_cmd)->next = NULL; - last_comand_pointer = &((*last_cmd)->next); - (*last_cmd)->type = JTAG_SLEEP; + jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); + + jtag_queue_command(cmd); - (*last_cmd)->cmd.sleep = cmd_queue_alloc(sizeof(sleep_command_t)); - (*last_cmd)->cmd.sleep->us = us; + cmd->type = JTAG_SLEEP; + + cmd->cmd.sleep = cmd_queue_alloc(sizeof(sleep_command_t)); + cmd->cmd.sleep->us = us; return ERROR_OK; } @@ -1562,7 +1620,7 @@ int interface_jtag_execute_queue(void) jtag_callback_queue_tail = NULL; jtag_command_queue = NULL; - last_comand_pointer = &jtag_command_queue; + last_command_pointer = &jtag_command_queue; return retval; } @@ -2315,6 +2373,8 @@ int jtag_register_commands(struct command_context_s *cmd_ctx) COMMAND_ANY, "verify value captured during Capture-IR "); register_command(cmd_ctx, NULL, "verify_jtag", handle_verify_jtag_command, COMMAND_ANY, "verify value capture "); + register_command(cmd_ctx, NULL, "tms_sequence", handle_tms_sequence_command, + COMMAND_ANY, "choose short(default) or long tms_sequence "); return ERROR_OK; } @@ -3134,6 +3194,7 @@ static int handle_verify_jtag_command(struct command_context_s *cmd_ctx, char *c return ERROR_OK; } + int jtag_power_dropout(int *dropout) { return jtag->power_dropout(dropout); @@ -3253,19 +3314,12 @@ int tap_move_ndx( tap_state_t astate ) * * DRSHIFT->DRSHIFT and IRSHIFT->IRSHIFT have to be caught in interface specific code */ -static struct +struct tms_sequences { u8 bits; u8 bit_count; -} tms_seqs[6][6] = /* [from_state_ndx][to_state_ndx] */ -{ - /* value clocked to TMS to move from one of six stable states to another. - * N.B. OOCD clocks TMS from LSB first, so read these right-to-left. - * N.B. These values are tightly bound to the table in tap_get_tms_path_len(). - * N.B. Reset only needs to be 0b11111, but in JLink an even byte of 1's is more stable. - * These extra ones cause no TAP state problem, because we go into reset and stay in reset. - */ +}; /* * These macros allow us to specify TMS state transitions by bits rather than hex bytes. @@ -3285,7 +3339,31 @@ static struct #define B8(bits,count) { ((u8)B8__(HEX__(bits))), (count) } -#if 0 && ((BUILD_FT2232_FTD2XX==1) || (BUILD_FT2232_LIBFTDI==1) || (BUILD_JLINK==1)) +static const struct tms_sequences old_tms_seqs[6][6] = /* [from_state_ndx][to_state_ndx] */ +{ + /* value clocked to TMS to move from one of six stable states to another. + * N.B. OOCD clocks TMS from LSB first, so read these right-to-left. + * N.B. These values are tightly bound to the table in tap_get_tms_path_len(). + * N.B. Reset only needs to be 0b11111, but in JLink an even byte of 1's is more stable. + * These extra ones cause no TAP state problem, because we go into reset and stay in reset. + */ + + + + /* to state: */ + /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ + { B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */ + { B8(1111111,7), B8(0000000,7), B8(0100101,7), B8(0000101,7), B8(0101011,7), B8(0001011,7) }, /* IDLE */ + { B8(1111111,7), B8(0110001,7), B8(0000000,7), B8(0000001,7), B8(0001111,7), B8(0101111,7) }, /* DRSHIFT */ + { B8(1111111,7), B8(0110000,7), B8(0100000,7), B8(0010111,7), B8(0011110,7), B8(0101111,7) }, /* DRPAUSE */ + { B8(1111111,7), B8(0110001,7), B8(0000111,7), B8(0010111,7), B8(0000000,7), B8(0000001,7) }, /* IRSHIFT */ + { B8(1111111,7), B8(0110000,7), B8(0011100,7), B8(0010111,7), B8(0011110,7), B8(0101111,7) }, /* IRPAUSE */ +}; + + + +static const struct tms_sequences short_tms_seqs[6][6] = /* [from_state_ndx][to_state_ndx] */ +{ /* this is the table submitted by Jeff Williams on 3/30/2009 with this comment: OK, I added Peter's version of the state table, and it works OK for @@ -3312,47 +3390,28 @@ static struct /* to state: */ /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ - { B8(1111111,7), B8(0000000,7), B8(00101,5), B8(01010,5), B8(001101,6), B8(010110,6) }, /* RESET */ + { B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */ { B8(1111111,7), B8(0000000,7), B8(001,3), B8(0101,4), B8(0011,4), B8(01011,5) }, /* IDLE */ - { B8(1111111,7), B8(011,3), B8(00111,5), B8(01,2), B8(001111,6), B8(0101111,7) }, /* DRSHIFT */ - { B8(1111111,7), B8(011,3), B8(01,2), B8(0,1), B8(001111,6), B8(0101111,7) }, /* DRPAUSE */ + { B8(1111111,7), B8(011,3), B8(00111,5), B8(01,2), B8(001111,6), B8(0101111,7) }, /* DRSHIFT */ + { B8(1111111,7), B8(011,3), B8(01,2), B8(0,1), B8(001111,6), B8(0101111,7) }, /* DRPAUSE */ { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(001111,6), B8(01,2) }, /* IRSHIFT */ { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(01,2), B8(0,1) } /* IRPAUSE */ -#else /* this is the old table, converted from hex and with the bit_count set to 7 for each combo, like before */ - - /* to state: */ - /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ - { B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */ - { B8(1111111,7), B8(0000000,7), B8(0100101,7), B8(0000101,7), B8(0101011,7), B8(0001011,7) }, /* IDLE */ - { B8(1111111,7), B8(0110001,7), B8(0000000,7), B8(0000001,7), B8(0001111,7), B8(0101111,7) }, /* DRSHIFT */ - { B8(1111111,7), B8(0110000,7), B8(0100000,7), B8(0010111,7), B8(0011110,7), B8(0101111,7) }, /* DRPAUSE */ - { B8(1111111,7), B8(0110001,7), B8(0000111,7), B8(0010111,7), B8(0000000,7), B8(0000001,7) }, /* IRSHIFT */ - { B8(1111111,7), B8(0110000,7), B8(0011100,7), B8(0010111,7), B8(0011110,7), B8(0101111,7) }, /* IRPAUSE */ - -#endif - -#if 0 /* keeping old hex stuff for awhile, for reference */ - /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ - { 0x7f, 0x00, 0x17, 0x0a, 0x1b, 0x16 }, /* RESET */ - { 0x7f, 0x00, 0x25, 0x05, 0x2b, 0x0b }, /* IDLE */ - { 0x7f, 0x31, 0x00, 0x01, 0x0f, 0x2f }, /* DRSHIFT */ - { 0x7f, 0x30, 0x20, 0x17, 0x1e, 0x2f }, /* DRPAUSE */ - { 0x7f, 0x31, 0x07, 0x17, 0x00, 0x01 }, /* IRSHIFT */ - { 0x7f, 0x30, 0x1c, 0x17, 0x20, 0x2f } /* IRPAUSE */ -#endif }; +typedef const struct tms_sequences tms_table[6][6]; + +static tms_table *tms_seqs=&short_tms_seqs; int tap_get_tms_path( tap_state_t from, tap_state_t to ) { - return tms_seqs[tap_move_ndx(from)][tap_move_ndx(to)].bits; + return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bits; } int tap_get_tms_path_len( tap_state_t from, tap_state_t to ) { - return tms_seqs[tap_move_ndx(from)][tap_move_ndx(to)].bit_count; + return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bit_count; } @@ -3612,5 +3671,29 @@ void jtag_alloc_in_value32(scan_field_t *field) } #endif +static int handle_tms_sequence_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +{ + if (argc == 1) + { + if (strcmp(args[0], "short") == 0) + { + tms_seqs=&short_tms_seqs; + } + else if (strcmp(args[0], "long") == 0) + { + tms_seqs=&old_tms_seqs; + } else + { + return ERROR_COMMAND_SYNTAX_ERROR; + } + } else if (argc != 0) + { + return ERROR_COMMAND_SYNTAX_ERROR; + } + + command_print(cmd_ctx, "tms sequence is %s", (tms_seqs==&short_tms_seqs) ? "short": "long"); + + return ERROR_OK; +} /*-------------------------------------------*/