interface: define TMS sequence command
authorDavid Brownell <dbrownell@users.sourceforge.net>
Sat, 27 Feb 2010 08:12:38 +0000 (00:12 -0800)
committerDavid Brownell <dbrownell@users.sourceforge.net>
Sat, 27 Feb 2010 08:12:38 +0000 (00:12 -0800)
For support of SWD we need to be able to clock out special bit
sequences over TMS or SWDIO.  Create this as a generic operation,
not yet called by anything, which is split as usual into:

 - upper level abstraction ... here, jtag_add_tms_seq();
 - midlayer implementation logic hooking that to the lowlevel code;
 - lowlevel minidriver operation ... here, interface_add_tms_seq();
 - message type for request queue, here JTAG_TMS.

This is done slightly differently than other operations: there's a flag
saying whether the interface driver supports this request.  (In fact a
flag *word* so upper layers can learn about other capabilities too ...
for example, supporting SWD operations.)

That approach (flag) lets this method *eventually* be used to eliminate
pathmove() and statemove() support from most adapter drivers, by moving
all that logic into the mid-layer and increasing uniformity between the
various drivers.  (Which will in turn reduce subtle bugginess.)

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
src/jtag/commands.h
src/jtag/core.c
src/jtag/drivers/driver.c
src/jtag/interface.h
src/jtag/jtag.h
src/jtag/minidriver.h
src/jtag/minidummy/minidummy.c
src/jtag/zy1000/zy1000.c

index b10b545369e28643345fbc8bd7dfef4d44959258..692eee430fbf8c101a99f35ecc8f425ec9aba847 100644 (file)
@@ -98,19 +98,39 @@ struct sleep_command {
        uint32_t us;
 };
 
+/**
+ * Encapsulates a series of bits to be clocked out, affecting state
+ * and mode of the interface.
+ *
+ * In JTAG mode these are clocked out on TMS, using TCK.  They may be
+ * used for link resets, transitioning between JTAG and SWD modes, or
+ * to implement JTAG state machine transitions (implementing pathmove
+ * or statemove operations).
+ *
+ * In SWD mode these are clocked out on SWDIO, using SWCLK, and are
+ * used for link resets and transitioning between SWD and JTAG modes.
+ */
+struct tms_command {
+       /** How many bits should be clocked out. */
+       unsigned        num_bits;
+       /** The bits to clock out; the LSB is bit 0 of bits[0].  */
+       const uint8_t           *bits;
+};
+
 /**
  * Defines a container type that hold a pointer to a JTAG command
  * structure of any defined type.
  */
 union jtag_command_container {
-       struct scan_command*         scan;
-       struct statemove_command*    statemove;
-       struct pathmove_command*     pathmove;
-       struct runtest_command*      runtest;
-       struct stableclocks_command* stableclocks;
-       struct reset_command*        reset;
-       struct end_state_command*    end_state;
-       struct sleep_command* sleep;
+       struct scan_command             *scan;
+       struct statemove_command        *statemove;
+       struct pathmove_command         *pathmove;
+       struct runtest_command          *runtest;
+       struct stableclocks_command     *stableclocks;
+       struct reset_command            *reset;
+       struct end_state_command        *end_state;
+       struct sleep_command            *sleep;
+       struct tms_command              *tms;
 };
 
 /**
@@ -124,7 +144,8 @@ enum jtag_command_type {
        JTAG_RESET        = 4,
        JTAG_PATHMOVE     = 6,
        JTAG_SLEEP        = 7,
-       JTAG_STABLECLOCKS = 8
+       JTAG_STABLECLOCKS = 8,
+       JTAG_TMS          = 9,
 };
 
 struct jtag_command {
index 4f517c098e0e354659b150ad1e7dce1f327a7ef8..7f417b737ce4cc7a0c101c7f7d6b4ddb2f61e705 100644 (file)
@@ -488,6 +488,35 @@ void jtag_add_tlr(void)
        jtag_notify_event(JTAG_TRST_ASSERTED);
 }
 
+/**
+ * If supported by the underlying adapter, this clocks a raw bit sequence
+ * onto TMS for switching betwen JTAG and SWD modes.
+ *
+ * DO NOT use this to bypass the integrity checks and logging provided
+ * by the jtag_add_pathmove() and jtag_add_statemove() calls.
+ *
+ * @param nbits How many bits to clock out.
+ * @param seq The bit sequence.  The LSB is bit 0 of seq[0].
+ * @param state The JTAG tap state to record on completion.  Use
+ *     TAP_INVALID to represent being in in SWD mode.
+ *
+ * @todo Update naming conventions to stop assuming everything is JTAG.
+ */
+int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state state)
+{
+       int retval;
+
+       if (!(jtag->supported & DEBUG_CAP_TMS_SEQ))
+               return ERROR_JTAG_NOT_IMPLEMENTED;
+
+       jtag_checks();
+       cmd_queue_cur_state = state;
+
+       retval = interface_add_tms_seq(nbits, seq);
+       jtag_set_error(retval);
+       return retval;
+}
+
 void jtag_add_pathmove(int num_states, const tap_state_t *path)
 {
        tap_state_t cur_state = cmd_queue_cur_state;
index 45c5d10afa8b4730cf78f83d8513620139b64f26..14efe965e7aad3037b12ac2a88b3809dcf0d4d06 100644 (file)
@@ -388,6 +388,31 @@ int interface_jtag_add_tlr(void)
        return ERROR_OK;
 }
 
+int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq)
+{
+       struct jtag_command *cmd;
+
+       cmd = cmd_queue_alloc(sizeof(struct jtag_command));
+       if (cmd == NULL)
+               return ERROR_FAIL;
+
+       cmd->type = JTAG_TMS;
+       cmd->cmd.tms = cmd_queue_alloc(sizeof(*cmd->cmd.tms));
+       if (!cmd->cmd.tms)
+               return ERROR_FAIL;
+
+       /* copy the bits; our caller doesn't guarantee they'll persist */
+       cmd->cmd.tms->num_bits = num_bits;
+       cmd->cmd.tms->bits = buf_cpy(seq,
+                       cmd_queue_alloc(DIV_ROUND_UP(num_bits, 8)), num_bits);
+       if (!cmd->cmd.tms->bits)
+               return ERROR_FAIL;
+
+       jtag_queue_command(cmd);
+
+       return ERROR_OK;
+}
+
 int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
 {
        /* allocate memory for a new list member */
index a264d69f274ba61c61fdad96ec2471952421b24a..0d474049e4860f1f22dc3c2230f431bb91460e71 100644 (file)
@@ -184,10 +184,28 @@ static inline tap_state_t jtag_debug_state_machine(const void *tms_buf,
 }
 #endif // _DEBUG_JTAG_IO_
 
+/**
+ * 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.
        char* name;
 
+       /**
+        * Bit vector listing capabilities exposed by this driver.
+        */
+       unsigned supported;
+#define DEBUG_CAP_TMS_SEQ      (1 << 0)
+
        /**
         * Execute queued commands.
         * @returns ERROR_OK on success, or an error code on failure.
index 055575407a273c4a8581c49900143a5ae0a5e347..7e5dc102b794cb2d48f3549f1f5c44b616bbc4df 100644 (file)
@@ -575,6 +575,8 @@ tap_state_t jtag_get_end_state(void);
 
 void jtag_add_sleep(uint32_t us);
 
+int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state t);
+
 /**
  * Function jtag_add_clocks
  * first checks that the state in which the clocks are to be issued is
@@ -693,7 +695,7 @@ 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.,
+ * unsafe while nTRST is active or the JTAG clock is gated off.
  */
 bool is_jtag_poll_safe(void);
 
index 2109c75f69ff4deee0ef87982d99687765ecb2af..5caec58b137112cf21e1c9e9d35c74b5ee5a9f5b 100644 (file)
@@ -67,6 +67,8 @@ int interface_jtag_add_tlr(void);
 int interface_jtag_add_pathmove(int num_states, const tap_state_t* path);
 int interface_jtag_add_runtest(int num_cycles, tap_state_t endstate);
 
+int interface_add_tms_seq(unsigned num_bits, const uint8_t *bits);
+
 /**
  * This drives the actual srst and trst pins. srst will always be 0
  * if jtag_reset_config & RESET_SRST_PULLS_TRST != 0 and ditto for
index 9c608cdbb460af9a292ac25b8eb39ef8035c6038..6410c2d2beafad132fc70e413c5f1a0e1d3e1d63 100644 (file)
@@ -147,6 +147,13 @@ int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
        return ERROR_OK;
 }
 
+int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq)
+{
+       /* synchronously do the operation here */
+
+       return ERROR_OK;
+}
+
 void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, int little, int count)
 {
        int i;
index d920c30b29ca95aee3d7cecd917dd7cb1deef6a3..e21104c7f45c1a8fdd2d679f51e3283f39bf892f 100644 (file)
@@ -804,7 +804,16 @@ int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
        return ERROR_OK;
 }
 
-
+int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq)
+{
+       /* FIXME just implement this, like pathmove but without
+        * JTAG-specific state transition checking.  Then update
+        * zy1000_interface to report that it's supported.
+        *
+        * Eventually interface_jtag_add_pathmove() could vanish.
+        */
+       return ERROR_JTAG_NOT_IMPLEMENTED;
+}
 
 void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, int little, int count)
 {

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)