This is an automated email from Gerrit.

Andreas Fritiofson (andreas.fritiof...@gmail.com) just uploaded a new patch set 
to Gerrit, which you can find at http://openocd.zylin.com/1959

-- gerrit

commit f2eb7e924bd71afc6312938cb3c25e40bfda6694
Author: Andreas Fritiofson <andreas.fritiof...@gmail.com>
Date:   Tue Feb 18 21:43:23 2014 +0100

    [WIP] swd: Convert API to asynchronous
    
    Change-Id: I859568dbb2ad4e92411980751c3f747bd70638b8
    Signed-off-by: Andreas Fritiofson <andreas.fritiof...@gmail.com>

diff --git a/src/jtag/drivers/cmsis_dap_usb.c b/src/jtag/drivers/cmsis_dap_usb.c
index cf7ff49..3cf727c 100644
--- a/src/jtag/drivers/cmsis_dap_usb.c
+++ b/src/jtag/drivers/cmsis_dap_usb.c
@@ -473,8 +473,13 @@ static int cmsis_dap_cmd_DAP_Delay(uint16_t delay_us)
 }
 #endif
 
-static int cmsis_dap_swd_read_reg(uint8_t cmd, uint32_t *value)
+static int queued_retval;
+
+static void cmsis_dap_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, 
uint32_t *value)
 {
+       if (queued_retval != ERROR_OK)
+               return;
+
        uint8_t *buffer = cmsis_dap_handle->packet_buffer;
        int retval;
        uint32_t val;
@@ -491,7 +496,8 @@ static int cmsis_dap_swd_read_reg(uint8_t cmd, uint32_t 
*value)
        /* TODO - need better response checking */
        if (retval != ERROR_OK || buffer[1] != 0x01) {
                LOG_ERROR("CMSIS-DAP: Read Error (0x%02" PRIx8 ")", buffer[2]);
-               return buffer[2];
+               queued_retval = buffer[2];
+               return;
        }
 
        val = le_to_h_u32(&buffer[3]);
@@ -500,11 +506,14 @@ static int cmsis_dap_swd_read_reg(uint8_t cmd, uint32_t 
*value)
        if (value)
                *value = val;
 
-       return retval;
+       queued_retval = retval;
 }
 
-static int cmsis_dap_swd_write_reg(uint8_t cmd, uint32_t value)
+static void cmsis_dap_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, 
uint32_t value)
 {
+       if (queued_retval != ERROR_OK)
+               return;
+
        uint8_t *buffer = cmsis_dap_handle->packet_buffer;
 
        DEBUG_IO("CMSIS-DAP: Write Reg 0x%02" PRIx8 " 0x%08" PRIx32, cmd, 
value);
@@ -525,6 +534,13 @@ static int cmsis_dap_swd_write_reg(uint8_t cmd, uint32_t 
value)
                retval = buffer[2];
        }
 
+       queued_retval = retval;
+}
+
+static int cmsis_dap_swd_run(struct adiv5_dap *dap)
+{
+       int retval = queued_retval;
+       queued_retval = ERROR_OK;
        return retval;
 }
 
@@ -1066,6 +1082,7 @@ static const struct swd_driver cmsis_dap_swd_driver = {
        .init       = cmsis_dap_swd_init,
        .read_reg   = cmsis_dap_swd_read_reg,
        .write_reg  = cmsis_dap_swd_write_reg,
+       .swd_run    = cmsis_dap_swd_run,
 };
 
 const char *cmsis_dap_transport[] = {"cmsis-dap", NULL};
diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c
index 39c6ad2..5511c69 100644
--- a/src/jtag/drivers/ftdi.c
+++ b/src/jtag/drivers/ftdi.c
@@ -852,12 +852,27 @@ static const struct command_registration 
ftdi_command_handlers[] = {
        COMMAND_REGISTRATION_DONE
 };
 
+/* FIXME: Where to store per-instance data? We need an SWD context. */
+static struct swd_cmd_queue_entry {
+       uint8_t cmd;
+       uint32_t *dst;
+       uint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)];
+} *swd_cmd_queue;
+static size_t swd_cmd_queue_length;
+static size_t swd_cmd_queue_alloced;
+static int queued_retval;
+static int swd_trn;
+
 static int ftdi_swd_init(uint8_t trn)
 {
-       LOG_INFO("Init SWD");
+       LOG_INFO("FTDI SWD mode enabled");
        swd_mode = true;
+       swd_trn = trn;
 
-       return ERROR_OK;
+       swd_cmd_queue_alloced = 10;
+       swd_cmd_queue = malloc(swd_cmd_queue_alloced * sizeof(*swd_cmd_queue));
+
+       return swd_cmd_queue != NULL ? ERROR_OK : ERROR_FAIL;
 }
 
 static void ftdi_swd_swdio_en(bool enable)
@@ -867,89 +882,136 @@ static void ftdi_swd_swdio_en(bool enable)
                ftdi_set_signal(trst, enable ? '1' : '0');
 }
 
-static int ftdi_swd_read_reg(uint8_t cmd, uint32_t *value)
+/**
+ * Flush the MPSSE queue and process the SWD transaction queue
+ * @param dap
+ * @return
+ */
+static int ftdi_swd_run_queue(struct adiv5_dap *dap)
 {
+       LOG_DEBUG("Executing %zu queued transactions", swd_cmd_queue_length);
+       int retval;
+       if (queued_retval != ERROR_OK) {
+               LOG_DEBUG("Skipping due to previous errors: %d", queued_retval);
+               goto skip;
+       }
 
-       cmd |= (1 << 0) | (1 << 7); /* Add Start and Park bits */
-       mpsse_clock_data_out(mpsse_ctx, &cmd, 0, 8, SWD_MODE);
+       /* A transaction must be followed by another transaction or at least 8 
idle cycles to
+        * ensure that data is clocked through the AP. */
+       mpsse_clock_data_out(mpsse_ctx, NULL, 0, 8, SWD_MODE);
 
-       ftdi_swd_swdio_en(false);
+       queued_retval = mpsse_flush(mpsse_ctx);
+       if (queued_retval != ERROR_OK) {
+               LOG_ERROR("MPSSE failed");
+               goto skip;
+       }
 
-       uint8_t trn_ack_data_parity_trn[5] = { 0 };
-       mpsse_clock_data_in(mpsse_ctx, trn_ack_data_parity_trn, 0, 1 + 3 + 32 + 
1 + 1, SWD_MODE);
+       for (size_t i = 0; i < swd_cmd_queue_length; i++) {
+               int ack = 
buf_get_u32(&swd_cmd_queue[i].trn_ack_data_parity_trn, swd_trn, 3);
 
-       ftdi_swd_swdio_en(true);
+               LOG_DEBUG("%s %s %s reg %X = %08"PRIx32,
+                               ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT 
? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK",
+                               swd_cmd_queue[i].cmd & SWD_CMD_APnDP ? "AP" : 
"DP",
+                               swd_cmd_queue[i].cmd & SWD_CMD_RnW ? "read" : 
"write",
+                               (swd_cmd_queue[i].cmd & SWD_CMD_A32) >> 1,
+                               
buf_get_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, swd_trn + 3, 32));
 
-       static const uint8_t idle = 0x00;
-       mpsse_clock_data_out(mpsse_ctx, &idle, 0, 8, SWD_MODE);
+               if (ack != SWD_ACK_OK) {
+                       queued_retval = ack;
+                       goto skip;
 
-       int retval = mpsse_flush(mpsse_ctx);
+               } else if (swd_cmd_queue[i].cmd & SWD_CMD_RnW) {
+                       uint32_t data = 
buf_get_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, swd_trn + 3, 32);
+                       int parity = 
buf_get_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, swd_trn + 3 + 32, 1);
 
-       if (retval != ERROR_OK) {
-               LOG_ERROR("MPSSE failed");
-               return retval;
+                       if (parity != parity_u32(data)) {
+                               LOG_ERROR("SWD Read data parity mismatch");
+                               queued_retval = ERROR_FAIL;
+                               goto skip;
+                       }
+
+                       if (swd_cmd_queue[i].dst != NULL)
+                               *swd_cmd_queue[i].dst = data;
+               }
        }
 
-       unsigned ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3);
-       uint32_t data = buf_get_u32(trn_ack_data_parity_trn, 4, 32);
-       int parity = buf_get_u32(trn_ack_data_parity_trn, 36, 1);
-       LOG_DEBUG("%s read reg %x = %08"PRIx32, cmd & 2 ? "AP" : "DP", (cmd >> 
1) & 0xc, data);
+skip:
+       swd_cmd_queue_length = 0;
+       retval = queued_retval;
+       queued_retval = ERROR_OK;
+       return retval;
+}
 
-       if (ack != 0x1) {
-               LOG_ERROR("Ack = %d", ack);
-               return ERROR_FAIL;
-       }
+static void ftdi_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd, uint32_t 
*dst, uint32_t data)
+{
+       if (queued_retval != ERROR_OK)
+               return;
 
-       if (parity != parity_u32(data)) {
-               LOG_ERROR("Parity mismatch");
-               return ERROR_FAIL;
+       if (swd_cmd_queue_length >= swd_cmd_queue_alloced) {
+               /* Not enough room in the queue. Run the queue and increase its 
size for next time.
+                * Note that it's not possible to avoid running the queue here, 
because mpsse contains
+                * pointers into the queue which may be invalid after the 
realloc. */
+               queued_retval = ftdi_swd_run_queue(dap);
+               struct swd_cmd_queue_entry *q = realloc(swd_cmd_queue, 
swd_cmd_queue_alloced * 2 * sizeof(*swd_cmd_queue));
+               if (q != NULL) {
+                       swd_cmd_queue = q;
+                       swd_cmd_queue_alloced *= 2;
+                       LOG_DEBUG("Increased SWD command queue to %zu 
elements", swd_cmd_queue_alloced);
+               }
        }
 
-       if (value != NULL)
-               *value = data;
-
-       return ERROR_OK;
-}
+       size_t i = swd_cmd_queue_length++;
+       swd_cmd_queue[i].cmd = cmd | SWD_CMD_START | (1 << 7); /* Park bit 
needs to be driven high, despite some docs? */
 
-static int ftdi_swd_write_reg(uint8_t cmd, uint32_t value)
-{
-       cmd |= (1 << 0) | (1 << 7); /* Add Start and Park bits */
-       LOG_DEBUG("%s write reg %x = %08"PRIx32, cmd & 2 ? "AP" : "DP", (cmd >> 
1) & 0xc, value);
-       mpsse_clock_data_out(mpsse_ctx, &cmd, 0, 8, SWD_MODE);
+       mpsse_clock_data_out(mpsse_ctx, &swd_cmd_queue[i].cmd, 0, 8, SWD_MODE);
 
-       ftdi_swd_swdio_en(false);
+       if (swd_cmd_queue[i].cmd & SWD_CMD_RnW) {
+               /* Queue a read transaction */
+               swd_cmd_queue[i].dst = dst;
 
-       uint8_t trn_ack_trn[5] = { 0 };
-       mpsse_clock_data_in(mpsse_ctx, trn_ack_trn, 0, 1 + 3 + 1, SWD_MODE);
+               ftdi_swd_swdio_en(false);
+               mpsse_clock_data_in(mpsse_ctx, 
swd_cmd_queue[i].trn_ack_data_parity_trn,
+                               0, swd_trn + 3 + 32 + 1 + swd_trn, SWD_MODE);
+               ftdi_swd_swdio_en(true);
+       } else {
+               /* Queue a write transaction */
+               ftdi_swd_swdio_en(false);
 
-       ftdi_swd_swdio_en(true);
+               mpsse_clock_data_in(mpsse_ctx, 
swd_cmd_queue[i].trn_ack_data_parity_trn,
+                               0, swd_trn + 3 + swd_trn, SWD_MODE);
 
-       uint8_t data_parity_idle[6] = { 0 };
-       buf_set_u32(data_parity_idle, 0, 32, value);
-       buf_set_u32(data_parity_idle, 32, 1, parity_u32(value));
-       buf_set_u32(data_parity_idle, 33, 8, 0);
-       mpsse_clock_data_out(mpsse_ctx, data_parity_idle, 0, 32 + 1 + 8, 
SWD_MODE);
+               ftdi_swd_swdio_en(true);
 
-       int retval = mpsse_flush(mpsse_ctx);
+               buf_set_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, swd_trn + 
3, 32, data);
+               buf_set_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, swd_trn + 
3 + 32, 1, parity_u32(data));
 
-       if (retval != ERROR_OK) {
-               LOG_ERROR("MPSSE failed");
-               return retval;
+               mpsse_clock_data_out(mpsse_ctx, 
swd_cmd_queue[i].trn_ack_data_parity_trn,
+                               swd_trn + 3, 32 + 1, SWD_MODE);
        }
 
-       unsigned ack = buf_get_u32(trn_ack_trn, 1, 3);
-       if (ack != 0x1) {
-               LOG_ERROR("Ack = %d", ack);
-               return ERROR_FAIL;
-       }
+       /* Insert idle cycles after AP accesses to avoid WAIT */
+       if (cmd & SWD_CMD_APnDP)
+               mpsse_clock_data_out(mpsse_ctx, NULL, 0, dap->memaccess_tck, 
SWD_MODE);
 
-       return ERROR_OK;
+}
+
+static void ftdi_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t 
*value)
+{
+       assert(cmd & SWD_CMD_RnW);
+       ftdi_swd_queue_cmd(dap, cmd, value, 0);
+}
+
+static void ftdi_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t 
value)
+{
+       assert(!(cmd & SWD_CMD_RnW));
+       ftdi_swd_queue_cmd(dap, cmd, NULL, value);
 }
 
 static const struct swd_driver ftdi_swd = {
                .init       = ftdi_swd_init,
                .read_reg   = ftdi_swd_read_reg,
                .write_reg  = ftdi_swd_write_reg,
+               .swd_run    = ftdi_swd_run_queue,
 };
 
 static const char * const ftdi_transports[] = { "jtag", "swd", NULL };
diff --git a/src/jtag/swd.h b/src/jtag/swd.h
index b75a83e..6a26acb 100644
--- a/src/jtag/swd.h
+++ b/src/jtag/swd.h
@@ -20,6 +20,8 @@
 #ifndef SWD_H
 #define SWD_H
 
+#include <target/arm_adi_v5.h>
+
 /* Bits in SWD command packets, written from host to target
  * first bit on the wire is START
  */
@@ -53,51 +55,47 @@ static inline uint8_t swd_cmd(bool is_read, bool is_ap, 
uint8_t regnum)
 
 /* SWD_ACK_* bits are defined in <target/arm_adi_v5.h> */
 
-/*
- * FOR NOW  ... SWD driver ops are synchronous and return ACK
- * status ... no queuing.
- *
- * Individual ops are request/response, and fast-fail permits much
- * better fault handling.  Upper layers may queue if desired.
- */
-
 struct swd_driver {
        /**
-        * Initialize the debug link so it can perform
-        * synchronous SWD operations.
+        * Initialize the debug link so it can perform SWD operations.
         * @param trn value from WCR: how many clocks
         * to not drive the SWDIO line at certain points in
         * the SWD protocol (at least 1 clock).
         *
         * As an example, this would switch a dual-mode debug adapter
         * into SWD mode and out of JTAG mode.
-         *
-         * @return ERROR_OK on success, else a negative fault code.
+        *
+        * @return ERROR_OK on success, else a negative fault code.
         */
        int (*init)(uint8_t trn);
 
 
-        /**
-         * Synchronous read of an AP or DP register.
-         *
-         * @param cmd with APnDP/RnW/addr/parity bits
-         * @param where to store value to read from register
-         *
-         * @return SWD_ACK_* code for the transaction
-         *             or (negative) fault code
-         */
-        int (*read_reg)(uint8_t cmd, uint32_t *value);
-
-        /**
-         * Synchronous write of an AP or DP register.
-         *
-         * @param cmd with APnDP/RnW/addr/parity bits
-         * @param value to be written to the register
-         *
-         * @return SWD_ACK_* code for the transaction
-         *             or (negative) fault code
-         */
-        int (*write_reg)(uint8_t cmd, uint32_t value);
+       /**
+        * Queued read of an AP or DP register.
+        *
+        * @param dap The DAP controlled by the SWD link.
+        * @param Command byte with APnDP/RnW/addr/parity bits
+        * @param Where to store value to read from register
+        */
+       void (*read_reg)(struct adiv5_dap *dap, uint8_t cmd, uint32_t *value);
+
+       /**
+        * Queued write of an AP or DP register.
+        *
+        * @param dap The DAP controlled by the SWD link.
+        * @param Command byte with APnDP/RnW/addr/parity bits
+        * @param Value to be written to the register
+        */
+       void (*write_reg)(struct adiv5_dap *dap, uint8_t cmd, uint32_t value);
+
+       /**
+        * Execute any queued transactions and collect the result.
+        *
+        * @param dap The DAP controlled by the SWD link.
+        * @return ERROR_OK on success, Ack response code on WAIT/FAULT
+        * or negative error code on other kinds of failure.
+        */
+       int (*swd_run)(struct adiv5_dap *dap);
 
        /**
         * Configures data collection from the Single-wire
@@ -108,10 +106,10 @@ struct swd_driver {
         * is normally connected to a microcontroller's UART TX,
         * but which may instead be connected to SWO for use in
         * collecting ITM (and possibly ETM) trace data.
-         *
-         * @return ERROR_OK on success, else a negative fault code.
+        *
+        * @return ERROR_OK on success, else a negative fault code.
         */
-       int *(*trace)(bool swo);
+       int *(*trace)(struct adiv5_dap *dap, bool swo);
 };
 
 int swd_init_reset(struct command_context *cmd_ctx);
diff --git a/src/target/adi_v5_cmsis_dap.c b/src/target/adi_v5_cmsis_dap.c
index 948d378..1f068df 100644
--- a/src/target/adi_v5_cmsis_dap.c
+++ b/src/target/adi_v5_cmsis_dap.c
@@ -60,24 +60,18 @@ static int (cmsis_dap_queue_ap_abort)(struct adiv5_dap 
*dap, uint8_t *ack)
 
        /* FIXME: implement this properly cmsis-dap has DAP_WriteABORT()
         * for now just hack @ everything */
-       return jtag_interface->swd->write_reg(
+       jtag_interface->swd->write_reg(dap,
                        (CMSIS_CMD_DP | CMSIS_CMD_WRITE | 
CMSIS_CMD_A32(DP_ABORT)), 0x1e);
+       return ERROR_OK;
 }
 
 static int cmsis_dap_queue_dp_read(struct adiv5_dap *dap, unsigned reg, 
uint32_t *data)
 {
        LOG_DEBUG("CMSIS-ADI: cmsis_dap_queue_dp_read %d", reg);
 
-       int retval = jtag_interface->swd->read_reg(
+       jtag_interface->swd->read_reg(dap,
                        (CMSIS_CMD_DP | CMSIS_CMD_READ | CMSIS_CMD_A32(reg)), 
data);
-
-       if (retval != ERROR_OK) {
-               /* fault response */
-               uint8_t ack = retval & 0xff;
-               cmsis_dap_queue_ap_abort(dap, &ack);
-       }
-
-       return retval;
+       return ERROR_OK;
 }
 
 static int (cmsis_dap_queue_dp_write)(struct adiv5_dap *dap, unsigned reg, 
uint32_t data)
@@ -91,16 +85,9 @@ static int (cmsis_dap_queue_dp_write)(struct adiv5_dap *dap, 
unsigned reg, uint3
                data &= ~CORUNDETECT;
        }
 
-       int retval = jtag_interface->swd->write_reg(
+       jtag_interface->swd->write_reg(dap,
                        (CMSIS_CMD_DP | CMSIS_CMD_WRITE | CMSIS_CMD_A32(reg)), 
data);
-
-       if (retval != ERROR_OK) {
-               /* fault response */
-               uint8_t ack = retval & 0xff;
-               cmsis_dap_queue_ap_abort(dap, &ack);
-       }
-
-       return retval;
+       return ERROR_OK;
 }
 
 /** Select the AP register bank matching bits 7:4 of reg. */
@@ -125,15 +112,9 @@ static int (cmsis_dap_queue_ap_read)(struct adiv5_dap 
*dap, unsigned reg, uint32
        if (retval != ERROR_OK)
                return retval;
 
-       retval = jtag_interface->swd->read_reg(
+       jtag_interface->swd->read_reg(dap,
                        (CMSIS_CMD_AP | CMSIS_CMD_READ | CMSIS_CMD_A32(reg)), 
data);
 
-       if (retval != ERROR_OK) {
-               /* fault response */
-               uint8_t ack = retval & 0xff;
-               cmsis_dap_queue_ap_abort(dap, &ack);
-       }
-
        return retval;
 }
 
@@ -150,15 +131,9 @@ static int (cmsis_dap_queue_ap_write)(struct adiv5_dap 
*dap, unsigned reg, uint3
        if (retval != ERROR_OK)
                return retval;
 
-       retval = jtag_interface->swd->write_reg(
+       jtag_interface->swd->write_reg(dap,
                        (CMSIS_CMD_AP | CMSIS_CMD_WRITE | CMSIS_CMD_A32(reg)), 
data);
 
-       if (retval != ERROR_OK) {
-               /* fault response */
-               uint8_t ack = retval & 0xff;
-               cmsis_dap_queue_ap_abort(dap, &ack);
-       }
-
        return retval;
 }
 
@@ -168,6 +143,13 @@ static int cmsis_dap_run(struct adiv5_dap *dap)
        LOG_DEBUG("CMSIS-ADI: cmsis_dap_run");
        /* FIXME: for now the CMSIS-DAP interface hard-wires a zero-size queue. 
*/
 
+       int retval = jtag_interface->swd->swd_run(dap);
+       if (retval != ERROR_OK) {
+               /* fault response */
+               uint8_t ack = retval & 0xff;
+               cmsis_dap_queue_ap_abort(dap, &ack);
+       }
+
        return ERROR_OK;
 }
 
diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c
index 104832e..4719a2e 100644
--- a/src/target/adi_v5_swd.c
+++ b/src/target/adi_v5_swd.c
@@ -57,179 +57,146 @@
 
 /* YUK! - but this is currently a global.... */
 extern struct jtag_interface *jtag_interface;
+static bool do_sync;
 
-static int swd_finish_read(struct adiv5_dap *dap)
+static void swd_finish_read(struct adiv5_dap *dap)
 {
        const struct swd_driver *swd = jtag_interface->swd;
-       int retval = ERROR_OK;
        if (dap->last_read != NULL) {
-               retval = swd->read_reg(swd_cmd(true, false, DP_RDBUFF), 
dap->last_read);
+               swd->read_reg(dap, swd_cmd(true, false, DP_RDBUFF), 
dap->last_read);
                dap->last_read = NULL;
        }
-       return retval;
 }
 
-static int (swd_queue_dp_write)(struct adiv5_dap *dap, unsigned reg,
+static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned reg,
                uint32_t data);
 
-static int swd_clear_sticky_errors(struct adiv5_dap *dap)
+static void swd_clear_sticky_errors(struct adiv5_dap *dap)
 {
        const struct swd_driver *swd = jtag_interface->swd;
        assert(swd);
 
-       return swd->write_reg(swd_cmd(false,  false, DP_ABORT),
+       swd->write_reg(dap, swd_cmd(false,  false, DP_ABORT),
                STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR);
 }
 
+static int swd_run_inner(struct adiv5_dap *dap)
+{
+       const struct swd_driver *swd = jtag_interface->swd;
+
+       int retval = swd->swd_run(dap);
+
+       if (retval != ERROR_OK) {
+               /* fault response */
+               swd_clear_sticky_errors(dap);
+       }
+
+       return retval;
+}
+
+static inline int check_sync(struct adiv5_dap *dap)
+{
+       return do_sync ? swd_run_inner(dap) : ERROR_OK;
+}
+
 static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)
 {
        const struct swd_driver *swd = jtag_interface->swd;
        assert(swd);
 
-       return swd->write_reg(swd_cmd(false,  false, DP_ABORT),
+       swd->write_reg(dap, swd_cmd(false,  false, DP_ABORT),
                DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR);
+       return check_sync(dap);
 }
 
 /** Select the DP register bank matching bits 7:4 of reg. */
-static int swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned reg)
+static void swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned reg)
 {
        uint32_t select_dp_bank = (reg & 0x000000F0) >> 4;
 
        if (reg == DP_SELECT)
-               return ERROR_OK;
+               return;
 
        if (select_dp_bank == dap->dp_bank_value)
-               return ERROR_OK;
+               return;
 
        dap->dp_bank_value = select_dp_bank;
        select_dp_bank |= dap->ap_current | dap->ap_bank_value;
 
-       return swd_queue_dp_write(dap, DP_SELECT, select_dp_bank);
+       swd_queue_dp_write(dap, DP_SELECT, select_dp_bank);
 }
 
 static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg,
                uint32_t *data)
 {
-       int retval;
-       /* REVISIT status return vs ack ... */
        const struct swd_driver *swd = jtag_interface->swd;
        assert(swd);
 
-       retval = swd_queue_dp_bankselect(dap, reg);
-       if (retval != ERROR_OK)
-               return retval;
-
-       retval = swd->read_reg(swd_cmd(true,  false, reg), data);
+       swd_queue_dp_bankselect(dap, reg);
+       swd->read_reg(dap, swd_cmd(true,  false, reg), data);
 
-       if (retval != ERROR_OK) {
-               /* fault response */
-               swd_clear_sticky_errors(dap);
-       }
-
-       return retval;
+       return check_sync(dap);
 }
 
 
 static int (swd_queue_dp_write)(struct adiv5_dap *dap, unsigned reg,
                uint32_t data)
 {
-       int retval;
-       /* REVISIT status return vs ack ... */
        const struct swd_driver *swd = jtag_interface->swd;
        assert(swd);
 
-       retval = swd_finish_read(dap);
-       if (retval != ERROR_OK)
-               return retval;
-
-       retval = swd_queue_dp_bankselect(dap, reg);
-       if (retval != ERROR_OK)
-               return retval;
-
-       retval = swd->write_reg(swd_cmd(false,  false, reg), data);
-
-       if (retval != ERROR_OK) {
-               /* fault response */
-               swd_clear_sticky_errors(dap);
-       }
+       swd_finish_read(dap);
+       swd_queue_dp_bankselect(dap, reg);
+       swd->write_reg(dap, swd_cmd(false,  false, reg), data);
 
-       return retval;
+       return check_sync(dap);
 }
 
 /** Select the AP register bank matching bits 7:4 of reg. */
-static int swd_queue_ap_bankselect(struct adiv5_dap *dap, unsigned reg)
+static void swd_queue_ap_bankselect(struct adiv5_dap *dap, unsigned reg)
 {
        uint32_t select_ap_bank = reg & 0x000000F0;
 
        if (select_ap_bank == dap->ap_bank_value)
-               return ERROR_OK;
+               return;
 
        dap->ap_bank_value = select_ap_bank;
        select_ap_bank |= dap->ap_current | dap->dp_bank_value;
 
-       return swd_queue_dp_write(dap, DP_SELECT, select_ap_bank);
+       swd_queue_dp_write(dap, DP_SELECT, select_ap_bank);
 }
 
-static int (swd_queue_ap_read)(struct adiv5_dap *dap, unsigned reg,
+static int swd_queue_ap_read(struct adiv5_dap *dap, unsigned reg,
                uint32_t *data)
 {
-       /* REVISIT status return ... */
        const struct swd_driver *swd = jtag_interface->swd;
        assert(swd);
 
-       int retval = swd_queue_ap_bankselect(dap, reg);
-       if (retval != ERROR_OK)
-               return retval;
-
-       retval = swd->read_reg(swd_cmd(true,  true, reg), dap->last_read);
+       swd_queue_ap_bankselect(dap, reg);
+       swd->read_reg(dap, swd_cmd(true,  true, reg), dap->last_read);
        dap->last_read = data;
 
-       if (retval != ERROR_OK) {
-               /* fault response */
-               swd_clear_sticky_errors(dap);
-               return retval;
-       }
-
-       return retval;
+       return check_sync(dap);
 }
 
-static int (swd_queue_ap_write)(struct adiv5_dap *dap, unsigned reg,
+static int swd_queue_ap_write(struct adiv5_dap *dap, unsigned reg,
                uint32_t data)
 {
-       /* REVISIT status return ... */
        const struct swd_driver *swd = jtag_interface->swd;
        assert(swd);
-       int retval;
 
-       retval = swd_finish_read(dap);
-       if (retval != ERROR_OK)
-               return retval;
-
-       retval = swd_queue_ap_bankselect(dap, reg);
-       if (retval != ERROR_OK)
-               return retval;
+       swd_finish_read(dap);
+       swd_queue_ap_bankselect(dap, reg);
+       swd->write_reg(dap, swd_cmd(false,  true, reg), data);
 
-       retval = swd->write_reg(swd_cmd(false,  true, reg), data);
-
-       if (retval != ERROR_OK) {
-               /* fault response */
-               swd_clear_sticky_errors(dap);
-       }
-
-       return retval;
+       return check_sync(dap);
 }
 
 /** Executes all queued DAP operations. */
 static int swd_run(struct adiv5_dap *dap)
 {
-       /* for now the SWD interface hard-wires a zero-size queue.  */
-
-       int retval = swd_finish_read(dap);
-
-       /* FIXME but we still need to check and scrub
-        * any hardware errors ...
-        */
-       return retval;
+       swd_finish_read(dap);
+       return swd_run_inner(dap);
 }
 
 const struct dap_ops swd_dap_ops = {
@@ -452,14 +419,16 @@ static int swd_init(struct command_context *ctx)
 
  /* Note, debugport_init() does setup too */
 
-       status = swd_queue_dp_read(dap, DP_IDCODE, &idcode);
-
-       if (status == ERROR_OK)
-               LOG_INFO("SWD IDCODE %#8.8" PRIx32, idcode);
+       swd_queue_dp_read(dap, DP_IDCODE, &idcode);
 
        /* force clear all sticky faults */
        swd_clear_sticky_errors(dap);
 
+       status = swd_run(dap);
+
+       if (status == ERROR_OK)
+               LOG_INFO("SWD IDCODE %#8.8" PRIx32, idcode);
+
        /* this is a workaround to get polling working */
        jtag_add_reset(0, 0);
 
diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h
index 6d86c71..80b2c46 100644
--- a/src/target/arm_adi_v5.h
+++ b/src/target/arm_adi_v5.h
@@ -40,9 +40,9 @@
 #define JTAG_DP_APACC          0xB
 
 /* three-bit ACK values for SWD access (sent LSB first) */
-#define SWD_ACK_OK             0x4
-#define SWD_ACK_WAIT           0x2
-#define SWD_ACK_FAULT          0x1
+#define SWD_ACK_OK    0x1
+#define SWD_ACK_WAIT  0x2
+#define SWD_ACK_FAULT 0x4
 
 #define DPAP_WRITE             0
 #define DPAP_READ              1

-- 

------------------------------------------------------------------------------
Managing the Performance of Cloud-Based Applications
Take advantage of what the Cloud has to offer - Avoid Common Pitfalls.
Read the Whitepaper.
http://pubads.g.doubleclick.net/gampad/clk?id=121054471&iu=/4140/ostg.clktrk
_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to