SVF: clean up, mostly for TAP state name handling
[openocd.git] / src / jtag / jtag.h
index a2156b32eefb7f828ac6f77fe7bd95c329084e3d..1dae00fa31607a7a783b88a4c8ca24065444573d 100644 (file)
@@ -2,7 +2,7 @@
 *   Copyright (C) 2005 by Dominic Rath                                    *
 *   Dominic.Rath@gmx.de                                                   *
 *                                                                         *
-*   Copyright (C) 2007,2008 Øyvind Harboe                                 *
+*   Copyright (C) 2007,2008 Øyvind Harboe                                 *
 *   oyvind.harboe@zylin.com                                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 
 
 #ifdef _DEBUG_JTAG_IO_
-#define DEBUG_JTAG_IO(expr ...)                LOG_DEBUG(expr)
+#define DEBUG_JTAG_IO(expr ...) \
+       do { if (1) LOG_DEBUG(expr); } while (0)
 #else
-#define DEBUG_JTAG_IO(expr ...)
+#define DEBUG_JTAG_IO(expr ...) \
+       do { if (0) LOG_DEBUG(expr); } while (0)
 #endif
 
 #ifndef DEBUG_JTAG_IOZ
 
 /*-----<Macros>--------------------------------------------------*/
 
-/** When given an array, compute its DIMension, i.e. number of elements in the array */
+/**
+ * When given an array, compute its DIMension; in other words, the
+ * 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 */
 
 /*-----</Macros>-------------------------------------------------*/
 
-
-
-/*
- * 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.
+/**
+ * Defines JTAG Test Access Port states.
+ *
+ * These definitions were gleaned from the ARM7TDMI-S Technical
+ * Reference Manual and validated against several other ARM core
+ * technical manuals.  tap_get_tms_path() is sensitive to this numbering
+ * and ordering of the TAP states; furthermore, some interfaces require
+ * specific numbers be used, as they are handed-off directly to their
+ * hardware implementations.
  */
-
 typedef enum tap_state
 {
-#if BUILD_ECOSBOARD
-/* These are the old numbers. Leave as-is for now... */
+#if BUILD_ZY1000
+       /* 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,
@@ -96,439 +98,189 @@ typedef enum tap_state
 #endif
 } tap_state_t;
 
-typedef struct tap_transition_s
-{
-       tap_state_t high;
-       tap_state_t low;
-} tap_transition_t;
-
-//extern tap_transition_t tap_transitions[16];    /* describe the TAP state diagram */
-
-
-#ifdef INCLUDE_JTAG_INTERFACE_H
-
-/*-----<Cable Helper API>-------------------------------------------*/
-
-/* The "Cable Helper API" is what the cable drivers can use to help implement
- * their "Cable API".  So a Cable Helper API is a set of helper functions used by
- * cable drivers, and this is different from a Cable API.  A "Cable API" is what
- * higher level code used to talk to a cable.
- */
-
-
-/** implementation of wrapper function tap_set_state() */
-void tap_set_state_impl(tap_state_t new_state);
-
-/**
- * Function tap_set_state
- * sets the state of a "state follower" which tracks the state of the TAPs connected to the
- * cable.  The state follower is hopefully always in the same state as the actual
- * TAPs in the jtag chain, and will be so if there are no bugs in the tracking logic within that
- * cable driver. All the cable drivers call this function to indicate the state they think
- * the TAPs attached to their cables are in.  Because this function can also log transitions,
- * it will be helpful to call this function with every transition that the TAPs being manipulated
- * are expected to traverse, not just end points of a multi-step state path.
- * @param new_state is the state we think the TAPs are currently in or are about to enter.
- */
-#if defined(_DEBUG_JTAG_IO_)
-#define tap_set_state(new_state) \
-       do { \
-               LOG_DEBUG( "tap_set_state(%s)", tap_state_name(new_state) ); \
-               tap_set_state_impl(new_state); \
-       } while (0)
-#else
-static inline void tap_set_state(tap_state_t new_state)
-{
-       tap_set_state_impl(new_state);
-}
-
-#endif
-
 /**
- * Function tap_get_state
- * gets the state of the "state follower" which tracks the state of the TAPs connected to
- * the cable.
- * @see tap_set_state
- * @return tap_state_t - The state the TAPs are in now.
- */
-tap_state_t tap_get_state(void);
-
-/**
- * Function tap_set_end_state
- * sets the state of an "end state follower" which tracks the state that any cable driver
- * thinks will be the end (resultant) state of the current TAP SIR or SDR operation.  At completion
- * of that TAP operation this value is copied into the state follower via tap_set_state().
- * @param new_end_state is that state the TAPs should enter at completion of a pending TAP operation.
- */
-void        tap_set_end_state(tap_state_t new_end_state);
-
-/**
- * Function tap_get_end_state
- * @see tap_set_end_state
- * @return tap_state_t - The state the TAPs should be in at completion of the current TAP operation.
+ * Function tap_state_name
+ * Returns a string suitable for display representing the JTAG tap_state
  */
-tap_state_t tap_get_end_state(void);
+const char *tap_state_name(tap_state_t state);
 
-/**
- * Function tap_get_tms_path
- * returns a 7 bit long "bit sequence" indicating what has to be done with TMS
- * during a sequence of seven TAP clock cycles in order to get from
- * state \a "from" to state \a "to".
- * @param from is the starting state
- * @param to is the resultant or final state
- * @return int - a 7 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);
+/// Provides user-friendly name lookup of TAP states.
+tap_state_t tap_state_by_name(const char *name);
 
+/// The current TAP state of the pending JTAG command queue.
+extern tap_state_t cmd_queue_cur_state;
 
 /**
- * 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().
+ * This structure defines a single scan field in the scan. It provides
+ * fields for the field's width and pointers to scan input and output
+ * values.
  *
- * 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.
+ * In addition, this structure includes a value and mask that is used by
+ * jtag_add_dr_scan_check() to validate the value that was scanned out.
  *
- * @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
- * sequence of stable states which are given in this order: <p>
- * { TAP_RESET, TAP_IDLE, TAP_DRSHIFT, TAP_DRPAUSE, TAP_IRSHIFT, TAP_IRPAUSE }
- * <p>
- * This sequence corresponds to look up tables which are used in some of the
- * cable drivers.
- * @param astate is the stable state to find in the sequence.  If a non stable
- *  state is passed, this may cause the program to output an error message
- *  and terminate.
- * @return int - the array (or sequence) index as described above
- */
-int tap_move_ndx(tap_state_t astate);
-
-/**
- * Function tap_is_state_stable
- * returns true if the \a astate is stable.
- */
-bool tap_is_state_stable(tap_state_t astate);
-
-/**
- * Function tap_state_transition
- * takes a current TAP state and returns the next state according to the tms value.
- * @param current_state is the state of a TAP currently.
- * @param tms is either zero or non-zero, just like a real TMS line in a jtag interface.
- * @return tap_state_t - the next state a TAP would enter.
- */
-tap_state_t tap_state_transition(tap_state_t current_state, bool tms);
-
-/**
- * Function tap_state_name
- * Returns a string suitable for display representing the JTAG tap_state
+ * The allocated, modified, and intmp fields are internal work space.
  */
-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>------------------------------------------*/
-
-#endif // INCLUDE_JTAG_INTERFACE_H
-
-
-extern tap_state_t cmd_queue_end_state;         /* finish DR scans in dr_end_state */
-extern tap_state_t cmd_queue_cur_state;         /* current TAP state */
-
 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*         in_value;           /* pointer to a 32-bit memory location to take data scanned out */
-
-       u8*         check_value;        /* Used together with jtag_add_dr_scan_check() to check data clocked
-                                          in */
-       u8*         check_mask;         /* mask to go with check_value */
-
-       /* internal work space */
-       int                     allocated;                      /* in_value has been allocated for the queue */
-       int                     modified;                       /* did we modify the in_value? */
-       u8                      intmp[4];                       /* temporary storage for checking synchronously */
+       /// A pointer to the tap structure to which this field refers.
+       jtag_tap_t* tap;
+
+       /// The number of bits this field specifies (up to 32)
+       int num_bits;
+       /// A pointer to value to be scanned into the device
+       uint8_t* out_value;
+       /// A pointer to a 32-bit memory location for data scanned out
+       uint8_t* in_value;
+
+       /// The value used to check the data scanned out.
+       uint8_t* check_value;
+       /// The mask to go with check_value
+       uint8_t* check_mask;
+
+       /// in_value has been allocated for the queue
+       int allocated;
+       /// Indicates we modified the in_value.
+       int modified;
+       /// temporary storage for performing value checks synchronously
+       uint8_t intmp[4];
 } scan_field_t;
 
-#ifdef INCLUDE_JTAG_INTERFACE_H
-
-enum scan_type {
-       /* IN: from device to host, OUT: from host to device */
-       SCAN_IN = 1, SCAN_OUT = 2, SCAN_IO = 3
-};
-
-typedef struct scan_command_s
-{
-       bool          ir_scan;      /* instruction/not data scan */
-       int           num_fields;   /* number of fields in *fields array */
-       scan_field_t* fields;       /* pointer to an array of data scan fields */
-       tap_state_t   end_state;    /* TAP state in which JTAG commands should finish */
-} scan_command_t;
-
-typedef struct statemove_command_s
-{
-       tap_state_t end_state;   /* TAP state in which JTAG commands should finish */
-} statemove_command_t;
-
-typedef struct pathmove_command_s
-{
-       int          num_states;    /* number of states in *path */
-       tap_state_t* path;          /* states that have to be passed */
-} pathmove_command_t;
-
-typedef struct runtest_command_s
-{
-       int         num_cycles;     /* number of cycles that should be spent in Run-Test/Idle */
-       tap_state_t end_state;      /* TAP state in which JTAG commands should finish */
-} runtest_command_t;
-
-
-typedef struct stableclocks_command_s
-{
-       int num_cycles;             /* number of clock cycles that should be sent */
-} stableclocks_command_t;
-
-
-typedef struct reset_command_s
-{
-       int trst;           /* trst/srst 0: deassert, 1: assert, -1: don't change */
-       int srst;
-} reset_command_t;
-
-typedef struct end_state_command_s
-{
-       tap_state_t end_state;   /* TAP state in which JTAG commands should finish */
-} end_state_command_t;
-
-typedef struct sleep_command_s
-{
-       u32 us;     /* number of microseconds to sleep */
-} sleep_command_t;
-
-typedef union jtag_command_container_u
-{
-       scan_command_t*         scan;
-       statemove_command_t*    statemove;
-       pathmove_command_t*     pathmove;
-       runtest_command_t*      runtest;
-       stableclocks_command_t* stableclocks;
-       reset_command_t*        reset;
-       end_state_command_t*    end_state;
-       sleep_command_t* sleep;
-} jtag_command_container_t;
-
-enum jtag_command_type {
-       JTAG_SCAN         = 1,
-       JTAG_STATEMOVE    = 2,
-       JTAG_RUNTEST      = 3,
-       JTAG_RESET        = 4,
-       JTAG_PATHMOVE     = 6,
-       JTAG_SLEEP        = 7,
-       JTAG_STABLECLOCKS = 8
-};
-
-typedef struct jtag_command_s
-{
-       jtag_command_container_t cmd;
-       enum jtag_command_type   type;
-       struct jtag_command_s*   next;
-} jtag_command_t;
-
-extern jtag_command_t* jtag_command_queue;
-
-extern void* cmd_queue_alloc(size_t size);
-extern void cmd_queue_free(void);
-
-extern void jtag_queue_command(jtag_command_t *cmd);
-extern void jtag_command_queue_reset(void);
-
-#endif // INCLUDE_JTAG_INTERFACE_H
-
-/* forward declaration */
 typedef struct jtag_tap_event_action_s jtag_tap_event_action_t;
 
 /* this is really: typedef jtag_tap_t */
 /* But - the typedef is done in "types.h" */
-/* due to "forward decloration reasons" */
+/* due to "forward declaration reasons" */
 struct jtag_tap_s
 {
        const char* chip;
        const char* tapname;
        const char* dotted_name;
-       int         abs_chain_position;
-       int         enabled;
-       int         ir_length;          /* size of instruction register */
-       u32         ir_capture_value;
-       u8*         expected;           /* Capture-IR expected value */
-       u32         ir_capture_mask;
-       u8*         expected_mask;      /* Capture-IR expected mask */
-       u32         idcode;             /* device identification code */
-       u32*        expected_ids;       /* Array of expected identification codes */
-       u8          expected_ids_cnt;   /* Number of expected identification codes */
-       u8*         cur_instr;          /* current instruction */
-       int         bypass;             /* bypass register selected */
-
-       jtag_tap_event_action_t* event_action;
+       int abs_chain_position;
+       /// Is this TAP disabled after JTAG reset?
+       bool disabled_after_reset;
+       /// Is this TAP currently enabled?
+       bool enabled;
+       int ir_length; /**< size of instruction register */
+       uint32_t ir_capture_value;
+       uint8_t* expected; /**< Capture-IR expected value */
+       uint32_t ir_capture_mask;
+       uint8_t* expected_mask; /**< Capture-IR expected mask */
+       uint32_t idcode;
+       bool hasidcode; /* not all devices have idcode, we'll discover this during chain examination */
+       /**< device identification code */
+
+       /// Array of expected identification codes */
+       uint32_t* expected_ids;
+       /// Number of expected identification codes
+       uint8_t expected_ids_cnt;
+
+       /// current instruction
+       uint8_t* cur_instr;
+       /// Bypass register selected
+       int bypass;
+
+       jtag_tap_event_action_t *event_action;
 
        jtag_tap_t* next_tap;
 };
-extern jtag_tap_t* jtag_AllTaps(void);
-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);
-extern int         jtag_NumEnabledTaps(void);
-extern int         jtag_NumTotalTaps(void);
-
-static __inline__ jtag_tap_t* jtag_NextEnabledTap(jtag_tap_t* p)
-{
-       if (p == NULL)
-       {
-               /* start at the head of list */
-               p = jtag_AllTaps();
-       }
-       else
-       {
-               /* start *after* this one */
-               p = p->next_tap;
-       }
-       while (p)
-       {
-               if (p->enabled)
-               {
-                       break;
-               }
-               else
-               {
-                       p = p->next_tap;
-               }
-       }
-
-       return p;
-}
-
-
-enum reset_line_mode {
-       LINE_OPEN_DRAIN = 0x0,
-       LINE_PUSH_PULL  = 0x1,
-};
-
-#ifdef INCLUDE_JTAG_INTERFACE_H
 
-typedef struct jtag_interface_s
-{
-       char* name;
-
-       /* queued command execution
-        */
-       int (*execute_queue)(void);
-
-       /* interface initalization
-        */
-       int (*speed)(int speed);
-       int (*register_commands)(struct command_context_s* cmd_ctx);
-       int (*init)(void);
-       int (*quit)(void);
-
-       /* returns JTAG maxium speed for KHz. 0=RTCK. The function returns
-        *  a failure if it can't support the KHz/RTCK.
-        *
-        *  WARNING!!!! if RTCK is *slow* then think carefully about
-        *  whether you actually want to support this in the driver.
-        *  Many target scripts are written to handle the absence of RTCK
-        *  and use a fallback kHz TCK.
-        */
-       int (*khz)(int khz, int* jtag_speed);
-
-       /* returns the KHz for the provided JTAG speed. 0=RTCK. The function returns
-        *  a failure if it can't support the KHz/RTCK. */
-       int (*speed_div)(int speed, int* khz);
-
-       /* Read and clear the power dropout flag. Note that a power dropout
-        *  can be transitionary, easily much less than a ms.
-        *
-        *  So to find out if the power is *currently* on, you must invoke
-        *  this method twice. Once to clear the power dropout flag and a
-        *  second time to read the current state.
-        *
-        *  Currently the default implementation is never to detect power dropout.
-        */
-       int (*power_dropout)(int* power_dropout);
-
-       /* Read and clear the srst asserted detection flag.
-        *
-        * NB!!!! like power_dropout this does *not* read the current
-        * state. srst assertion is transitionary and *can* be much
-        * less than 1ms.
-        */
-       int (*srst_asserted)(int* srst_asserted);
-} jtag_interface_t;
-
-#endif // INCLUDE_JTAG_INTERFACE_H
+void jtag_tap_init(jtag_tap_t *tap);
+void jtag_tap_free(jtag_tap_t *tap);
 
-enum jtag_event {
-       JTAG_TRST_ASSERTED
-};
+extern jtag_tap_t* jtag_all_taps(void);
+extern const char *jtag_tap_name(const jtag_tap_t *tap);
+extern jtag_tap_t* jtag_tap_by_string(const char* dotted_name);
+extern jtag_tap_t* jtag_tap_by_jim_obj(Jim_Interp* interp, Jim_Obj* obj);
+extern jtag_tap_t* jtag_tap_next_enabled(jtag_tap_t* p);
+extern unsigned jtag_tap_count_enabled(void);
+extern unsigned jtag_tap_count(void);
 
-extern char* jtag_event_strings[];
 
-enum jtag_tap_event {
+/*
+ * - TRST_ASSERTED triggers two sets of callbacks, after operations to
+ *   reset the scan chain -- via TMS+TCK signaling, or deasserting the
+ *   nTRST signal -- are queued:
+ *
+ *    + Callbacks in C code fire first, patching internal state
+ *    + Then post-reset event scripts fire ... activating JTAG circuits
+ *      via TCK cycles, exiting SWD mode via TMS sequences, etc
+ *
+ *   During those callbacks, scan chain contents have not been validated.
+ *   JTAG operations that address a specific TAP (primarily DR/IR scans)
+ *   must *not* be queued.
+ *
+ * - TAP_EVENT_SETUP is reported after TRST_ASSERTED, and after the scan
+ *   chain has been validated.  JTAG operations including scans that
+ *   target specific TAPs may be performed.
+ *
+ * - TAP_EVENT_ENABLE and TAP_EVENT_DISABLE implement TAP activation and
+ *   deactivation outside the core using scripted code that understands
+ *   the specific JTAG router type.  They might be triggered indirectly
+ *   from EVENT_SETUP operations.
+ */
+enum jtag_event {
+       JTAG_TRST_ASSERTED,
+       JTAG_TAP_EVENT_SETUP,
        JTAG_TAP_EVENT_ENABLE,
-       JTAG_TAP_EVENT_DISABLE
+       JTAG_TAP_EVENT_DISABLE,
 };
 
-extern const Jim_Nvp nvp_jtag_tap_event[];
-
 struct jtag_tap_event_action_s
 {
-       enum jtag_tap_event      event;
+       enum jtag_event         event;
        Jim_Obj*                 body;
        jtag_tap_event_action_t* next;
 };
 
-extern int jtag_trst;
-extern int jtag_srst;
+/**
+ * Defines the function signature requide for JTAG event callback
+ * functions, which are added with jtag_register_event_callback()
+ * and removed jtag_unregister_event_callback().
+ * @param event The event to handle.
+ * @param prive A pointer to data that was passed to
+ *     jtag_register_event_callback().
+ * @returns Must return ERROR_OK on success, or an error code on failure.
+ *
+ * @todo Change to return void or define a use for its return code.
+ */
+typedef int (*jtag_event_handler_t)(enum jtag_event event, void* priv);
 
-typedef struct jtag_event_callback_s
-{
-       int (*callback)(enum jtag_event event, void* priv);
-       void*                         priv;
-       struct jtag_event_callback_s* next;
-} jtag_event_callback_t;
+extern int jtag_register_event_callback(jtag_event_handler_t f, void *x);
+extern int jtag_unregister_event_callback(jtag_event_handler_t f, void *x);
 
-extern jtag_event_callback_t* jtag_event_callbacks;
+extern int jtag_call_event_callbacks(enum jtag_event event);
+
+
+/// @returns The current JTAG speed setting.
+int jtag_get_speed(void);
+/**
+ * Given a @a speed setting, use the interface @c speed_div callback to
+ * adjust the setting.
+ * @param speed The speed setting to convert back to readable KHz.
+ * @returns ERROR_OK if the interface has not been initialized or on success;
+ *     otherwise, the error code produced by the @c speed_div callback.
+ */
+int jtag_get_speed_readable(int *speed);
+/**
+ * Set the JTAG speed. This routine will call the underlying
+ * interface @c speed callback, if the interface has been initialized.
+ * @param speed The new speed setting.
+ * @returns ERROR_OK during configuration or on success, or an error
+ *   code returned from the interface @c speed callback.
+ */
+int jtag_config_speed(int speed);
+
+
+/// Attempt to configure the interface for the specified KHz.
+int jtag_config_khz(unsigned khz);
+/**
+ * Attempt to enable RTCK/RCLK. If that fails, fallback to the
+ * specified frequency.
+ */
+int jtag_config_rclk(unsigned fallback_speed_khz);
+/// Retreives the clock speed of the JTAG interface in KHz.
+unsigned jtag_get_speed_khz(void);
 
-extern int jtag_speed;
-extern int jtag_speed_post_reset;
 
 enum reset_types {
        RESET_NONE            = 0x0,
@@ -539,124 +291,199 @@ enum reset_types {
        RESET_TRST_PULLS_SRST = 0x8,
        RESET_TRST_OPEN_DRAIN = 0x10,
        RESET_SRST_PUSH_PULL  = 0x20,
+       RESET_SRST_NO_GATING  = 0x40,
 };
 
-extern enum reset_types jtag_reset_config;
+enum reset_types jtag_get_reset_config(void);
+void jtag_set_reset_config(enum reset_types type);
+
+void jtag_set_nsrst_delay(unsigned delay);
+unsigned jtag_get_nsrst_delay(void);
+
+void jtag_set_ntrst_delay(unsigned delay);
+unsigned jtag_get_ntrst_delay(void);
+
+void jtag_set_nsrst_assert_width(unsigned delay);
+unsigned jtag_get_nsrst_assert_width(void);
+
+void jtag_set_ntrst_assert_width(unsigned delay);
+unsigned jtag_get_ntrst_assert_width(void);
+
+/// @returns The current state of TRST.
+int jtag_get_trst(void);
+/// @returns The current state of SRST.
+int jtag_get_srst(void);
 
-/* initialize interface upon startup. A successful no-op
- * upon subsequent invocations
+/// Enable or disable data scan verification checking.
+void jtag_set_verify(bool enable);
+/// @returns True if data scan verification will be performed.
+bool jtag_will_verify(void);
+
+/// Enable or disable verification of IR scan checking.
+void jtag_set_verify_capture_ir(bool enable);
+/// @returns True if IR scan verification will be performed.
+bool jtag_will_verify_capture_ir(void);
+
+/**
+ * Initialize interface upon startup.  Return a successful no-op upon
+ * subsequent invocations.
  */
 extern int  jtag_interface_init(struct command_context_s* cmd_ctx);
 
 /// Shutdown the JTAG interface upon program exit.
 extern int  jtag_interface_quit(void);
 
-/* initialize JTAG chain using only a RESET reset. If init fails,
+/**
+ * Initialize JTAG chain using only a RESET reset. If init fails,
  * try reset + init.
  */
 extern int  jtag_init(struct command_context_s* cmd_ctx);
 
-/* reset, then initialize JTAG chain */
-extern int  jtag_init_reset(struct command_context_s* cmd_ctx);
-extern int  jtag_register_commands(struct command_context_s* cmd_ctx);
+/// reset, then initialize JTAG chain
+extern int jtag_init_reset(struct command_context_s* cmd_ctx);
+extern int jtag_register_commands(struct command_context_s* cmd_ctx);
+extern int jtag_init_inner(struct command_context_s *cmd_ctx);
+
+/**
+ * @file
+ * The JTAG interface can be implemented with a software or hardware fifo.
+ *
+ * TAP_DRSHIFT and TAP_IRSHIFT are illegal end states; however,
+ * TAP_DRSHIFT/IRSHIFT can be emulated as end states, by using longer
+ * scans.
+ *
+ * Code that is relatively insensitive to the path taken through state
+ * machine (as long as it is JTAG compliant) can use @a endstate for
+ * jtag_add_xxx_scan(). Otherwise, the pause state must be specified as
+ * end state and a subsequent jtag_add_pathmove() must be issued.
+ */
 
-/* JTAG interface, can be implemented with a software or hardware fifo
+/**
+ * Generate an IR SCAN with a list of scan fields with one entry for
+ * each enabled TAP.
  *
- * TAP_DRSHIFT and TAP_IRSHIFT are illegal end states. TAP_DRSHIFT/IRSHIFT as end states
- * can be emulated by using a larger scan.
+ * If the input field list contains an instruction value for a TAP then
+ * that is used otherwise the TAP is set to bypass.
  *
- * Code that is relatively insensitive to the path(as long
- * as it is JTAG compliant) taken through state machine can use
- * endstate for jtag_add_xxx_scan(). Otherwise the pause state must be
- * specified as end state and a subsequent jtag_add_pathmove() must
- * be issued.
+ * TAPs for which no fields are passed are marked as bypassed for
+ * subsequent DR SCANs.
  *
  */
 extern void jtag_add_ir_scan(int num_fields, scan_field_t* fields, tap_state_t endstate);
-/* same as jtag_add_ir_scan except no verify is performed */
+/**
+ * The same as jtag_add_ir_scan except no verification is performed out
+ * the output values.
+ */
 extern void jtag_add_ir_scan_noverify(int num_fields, const scan_field_t *fields, tap_state_t state);
-extern void jtag_add_dr_scan(int num_fields, const scan_field_t* fields, tap_state_t endstate);
+/**
+ * Duplicate the scan fields passed into the function into an IR SCAN
+ * command.  This function assumes that the caller handles extra fields
+ * for bypassed TAPs.
+ */
+extern void jtag_add_plain_ir_scan(int num_fields, const scan_field_t* fields, tap_state_t endstate);
 
-/* set in_value to point to 32 bits of memory to scan into. This function
- * is a way to handle the case of synchronous and asynchronous
+
+/**
+ * Set in_value to point to 32 bits of memory to scan into. This
+ * function is a way to handle the case of synchronous and asynchronous
  * JTAG queues.
  *
  * In the event of an asynchronous queue execution the queue buffer
- * allocation method is used, for the synchronous case the temporary 32 bits come
- * from the input field itself.
+ * allocation method is used, for the synchronous case the temporary 32
+ * bits come from the input field itself.
  */
 extern void jtag_alloc_in_value32(scan_field_t *field);
 
-/* This version of jtag_add_dr_scan() uses the check_value/mask fields */
+/**
+ * Generate a DR SCAN using the fields passed to the function.
+ * For connected TAPs, the function checks in_fields and uses fields
+ * specified there.  For bypassed TAPs, the function generates a dummy
+ * 1-bit field.  The bypass status of TAPs is set by jtag_add_ir_scan().
+ */
+extern void jtag_add_dr_scan(int num_fields, const scan_field_t* fields, tap_state_t endstate);
+/// A version of jtag_add_dr_scan() that uses the check_value/mask fields
 extern void jtag_add_dr_scan_check(int num_fields, scan_field_t* fields, tap_state_t endstate);
-extern void jtag_add_plain_ir_scan(int num_fields, const scan_field_t* fields, tap_state_t endstate);
+/**
+ * Duplicate the scan fields passed into the function into a DR SCAN
+ * command.  Unlike jtag_add_dr_scan(), this function assumes that the
+ * caller handles extra fields for bypassed TAPs.
+ */
 extern void jtag_add_plain_dr_scan(int num_fields, const scan_field_t* fields, tap_state_t endstate);
 
+/**
+ * Defines the type of data passed to the jtag_callback_t interface.
+ * The underlying type must allow storing an @c int or pointer type.
+ */
+typedef intptr_t jtag_callback_data_t;
 
-/* Simplest/typical callback - do some conversion on the data clocked in.
- * This callback is for such conversion that can not fail.
- * For conversion types or checks that can
- * fail, use the jtag_callback_t variant */
-typedef void (*jtag_callback1_t)(u8 *in);
+/**
+ * Defines a simple JTAG callback that can allow conversions on data
+ * scanned in from an interface.
+ *
+ * This callback should only be used for conversion that cannot fail.
+ * For conversion types or checks that can fail, use the more complete
+ * variant: jtag_callback_t.
+ */
+typedef void (*jtag_callback1_t)(jtag_callback_data_t data0);
 
-/* A simpler version of jtag_add_callback4 */
-extern void jtag_add_callback(jtag_callback1_t, u8 *in);
+/// A simpler version of jtag_add_callback4().
+extern void jtag_add_callback(jtag_callback1_t, jtag_callback_data_t data0);
 
 
-/* This type can store an integer safely by a normal cast on 64 and
- * 32 bit systems. */
-typedef intptr_t jtag_callback_data_t;
 
-/* The generic callback mechanism.
+/**
+ * Defines the interface of the JTAG callback mechanism.
  *
- * The callback is invoked with three arguments. The first argument is
- * the pointer to the data clocked in.
+ * @param in the pointer to the data clocked in
+ * @param data1 An integer big enough to use as an @c int or a pointer.
+ * @param data2 An integer big enough to use as an @c int or a pointer.
+ * @param data3 An integer big enough to use as an @c int or a pointer.
+ * @returns an error code
  */
-typedef int (*jtag_callback_t)(u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3);
+typedef int (*jtag_callback_t)(jtag_callback_data_t data0, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3);
 
 
-/* This callback can be executed immediately the queue has been flushed. Note that
- * the JTAG queue can either be executed synchronously or asynchronously. Typically
- * for USB the queue is executed asynchronously. For low latency interfaces, the
- * queue may be executed synchronously.
- *
- * These callbacks are typically executed *after* the *entire* JTAG queue has been
- * executed for e.g. USB interfaces.
- *
- * The callbacks are guaranteeed to be invoked in the order that they were queued.
- *
- * The strange name is due to C's lack of overloading using function arguments
+/**
+ * This callback can be executed immediately the queue has been flushed.
  *
- * The callback mechansim is very general and does not really make any assumptions
- * about what the callback does and what the arguments are.
+ * The JTAG queue can be executed synchronously or asynchronously.
+ * Typically for USB, the queue is executed asynchronously.  For
+ * low-latency interfaces, the queue may be executed synchronously.
  *
- * in - typically used to point to the data to operate on. More often than not
- * this will be the data clocked in during a shift operation
+ * The callback mechanism is very general and does not make many
+ * assumptions about what the callback does or what its arguments are.
+ * These callbacks are typically executed *after* the *entire* JTAG
+ * queue has been executed for e.g. USB interfaces, and they are
+ * guaranteeed to be invoked in the order that they were queued.
  *
- * data1 - an integer that is big enough to be used either as an 'int' or
- * cast to/from a pointer
+ * If the execution of the queue fails before the callbacks, then --
+ * depending on driver implementation -- the callbacks may or may not be
+ * invoked.  @todo Can we make this behavior consistent?
  *
- * data2 - an integer that is big enough to be used either as an 'int' or
- * cast to/from a pointer
+ * The strange name is due to C's lack of overloading using function
+ * arguments.
  *
- * Why stop at 'data2' for arguments? Somewhat historical reasons. This is
- * sufficient to implement the jtag_check_value_mask(), besides the
- * line is best drawn somewhere...
+ * @param f The callback function to add.
+ * @param data0 Typically used to point to the data to operate on.
+ * Frequently this will be the data clocked in during a shift operation.
+ * @param data1 An integer big enough to use as an @c int or a pointer.
+ * @param data2 An integer big enough to use as an @c int or a pointer.
+ * @param data3 An integer big enough to use as an @c int or a pointer.
  *
- * If the execution of the queue fails before the callbacks, then the
- * callbacks may or may not be invoked depending on driver implementation.
  */
-extern void jtag_add_callback4(jtag_callback_t, u8 *in,
+extern void jtag_add_callback4(jtag_callback_t f, jtag_callback_data_t data0,
                jtag_callback_data_t data1, jtag_callback_data_t data2,
                jtag_callback_data_t data3);
 
 
-/* run a TAP_RESET reset. End state is TAP_RESET, regardless
- * of start state.
+/**
+ * Run a TAP_RESET reset where the end state is TAP_RESET,
+ * regardless of the start state.
  */
 extern void jtag_add_tlr(void);
 
-/* Application code *must* assume that interfaces will
+/**
+ * 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
@@ -696,19 +523,40 @@ extern void jtag_add_tlr(void);
  * can only implement a few transitions and therefore
  * a partial implementation of pathmove would have little practical
  * application.
+ *
+ * If an error occurs, jtag_error will contain one of these error codes:
+ *   - ERROR_JTAG_NOT_STABLE_STATE -- The final state was not stable.
+ *   - ERROR_JTAG_STATE_INVALID -- The path passed through TAP_RESET.
+ *   - ERROR_JTAG_TRANSITION_INVALID -- The path includes invalid
+ *     state transitions.
  */
 extern void jtag_add_pathmove(int num_states, const tap_state_t* path);
 
-/* go to TAP_IDLE, if we're not already there and cycle
- * precisely num_cycles in the TAP_IDLE after which move
- * to the end state, if it is != TAP_IDLE
+/**
+ * jtag_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.
  *
- * nb! num_cycles can be 0, in which case the fn will navigate
- * to endstate via TAP_IDLE
+ * Moves from the current state to the goal \a state.
+ * Both states must be stable.
+ */
+extern int jtag_add_statemove(tap_state_t goal_state);
+
+/**
+ * Goes to TAP_IDLE (if we're not already there), cycle
+ * precisely num_cycles in the TAP_IDLE state, after which move
+ * to @a endstate (unless it is also TAP_IDLE).
+ *
+ * @param num_cycles Number of cycles in TAP_IDLE state.  This argument
+ *     may be 0, in which case this routine will navigate to @a endstate
+ *     via TAP_IDLE.
+ * @param endstate The final state.
  */
 extern void jtag_add_runtest(int num_cycles, tap_state_t endstate);
 
-/* A reset of the TAP state machine can be requested.
+/**
+ * A reset of the TAP state machine can be requested.
  *
  * Whether tms or trst reset is used depends on the capabilities of
  * the target and jtag interface(reset_config  command configures this).
@@ -732,8 +580,24 @@ extern void jtag_add_runtest(int num_cycles, tap_state_t endstate);
  */
 extern void jtag_add_reset(int req_tlr_or_trst, int srst);
 
-extern void jtag_add_end_state(tap_state_t endstate);
-extern void jtag_add_sleep(u32 us);
+
+/**
+ * Function jtag_set_end_state
+ *
+ * Set a global variable to \a state if \a state != TAP_INVALID.
+ *
+ * Return the value of the global variable.
+ *
+ **/
+extern tap_state_t jtag_set_end_state(tap_state_t state);
+/**
+ * Function jtag_get_end_state
+ *
+ * Return the value of the global variable for end state
+ *
+ **/
+extern tap_state_t jtag_get_end_state(void);
+extern void jtag_add_sleep(uint32_t us);
 
 
 /**
@@ -744,7 +608,7 @@ extern void jtag_add_sleep(u32 us);
 void jtag_add_clocks(int num_cycles);
 
 
-/*
+/**
  * For software FIFO implementations, the queued commands can be executed
  * during this call or earlier. A sw queue might decide to push out
  * some of the jtag_add_xxx() operations once the queue is "big enough".
@@ -754,7 +618,7 @@ void jtag_add_clocks(int num_cycles);
  * matter if the operation was executed *before* jtag_execute_queue(),
  * jtag_execute_queue() will still return an error code.
  *
- * All jtag_add_xxx() calls that have in_handler!=NULL will have been
+ * All jtag_add_xxx() calls that have in_handler != NULL will have been
  * executed when this fn returns, but if what has been queued only
  * clocks data out, without reading anything back, then JTAG could
  * be running *after* jtag_execute_queue() returns. The API does
@@ -764,59 +628,39 @@ void jtag_add_clocks(int num_cycles);
  * jtag_add_xxx() commands can either be executed immediately or
  * at some time between the jtag_add_xxx() fn call and jtag_execute_queue().
  */
-extern int            jtag_execute_queue(void);
+extern int jtag_execute_queue(void);
 
-/* same as jtag_execute_queue() but does not clear the error flag */
+/// same as jtag_execute_queue() but does not clear the error flag
 extern void jtag_execute_queue_noclear(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;
-
-static __inline__ void jtag_set_error(int error)
-{
-       if ((error==ERROR_OK)||(jtag_error!=ERROR_OK))
-       {
-               /* keep first error */
-               return;
-       }
-       jtag_error=error;
-}
+/// @returns the number of times the scan queue has been flushed
+int jtag_get_flush_queue_count(void);
 
+/// Report Tcl event to all TAPs
+void jtag_notify_event(enum jtag_event);
 
 
-/* can be implemented by hw+sw */
-extern int            jtag_power_dropout(int* dropout);
-extern int            jtag_srst_asserted(int* srst_asserted);
+/* can be implemented by hw + sw */
+extern int jtag_power_dropout(int* dropout);
+extern int jtag_srst_asserted(int* srst_asserted);
 
 /* JTAG support functions */
 
-/* execute jtag queue and check value and use mask if mask is != NULL. invokes
- * jtag_set_error() with any error. */
-extern void jtag_check_value_mask(scan_field_t *field, u8 *value, u8 *mask);
-
-#ifdef INCLUDE_JTAG_INTERFACE_H
-extern enum scan_type jtag_scan_type(const scan_command_t* cmd);
-extern int            jtag_scan_size(const scan_command_t* cmd);
-extern int            jtag_read_buffer(u8* buffer, const scan_command_t* cmd);
-extern int            jtag_build_buffer(const scan_command_t* cmd, u8** buffer);
-#endif  // INCLUDE_JTAG_INTERFACE_H
-
-extern void           jtag_sleep(u32 us);
-extern int            jtag_call_event_callbacks(enum jtag_event event);
-extern int            jtag_register_event_callback(int (* callback)(enum jtag_event event, void* priv), void* priv);
-
-extern int jtag_verify_capture_ir;
-
-void jtag_tap_handle_event(jtag_tap_t* tap, enum jtag_tap_event e);
+/**
+ * Execute jtag queue and check value with an optional mask.
+ * @param field Pointer to scan field.
+ * @param value Pointer to scan value.
+ * @param mask Pointer to scan mask; may be NULL.
+ * @returns Nothing, but calls jtag_set_error() on any error.
+ */
+extern void jtag_check_value_mask(scan_field_t *field, uint8_t *value, uint8_t *mask);
 
-/* error codes
- * JTAG subsystem uses codes between -100 and -199 */
+extern void jtag_sleep(uint32_t us);
 
+/*
+ * The JTAG subsystem defines a number of error codes,
+ * using codes between -100 and -199.
+ */
 #define ERROR_JTAG_INIT_FAILED       (-100)
 #define ERROR_JTAG_INVALID_INTERFACE (-101)
 #define ERROR_JTAG_NOT_IMPLEMENTED   (-102)
@@ -824,8 +668,12 @@ void jtag_tap_handle_event(jtag_tap_t* tap, enum jtag_tap_event e);
 #define ERROR_JTAG_QUEUE_FAILED      (-104)
 #define ERROR_JTAG_NOT_STABLE_STATE  (-105)
 #define ERROR_JTAG_DEVICE_ERROR      (-107)
+#define ERROR_JTAG_STATE_INVALID     (-108)
+#define ERROR_JTAG_TRANSITION_INVALID (-109)
+#define ERROR_JTAG_INIT_SOFT_FAIL    (-110)
 
-/* jtag_add_dr_out() is a version of jtag_add_dr_scan() which
+/**
+ * jtag_add_dr_out() is a version of jtag_add_dr_scan() which
  * only scans data out. It operates on 32 bit integers instead
  * of 8 bit, which makes it a better impedance match with
  * the calling code which often operate on 32 bit integers.
@@ -835,9 +683,9 @@ void jtag_tap_handle_event(jtag_tap_t* tap, enum jtag_tap_event e);
  * num_bits[i] is the number of bits to clock out from value[i] LSB first.
  *
  * If the device is in bypass, then that is an error condition in
- * the caller code that is not detected by this fn, whereas jtag_add_dr_scan()
- * does detect it. Similarly if the device is not in bypass, data must
- * be passed to it.
+ * the caller code that is not detected by this fn, whereas
+ * jtag_add_dr_scan() does detect it. Similarly if the device is not in
+ * bypass, data must be passed to it.
  *
  * If anything fails, then jtag_error will be set and jtag_execute() will
  * return an error. There is no way to determine if there was a failure
@@ -851,16 +699,40 @@ void jtag_tap_handle_event(jtag_tap_t* tap, enum jtag_tap_event e);
  * clocking data back in. Patches gladly accepted!
  */
 extern void jtag_add_dr_out(jtag_tap_t* tap,
-               int num_fields, const int* num_bits, const u32* value,
+               int num_fields, const int* num_bits, const uint32_t* value,
                tap_state_t end_state);
 
 
 /**
- * Function jtag_add_statemove
- * 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.
+ * Set the current JTAG core execution error, unless one was set
+ * by a previous call previously.  Driver or application code must
+ * use jtag_error_clear to reset jtag_error once this routine has been
+ * called with a non-zero error code.
  */
-extern int jtag_add_statemove(tap_state_t goal_state);
+void jtag_set_error(int error);
+/// @returns The current value of jtag_error
+int jtag_get_error(void);
+/**
+ * Resets jtag_error to ERROR_OK, returning its previous value.
+ * @returns The previous value of @c jtag_error.
+ */
+int jtag_error_clear(void);
+
+/**
+ * Return true if it's safe for a background polling task to access the
+ * JTAG scan chain.  Polling may be explicitly disallowed, and is also
+ * unsafe while nTRST is active or the JTAG clock is gated off.,
+ */
+bool is_jtag_poll_safe(void);
+
+/**
+ * Return flag reporting whether JTAG polling is disallowed.
+ */
+bool jtag_poll_get_enabled(void);
+
+/**
+ * Assign flag reporting whether JTAG polling is disallowed.
+ */
+void jtag_poll_set_enabled(bool value);
 
 #endif /* JTAG_H */

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)