When the underlying JTAG adapter supports it, use the new TMS sequence
operation instead of a pathmove(). This will eliminate duplicated work,
and removes the need for separate pathmove() logic in those drivers.
Similarly for statemove() ... which someday we might consider removing.
It's already redundant, given pathmove().
Note that this moves a "paths may have at most 32 elements" constraint
into the core. The FT2232 code has it as an assertion, which we don't
seem to have triggered ... so this can't be a real problem. There are
only 16 JTAG states, so long paths wouldn't be useful anyway. Note that
the Jim "pathmove" command tops out at 8, and the XSVF logic breaks paths
into segments at stable states; so producing even a 32-element path is
pretty unlikely.
---
src/jtag/core.c | 66 ++++++++++++++++++++++++++++++++++++++++---------
src/jtag/interface.c | 2 -
src/jtag/interface.h | 4 +-
3 files changed, 57 insertions(+), 15 deletions(-)
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -528,6 +528,18 @@ int jtag_add_tms_seq(unsigned nbits, uin
void jtag_add_pathmove(int num_states, const tap_state_t *path)
{
tap_state_t cur_state = cmd_queue_cur_state;
+ uint32_t tms_path = 0;
+
+ /* For now, reject long paths instead of trying to segment them
+ * when going through some stable state. We don't seem to have
+ * any call paths which could trigger this, in any case.
+ */
+ if (num_states > 32) {
+ LOG_ERROR("JTAG path length %d is too long! Shorten it.",
+ num_states);
+ jtag_set_error(ERROR_JTAG_TRANSITION_INVALID);
+ return;
+ }
/* the last state has to be a stable state */
if (!tap_is_state_stable(path[num_states - 1]))
@@ -546,15 +558,34 @@ void jtag_add_pathmove(int num_states, c
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;
+ if (tap_state_transition(cur_state, true) == path[i]) {
+ cur_state = path[i];
+ tms_path |= 1 << i;
+ DEBUG_JTAG_IO("JTAG: --> %s",
+ tap_state_name(cur_state));
+ continue;
}
- cur_state = path[i];
+ if (tap_state_transition(cur_state, false) == path[i]) {
+ cur_state = path[i];
+ DEBUG_JTAG_IO("JTAG: --> %s",
+ tap_state_name(cur_state));
+ continue;
+ }
+
+ 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;
+ }
+
+ /* Can we pass that TMS sequence directly to the driver? */
+ if (jtag->supported & DEBUG_CAP_TMS_SEQ) {
+ uint8_t tms[4];
+
+ buf_set_u32(tms, 0, 32, tms_path);
+ jtag_add_tms_seq(num_states, tms, path[num_states - 1]);
+ return;
}
jtag_checks();
@@ -580,12 +611,20 @@ int jtag_add_statemove(tap_state_t goal_
else if (goal_state == cur_state)
/* nothing to do */ ;
- else if (tap_is_state_stable(cur_state) &&
tap_is_state_stable(goal_state))
+ 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);
+ uint8_t tms_bits = tap_get_tms_path(cur_state, goal_state);
+ unsigned tms_count;
+
+ tms_count = tap_get_tms_path_len(cur_state, goal_state);
+
+ /* Can we pass that TMS sequence directly to the driver? */
+ if (jtag->supported & DEBUG_CAP_TMS_SEQ)
+ return jtag_add_tms_seq(tms_count, &tms_bits,
+ goal_state);
+
tap_state_t moves[8];
- assert(tms_count < ARRAY_SIZE(moves));
for (unsigned i = 0; i < tms_count; i++, tms_bits >>= 1)
{
@@ -600,6 +639,9 @@ int jtag_add_statemove(tap_state_t goal_
else if (tap_state_transition(cur_state, true) == goal_state
|| tap_state_transition(cur_state, false) == goal_state)
{
+ /* REVISIT This should really be an error ... */
+ LOG_WARNING("odd %s -- current or goal not stable??",
+ __func__);
jtag_add_pathmove(1, &goal_state);
}
--- a/src/jtag/interface.c
+++ b/src/jtag/interface.c
@@ -196,7 +196,7 @@ typedef const struct tms_sequences tms_t
static tms_table *tms_seqs=&short_tms_seqs;
-int tap_get_tms_path(tap_state_t from, tap_state_t to)
+uint8_t tap_get_tms_path(tap_state_t from, tap_state_t to)
{
return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bits;
}
--- a/src/jtag/interface.h
+++ b/src/jtag/interface.h
@@ -97,7 +97,7 @@ tap_state_t tap_get_end_state(void);
/**
* This function provides a "bit sequence" indicating what has to be
- * done with TMS during a sequence of seven TAP clock cycles in order to
+ * done with TMS during a sequence of TAP clock cycles in order to
* get from state \a "from" to state \a "to".
*
* The length of the sequence must be determined with a parallel call to
@@ -108,7 +108,7 @@ tap_state_t tap_get_end_state(void);
* @return int The required TMS bit sequence, with the first bit in the
* sequence at bit 0.
*/
-int tap_get_tms_path(tap_state_t from, tap_state_t to);
+uint8_t tap_get_tms_path(tap_state_t from, tap_state_t to);
/**
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development