adi_v5_swd: Read RDBUFF once after a sequence of AP reads
[openocd.git] / src / target / arm_adi_v5.h
index 9f0dea9119186466e38f2f389c0f6f89290ba71e..c51e8f81b7d03cef3c5af0494b3c05dd70e87015 100644 (file)
 #define DPAP_WRITE             0
 #define DPAP_READ              1
 
+#define BANK_REG(bank, reg)    (((bank) << 4) | (reg))
+
 /* A[3:0] for DP registers; A[1:0] are always zero.
  * - JTAG accesses all of these via JTAG_DP_DPACC, except for
  *   IDCODE (JTAG_DP_IDCODE) and ABORT (JTAG_DP_ABORT).
  * - SWD accesses these directly, sometimes needing SELECT.CTRLSEL
  */
-#define DP_IDCODE              0               /* SWD: read */
-#define DP_ABORT               0               /* SWD: write */
-#define DP_CTRL_STAT           0x4             /* r/w */
-#define DP_WCR                 0x4             /* SWD: r/w (mux CTRLSEL) */
-#define DP_RESEND              0x8             /* SWD: read */
-#define DP_SELECT              0x8             /* JTAG: r/w; SWD: write */
-#define DP_RDBUFF              0xC             /* read-only */
+#define DP_IDCODE              BANK_REG(0x0, 0x0)      /* SWD: read */
+#define DP_ABORT               BANK_REG(0x0, 0x0)      /* SWD: write */
+#define DP_CTRL_STAT           BANK_REG(0x0, 0x4)      /* r/w */
+#define DP_RESEND              BANK_REG(0x0, 0x8)      /* SWD: read */
+#define DP_SELECT              BANK_REG(0x0, 0x8)      /* JTAG: r/w; SWD: write */
+#define DP_RDBUFF              BANK_REG(0x0, 0xC)      /* read-only */
+#define DP_WCR                 BANK_REG(0x1, 0x4)      /* SWD: r/w */
 
 #define WCR_TO_TRN(wcr) ((uint32_t)(1 + (3 & ((wcr)) >> 8)))   /* 1..4 clocks */
 #define WCR_TO_PRESCALE(wcr) ((uint32_t)(7 & ((wcr))))         /* impl defined */
@@ -161,6 +163,13 @@ struct adiv5_dap {
         */
        uint32_t ap_bank_value;
 
+       /**
+        * Cache for DP_SELECT bits identifying the current four-word DP
+        * register bank.  This caches DP register addresss bits 7:4; JTAG
+        * and SWD access primitves pass address bits 3:2; bits 1:0 are zero.
+        */
+       uint32_t dp_bank_value;
+
        /**
         * Cache for (MEM-AP) AP_REG_CSW register value.  This is written to
         * configure an access mode, such as autoincrementing AP_REG_TAR during
@@ -178,6 +187,12 @@ struct adiv5_dap {
        /* information about current pending SWjDP-AHBAP transaction */
        uint8_t  ack;
 
+       /**
+        * Holds the pointer to the destination word for the last queued read,
+        * for use with posted AP read sequence optimization.
+        */
+       uint32_t *last_read;
+
        /**
         * Configures how many extra tck clocks are added after starting a
         * MEM-AP access before we try to read its status (and/or result).
@@ -401,6 +416,35 @@ static inline int dap_dp_read_atomic(struct adiv5_dap *dap, unsigned reg,
        return dap_run(dap);
 }
 
+static inline int dap_dp_poll_register(struct adiv5_dap *dap, unsigned reg,
+                                      uint32_t mask, uint32_t value, int timeout)
+{
+       assert(timeout > 0);
+       assert((value & mask) == value);
+
+       int ret;
+       uint32_t regval;
+       LOG_DEBUG("DAP: poll %x, mask 0x08%" PRIx32 ", value 0x%08" PRIx32,
+                 reg, mask, value);
+       do {
+               ret = dap_dp_read_atomic(dap, reg, &regval);
+               if (ret != ERROR_OK)
+                       return ret;
+
+               if ((regval & mask) == value)
+                       break;
+
+               alive_sleep(10);
+       } while (--timeout);
+
+       if (!timeout) {
+               LOG_DEBUG("DAP: poll %x timeout", reg);
+               return ERROR_FAIL;
+       } else {
+               return ERROR_OK;
+       }
+}
+
 /** Accessor for currently selected DAP-AP number (0..255) */
 static inline uint8_t dap_ap_get_select(struct adiv5_dap *swjdp)
 {

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)