This layers parts of XSVF directly over SVF, to handle XSTATE better,
instead of expecting jtag_add_pathmove() to conform (it doesn't).
It also removes related bogus comments about jtag_add_pathmove().

There is one set of XSTATE cases that's not handled right yet:  when
it's used to build some arbitrary path, not moving between two stable
states.  The path isn't collected yet, but -- new! -- that error case
will now trigger a specific warning.

Handling of state transition paths is, overall, still a mess.  I think
they should all be specified as paths not unlike SVF uses, and then
compiled to the bitstrings ... so that we can actually make sense of
the paths.  (See the extra clocks, detours through RUN, etc.)
---
I can't see this causing any regressions, but it should make
XSVF conform better to the spec in at least three ways:  handling
of RESET, skipping NOP transitions, and doing what SVF specifies
(instead of what the "new" default paths do) where relevant.

Run on top of current git, to get some RESET handling fixes.

 src/jtag/jtag.h      |   24 ---------------------
 src/svf/svf.c        |   18 +++++++++-------
 src/svf/svf.h        |   21 +++++++++++++++++++
 src/xsvf/Makefile.am |    1 
 src/xsvf/xsvf.c      |   54 ++++++++++++++++++++++++++++---------------------
 5 files changed, 65 insertions(+), 53 deletions(-)

--- a/src/jtag/jtag.h
+++ b/src/jtag/jtag.h
@@ -538,29 +538,7 @@ extern void jtag_add_pathmove(int num_st
  * @return ERROR_OK on success, or an error code on failure.
  *
  * Moves from the current state to the goal \a state.
- *
- * This needs to be handled according to the xsvf spec, see the XSTATE
- * command description.  From the XSVF spec, pertaining to XSTATE:
- *
- * For special states known as stable states (Test-Logic-Reset,
- * Run-Test/Idle, Pause-DR, Pause- IR), an XSVF interpreter follows
- * predefined TAP state paths when the starting state is a stable state
- * and when the XSTATE specifies a new stable state.  See the STATE
- * command in the [Ref 5] for the TAP state paths between stable
- * states.
- *
- * For non-stable states, XSTATE should specify a state that is only one
- * TAP state transition distance from the current TAP state to avoid
- * undefined TAP state paths. A sequence of multiple XSTATE commands can
- * be issued to transition the TAP through a specific state path.
- *
- * @note Unless @c tms_bits holds a path that agrees with [Ref 5] in the
- * above spec, then this code is not fully conformant to the xsvf spec.
- * This puts a burden on tap_get_tms_path() function from the xsvf spec.
- * If in doubt, you should confirm that that burden is being met.
- *
- * Otherwise, @a goal_state must be immediately reachable in one clock
- * cycle, and does not need to be a stable state.
+ * Both states must be stable.
  */
 extern int jtag_add_statemove(tap_state_t goal_state);
 
--- a/src/svf/svf.c
+++ b/src/svf/svf.c
@@ -31,8 +31,8 @@
 #include "config.h"
 #endif
 
-#include "svf.h"
 #include "jtag.h"
+#include "svf.h"
 #include "time_support.h"
 
 
@@ -311,7 +311,7 @@ static const char* tap_state_svf_name(ta
        return ret;
 }
 
-static int svf_add_statemove(tap_state_t state_to)
+int svf_add_statemove(tap_state_t state_to)
 {
        tap_state_t state_from = cmd_queue_cur_state;
        uint8_t index;
@@ -619,9 +619,10 @@ static int svf_parse_cmd_string(char *st
        return ERROR_OK;
 }
 
-static int svf_tap_state_is_stable(tap_state_t state)
+bool svf_tap_state_is_stable(tap_state_t state)
 {
-       return ((TAP_RESET == state) || (TAP_IDLE == state) || (TAP_DRPAUSE == 
state) || (TAP_IRPAUSE == state));
+       return (TAP_RESET == state) || (TAP_IDLE == state)
+                       || (TAP_DRPAUSE == state) || (TAP_IRPAUSE == state);
 }
 
 static int svf_tap_state_is_valid(tap_state_t state)
@@ -1082,6 +1083,7 @@ static int svf_run_command(struct comman
                        field.num_bits = i;
                        field.out_value = &svf_tdi_buffer[svf_buffer_index];
                        field.in_value = &svf_tdi_buffer[svf_buffer_index];
+                       /* NOTE:  doesn't use SVF-specified state paths */
                        jtag_add_plain_dr_scan(1, &field, 
svf_para.dr_end_state);
 
                        svf_buffer_index += (i + 7) >> 3;
@@ -1177,6 +1179,7 @@ static int svf_run_command(struct comman
                        field.num_bits = i;
                        field.out_value = &svf_tdi_buffer[svf_buffer_index];
                        field.in_value = &svf_tdi_buffer[svf_buffer_index];
+                       /* NOTE:  doesn't use SVF-specified state paths */
                        jtag_add_plain_ir_scan(1, &field, 
svf_para.ir_end_state);
 
                        svf_buffer_index += (i + 7) >> 3;
@@ -1337,8 +1340,10 @@ static int svf_run_command(struct comman
                                        free(path);
                                        return ERROR_FAIL;
                                }
+                               /* OpenOCD refuses paths containing TAP_RESET */
                                if (TAP_RESET == path[i])
                                {
+                                       /* FIXME last state MUST be stable! */
                                        if (i > 0)
                                        {
                                                jtag_add_pathmove(i, path);
@@ -1378,10 +1383,9 @@ static int svf_run_command(struct comman
                        state = svf_find_string_in_array(argus[1], (char 
**)svf_tap_state_name, dimof(svf_tap_state_name));
                        if (svf_tap_state_is_stable(state))
                        {
-                               // TODO: move to state
+                               LOG_DEBUG("\tmove to %s by svf_add_statemove",
+                                               svf_tap_state_name[state]);
                                svf_add_statemove(state);
-
-                               LOG_DEBUG("\tmove to %s by svf_add_statemove", 
svf_tap_state_name[state]);
                        }
                        else
                        {
--- a/src/svf/svf.h
+++ b/src/svf/svf.h
@@ -24,4 +24,25 @@
 
 extern int svf_register_commands(struct command_context_s *cmd_ctx);
 
+/**
+ * svf_add_statemove() moves from the current state to @a goal_state.
+ *
+ * @param goal_state The final TAP state.
+ * @return ERROR_OK on success, or an error code on failure.
+ *
+ * This differs from jtag_add_statemove() in that the particular state
+ * transitions used are specified by the SVF specification, and that
+ * the current and goal states must satisfy svf_tap_state_is_stable():
+ * stable states which are neither IRSHIFT nor DRSHIFT.
+ */
+extern int svf_add_statemove(tap_state_t goal_state);
+
+/**
+ * svf_tap_state_is_stable() returns true for stable non-SHIFT sates
+ *
+ * @param state The TAP state in question
+ * @return true iff the state is stable and not a SHIFT state.
+ */
+extern bool svf_tap_state_is_stable(tap_state_t state);
+
 #endif /* SVF_H */
--- a/src/xsvf/Makefile.am
+++ b/src/xsvf/Makefile.am
@@ -1,6 +1,7 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/server \
        -I$(top_srcdir)/src/helper \
+       -I$(top_srcdir)/src/svf \
        -I$(top_srcdir)/src/jtag
 
 METASOURCES = AUTO
--- a/src/xsvf/xsvf.c
+++ b/src/xsvf/xsvf.c
@@ -42,6 +42,7 @@
 
 #include "xsvf.h"
 #include "jtag.h"
+#include "svf.h"
 
 
 /* XSVF commands, from appendix B of xapp503.pdf  */
@@ -502,32 +503,39 @@ static int handle_xsvf_command(struct co
 
                                LOG_DEBUG("XSTATE 0x%02X %s", uc, 
tap_state_name(mystate));
 
-                               /*      there is no need for the lookahead code 
that was here since we
-                                       queue up the jtag commands anyway.  
This is a simple way to handle
-                                       the XSTATE.
-                               */
+                               /* NOTE: the current state is SVF-stable! */
 
-                               if (jtag_add_statemove(mystate) != ERROR_OK)
+                               /* no change == NOP */
+                               if (mystate == cmd_queue_cur_state
+                                               && mystate != TAP_RESET)
+                                       break;
+
+                               /* Hand off to SVF? */
+                               if (svf_tap_state_is_stable(mystate))
                                {
-                                       /*      For special states known as 
stable states
-                                               (Test-Logic-Reset, 
Run-Test/Idle, Pause-DR, Pause- IR),
-                                               an XSVF interpreter follows 
predefined TAP state paths
-                                               when the starting state is a 
stable state and when the
-                                               XSTATE specifies a new stable 
state (see the STATE
-                                               command in the [Ref 5] for the 
TAP state paths between
-                                               stable states). For non-stable 
states, XSTATE should
-                                               specify a state that is only 
one TAP state transition
-                                               distance from the current TAP 
state to avoid undefined
-                                               TAP state paths. A sequence of 
multiple XSTATE commands
-                                               can be issued to transition the 
TAP through a specific
-                                               state path.
-                                       */
+                                       int retval;
 
-                                       LOG_ERROR("XSTATE %s is not reachable 
from current state %s in one clock cycle",
-                                               tap_state_name(mystate),
-                                               
tap_state_name(cmd_queue_cur_state)
-);
+                                       retval = svf_add_statemove(mystate);
+                                       if (retval != ERROR_OK)
+                                               unsupported = 1;
+                                       break;
                                }
+
+                               /*
+                                * A sequence of XSTATE transitions, each TAP
+                                * state adjacent to the previous one.
+                                *
+                                * NOTE: OpenOCD requires something that XSVF
+                                * doesn't:  the last TAP state in the path
+                                * must be stable.
+                                *
+                                * FIXME Implement path collection; submit via
+                                * jtag_add_pathmove() after teaching it to
+                                * report errors.
+                                */
+                               LOG_ERROR("XSVF: 'XSTATE %s' ... NYET",
+                                               tap_state_name(mystate));
+                               unsupported = 1;
                        }
                        break;
 
@@ -758,7 +766,7 @@ static int handle_xsvf_command(struct co
                                 * be issuing a number of clocks in this state. 
 This set of allowed states is also
                                 * determined by the SVF RUNTEST command's 
allowed states.
                                 */
-                               if (wait_state != TAP_IRPAUSE && wait_state != 
TAP_DRPAUSE && wait_state != TAP_RESET && wait_state != TAP_IDLE)
+                               if (!svf_tap_state_is_stable(wait_state))
                                {
                                        LOG_ERROR("illegal XWAITSTATE 
wait_state: \"%s\"", tap_state_name(wait_state));
                                        unsupported = 1;
_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to