static int osbdm_add_pathmove( struct queue *queue, tap_state_t *path, int num_states) { assert(num_states <= 32); struct sequence *next = queue_add_tail(queue, num_states); if (!next) { LOG_ERROR("BUG: can't allocate bit sequence"); return ERROR_FAIL; } uint32_t tms = 0; for (int i = 0; i < num_states; i++) { if (tap_state_transition(tap_get_state(), 1) == path[i]) { tms |= (1 << i); } else if (tap_state_transition(tap_get_state(), 0) == path[i]) { tms &= ~(1 << i); /* This line not so needed */ } else { LOG_ERROR("BUG: %s -> %s isn't a valid TAP state transition", tap_state_name(tap_get_state()), tap_state_name(path[i])); return ERROR_FAIL; } tap_set_state(path[i]); } buf_set_u32(next->tms, 0, num_states, tms); tap_set_end_state(tap_get_state()); return ERROR_OK; }
/** * Function move_to_state * moves the TAP controller from the current state to a * \a goal_state through a path given by tap_get_tms_path(). State transition * logging is performed by delegation to clock_tms(). * * @param goal_state is the destination state for the move. */ static void move_to_state(tap_state_t goal_state) { tap_state_t start_state = tap_get_state(); /* goal_state is 1/2 of a tuple/pair of states which allow convenient lookup of the required TMS pattern to move to this state from the start state. */ /* do the 2 lookups */ int tms_bits = tap_get_tms_path(start_state, goal_state); int tms_count = tap_get_tms_path_len(start_state, goal_state); DEBUG_JTAG_IO("start=%s goal=%s", tap_state_name(start_state), tap_state_name(goal_state)); /* Track state transitions step by step */ for (int i = 0; i < tms_count; i++) tap_set_state(tap_state_transition(tap_get_state(), (tms_bits >> i) & 1)); mpsse_clock_tms_cs_out(mpsse_ctx, (uint8_t *)&tms_bits, 0, tms_count, false, JTAG_MODE); }
static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size, struct scan_command *command) { tap_state_t saved_end_state; saved_end_state = tap_get_end_state(); /* Move to appropriate scan state */ vsllink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT); if (tap_get_state() != tap_get_end_state()) vsllink_state_move(); vsllink_end_state(saved_end_state); /* Scan */ vsllink_tap_append_scan(scan_size, buffer, command); /* Goto Pause and record position to insert tms:0 */ vsllink_tap_append_step(0, 0); vsllink_tms_offset = tap_length; tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE); if (tap_get_state() != tap_get_end_state()) vsllink_state_move(); }
static void ftdi_execute_runtest(struct jtag_command *cmd) { int i; uint8_t zero = 0; DEBUG_JTAG_IO("runtest %i cycles, end in %s", cmd->cmd.runtest->num_cycles, tap_state_name(cmd->cmd.runtest->end_state)); if (tap_get_state() != TAP_IDLE) move_to_state(TAP_IDLE); /* TODO: Reuse ftdi_execute_stableclocks */ i = cmd->cmd.runtest->num_cycles; while (i > 0) { /* there are no state transitions in this code, so omit state tracking */ unsigned this_len = i > 7 ? 7 : i; mpsse_clock_tms_cs_out(mpsse_ctx, &zero, 0, this_len, false, JTAG_MODE); i -= this_len; } ftdi_end_state(cmd->cmd.runtest->end_state); if (tap_get_state() != tap_get_end_state()) move_to_state(tap_get_end_state()); DEBUG_JTAG_IO("runtest: %i, end in %s", cmd->cmd.runtest->num_cycles, tap_state_name(tap_get_end_state())); }
static int ftdi_execute_stableclocks(struct jtag_command *cmd) { int retval = ERROR_OK; /* this is only allowed while in a stable state. A check for a stable * state was done in jtag_add_clocks() */ int num_cycles = cmd->cmd.stableclocks->num_cycles; /* 7 bits of either ones or zeros. */ uint8_t tms = tap_get_state() == TAP_RESET ? 0x7f : 0x00; /* TODO: Use mpsse_clock_data with in=out=0 for this, if TMS can be set to * the correct level and remain there during the scan */ while (num_cycles > 0 && retval == ERROR_OK) { /* there are no state transitions in this code, so omit state tracking */ unsigned this_len = num_cycles > 7 ? 7 : num_cycles; retval = mpsse_clock_tms_cs_out(mpsse_ctx, &tms, 0, this_len, false, JTAG_MODE); num_cycles -= this_len; } DEBUG_JTAG_IO("clocks %i while in %s", cmd->cmd.stableclocks->num_cycles, tap_state_name(tap_get_state())); return retval; }
static void amt_jtagaccel_runtest(int num_cycles) { int i = 0; uint8_t aw_scan_tms_5; uint8_t aw_scan_tms_1to4; tap_state_t saved_end_state = tap_get_end_state(); /* only do a state_move when we're not already in IDLE */ if (tap_get_state() != TAP_IDLE) { amt_jtagaccel_end_state(TAP_IDLE); amt_jtagaccel_state_move(); } while (num_cycles - i >= 5) { aw_scan_tms_5 = 0x40; AMT_AW(aw_scan_tms_5); i += 5; } if (num_cycles - i > 0) { aw_scan_tms_1to4 = 0x80 | ((num_cycles - i - 1) & 0x3) << 4; AMT_AW(aw_scan_tms_1to4); } amt_jtagaccel_end_state(saved_end_state); if (tap_get_state() != tap_get_end_state()) amt_jtagaccel_state_move(); }
static int ftdi_execute_pathmove(struct jtag_command *cmd) { int retval = ERROR_OK; tap_state_t *path = cmd->cmd.pathmove->path; int num_states = cmd->cmd.pathmove->num_states; DEBUG_JTAG_IO("pathmove: %i states, current: %s end: %s", num_states, tap_state_name(tap_get_state()), tap_state_name(path[num_states-1])); int state_count = 0; unsigned bit_count = 0; uint8_t tms_byte = 0; DEBUG_JTAG_IO("-"); /* this loop verifies that the path is legal and logs each state in the path */ while (num_states-- && retval == ERROR_OK) { /* either TMS=0 or TMS=1 must work ... */ if (tap_state_transition(tap_get_state(), false) == path[state_count]) buf_set_u32(&tms_byte, bit_count++, 1, 0x0); else if (tap_state_transition(tap_get_state(), true) == path[state_count]) { buf_set_u32(&tms_byte, bit_count++, 1, 0x1); /* ... or else the caller goofed BADLY */ } else { LOG_ERROR("BUG: %s -> %s isn't a valid " "TAP state transition", tap_state_name(tap_get_state()), tap_state_name(path[state_count])); exit(-1); } tap_set_state(path[state_count]); state_count++; if (bit_count == 7 || num_states == 0) { retval = mpsse_clock_tms_cs_out(mpsse_ctx, &tms_byte, 0, bit_count, false, JTAG_MODE); bit_count = 0; } } tap_set_end_state(tap_get_state()); return retval; }
/* Goes to the end state. */ static void jlink_state_move(void) { uint8_t tms_scan; uint8_t tms_scan_bits; tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state()); tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); jlink_clock_data(NULL, 0, &tms_scan, 0, NULL, 0, tms_scan_bits); tap_set_state(tap_get_end_state()); }
/* Goes to the end state. */ static void vsllink_state_move(void) { int i; uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state()); uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); for (i = 0; i < tms_scan_bits; i++) vsllink_tap_append_step((tms_scan >> i) & 1, 0); tap_set_state(tap_get_end_state()); }
static void jtag_vpi_state_move(tap_state_t state) { uint8_t tms_scan; int tms_len; LOG_DEBUG("jtag_vpi_state_move: (from %s to %s)", tap_state_name(tap_get_state()), tap_state_name(state)); if (tap_get_state() == state) return; tms_scan = tap_get_tms_path(tap_get_state(), state); tms_len = tap_get_tms_path_len(tap_get_state(), state); jtag_vpi_tms_seq(&tms_scan, tms_len); tap_set_state(state); }
static void amt_jtagaccel_state_move(void) { uint8_t aw_scan_tms_5; uint8_t tms_scan[2]; tap_state_t cur_state = tap_get_state(); tap_state_t end_state = tap_get_end_state(); tms_scan[0] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][0]; tms_scan[1] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][1]; aw_scan_tms_5 = 0x40 | (tms_scan[0] & 0x1f); AMT_AW(aw_scan_tms_5); int jtag_speed = 0; int retval = jtag_get_speed(&jtag_speed); assert(retval == ERROR_OK); if (jtag_speed > 3 || rtck_enabled) amt_wait_scan_busy(); if (tms_scan[0] & 0x80) { aw_scan_tms_5 = 0x40 | (tms_scan[1] & 0x1f); AMT_AW(aw_scan_tms_5); if (jtag_speed > 3 || rtck_enabled) amt_wait_scan_busy(); } tap_set_state(end_state); }
static int usbp5_state_move(tap_state_t state) { if (tap_get_state() == state) return ERROR_OK; uint8_t tms_scan = tap_get_tms_path(tap_get_state(), state); int tms_len = tap_get_tms_path_len(tap_get_state(), state); int retval = usbp5_tms_seq(&tms_scan, tms_len); if (retval != ERROR_OK) return retval; tap_set_state(state); return ERROR_OK; }
void amt_jtagaccel_state_move(void) { u8 aw_scan_tms_5; u8 tms_scan[2]; tap_state_t cur_state = tap_get_state(); tap_state_t end_state = tap_get_end_state(); tms_scan[0] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][0]; tms_scan[1] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][1]; aw_scan_tms_5 = 0x40 | (tms_scan[0] & 0x1f); AMT_AW(aw_scan_tms_5); if (jtag_speed > 3 || rtck_enabled) amt_wait_scan_busy(); if (tms_scan[0] & 0x80) { aw_scan_tms_5 = 0x40 | (tms_scan[1] & 0x1f); AMT_AW(aw_scan_tms_5); if (jtag_speed > 3 || rtck_enabled) amt_wait_scan_busy(); } tap_set_state(end_state); }
/** * jtag_vpi_path_move - ask a TMS sequence transition to JTAG * @cmd: path transition * * Write a serie of TMS transitions, where each transition consists in : * - writing out TCK=0, TMS=<new_state>, TDI=<???> * - writing out TCK=1, TMS=<new_state>, TDI=<???> which triggers the transition * The function ensures that at the end of the sequence, the clock (TCK) is put * low. */ static void jtag_vpi_path_move(struct pathmove_command *cmd) { int i; const uint8_t tms_0 = 0; const uint8_t tms_1 = 1; LOG_DEBUG("jtag_vpi_path_move: (num_states=%d, last_state=%d)", cmd->num_states, cmd->path[cmd->num_states - 1]); for (i = 0; i < cmd->num_states; i++) { if (tap_state_transition(tap_get_state(), false) == cmd->path[i]) jtag_vpi_tms_seq(&tms_0, 1); if (tap_state_transition(tap_get_state(), true) == cmd->path[i]) jtag_vpi_tms_seq(&tms_1, 1); tap_set_state(cmd->path[i]); } }
static void jlink_stableclocks(int num_cycles) { int i; uint8_t tms = tap_get_state() == TAP_RESET; /* Execute num_cycles. */ for (i = 0; i < num_cycles; i++) jlink_clock_data(NULL, 0, &tms, 0, NULL, 0, 1); }
static void vsllink_path_move(int num_states, tap_state_t *path) { for (int i = 0; i < num_states; i++) { if (path[i] == tap_state_transition(tap_get_state(), false)) vsllink_tap_append_step(0, 0); else if (path[i] == tap_state_transition(tap_get_state(), true)) vsllink_tap_append_step(1, 0); else { LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(tap_get_state()), tap_state_name(path[i])); exit(-1); } tap_set_state(path[i]); } tap_set_end_state(tap_get_state()); }
static void jlink_runtest(int num_cycles) { tap_state_t saved_end_state = tap_get_end_state(); /* Only do a state_move when we're not already in IDLE. */ if (tap_get_state() != TAP_IDLE) { jlink_end_state(TAP_IDLE); jlink_state_move(); /* num_cycles--; */ } jlink_stableclocks(num_cycles); /* Finish in end_state. */ jlink_end_state(saved_end_state); if (tap_get_state() != tap_get_end_state()) jlink_state_move(); }
static void ftdi_execute_sleep(struct jtag_command *cmd) { DEBUG_JTAG_IO("sleep %" PRIi32, cmd->cmd.sleep->us); mpsse_flush(mpsse_ctx); jtag_sleep(cmd->cmd.sleep->us); DEBUG_JTAG_IO("sleep %" PRIi32 " usec while in %s", cmd->cmd.sleep->us, tap_state_name(tap_get_state())); }
static void ftdi_execute_statemove(struct jtag_command *cmd) { DEBUG_JTAG_IO("statemove end in %s", tap_state_name(cmd->cmd.statemove->end_state)); ftdi_end_state(cmd->cmd.statemove->end_state); /* shortest-path move to desired end state */ if (tap_get_state() != tap_get_end_state() || tap_get_end_state() == TAP_RESET) move_to_state(tap_get_end_state()); }
static void jlink_path_move(int num_states, tap_state_t *path) { int i; uint8_t tms = 0xff; for (i = 0; i < num_states; i++) { if (path[i] == tap_state_transition(tap_get_state(), false)) jlink_clock_data(NULL, 0, NULL, 0, NULL, 0, 1); else if (path[i] == tap_state_transition(tap_get_state(), true)) jlink_clock_data(NULL, 0, &tms, 0, NULL, 0, 1); else { LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition.", tap_state_name(tap_get_state()), tap_state_name(path[i])); exit(-1); } tap_set_state(path[i]); } tap_set_end_state(tap_get_state()); }
static int ftdi_execute_sleep(struct jtag_command *cmd) { int retval = ERROR_OK; DEBUG_JTAG_IO("sleep %" PRIi32, cmd->cmd.sleep->us); retval = mpsse_flush(mpsse_ctx); jtag_sleep(cmd->cmd.sleep->us); DEBUG_JTAG_IO("sleep %" PRIi32 " usec while in %s", cmd->cmd.sleep->us, tap_state_name(tap_get_state())); return retval; }
static int osbdm_add_statemove( struct queue *queue, tap_state_t new_state, int skip_first) { int len = 0; int tms = 0; tap_set_end_state(new_state); if (tap_get_end_state() == TAP_RESET) { /* Ignore current state */ tms = 0xff; len = 5; } else if (tap_get_state() != tap_get_end_state()) { tms = tap_get_tms_path(tap_get_state(), new_state); len = tap_get_tms_path_len(tap_get_state(), new_state); } if (len && skip_first) { len--; tms >>= 1; }
static int usbp5_path_move(struct pathmove_command *cmd) { uint8_t trans[DIV_ROUND_UP(cmd->num_states, 8)]; memset(trans, 0, DIV_ROUND_UP(cmd->num_states, 8)); for (int i = 0; i < cmd->num_states; i++) { if (tap_state_transition(tap_get_state(), true) == cmd->path[i]) buf_set_u32(trans, i, 1, 1); tap_set_state(cmd->path[i]); } return usbp5_tms_seq(trans, cmd->num_states); }
static void vsllink_runtest(int num_cycles) { tap_state_t saved_end_state = tap_get_end_state(); if (tap_get_state() != TAP_IDLE) { /* enter IDLE state */ vsllink_end_state(TAP_IDLE); vsllink_state_move(); } vsllink_stableclocks(num_cycles, 0); /* post-process */ /* set end_state */ vsllink_end_state(saved_end_state); if (tap_get_end_state() != tap_get_end_state()) vsllink_state_move(); }
/** * Moves to the requied jtag state in 2 wire mode. * @param goal_state contains the destination JTAG state, */ static void cjtag_move_to_state(tap_state_t goal_state) { tap_state_t start_state = tap_get_state(); switch (start_state) { case TAP_IDLE: if (goal_state == TAP_DRSHIFT) cjtag_transitions("100",TDI_0); else if (goal_state == TAP_IRSHIFT) cjtag_transitions("1100",TDI_0); break; case TAP_DRPAUSE: if (goal_state == TAP_DRSHIFT) cjtag_transitions("10",TDI_0); else if (goal_state == TAP_IRSHIFT) cjtag_transitions("111100",TDI_0); break; case TAP_IRPAUSE: if (goal_state == TAP_DRSHIFT) cjtag_transitions("11100",TDI_0); else if (goal_state == TAP_IRSHIFT) cjtag_transitions("10",TDI_0); break; case TAP_IREXIT1: if (goal_state == TAP_IRPAUSE) cjtag_transitions("0",TDI_0); else if (goal_state == TAP_IDLE) cjtag_transitions("10",TDI_0); break; case TAP_DREXIT1: if (goal_state == TAP_DRPAUSE) cjtag_transitions("0",TDI_0); else if (goal_state == TAP_IDLE) cjtag_transitions("10",TDI_0); break; default: break; } tap_set_state(goal_state); }
static void amt_jtagaccel_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size) { int bits_left = scan_size; int bit_count = 0; tap_state_t saved_end_state = tap_get_end_state(); uint8_t aw_tdi_option; uint8_t dw_tdi_scan; uint8_t dr_tdo; uint8_t aw_tms_scan; uint8_t tms_scan[2]; int jtag_speed_var; int retval = jtag_get_speed(&jtag_speed_var); assert(retval == ERROR_OK); if (ir_scan) amt_jtagaccel_end_state(TAP_IRSHIFT); else amt_jtagaccel_end_state(TAP_DRSHIFT); /* Only move if we're not already there */ if (tap_get_state() != tap_get_end_state()) amt_jtagaccel_state_move(); amt_jtagaccel_end_state(saved_end_state); /* handle unaligned bits at the beginning */ if ((scan_size - 1) % 8) { aw_tdi_option = 0x30 | (((scan_size - 1) % 8) - 1); AMT_AW(aw_tdi_option); dw_tdi_scan = buf_get_u32(buffer, bit_count, (scan_size - 1) % 8) & 0xff; AMT_DW(dw_tdi_scan); if (jtag_speed_var > 3 || rtck_enabled) amt_wait_scan_busy(); if ((type == SCAN_IN) || (type == SCAN_IO)) { AMT_DR(dr_tdo); dr_tdo = dr_tdo >> (8 - ((scan_size - 1) % 8)); buf_set_u32(buffer, bit_count, (scan_size - 1) % 8, dr_tdo); }
static int ftdi_execute_scan(struct jtag_command *cmd) { int retval = ERROR_OK; DEBUG_JTAG_IO("%s type:%d", cmd->cmd.scan->ir_scan ? "IRSCAN" : "DRSCAN", jtag_scan_type(cmd->cmd.scan)); if (cmd->cmd.scan->ir_scan) { if (tap_get_state() != TAP_IRSHIFT) move_to_state(TAP_IRSHIFT); } else { if (tap_get_state() != TAP_DRSHIFT) move_to_state(TAP_DRSHIFT); } ftdi_end_state(cmd->cmd.scan->end_state); struct scan_field *field = cmd->cmd.scan->fields; unsigned scan_size = 0; for (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) { scan_size += field->num_bits; DEBUG_JTAG_IO("%s%s field %d/%d %d bits", field->in_value ? "in" : "", field->out_value ? "out" : "", i, cmd->cmd.scan->num_fields, field->num_bits); if (i == cmd->cmd.scan->num_fields - 1 && tap_get_state() != tap_get_end_state()) { /* Last field, and we're leaving IRSHIFT/DRSHIFT. Clock last bit during tap *movement */ mpsse_clock_data(mpsse_ctx, field->out_value, 0, field->in_value, 0, field->num_bits - 1, JTAG_MODE); uint8_t last_bit = 0; if (field->out_value) bit_copy(&last_bit, 0, field->out_value, field->num_bits - 1, 1); uint8_t tms_bits = 0x01; retval = mpsse_clock_tms_cs(mpsse_ctx, &tms_bits, 0, field->in_value, field->num_bits - 1, 1, last_bit, JTAG_MODE); tap_set_state(tap_state_transition(tap_get_state(), 1)); retval = mpsse_clock_tms_cs_out(mpsse_ctx, &tms_bits, 1, 1, last_bit, JTAG_MODE); tap_set_state(tap_state_transition(tap_get_state(), 0)); } else mpsse_clock_data(mpsse_ctx, field->out_value, 0, field->in_value, 0, field->num_bits, JTAG_MODE); if (retval != ERROR_OK) { LOG_ERROR("failed to add field %d in scan", i); return retval; } } if (tap_get_state() != tap_get_end_state()) move_to_state(tap_get_end_state()); DEBUG_JTAG_IO("%s scan, %i bits, end in %s", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size, tap_state_name(tap_get_end_state())); return retval; }
/** * Performs a cJTAG scan * @param cmd contains the JTAG scan command to perform. */ void cjtag_execute_scan(struct jtag_command *cmd) { int i; unsigned char ucTDI = 0; unsigned int ulPreamble = 0; if (cmd->cmd.scan->num_fields != 1) { LOG_ERROR("Unexpected field size of %d", cmd->cmd.scan->num_fields); return; } struct scan_field *field = cmd->cmd.scan->fields; if ((field->num_bits + MAX_PREAMBLE + MAX_POSTAMBLE) > MAX_SUPPORTED_SCAN_LENGTH) { LOG_ERROR("Scan length too long at %d", field->num_bits); return; } ulTxCount = 0; if (cmd->cmd.scan->ir_scan) { if (tap_get_state() != TAP_IRSHIFT) cjtag_move_to_state(TAP_IRSHIFT); } else { if (tap_get_state() != TAP_DRSHIFT) cjtag_move_to_state(TAP_DRSHIFT); } ulPreamble = ulTxCount; tap_set_end_state(cmd->cmd.scan->end_state); for (i = 0; i < field->num_bits - 1; i++) { if (field->out_value) bit_copy(&ucTDI, 0, field->out_value, i, 1); if (ucTDI) send_JTAG(TMS_0 | TDI_1); else send_JTAG(TMS_0 | TDI_0); } if (field->out_value) bit_copy(&ucTDI, 0, field->out_value, i, 1); if (ucTDI) send_JTAG(TMS_1 | TDI_1); else send_JTAG(TMS_1 | TDI_0); if (cmd->cmd.scan->ir_scan) tap_set_state(TAP_IREXIT1); else tap_set_state(TAP_DREXIT1); /* Move to the end state... */ cjtag_move_to_state(cmd->cmd.scan->end_state); /* Perform the scan... */ mpsse_read(local_ctx, pucRxBuffer, field->num_bits + ulTxCount); if (field->in_value) { for (i = 0; i < field->num_bits; i++) { bit_copy(field->in_value, i, (const unsigned char *)&pucRxBuffer[i + ulPreamble], 7, 1); } } }
static void jlink_execute_scan(struct jtag_command *cmd) { DEBUG_JTAG_IO("%s type:%d", cmd->cmd.scan->ir_scan ? "IRSCAN" : "DRSCAN", jtag_scan_type(cmd->cmd.scan)); /* Make sure there are no trailing fields with num_bits == 0, or the logic below will fail. */ while (cmd->cmd.scan->num_fields > 0 && cmd->cmd.scan->fields[cmd->cmd.scan->num_fields - 1].num_bits == 0) { cmd->cmd.scan->num_fields--; LOG_DEBUG("discarding trailing empty field"); } if (cmd->cmd.scan->num_fields == 0) { LOG_DEBUG("empty scan, doing nothing"); return; } if (cmd->cmd.scan->ir_scan) { if (tap_get_state() != TAP_IRSHIFT) { jlink_end_state(TAP_IRSHIFT); jlink_state_move(); } } else { if (tap_get_state() != TAP_DRSHIFT) { jlink_end_state(TAP_DRSHIFT); jlink_state_move(); } } jlink_end_state(cmd->cmd.scan->end_state); struct scan_field *field = cmd->cmd.scan->fields; unsigned scan_size = 0; for (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) { scan_size += field->num_bits; DEBUG_JTAG_IO("%s%s field %d/%d %d bits", field->in_value ? "in" : "", field->out_value ? "out" : "", i, cmd->cmd.scan->num_fields, field->num_bits); if (i == cmd->cmd.scan->num_fields - 1 && tap_get_state() != tap_get_end_state()) { /* Last field, and we're leaving IRSHIFT/DRSHIFT. Clock last bit during tap * movement. This last field can't have length zero, it was checked above. */ jlink_clock_data(field->out_value, 0, NULL, 0, field->in_value, 0, field->num_bits - 1); uint8_t last_bit = 0; if (field->out_value) bit_copy(&last_bit, 0, field->out_value, field->num_bits - 1, 1); uint8_t tms_bits = 0x01; jlink_clock_data(&last_bit, 0, &tms_bits, 0, field->in_value, field->num_bits - 1, 1); tap_set_state(tap_state_transition(tap_get_state(), 1)); jlink_clock_data(&last_bit, 0, &tms_bits, 1, NULL, 0, 1); tap_set_state(tap_state_transition(tap_get_state(), 0)); } else jlink_clock_data(field->out_value, 0, NULL, 0, field->in_value, 0, field->num_bits); } if (tap_get_state() != tap_get_end_state()) { jlink_end_state(tap_get_end_state()); jlink_state_move(); } DEBUG_JTAG_IO("%s scan, %i bits, end in %s", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size, tap_state_name(tap_get_end_state())); }
static int vsllink_execute_queue(void) { struct jtag_command *cmd = jtag_command_queue; int scan_size; enum scan_type type; uint8_t *buffer; DEBUG_JTAG_IO("-------------------------------------" " vsllink " "-------------------------------------"); while (cmd != NULL) { switch (cmd->type) { case JTAG_RUNTEST: DEBUG_JTAG_IO("runtest %i cycles, end in %s", cmd->cmd.runtest->num_cycles, tap_state_name(cmd->cmd.runtest->end_state)); vsllink_end_state(cmd->cmd.runtest->end_state); vsllink_runtest(cmd->cmd.runtest->num_cycles); break; case JTAG_TLR_RESET: DEBUG_JTAG_IO("statemove end in %s", tap_state_name(cmd->cmd.statemove->end_state)); vsllink_end_state(cmd->cmd.statemove->end_state); vsllink_state_move(); break; case JTAG_PATHMOVE: DEBUG_JTAG_IO("pathmove: %i states, end in %s", cmd->cmd.pathmove->num_states, tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1])); vsllink_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path); break; case JTAG_SCAN: DEBUG_JTAG_IO("JTAG Scan..."); vsllink_end_state(cmd->cmd.scan->end_state); scan_size = jtag_build_buffer( cmd->cmd.scan, &buffer); if (cmd->cmd.scan->ir_scan) DEBUG_JTAG_IO( "JTAG Scan write IR(%d bits), " "end in %s:", scan_size, tap_state_name(cmd->cmd.scan->end_state)); else DEBUG_JTAG_IO( "JTAG Scan write DR(%d bits), " "end in %s:", scan_size, tap_state_name(cmd->cmd.scan->end_state)); #ifdef _DEBUG_JTAG_IO_ vsllink_debug_buffer(buffer, DIV_ROUND_UP(scan_size, 8)); #endif type = jtag_scan_type(cmd->cmd.scan); vsllink_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size, cmd->cmd.scan); break; case JTAG_RESET: DEBUG_JTAG_IO("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); vsllink_tap_execute(); if (cmd->cmd.reset->trst == 1) tap_set_state(TAP_RESET); vsllink_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); break; case JTAG_SLEEP: DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us); vsllink_tap_execute(); jtag_sleep(cmd->cmd.sleep->us); break; case JTAG_STABLECLOCKS: DEBUG_JTAG_IO("add %d clocks", cmd->cmd.stableclocks->num_cycles); switch (tap_get_state()) { case TAP_RESET: /* tms must be '1' to stay * n TAP_RESET mode */ scan_size = 1; break; case TAP_DRSHIFT: case TAP_IDLE: case TAP_DRPAUSE: case TAP_IRSHIFT: case TAP_IRPAUSE: /* else, tms should be '0' */ scan_size = 0; break; /* above stable states are OK */ default: LOG_ERROR("jtag_add_clocks() " "in non-stable state \"%s\"", tap_state_name(tap_get_state()) ); exit(-1); } vsllink_stableclocks(cmd->cmd.stableclocks->num_cycles, scan_size); break; case JTAG_TMS: DEBUG_JTAG_IO("add %d jtag tms", cmd->cmd.tms->num_bits); vsllink_tms(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits); break; default: LOG_ERROR("BUG: unknown JTAG command type " "encountered: %d", cmd->type); exit(-1); } cmd = cmd->next; } return vsllink_tap_execute(); }