aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/jtag/swd.h8
-rw-r--r--src/target/adi_v5_jtag.c24
-rw-r--r--src/target/adi_v5_swd.c9
-rw-r--r--src/target/arm_adi_v5.c38
-rw-r--r--src/target/arm_adi_v5.h28
5 files changed, 63 insertions, 44 deletions
diff --git a/src/jtag/swd.h b/src/jtag/swd.h
index 0b32105a..0d1702c7 100644
--- a/src/jtag/swd.h
+++ b/src/jtag/swd.h
@@ -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.
diff --git a/src/target/adi_v5_jtag.c b/src/target/adi_v5_jtag.c
index df811349..c2100eb4 100644
--- a/src/target/adi_v5_jtag.c
+++ b/src/target/adi_v5_jtag.c
@@ -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,
diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c
index 594b5081..a3735661 100644
--- a/src/target/adi_v5_swd.c
+++ b/src/target/adi_v5_swd.c
@@ -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,
diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c
index d2ec960a..2d47da3e 100644
--- a/src/target/arm_adi_v5.c
+++ b/src/target/arm_adi_v5.c
@@ -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
diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h
index ee04d417..88b7e5c8 100644
--- a/src/target/arm_adi_v5.h
+++ b/src/target/arm_adi_v5.h
@@ -158,6 +158,15 @@
#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);
@@ -339,6 +352,21 @@ enum ap_type {
};
/**
+ * 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
* have slight differences in DP register support.