Exemplo n.º 1
0
/* 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);
}
Exemplo n.º 2
0
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];
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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
Exemplo n.º 7
0
/**
 * 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]);
	}
}
Exemplo n.º 8
0
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());
}
Exemplo n.º 9
0
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());
}
Exemplo n.º 10
0
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);
}
Exemplo n.º 11
0
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()));
}
Exemplo n.º 12
0
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;

}