David Brownell david-b at pacbell.net fix warnings
[fw/openocd] / src / jtag / jtag.h
index 386d517e13510ab77c64268a1ef521c5310494b5..c0f94856b8ced9f49ad44aff771d23afddf84cff 100644 (file)
 #include "command.h"
 
 
-#if 0
-#define _DEBUG_JTAG_IO_
+#ifdef _DEBUG_JTAG_IO_
+#define DEBUG_JTAG_IO(expr ...)                LOG_DEBUG(expr)
+#else
+#define DEBUG_JTAG_IO(expr ...)
 #endif
 
 #ifndef DEBUG_JTAG_IOZ
 #define DEBUG_JTAG_IOZ 64
 #endif
 
+/*-----<Macros>--------------------------------------------------*/
+
+/** When given an array, compute its DIMension, i.e. number of elements in the array */
+#define DIM(x)                                 (sizeof(x)/sizeof((x)[0]))
+
+/** Calculate the number of bytes required to hold @a n TAP scan bits */
+#define TAP_SCAN_BYTES(n)              CEIL(n, 8)
+
+/*-----</Macros>-------------------------------------------------*/
+
 
-/* 16 Tap States, from page 21 of ASSET InterTech, Inc.'s svf.pdf
+
+/*
+ * Tap states from ARM7TDMI-S Technical reference manual.
+ * Also, validated against several other ARM core technical manuals.
+ *
+ * N.B. tap_get_tms_path() was changed to reflect this corrected
+ * numbering and ordering of the TAP states.
+ *
+ * DANGER!!!! some interfaces care about the actual numbers used
+ * as they are handed off directly to hardware implementations.
  */
-enum tap_state {
+
+typedef enum tap_state
+{
+#if BUILD_ECOSBOARD
+/* These are the old numbers. Leave as-is for now... */
        TAP_RESET    = 0, TAP_IDLE = 8,
        TAP_DRSELECT = 1, TAP_DRCAPTURE = 2, TAP_DRSHIFT = 3, TAP_DREXIT1 = 4,
        TAP_DRPAUSE  = 5, TAP_DREXIT2 = 6, TAP_DRUPDATE = 7,
        TAP_IRSELECT = 9, TAP_IRCAPTURE = 10, TAP_IRSHIFT = 11, TAP_IREXIT1 = 12,
-       TAP_IRPAUSE  = 13, TAP_IREXIT2 = 14, TAP_IRUPDATE = 15
-};
+       TAP_IRPAUSE  = 13, TAP_IREXIT2 = 14, TAP_IRUPDATE = 15,
 
-typedef enum tap_state tap_state_t;
+       TAP_NUM_STATES = 16, TAP_INVALID = -1,
+#else
+       /* Proper ARM recommended numbers */
+       TAP_DREXIT2 = 0x0,
+       TAP_DREXIT1 = 0x1,
+       TAP_DRSHIFT = 0x2,
+       TAP_DRPAUSE = 0x3,
+       TAP_IRSELECT = 0x4,
+       TAP_DRUPDATE = 0x5,
+       TAP_DRCAPTURE = 0x6,
+       TAP_DRSELECT = 0x7,
+       TAP_IREXIT2 = 0x8,
+       TAP_IREXIT1 = 0x9,
+       TAP_IRSHIFT = 0xa,
+       TAP_IRPAUSE = 0xb,
+       TAP_IDLE = 0xc,
+       TAP_IRUPDATE = 0xd,
+       TAP_IRCAPTURE = 0xe,
+       TAP_RESET = 0x0f,
+
+       TAP_NUM_STATES = 0x10,
+
+       TAP_INVALID = -1,
+#endif
+} tap_state_t;
 
 typedef struct tap_transition_s
 {
@@ -133,6 +181,25 @@ tap_state_t tap_get_end_state(void);
  */
 int tap_get_tms_path(tap_state_t from, tap_state_t to);
 
+
+/**
+ * Function int tap_get_tms_path_len
+ * returns the total number of bits that represents a TMS path
+ * transition as given by the function tap_get_tms_path().
+ *
+ * For at least one interface (JLink) it's not OK to simply "pad" TMS sequences
+ * to fit a whole byte.  (I suspect this is a general TAP problem within OOCD.)
+ * Padding TMS causes all manner of instability that's not easily
+ * discovered.  Using this routine we can apply EXACTLY the state transitions
+ * required to make something work - no more - no less.
+ *
+ * @param from is the starting state
+ * @param to is the resultant or final state
+ * @return int - the total number of bits in a transition.
+ */
+int tap_get_tms_path_len(tap_state_t from, tap_state_t to);
+
+
 /**
  * Function tap_move_ndx
  * when given a stable state, returns an index from 0-5.  The index corresponds to a
@@ -169,6 +236,25 @@ tap_state_t tap_state_transition(tap_state_t current_state, bool tms);
  */
 const char* tap_state_name(tap_state_t state);
 
+#ifdef _DEBUG_JTAG_IO_
+/**
+ * @brief Prints verbose TAP state transitions for the given TMS/TDI buffers.
+ * @param tms_buf must points to a buffer containing the TMS bitstream.
+ * @param tdi_buf must points to a buffer containing the TDI bitstream.
+ * @param tap_len must specify the length of the TMS/TDI bitstreams.
+ * @param start_tap_state must specify the current TAP state.
+ * @returns the final TAP state; pass as @a start_tap_state in following call.
+ */
+tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf,
+               unsigned tap_len, tap_state_t start_tap_state);
+#else
+static inline tap_state_t jtag_debug_state_machine(const void *tms_buf,
+               const void *tdi_buf, unsigned tap_len, tap_state_t start_tap_state)
+{
+       return start_tap_state;
+}
+#endif // _DEBUG_JTAG_IO_
+
 /*-----</Cable Helper API>------------------------------------------*/
 
 
@@ -185,13 +271,12 @@ typedef struct scan_field_s
        jtag_tap_t* tap;                /* tap pointer this instruction refers to */
        int         num_bits;           /* number of bits this field specifies (up to 32) */
        u8*         out_value;          /* value to be scanned into the device */
-       u8*         out_mask;           /* only masked bits care */
        u8*         in_value;           /* pointer to a 32-bit memory location to take data scanned out */
        /* in_check_value/mask, in_handler_error_handler, in_handler_priv can be used by the in handler, otherwise they contain garbage  */
-       u8*          in_check_value;    /* used to validate scan results */
-       u8*          in_check_mask;     /* check specified bits against check_value */
-       in_handler_t in_handler;        /* process received buffer using this handler */
-       void*        in_handler_priv;   /* additional information for the in_handler */
+       u8*          in_check_value;    /* deprecated! only used from jtag_set_check_value. used to validate scan results */
+       u8*          in_check_mask;     /* deprecated! only used from jtag_set_check_value.  check specified bits against check_value */
+       in_handler_t in_handler;        /* deprecated! SET TO NULL. DO NOT USE! process received buffer using this handler */
+       void*        in_handler_priv;   /* deprecated! only used by obsolete in_handler implementations */
 } scan_field_t;
 
 enum scan_type {
@@ -309,7 +394,6 @@ struct jtag_tap_s
 };
 extern jtag_tap_t* jtag_AllTaps(void);
 extern jtag_tap_t* jtag_TapByPosition(int n);
-extern jtag_tap_t* jtag_TapByPosition(int n);
 extern jtag_tap_t* jtag_TapByString(const char* dotted_name);
 extern jtag_tap_t* jtag_TapByJimObj(Jim_Interp* interp, Jim_Obj* obj);
 extern jtag_tap_t* jtag_TapByAbsPosition(int abs_position);
@@ -477,6 +561,10 @@ extern int  jtag_register_commands(struct command_context_s* cmd_ctx);
 extern void jtag_add_ir_scan(int num_fields, scan_field_t* fields, tap_state_t endstate);
 extern int  interface_jtag_add_ir_scan(int num_fields, scan_field_t* fields, tap_state_t endstate);
 extern void jtag_add_dr_scan(int num_fields, scan_field_t* fields, tap_state_t endstate);
+/* same as jtag_add_dr_scan but the scan is executed immediately. sets jtag_error if there
+ * was a failure.
+ */
+extern void jtag_add_dr_scan_now(int num_fields, scan_field_t* fields, tap_state_t endstate);
 extern int  interface_jtag_add_dr_scan(int num_fields, scan_field_t* fields, tap_state_t endstate);
 extern void jtag_add_plain_ir_scan(int num_fields, scan_field_t* fields, tap_state_t endstate);
 extern int  interface_jtag_add_plain_ir_scan(int num_fields, scan_field_t* fields, tap_state_t endstate);
@@ -489,7 +577,18 @@ extern int  interface_jtag_add_plain_dr_scan(int num_fields, scan_field_t* field
 extern void jtag_add_tlr(void);
 extern int  interface_jtag_add_tlr(void);
 
-/* Do not use jtag_add_pathmove() unless you need to, but do use it
+/* Application code *must* assume that interfaces will
+ * implement transitions between states with different
+ * paths and path lengths through the state diagram. The
+ * path will vary across interface and also across versions
+ * of the same interface over time. Even if the OpenOCD code
+ * is unchanged, the actual path taken may vary over time
+ * and versions of interface firmware or PCB revisions.
+ *
+ * Use jtag_add_pathmove() when specific transition sequences
+ * are required.
+ *
+ * Do not use jtag_add_pathmove() unless you need to, but do use it
  * if you have to.
  *
  * DANGER! If the target is dependent upon a particular sequence
@@ -601,6 +700,16 @@ int  interface_jtag_add_clocks(int num_cycles);
  */
 extern int            jtag_execute_queue(void);
 
+/* this flag is set when an error occurs while executing the queue. cleared
+ * by jtag_execute_queue()
+ *
+ * this flag can also be set from application code if some error happens
+ * during processing that should be reported during jtag_execute_queue().
+ */
+extern int jtag_error;
+
+
+
 /* can be implemented by hw+sw */
 extern int            interface_jtag_execute_queue(void);
 extern int            jtag_power_dropout(int* dropout);
@@ -643,7 +752,7 @@ void jtag_tap_handle_event(jtag_tap_t* tap, enum jtag_tap_event e);
 
 /* jtag_add_dr_out() is a faster version of jtag_add_dr_scan()
  *
- * Current or end_state can not be TAP_RESET. end_state can be -1
+ * Current or end_state can not be TAP_RESET. end_state can be TAP_INVALID
  *
  * num_bits[i] is the number of bits to clock out from value[i] LSB first.
  *
@@ -666,7 +775,7 @@ extern void interface_jtag_add_dr_out(jtag_tap_t* tap, int num_fields, const int
 static __inline__ void jtag_add_dr_out(jtag_tap_t* tap, int num_fields, const int* num_bits, const u32* value,
                tap_state_t end_state)
 {
-       if (end_state != -1)
+       if (end_state != TAP_INVALID)
                cmd_queue_end_state = end_state;
        cmd_queue_cur_state = cmd_queue_end_state;
        interface_jtag_add_dr_out(tap, num_fields, num_bits, value, cmd_queue_end_state);