ipdbg: fix double free of virtual-ir data
[openocd.git] / src / jtag / swd.h
index 52f41d5d9a2c4eaca0cd51cad30f76355e3016d0..5f626c1bf8612f190680a23a4a82f0bea03f7e64 100644 (file)
@@ -1,45 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
 /***************************************************************************
  *   Copyright (C) 2009-2010 by David Brownell                             *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 #ifndef OPENOCD_JTAG_SWD_H
 #define OPENOCD_JTAG_SWD_H
 
+#include <helper/log.h>
 #include <target/arm_adi_v5.h>
 
 /* Bits in SWD command packets, written from host to target
  * first bit on the wire is START
  */
 #define SWD_CMD_START  (1 << 0)        /* always set */
-#define SWD_CMD_APnDP  (1 << 1)        /* set only for AP access */
-#define SWD_CMD_RnW    (1 << 2)                /* set only for read access */
+#define SWD_CMD_APNDP  (1 << 1)        /* set only for AP access */
+#define SWD_CMD_RNW    (1 << 2)                /* set only for read access */
 #define SWD_CMD_A32    (3 << 3)                /* bits A[3:2] of register addr */
 #define SWD_CMD_PARITY (1 << 5)        /* parity of APnDP|RnW|A32 */
 #define SWD_CMD_STOP   (0 << 6)        /* always clear for synch SWD */
 #define SWD_CMD_PARK   (1 << 7)        /* driven high by host */
 /* followed by TRN, 3-bits of ACK, TRN */
 
+/*
+ * The SWD subsystem error codes
+ */
+#define ERROR_SWD_FAIL (-400)  /** protocol or parity error */
+#define ERROR_SWD_FAULT        (-401)  /** device returned FAULT in ACK field */
+
 /**
  * Construct a "cmd" byte, in lSB bit order, which swd_driver.read_reg()
  * and swd_driver.write_reg() methods will use directly.
  */
 static inline uint8_t swd_cmd(bool is_read, bool is_ap, uint8_t regnum)
 {
-       uint8_t cmd = (is_ap ? SWD_CMD_APnDP : 0)
-               | (is_read ? SWD_CMD_RnW : 0)
+       uint8_t cmd = (is_ap ? SWD_CMD_APNDP : 0)
+               | (is_read ? SWD_CMD_RNW : 0)
                | ((regnum & 0xc) << 1);
 
        /* 8 cmd bits 4:1 may be set */
@@ -54,15 +50,58 @@ 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> */
 
 /**
- * Line reset.
+ * Test if we can rely on ACK returned by SWD command
+ *
+ * @param cmd Byte constructed by swd_cmd(), START, STOP and TRN are filtered off
+ * @returns true if ACK should be checked, false if should be ignored
+ */
+static inline bool swd_cmd_returns_ack(uint8_t cmd)
+{
+       uint8_t base_cmd = cmd & (SWD_CMD_APNDP | SWD_CMD_RNW | SWD_CMD_A32);
+
+       /* DPv2 does not reply to DP_TARGETSEL write cmd */
+       return base_cmd != swd_cmd(false, false, DP_TARGETSEL);
+}
+
+/**
+ * Convert SWD ACK value returned from DP to OpenOCD error code
  *
- * Line reset is at least 50 SWCLK cycles with SWDIO driven high, followed
- * by at least one idle (low) cycle.
+ * @param ack
+ * @returns error code
+ */
+static inline int swd_ack_to_error_code(uint8_t ack)
+{
+       switch (ack) {
+       case SWD_ACK_OK:
+               return ERROR_OK;
+       case SWD_ACK_WAIT:
+               return ERROR_WAIT;
+       case SWD_ACK_FAULT:
+               return ERROR_SWD_FAULT;
+       default:
+               return ERROR_SWD_FAIL;
+       }
+}
+
+/*
+ * The following sequences are updated to
+ * ARM(tm) Debug Interface v5 Architecture Specification    ARM IHI 0031E
+ */
+
+/**
+ * SWD Line reset.
+ *
+ * SWD Line reset is at least 50 SWCLK cycles with SWDIO driven high,
+ * followed by at least two idle (low) cycle.
+ * Bits are stored (and transmitted) LSB-first.
  */
 static const uint8_t swd_seq_line_reset[] = {
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03
+       /* At least 50 SWCLK cycles with SWDIO high */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       /* At least 2 idle (low) cycles */
+       0x00,
 };
-static const unsigned swd_seq_line_reset_len = 51;
+static const unsigned swd_seq_line_reset_len = 64;
 
 /**
  * JTAG-to-SWD sequence.
@@ -71,36 +110,53 @@ static const unsigned swd_seq_line_reset_len = 51;
  * high, putting either interface logic into reset state, followed by a
  * specific 16-bit sequence and finally a line reset in case the SWJ-DP was
  * already in SWD mode.
+ * Bits are stored (and transmitted) LSB-first.
  */
 static const uint8_t swd_seq_jtag_to_swd[] = {
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7b, 0x9e,
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
+       /* At least 50 TCK/SWCLK cycles with TMS/SWDIO high */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       /* Switching sequence from JTAG to SWD */
+       0x9e, 0xe7,
+       /* At least 50 TCK/SWCLK cycles with TMS/SWDIO high */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       /* At least 2 idle (low) cycles */
+       0x00,
 };
-static const unsigned swd_seq_jtag_to_swd_len = 118;
+static const unsigned swd_seq_jtag_to_swd_len = 136;
 
 /**
  * SWD-to-JTAG sequence.
  *
  * The SWD-to-JTAG sequence is at least 50 TCK/SWCLK cycles with TMS/SWDIO
  * high, putting either interface logic into reset state, followed by a
- * specific 16-bit sequence and finally at least 5 TCK cycles to put the
- * JTAG TAP in TLR.
+ * specific 16-bit sequence and finally at least 5 TCK/SWCLK cycles with
+ * TMS/SWDIO high to put the JTAG TAP in Test-Logic-Reset state.
+ * Bits are stored (and transmitted) LSB-first.
  */
 static const uint8_t swd_seq_swd_to_jtag[] = {
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x9c, 0xff
+       /* At least 50 TCK/SWCLK cycles with TMS/SWDIO high */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       /* Switching sequence from SWD to JTAG */
+       0x3c, 0xe7,
+       /* At least 5 TCK/SWCLK cycles with TMS/SWDIO high */
+       0xff,
 };
-static const unsigned swd_seq_swd_to_jtag_len = 71;
+static const unsigned swd_seq_swd_to_jtag_len = 80;
 
 /**
  * SWD-to-dormant sequence.
  *
  * This is at least 50 SWCLK cycles with SWDIO high to put the interface
  * in reset state, followed by a specific 16-bit sequence.
+ * Bits are stored (and transmitted) LSB-first.
  */
 static const uint8_t swd_seq_swd_to_dormant[] = {
-       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x8e, 0x03
+       /* At least 50 SWCLK cycles with SWDIO high */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        /* Switching sequence from SWD to dormant */
+       0xbc, 0xe3,
 };
-static const unsigned swd_seq_swd_to_dormant_len = 66;
+static const unsigned swd_seq_swd_to_dormant_len = 72;
 
 /**
  * Dormant-to-SWD sequence.
@@ -110,22 +166,82 @@ static const unsigned swd_seq_swd_to_dormant_len = 66;
  * sequence, followed by 4 TCK/SWCLK cycles with TMS/SWDIO low, followed by
  * a specific protocol-dependent activation code. For SWD the activation code
  * is an 8-bit sequence. The sequence ends with a line reset.
+ * Bits are stored (and transmitted) LSB-first.
  */
 static const uint8_t swd_seq_dormant_to_swd[] = {
+       /* At least 8 SWCLK cycles with SWDIO high */
        0xff,
+       /* Selection alert sequence */
        0x92, 0xf3, 0x09, 0x62, 0x95, 0x2d, 0x85, 0x86,
        0xe9, 0xaf, 0xdd, 0xe3, 0xa2, 0x0e, 0xbc, 0x19,
-       0x10, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f
+       /*
+        * 4 SWCLK cycles with SWDIO low ...
+        * + SWD activation code 0x1a ...
+        * + at least 8 SWCLK cycles with SWDIO high
+        */
+       0xa0, /* ((0x00)      & GENMASK(3, 0)) | ((0x1a << 4) & GENMASK(7, 4)) */
+       0xf1, /* ((0x1a >> 4) & GENMASK(3, 0)) | ((0xff << 4) & GENMASK(7, 4)) */
+       0xff,
+       /* At least 50 SWCLK cycles with SWDIO high */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       /* At least 2 idle (low) cycles */
+       0x00,
 };
-static const unsigned swd_seq_dormant_to_swd_len = 199;
-
-enum swd_special_seq {
-       LINE_RESET,
-       JTAG_TO_SWD,
-       SWD_TO_JTAG,
-       SWD_TO_DORMANT,
-       DORMANT_TO_SWD,
+static const unsigned swd_seq_dormant_to_swd_len = 224;
+
+/**
+ * JTAG-to-dormant sequence.
+ *
+ * This is at least 5 TCK cycles with TMS high to put the interface
+ * in test-logic-reset state, followed by a specific 31-bit sequence.
+ * Bits are stored (and transmitted) LSB-first.
+ */
+static const uint8_t swd_seq_jtag_to_dormant[] = {
+       /* At least 5 TCK cycles with TMS high */
+       0xff,
+       /*
+        * Still one TCK cycle with TMS high followed by 31 bits JTAG-to-DS
+        * select sequence 0xba, 0xbb, 0xbb, 0x33,
+        */
+       0x75, /* ((0xff >> 7) & GENMASK(0, 0)) | ((0xba << 1) & GENMASK(7, 1)) */
+       0x77, /* ((0xba >> 7) & GENMASK(0, 0)) | ((0xbb << 1) & GENMASK(7, 1)) */
+       0x77, /* ((0xbb >> 7) & GENMASK(0, 0)) | ((0xbb << 1) & GENMASK(7, 1)) */
+       0x67, /* ((0xbb >> 7) & GENMASK(0, 0)) | ((0x33 << 1) & GENMASK(7, 1)) */
+};
+static const unsigned swd_seq_jtag_to_dormant_len = 40;
+
+/**
+ * Dormant-to-JTAG sequence.
+ *
+ * This is at least 8 TCK/SWCLK cycles with TMS/SWDIO high to abort any ongoing
+ * selection alert sequence, followed by a specific 128-bit selection alert
+ * sequence, followed by 4 TCK/SWCLK cycles with TMS/SWDIO low, followed by
+ * a specific protocol-dependent activation code. For JTAG there are two
+ * possible activation codes:
+ * - "JTAG-Serial": 12 bits 0x00, 0x00
+ * - "Arm CoreSight JTAG-DP": 8 bits 0x0a
+ * We use "JTAG-Serial" only, which seams more generic.
+ * Since the target TAP can be either in Run/Test Idle or in Test-Logic-Reset
+ * states, Arm recommends to put the TAP in Run/Test Idle using one TCK cycle
+ * with TMS low. To keep the sequence length multiple of 8, 8 TCK cycle with
+ * TMS low are sent (allowed by JTAG state machine).
+ * Bits are stored (and transmitted) LSB-first.
+ */
+static const uint8_t swd_seq_dormant_to_jtag[] = {
+       /* At least 8 TCK/SWCLK cycles with TMS/SWDIO high */
+       0xff,
+       /* Selection alert sequence */
+       0x92, 0xf3, 0x09, 0x62, 0x95, 0x2d, 0x85, 0x86,
+       0xe9, 0xaf, 0xdd, 0xe3, 0xa2, 0x0e, 0xbc, 0x19,
+       /*
+        * 4 TCK/SWCLK cycles with TMS/SWDIO low ...
+        * + 12 bits JTAG-serial activation code 0x00, 0x00
+        */
+       0x00, 0x00,
+       /* put the TAP in Run/Test Idle */
+       0x00,
 };
+static const unsigned swd_seq_dormant_to_jtag_len = 160;
 
 struct swd_driver {
        /**
@@ -138,24 +254,6 @@ struct swd_driver {
         */
        int (*init)(void);
 
-       /**
-        * Set the SWCLK frequency of the SWD link.
-        *
-        * The driver should round the desired value, downwards if possible, to
-        * the nearest supported frequency. A negative value should be ignored
-        * and can be used to query the current setting. If the driver does not
-        * support a variable frequency a fixed, nominal, value should be
-        * returned.
-        *
-        * If the frequency is increased, it must not apply before the currently
-        * queued transactions are executed. If the frequency is lowered, it may
-        * apply immediately.
-        *
-        * @param hz The desired frequency in Hz.
-        * @return The actual resulting frequency after rounding.
-        */
-       int_least32_t (*frequency)(int_least32_t hz);
-
        /**
         * Queue a special SWDIO sequence.
         *
@@ -209,6 +307,5 @@ struct swd_driver {
 };
 
 int swd_init_reset(struct command_context *cmd_ctx);
-void swd_add_reset(int req_srst);
 
 #endif /* OPENOCD_JTAG_SWD_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)