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>
This commit is contained in:
parent
5d08bcb715
commit
be2d25efcc
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue