]> git.sur5r.net Git - openocd/blobdiff - src/jtag/interface.h
armv7m_trace, stlink: provide APIs to capture trace with an adapter
[openocd] / src / jtag / interface.h
index 79e3a3e9fb4d3b81b90a3b4a45b2f063074e2e8e..e7b20148e3b4c9d451d555bfaffce6066072c23c 100644 (file)
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
  ***************************************************************************/
+
 #ifndef OPENOCD_JTAG_INTERFACE_H
 #define OPENOCD_JTAG_INTERFACE_H
 
-#include "jtag.h"
+#include <jtag/jtag.h>
+#include <target/armv7m_trace.h>
 
 /* @file
  * The "Cable Helper API" is what the cable drivers can use to help
@@ -54,12 +56,12 @@ void tap_set_state_impl(tap_state_t new_state);
  * expected to traverse, not just end points of a multi-step state path.
  *
  * @param new_state The state we think the TAPs are currently in (or
- *     are about to enter).
+ * 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) ); \
+               LOG_DEBUG("tap_set_state(%s)", tap_state_name(new_state)); \
                tap_set_state_impl(new_state); \
        } while (0)
 #else
@@ -85,7 +87,7 @@ tap_state_t tap_get_state(void);
  * state follower via tap_set_state().
  *
  * @param new_end_state The state the TAPs should enter at completion of
- *     a pending TAP operation.
+ * a pending TAP operation.
  */
 void tap_set_end_state(tap_state_t new_end_state);
 
@@ -106,11 +108,10 @@ tap_state_t tap_get_end_state(void);
  * @param from The starting state.
  * @param to The desired final state.
  * @return int The required TMS bit sequence, with the first bit in the
- *     sequence at bit 0.
+ * sequence at bit 0.
  */
 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
@@ -160,12 +161,9 @@ bool tap_is_state_stable(tap_state_t astate);
  */
 tap_state_t tap_state_transition(tap_state_t current_state, bool tms);
 
-/// Provides user-friendly name lookup of TAP states.
-tap_state_t tap_state_by_name(const char *name);
-
-/// Allow switching between old and new TMS tables. @see tap_get_tms_path
+/** Allow switching between old and new TMS tables. @see tap_get_tms_path */
 void tap_use_new_tms_table(bool use_new);
-/// @returns True if new TMS table is active; false otherwise.
+/** @returns True if new TMS table is active; false otherwise. */
 bool tap_uses_new_tms_table(void);
 
 #ifdef _DEBUG_JTAG_IO_
@@ -185,56 +183,155 @@ static inline tap_state_t jtag_debug_state_machine(const void *tms_buf,
 {
        return start_tap_state;
 }
-#endif // _DEBUG_JTAG_IO_
+#endif /* _DEBUG_JTAG_IO_ */
 
-typedef struct jtag_interface_s
-{
-       char* name;
+/**
+ * Represents a driver for a debugging interface.
+ *
+ * @todo Rename; perhaps "debug_driver".  This isn't an interface,
+ * it's a driver!  Also, not all drivers support JTAG.
+ *
+ * @todo We need a per-instance structure too, and changes to pass
+ * that structure to the driver.  Instances can for example be in
+ * either SWD or JTAG modes.  This will help remove globals, and
+ * eventually to cope with systems which have more than one such
+ * debugging interface.
+ */
+struct jtag_interface {
+       /** The name of the JTAG interface driver. */
+       const char * const name;
 
-       /* queued command execution
+       /**
+        * Bit vector listing capabilities exposed by this driver.
+        */
+       unsigned supported;
+#define DEBUG_CAP_TMS_SEQ      (1 << 0)
+
+       /** transports supported in C code (NULL terminated vector) */
+       const char * const *transports;
+
+       const struct swd_driver *swd;
+
+       /**
+        * Execute queued commands.
+        * @returns ERROR_OK on success, or an error code on failure.
         */
        int (*execute_queue)(void);
 
-       /* interface initalization
+       /**
+        * Set the interface speed.
+        * @param speed The new interface speed setting.
+        * @returns ERROR_OK on success, or an error code on failure.
         */
        int (*speed)(int speed);
-       int (*register_commands)(struct command_context_s* cmd_ctx);
+
+       /**
+        * The interface driver may register additional commands to expose
+        * additional features not covered by the standard command set.
+        */
+       const struct command_registration *commands;
+
+       /**
+        * Interface driver must initialize any resources and connect to a
+        * JTAG device.
+        *
+        * quit() is invoked if and only if init() succeeds. quit() is always
+        * invoked if init() succeeds. Same as malloc() + free(). Always
+        * invoke free() if malloc() succeeds and do not invoke free()
+        * otherwise.
+        *
+        * @returns ERROR_OK on success, or an error code on failure.
+        */
        int (*init)(void);
+
+       /**
+        * Interface driver must tear down all resources and disconnect from
+        * the JTAG device.
+        *
+        * @returns ERROR_OK on success, or an error code on failure.
+        */
        int (*quit)(void);
 
-       /* returns JTAG maxium speed for KHz. 0=RTCK. The function returns
+       /**
+        * 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.
+        * @returns ERROR_OK on success, or an error code on failure.
         */
-       int (*khz)(int khz, intjtag_speed);
+       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);
+       /**
+        * Calculate the clock frequency (in KHz) for the given @a speed.
+        * @param speed The desired interface speed setting.
+        * @param khz On return, contains the speed in KHz (0 for RTCK).
+        * @returns ERROR_OK on success, or an error code if the
+        * interface cannot support the specified speed (KHz or 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.
+       /**
+        * 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.
+        * To find out if the power is *currently* on, one must invoke this
+        * method twice.  Once to clear the power dropout flag and a second
+        * time to read the current state.  The default implementation
+        * never reports power dropouts.
         *
-        *  Currently the default implementation is never to detect power dropout.
+        * @returns ERROR_OK on success, or an error code on failure.
         */
-       int (*power_dropout)(intpower_dropout);
+       int (*power_dropout)(int *power_dropout);
 
-       /* Read and clear the srst asserted detection flag.
+       /**
+        * 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.
+        * Like power_dropout this does *not* read the current
+        * state.  SRST assertion is transitionary and may be much
+        * less than 1ms, so the interface driver must watch for these
+        * events until this routine is called.
+        *
+        * @param srst_asserted On return, indicates whether SRST has
+        * been asserted.
+        * @returns ERROR_OK on success, or an error code on failure.
         */
-       int (*srst_asserted)(int* srst_asserted);
-} jtag_interface_t;
+       int (*srst_asserted)(int *srst_asserted);
+
+       /**
+        * Configure trace parameters for the adapter
+        *
+        * @param enabled Whether to enable trace
+        * @param pin_protocol Configured pin protocol
+        * @param port_size Trace port width for sync mode
+        * @param trace_freq A pointer to the configured trace
+        * frequency; if it points to 0, the adapter driver must write
+        * its maximum supported rate there
+        * @returns ERROR_OK on success, an error code on failure.
+        */
+       int (*config_trace)(bool enabled, enum tpio_pin_protocol pin_protocol,
+                           uint32_t port_size, unsigned int *trace_freq);
+
+       /**
+        * Poll for new trace data
+        *
+        * @param buf A pointer to buffer to store received data
+        * @param size A pointer to buffer size; must be filled with
+        * the actual amount of bytes written
+        *
+        * @returns ERROR_OK on success, an error code on failure.
+        */
+       int (*poll_trace)(uint8_t *buf, size_t *size);
+};
+
+extern const char * const jtag_only[];
 
+void adapter_assert_reset(void);
+void adapter_deassert_reset(void);
+int adapter_config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
+                        uint32_t port_size, unsigned int *trace_freq);
+int adapter_poll_trace(uint8_t *buf, size_t *size);
 
-#endif // OPENOCD_JTAG_INTERFACE_H
+#endif /* OPENOCD_JTAG_INTERFACE_H */