/* xsvf has it's own definition of a statemove. This needs * to be handled according to the xsvf spec, which has nothing * to do with the JTAG spec or OpenOCD as such. * * Implemented via jtag_add_pathmove(). */ static void xsvf_add_statemove(tap_state_t state) { tap_state_t moves[7]; /* max # of transitions */ tap_state_t curstate = cmd_queue_cur_state; int i; u8 move = tap_get_tms_path(cmd_queue_cur_state, state); if (state != TAP_RESET && state==cmd_queue_cur_state) return; if(state==TAP_RESET) { jtag_add_tlr(); return; } for (i=0; i<7; i++) { int j = (move >> i) & 1; if (j) { curstate = tap_state_transition(curstate, true); } else { curstate = tap_state_transition(curstate, false); } moves[i] = curstate; } jtag_add_pathmove(7, moves); }
void jtag_add_pathmove(int num_states, const tap_state_t *path) { tap_state_t cur_state = cmd_queue_cur_state; /* the last state has to be a stable state */ if (!tap_is_state_stable(path[num_states - 1])) { LOG_ERROR("BUG: TAP path doesn't finish in a stable state"); jtag_set_error(ERROR_JTAG_NOT_STABLE_STATE); return; } for (int i = 0; i < num_states; i++) { if (path[i] == TAP_RESET) { LOG_ERROR("BUG: TAP_RESET is not a valid state for pathmove sequences"); jtag_set_error(ERROR_JTAG_STATE_INVALID); return; } if (tap_state_transition(cur_state, true) != path[i] && tap_state_transition(cur_state, false) != path[i]) { LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(cur_state), tap_state_name(path[i])); jtag_set_error(ERROR_JTAG_TRANSITION_INVALID); return; } cur_state = path[i]; } jtag_checks(); jtag_set_error(interface_jtag_add_pathmove(num_states, path)); cmd_queue_cur_state = path[num_states - 1]; }
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; }
int interface_jtag_add_pathmove(int num_states, const tap_state_t *path) { int state_count; int tms = 0; state_count = 0; tap_state_t cur_state = cmd_queue_cur_state; while (num_states) { if (tap_state_transition(cur_state, false) == path[state_count]) tms = 0; else if (tap_state_transition(cur_state, true) == path[state_count]) tms = 1; else { LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(cur_state), tap_state_name(path[state_count])); exit(-1); } /* synchronously do the operation here */ cur_state = path[state_count]; state_count++; num_states--; } /* synchronously do the operation here */ return ERROR_OK; }
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; }
int jtag_add_statemove(tap_state_t goal_state) { tap_state_t cur_state = cmd_queue_cur_state; if (goal_state != cur_state) { LOG_DEBUG("cur_state=%s goal_state=%s", tap_state_name(cur_state), tap_state_name(goal_state)); } /* If goal is RESET, be paranoid and force that that transition * (e.g. five TCK cycles, TMS high). Else trust "cur_state". */ if (goal_state == TAP_RESET) jtag_add_tlr(); else if (goal_state == cur_state) /* nothing to do */; else if (tap_is_state_stable(cur_state) && tap_is_state_stable(goal_state)) { unsigned tms_bits = tap_get_tms_path(cur_state, goal_state); unsigned tms_count = tap_get_tms_path_len(cur_state, goal_state); tap_state_t moves[8]; assert(tms_count < ARRAY_SIZE(moves)); for (unsigned i = 0; i < tms_count; i++, tms_bits >>= 1) { bool bit = tms_bits & 1; cur_state = tap_state_transition(cur_state, bit); moves[i] = cur_state; } jtag_add_pathmove(tms_count, moves); } else if (tap_state_transition(cur_state, true) == goal_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 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_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 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 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 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; }