diff options
author | Antonio Borneo <borneo.antonio@gmail.com> | 2019-01-23 16:46:31 +0100 |
---|---|---|
committer | Tomas Vanek <vanekt@fbl.cz> | 2020-01-02 21:24:54 +0000 |
commit | be2d25efcc0132e02c76c304487a8759ca587b0c (patch) | |
tree | f81a3aaa2870cfdee9a50b3f4fc1ae3923ad6ffb /src | |
parent | 5d08bcb715599466dc88d1cdf5b599a7bba1be6a (diff) | |
download | riscv-openocd-be2d25efcc0132e02c76c304487a8759ca587b0c.zip riscv-openocd-be2d25efcc0132e02c76c304487a8759ca587b0c.tar.gz riscv-openocd-be2d25efcc0132e02c76c304487a8759ca587b0c.tar.bz2 |
arm_adi_v5: add API send_sequence() and use it
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/jtag/swd.h | 8 | ||||
-rw-r--r-- | src/target/adi_v5_jtag.c | 24 | ||||
-rw-r--r-- | src/target/adi_v5_swd.c | 9 | ||||
-rw-r--r-- | src/target/arm_adi_v5.c | 38 | ||||
-rw-r--r-- | src/target/arm_adi_v5.h | 28 |
5 files changed, 63 insertions, 44 deletions
diff --git a/src/jtag/swd.h b/src/jtag/swd.h index 0b32105..0d1702c 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 df81134..c2100eb 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 594b508..a373566 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 d2ec960..2d47da3 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 ee04d41..88b7e5c 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. |