arm_adi_v5: add API send_sequence() and use it
authorAntonio Borneo <borneo.antonio@gmail.com>
Wed, 23 Jan 2019 15:46:31 +0000 (16:46 +0100)
committerTomas Vanek <vanekt@fbl.cz>
Thu, 2 Jan 2020 21:24:54 +0000 (21:24 +0000)
The method to send an arbitrary sequence to DAP depends on the
transport and is thus different on JTAG and SWD. This is already
coded in dap_to_jtag() and dap_to_swd().

Add a new API send_sequence() in struct dap_ops.
Add the implementations of send_sequence() in adi_v5_jtag.c and
adi_v5_swd.c
Rewrite dap_to_jtag() and dap_to_swd() using the new API.
Move the enum swd_special_seq in arm_adi_v5.h to solve a circular
dependencies among swd.h and arm_adi_v5.h

Change-Id: I9db13a00f129761eab283783c094cfff2dd92610
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: http://openocd.zylin.com/4902
Tested-by: jenkins
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
src/jtag/swd.h
src/target/adi_v5_jtag.c
src/target/adi_v5_swd.c
src/target/arm_adi_v5.c
src/target/arm_adi_v5.h

index 0b32105a27961900c81fc49482fb97407a47f476..0d1702c73e7ed58d96c3d23b921ce353829b92fa 100644 (file)
@@ -213,14 +213,6 @@ static const uint8_t swd_seq_dormant_to_jtag[] = {
 };
 static const unsigned swd_seq_dormant_to_jtag_len = 160;
 
-enum swd_special_seq {
-       LINE_RESET,
-       JTAG_TO_SWD,
-       SWD_TO_JTAG,
-       SWD_TO_DORMANT,
-       DORMANT_TO_SWD,
-};
-
 struct swd_driver {
        /**
         * Initialize the debug link so it can perform SWD operations.
index df8113492159c146b54820f5ed2b072f9f5335e5..c2100eb47195df2f73812726f8c6cabda415fad5 100644 (file)
@@ -38,6 +38,7 @@
 #include "arm_adi_v5.h"
 #include <helper/time_support.h>
 #include <helper/list.h>
+#include <jtag/swd.h>
 
 /*#define DEBUG_WAIT*/
 
@@ -663,6 +664,28 @@ static int jtag_check_reconnect(struct adiv5_dap *dap)
        return ERROR_OK;
 }
 
+static int jtag_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)
+{
+       int retval;
+
+       switch (seq) {
+       case JTAG_TO_SWD:
+               retval =  jtag_add_tms_seq(swd_seq_jtag_to_swd_len,
+                               swd_seq_jtag_to_swd, TAP_INVALID);
+               break;
+       case SWD_TO_JTAG:
+               retval = jtag_add_tms_seq(swd_seq_swd_to_jtag_len,
+                               swd_seq_swd_to_jtag, TAP_RESET);
+               break;
+       default:
+               LOG_ERROR("Sequence %d not supported", seq);
+               return ERROR_FAIL;
+       }
+       if (retval == ERROR_OK)
+               retval = jtag_execute_queue();
+       return retval;
+}
+
 static int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg,
                uint32_t *data)
 {
@@ -782,6 +805,7 @@ static int jtag_dp_sync(struct adiv5_dap *dap)
 */
 const struct dap_ops jtag_dp_ops = {
        .connect             = jtag_connect,
+       .send_sequence       = jtag_send_sequence,
        .queue_dp_read       = jtag_dp_q_read,
        .queue_dp_write      = jtag_dp_q_write,
        .queue_ap_read       = jtag_ap_q_read,
index 594b5081fd990b9878f3f65cbb9eef615693757d..a3735661b68459d6e59adf0c9415a0912bb58b32 100644 (file)
@@ -142,6 +142,14 @@ static int swd_connect(struct adiv5_dap *dap)
        return status;
 }
 
+static int swd_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)
+{
+       const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
+       assert(swd);
+
+       return swd->switch_seq(seq);
+}
+
 static inline int check_sync(struct adiv5_dap *dap)
 {
        return do_sync ? swd_run_inner(dap) : ERROR_OK;
@@ -320,6 +328,7 @@ static void swd_quit(struct adiv5_dap *dap)
 
 const struct dap_ops swd_dap_ops = {
        .connect = swd_connect,
+       .send_sequence = swd_send_sequence,
        .queue_dp_read = swd_queue_dp_read,
        .queue_dp_write = swd_queue_dp_write,
        .queue_ap_read = swd_queue_ap_read,
index d2ec960a82076f2ab7b3eba7c9b78b578a89da11..2d47da3ea6c24787ea8671e48e167c3c9076b51a 100644 (file)
@@ -804,26 +804,9 @@ int mem_ap_init(struct adiv5_ap *ap)
  */
 int dap_to_swd(struct adiv5_dap *dap)
 {
-       int retval;
-
        LOG_DEBUG("Enter SWD mode");
 
-       if (transport_is_jtag()) {
-               retval =  jtag_add_tms_seq(swd_seq_jtag_to_swd_len,
-                               swd_seq_jtag_to_swd, TAP_INVALID);
-               if (retval == ERROR_OK)
-                       retval = jtag_execute_queue();
-               return retval;
-       }
-
-       if (transport_is_swd()) {
-               const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
-
-               return swd->switch_seq(JTAG_TO_SWD);
-       }
-
-       LOG_ERROR("Nor JTAG nor SWD transport");
-       return ERROR_FAIL;
+       return dap_send_sequence(dap, JTAG_TO_SWD);
 }
 
 /**
@@ -839,26 +822,9 @@ int dap_to_swd(struct adiv5_dap *dap)
  */
 int dap_to_jtag(struct adiv5_dap *dap)
 {
-       int retval;
-
        LOG_DEBUG("Enter JTAG mode");
 
-       if (transport_is_jtag()) {
-               retval = jtag_add_tms_seq(swd_seq_swd_to_jtag_len,
-                               swd_seq_swd_to_jtag, TAP_RESET);
-               if (retval == ERROR_OK)
-                       retval = jtag_execute_queue();
-               return retval;
-       }
-
-       if (transport_is_swd()) {
-               const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
-
-               return swd->switch_seq(SWD_TO_JTAG);
-       }
-
-       LOG_ERROR("Nor JTAG nor SWD transport");
-       return ERROR_FAIL;
+       return dap_send_sequence(dap, SWD_TO_JTAG);
 }
 
 /* CID interpretation -- see ARM IHI 0029B section 3
index ee04d417734a17323642e1aa532b80ebf9ac6d8b..88b7e5c874732d0055c6e759620582e28ed494b9 100644 (file)
 #define DP_APSEL_MAX        (255)
 #define DP_APSEL_INVALID    (-1)
 
+/* FIXME: not SWD specific; should be renamed, e.g. adiv5_special_seq */
+enum swd_special_seq {
+       LINE_RESET,
+       JTAG_TO_SWD,
+       SWD_TO_JTAG,
+       SWD_TO_DORMANT,
+       DORMANT_TO_SWD,
+};
+
 /**
  * This represents an ARM Debug Interface (v5) Access Port (AP).
  * Most common is a MEM-AP, for memory access.
@@ -291,6 +300,10 @@ struct adiv5_dap {
 struct dap_ops {
        /** connect operation for SWD */
        int (*connect)(struct adiv5_dap *dap);
+
+       /** send a sequence to the DAP */
+       int (*send_sequence)(struct adiv5_dap *dap, enum swd_special_seq seq);
+
        /** DP register read. */
        int (*queue_dp_read)(struct adiv5_dap *dap, unsigned reg,
                        uint32_t *data);
@@ -338,6 +351,21 @@ enum ap_type {
        AP_TYPE_AHB5_AP = 0x5,  /* AHB5 Memory-AP. */
 };
 
+/**
+ * Send an adi-v5 sequence to the DAP.
+ *
+ * @param dap The DAP used for reading.
+ * @param seq The sequence to send.
+ *
+ * @return ERROR_OK for success, else a fault code.
+ */
+static inline int dap_send_sequence(struct adiv5_dap *dap,
+               enum swd_special_seq seq)
+{
+       assert(dap->ops != NULL);
+       return dap->ops->send_sequence(dap, seq);
+}
+
 /**
  * Queue a DP register read.
  * Note that not all DP registers are readable; also, that JTAG and SWD