SVF: clean up, mostly for TAP state name handling
[openocd.git] / src / jtag / jtag.h
index 459f7fd0ed3a45ec7101d4737c47ea9cfd0c50f4..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
@@ -100,7 +102,10 @@ typedef enum tap_state
  * Function tap_state_name
  * Returns a string suitable for display representing the JTAG tap_state
  */
-const char* tap_state_name(tap_state_t state);
+const char *tap_state_name(tap_state_t state);
+
+/// 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;
@@ -123,28 +128,28 @@ typedef struct scan_field_s
        /// The number of bits this field specifies (up to 32)
        int num_bits;
        /// A pointer to value to be scanned into the device
-       u8* out_value;
+       uint8_t* out_value;
        /// A pointer to a 32-bit memory location for data scanned out
-       u8* in_value;
+       uint8_t* in_value;
 
        /// The value used to check the data scanned out.
-       u8* check_value;
+       uint8_t* check_value;
        /// The mask to go with check_value
-       u8* check_mask;
+       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
-       u8 intmp[4];
+       uint8_t intmp[4];
 } scan_field_t;
 
 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;
@@ -156,20 +161,21 @@ struct jtag_tap_s
        /// Is this TAP currently enabled?
        bool 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;
+       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 */
-       u32* expected_ids;
+       uint32_t* expected_ids;
        /// Number of expected identification codes
-       u8 expected_ids_cnt;
+       uint8_t expected_ids_cnt;
 
        /// current instruction
-       u8* cur_instr;
+       uint8_t* cur_instr;
        /// Bypass register selected
        int bypass;
 
@@ -185,27 +191,36 @@ 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_by_position(unsigned abs_position);
 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);
 
 
 /*
- * There are three cases when JTAG_TRST_ASSERTED callback is invoked. The
- * event is invoked *after* TRST is asserted(or queued rather). It is illegal
- * to communicate with the JTAG interface during the callback(as there is
- * currently a queue being built).
+ * - 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
  *
- * - TMS reset
- * - SRST pulls TRST
- * - TRST asserted
+ *   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 activation/deactivation is currently implemented outside the core
- * using scripted code that understands the specific router type.
+ * - 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,
 };
@@ -253,13 +268,16 @@ int jtag_get_speed_readable(int *speed);
  * @returns ERROR_OK during configuration or on success, or an error
  *   code returned from the interface @c speed callback.
  */
-int jtag_set_speed(int speed);
+int jtag_config_speed(int speed);
 
 
 /// Attempt to configure the interface for the specified KHz.
 int jtag_config_khz(unsigned khz);
-/// Set the clock speed of the JTAG interface in KHz.
-void jtag_set_speed_khz(unsigned speed);
+/**
+ * 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);
 
@@ -273,6 +291,7 @@ enum reset_types {
        RESET_TRST_PULLS_SRST = 0x8,
        RESET_TRST_OPEN_DRAIN = 0x10,
        RESET_SRST_PUSH_PULL  = 0x20,
+       RESET_SRST_NO_GATING  = 0x40,
 };
 
 enum reset_types jtag_get_reset_config(void);
@@ -284,6 +303,12 @@ 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.
@@ -315,8 +340,9 @@ extern int  jtag_interface_quit(void);
 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);
+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
@@ -384,6 +410,11 @@ extern void jtag_add_dr_scan_check(int num_fields, scan_field_t* fields, tap_sta
  */
 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;
 
 /**
  * Defines a simple JTAG callback that can allow conversions on data
@@ -393,17 +424,12 @@ extern void jtag_add_plain_dr_scan(int num_fields, const scan_field_t* fields, t
  * For conversion types or checks that can fail, use the more complete
  * variant: jtag_callback_t.
  */
-typedef void (*jtag_callback1_t)(u8 *in);
+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);
+extern void jtag_add_callback(jtag_callback1_t, jtag_callback_data_t data0);
 
 
-/**
- * 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;
 
 /**
  * Defines the interface of the JTAG callback mechanism.
@@ -414,7 +440,7 @@ typedef intptr_t jtag_callback_data_t;
  * @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);
 
 
 /**
@@ -438,14 +464,14 @@ typedef int (*jtag_callback_t)(u8 *in, jtag_callback_data_t data1, jtag_callback
  * arguments.
  *
  * @param f The callback function to add.
- * @param in Typically used to point to the data to operate on.
+ * @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.
  *
  */
-extern void jtag_add_callback4(jtag_callback_t f, 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);
 
@@ -513,29 +539,7 @@ extern void jtag_add_pathmove(int num_states, const tap_state_t* path);
  * @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);
 
@@ -593,7 +597,7 @@ extern tap_state_t jtag_set_end_state(tap_state_t state);
  *
  **/
 extern tap_state_t jtag_get_end_state(void);
-extern void jtag_add_sleep(u32 us);
+extern void jtag_add_sleep(uint32_t us);
 
 
 /**
@@ -614,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
@@ -632,8 +636,11 @@ extern void jtag_execute_queue_noclear(void);
 /// @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 */
+
+/* can be implemented by hw + sw */
 extern int jtag_power_dropout(int* dropout);
 extern int jtag_srst_asserted(int* srst_asserted);
 
@@ -646,9 +653,9 @@ extern int jtag_srst_asserted(int* srst_asserted);
  * @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, u8 *value, u8 *mask);
+extern void jtag_check_value_mask(scan_field_t *field, uint8_t *value, uint8_t *mask);
 
-extern void jtag_sleep(u32 us);
+extern void jtag_sleep(uint32_t us);
 
 /*
  * The JTAG subsystem defines a number of error codes,
@@ -663,6 +670,7 @@ extern void jtag_sleep(u32 us);
 #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
@@ -691,7 +699,7 @@ extern void jtag_sleep(u32 us);
  * 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);
 
 
@@ -710,4 +718,21 @@ int jtag_get_error(void);
  */
 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)