swd: Remove DAP from parameter list
Making the SWD driver aware of the DAP that controls it is a layering violation. The only usage for the DAP pointer is to store the number of idle cycles the AP may need to avoid WAITs. Replace the DAP pointer with a cycle count hint instead to avoid future misuse. Change-Id: I3e64e11a43ba2396bd646a4cf8f9bc331805d802 Signed-off-by: Andreas Fritiofson <andreas.fritiofson@gmail.com> Reviewed-on: http://openocd.zylin.com/3141 Tested-by: jenkins Reviewed-by: Paul Fertser <fercerpav@gmail.com>
This commit is contained in:
@@ -45,6 +45,8 @@ extern struct jtag_interface *jtag_interface;
|
||||
*/
|
||||
static void bitbang_stableclocks(int num_cycles);
|
||||
|
||||
static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk);
|
||||
|
||||
struct bitbang_interface *bitbang_interface;
|
||||
|
||||
/* DANGER!!!! clock absolutely *MUST* be 0 in idle or reset won't work!
|
||||
@@ -378,7 +380,7 @@ static void bitbang_exchange(bool rnw, uint8_t buf[], unsigned int offset, unsig
|
||||
}
|
||||
}
|
||||
|
||||
int bitbang_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq)
|
||||
int bitbang_swd_switch_seq(enum swd_special_seq seq)
|
||||
{
|
||||
LOG_DEBUG("bitbang_swd_switch_seq");
|
||||
|
||||
@@ -409,16 +411,13 @@ void bitbang_switch_to_swd(void)
|
||||
bitbang_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len);
|
||||
}
|
||||
|
||||
static void swd_clear_sticky_errors(struct adiv5_dap *dap)
|
||||
static void swd_clear_sticky_errors(void)
|
||||
{
|
||||
const struct swd_driver *swd = jtag_interface->swd;
|
||||
assert(swd);
|
||||
|
||||
swd->write_reg(dap, swd_cmd(false, false, DP_ABORT),
|
||||
STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR);
|
||||
bitbang_swd_write_reg(swd_cmd(false, false, DP_ABORT),
|
||||
STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);
|
||||
}
|
||||
|
||||
static void bitbang_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *value)
|
||||
static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
|
||||
{
|
||||
LOG_DEBUG("bitbang_swd_read_reg");
|
||||
assert(cmd & SWD_CMD_RnW);
|
||||
@@ -459,11 +458,11 @@ static void bitbang_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *v
|
||||
if (value)
|
||||
*value = data;
|
||||
if (cmd & SWD_CMD_APnDP)
|
||||
bitbang_exchange(true, NULL, 0, dap->ap[dap_ap_get_select(dap)].memaccess_tck);
|
||||
bitbang_exchange(true, NULL, 0, ap_delay_clk);
|
||||
return;
|
||||
case SWD_ACK_WAIT:
|
||||
LOG_DEBUG("SWD_ACK_WAIT");
|
||||
swd_clear_sticky_errors(dap);
|
||||
swd_clear_sticky_errors();
|
||||
break;
|
||||
case SWD_ACK_FAULT:
|
||||
LOG_DEBUG("SWD_ACK_FAULT");
|
||||
@@ -477,7 +476,7 @@ static void bitbang_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *v
|
||||
}
|
||||
}
|
||||
|
||||
static void bitbang_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t value)
|
||||
static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
|
||||
{
|
||||
LOG_DEBUG("bitbang_swd_write_reg");
|
||||
assert(!(cmd & SWD_CMD_RnW));
|
||||
@@ -511,11 +510,11 @@ static void bitbang_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t v
|
||||
switch (ack) {
|
||||
case SWD_ACK_OK:
|
||||
if (cmd & SWD_CMD_APnDP)
|
||||
bitbang_exchange(true, NULL, 0, dap->ap[dap_ap_get_select(dap)].memaccess_tck);
|
||||
bitbang_exchange(true, NULL, 0, ap_delay_clk);
|
||||
return;
|
||||
case SWD_ACK_WAIT:
|
||||
LOG_DEBUG("SWD_ACK_WAIT");
|
||||
swd_clear_sticky_errors(dap);
|
||||
swd_clear_sticky_errors();
|
||||
break;
|
||||
case SWD_ACK_FAULT:
|
||||
LOG_DEBUG("SWD_ACK_FAULT");
|
||||
@@ -529,7 +528,7 @@ static void bitbang_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t v
|
||||
}
|
||||
}
|
||||
|
||||
static int bitbang_swd_run_queue(struct adiv5_dap *dap)
|
||||
static int bitbang_swd_run_queue(void)
|
||||
{
|
||||
LOG_DEBUG("bitbang_swd_run_queue");
|
||||
/* A transaction must be followed by another transaction or at least 8 idle cycles to
|
||||
|
||||
@@ -45,6 +45,6 @@ int bitbang_execute_queue(void);
|
||||
|
||||
extern struct bitbang_interface *bitbang_interface;
|
||||
void bitbang_switch_to_swd(void);
|
||||
int bitbang_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq);
|
||||
int bitbang_swd_switch_seq(enum swd_special_seq seq);
|
||||
|
||||
#endif /* BITBANG_H */
|
||||
|
||||
@@ -515,7 +515,7 @@ static int cmsis_dap_cmd_DAP_Delay(uint16_t delay_us)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cmsis_dap_swd_run_queue(struct adiv5_dap *dap)
|
||||
static int cmsis_dap_swd_run_queue(void)
|
||||
{
|
||||
uint8_t *buffer = cmsis_dap_handle->packet_buffer;
|
||||
|
||||
@@ -619,11 +619,11 @@ skip:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void cmsis_dap_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd, uint32_t *dst, uint32_t data)
|
||||
static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data)
|
||||
{
|
||||
if (pending_transfer_count == pending_queue_len) {
|
||||
/* Not enough room in the queue. Run the queue. */
|
||||
queued_retval = cmsis_dap_swd_run_queue(dap);
|
||||
queued_retval = cmsis_dap_swd_run_queue();
|
||||
}
|
||||
|
||||
if (queued_retval != ERROR_OK)
|
||||
@@ -638,16 +638,16 @@ static void cmsis_dap_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd, uint32_t
|
||||
pending_transfer_count++;
|
||||
}
|
||||
|
||||
static void cmsis_dap_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t value)
|
||||
static void cmsis_dap_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
|
||||
{
|
||||
assert(!(cmd & SWD_CMD_RnW));
|
||||
cmsis_dap_swd_queue_cmd(dap, cmd, NULL, value);
|
||||
cmsis_dap_swd_queue_cmd(cmd, NULL, value);
|
||||
}
|
||||
|
||||
static void cmsis_dap_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *value)
|
||||
static void cmsis_dap_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
|
||||
{
|
||||
assert(cmd & SWD_CMD_RnW);
|
||||
cmsis_dap_swd_queue_cmd(dap, cmd, value, 0);
|
||||
cmsis_dap_swd_queue_cmd(cmd, value, 0);
|
||||
}
|
||||
|
||||
static int cmsis_dap_get_version_info(void)
|
||||
@@ -707,7 +707,7 @@ static int cmsis_dap_get_status(void)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int cmsis_dap_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq)
|
||||
static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
|
||||
{
|
||||
uint8_t *buffer = cmsis_dap_handle->packet_buffer;
|
||||
const uint8_t *s;
|
||||
@@ -1002,7 +1002,7 @@ static int cmsis_dap_khz(int khz, int *jtag_speed)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int_least32_t cmsis_dap_swd_frequency(struct adiv5_dap *dap, int_least32_t hz)
|
||||
static int_least32_t cmsis_dap_swd_frequency(int_least32_t hz)
|
||||
{
|
||||
if (hz > 0)
|
||||
cmsis_dap_speed(hz / 1000);
|
||||
|
||||
@@ -128,7 +128,7 @@ static uint16_t direction;
|
||||
static uint16_t jtag_output_init;
|
||||
static uint16_t jtag_direction_init;
|
||||
|
||||
static int ftdi_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq);
|
||||
static int ftdi_swd_switch_seq(enum swd_special_seq seq);
|
||||
|
||||
static struct signal *find_signal_by_name(const char *name)
|
||||
{
|
||||
@@ -941,7 +941,7 @@ static void ftdi_swd_swdio_en(bool enable)
|
||||
* @param dap
|
||||
* @return
|
||||
*/
|
||||
static int ftdi_swd_run_queue(struct adiv5_dap *dap)
|
||||
static int ftdi_swd_run_queue(void)
|
||||
{
|
||||
LOG_DEBUG("Executing %zu queued transactions", swd_cmd_queue_length);
|
||||
int retval;
|
||||
@@ -1008,13 +1008,13 @@ skip:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void ftdi_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd, uint32_t *dst, uint32_t data)
|
||||
static void ftdi_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk)
|
||||
{
|
||||
if (swd_cmd_queue_length >= swd_cmd_queue_alloced) {
|
||||
/* Not enough room in the queue. Run the queue and increase its size for next time.
|
||||
* Note that it's not possible to avoid running the queue here, because mpsse contains
|
||||
* pointers into the queue which may be invalid after the realloc. */
|
||||
queued_retval = ftdi_swd_run_queue(dap);
|
||||
queued_retval = ftdi_swd_run_queue();
|
||||
struct swd_cmd_queue_entry *q = realloc(swd_cmd_queue, swd_cmd_queue_alloced * 2 * sizeof(*swd_cmd_queue));
|
||||
if (q != NULL) {
|
||||
swd_cmd_queue = q;
|
||||
@@ -1057,23 +1057,23 @@ static void ftdi_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd, uint32_t *dst
|
||||
|
||||
/* Insert idle cycles after AP accesses to avoid WAIT */
|
||||
if (cmd & SWD_CMD_APnDP)
|
||||
mpsse_clock_data_out(mpsse_ctx, NULL, 0, dap->ap[dap_ap_get_select(dap)].memaccess_tck, SWD_MODE);
|
||||
mpsse_clock_data_out(mpsse_ctx, NULL, 0, ap_delay_clk, SWD_MODE);
|
||||
|
||||
}
|
||||
|
||||
static void ftdi_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *value)
|
||||
static void ftdi_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
|
||||
{
|
||||
assert(cmd & SWD_CMD_RnW);
|
||||
ftdi_swd_queue_cmd(dap, cmd, value, 0);
|
||||
ftdi_swd_queue_cmd(cmd, value, 0, ap_delay_clk);
|
||||
}
|
||||
|
||||
static void ftdi_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t value)
|
||||
static void ftdi_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
|
||||
{
|
||||
assert(!(cmd & SWD_CMD_RnW));
|
||||
ftdi_swd_queue_cmd(dap, cmd, NULL, value);
|
||||
ftdi_swd_queue_cmd(cmd, NULL, value, ap_delay_clk);
|
||||
}
|
||||
|
||||
static int_least32_t ftdi_swd_frequency(struct adiv5_dap *dap, int_least32_t hz)
|
||||
static int_least32_t ftdi_swd_frequency(int_least32_t hz)
|
||||
{
|
||||
if (hz > 0)
|
||||
freq = mpsse_set_frequency(mpsse_ctx, hz);
|
||||
@@ -1081,7 +1081,7 @@ static int_least32_t ftdi_swd_frequency(struct adiv5_dap *dap, int_least32_t hz)
|
||||
return freq;
|
||||
}
|
||||
|
||||
static int ftdi_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq)
|
||||
static int ftdi_swd_switch_seq(enum swd_special_seq seq)
|
||||
{
|
||||
switch (seq) {
|
||||
case LINE_RESET:
|
||||
|
||||
@@ -87,11 +87,9 @@ static void jlink_runtest(int num_cycles);
|
||||
static void jlink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
|
||||
int scan_size, struct scan_command *command);
|
||||
static void jlink_reset(int trst, int srst);
|
||||
static int jlink_swd_run_queue(struct adiv5_dap *dap);
|
||||
static void jlink_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd,
|
||||
uint32_t *dst, uint32_t data);
|
||||
static int jlink_swd_switch_seq(struct adiv5_dap *dap,
|
||||
enum swd_special_seq seq);
|
||||
static int jlink_swd_run_queue(void);
|
||||
static void jlink_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk);
|
||||
static int jlink_swd_switch_seq(enum swd_special_seq seq);
|
||||
|
||||
/* J-Link tap buffer functions */
|
||||
static void jlink_tap_init(void);
|
||||
@@ -1568,22 +1566,19 @@ static int jlink_swd_init(void)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static void jlink_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd,
|
||||
uint32_t value)
|
||||
static void jlink_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
|
||||
{
|
||||
assert(!(cmd & SWD_CMD_RnW));
|
||||
jlink_swd_queue_cmd(dap, cmd, NULL, value);
|
||||
jlink_swd_queue_cmd(cmd, NULL, value, ap_delay_clk);
|
||||
}
|
||||
|
||||
static void jlink_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd,
|
||||
uint32_t *value)
|
||||
static void jlink_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
|
||||
{
|
||||
assert(cmd & SWD_CMD_RnW);
|
||||
jlink_swd_queue_cmd(dap, cmd, value, 0);
|
||||
jlink_swd_queue_cmd(cmd, value, 0, ap_delay_clk);
|
||||
}
|
||||
|
||||
static int_least32_t jlink_swd_frequency(struct adiv5_dap *dap,
|
||||
int_least32_t hz)
|
||||
static int_least32_t jlink_swd_frequency(int_least32_t hz)
|
||||
{
|
||||
if (hz > 0)
|
||||
jlink_speed(hz / 1000);
|
||||
@@ -1762,7 +1757,7 @@ static void jlink_queue_data_in(uint32_t len)
|
||||
tap_length += len;
|
||||
}
|
||||
|
||||
static int jlink_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq)
|
||||
static int jlink_swd_switch_seq(enum swd_special_seq seq)
|
||||
{
|
||||
const uint8_t *s;
|
||||
unsigned int s_len;
|
||||
@@ -1793,7 +1788,7 @@ static int jlink_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int jlink_swd_run_queue(struct adiv5_dap *dap)
|
||||
static int jlink_swd_run_queue(void)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
@@ -1849,14 +1844,13 @@ skip:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void jlink_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd,
|
||||
uint32_t *dst, uint32_t data)
|
||||
static void jlink_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk)
|
||||
{
|
||||
uint8_t data_parity_trn[DIV_ROUND_UP(32 + 1, 8)];
|
||||
if (tap_length + 46 + 8 + dap->ap[dap_ap_get_select(dap)].memaccess_tck >= sizeof(tdi_buffer) * 8 ||
|
||||
if (tap_length + 46 + 8 + ap_delay_clk >= sizeof(tdi_buffer) * 8 ||
|
||||
pending_scan_results_length == MAX_PENDING_SCAN_RESULTS) {
|
||||
/* Not enough room in the queue. Run the queue. */
|
||||
queued_retval = jlink_swd_run_queue(dap);
|
||||
queued_retval = jlink_swd_run_queue();
|
||||
}
|
||||
|
||||
if (queued_retval != ERROR_OK)
|
||||
@@ -1889,7 +1883,7 @@ static void jlink_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd,
|
||||
|
||||
/* Insert idle cycles after AP accesses to avoid WAIT. */
|
||||
if (cmd & SWD_CMD_APnDP)
|
||||
jlink_queue_data_out(NULL, dap->ap[dap_ap_get_select(dap)].memaccess_tck);
|
||||
jlink_queue_data_out(NULL, ap_delay_clk);
|
||||
}
|
||||
|
||||
static const struct swd_driver jlink_swd = {
|
||||
|
||||
@@ -663,9 +663,9 @@ static int sysfsgpio_init(void)
|
||||
|
||||
if (sysfsgpio_swd_mode_possible()) {
|
||||
if (swd_mode)
|
||||
bitbang_swd_switch_seq(NULL, JTAG_TO_SWD);
|
||||
bitbang_swd_switch_seq(JTAG_TO_SWD);
|
||||
else
|
||||
bitbang_swd_switch_seq(NULL, SWD_TO_JTAG);
|
||||
bitbang_swd_switch_seq(SWD_TO_JTAG);
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
|
||||
@@ -72,10 +72,8 @@ static void vsllink_tap_append_scan(int length, uint8_t *buffer,
|
||||
struct scan_command *command);
|
||||
|
||||
/* VSLLink SWD functions */
|
||||
static int_least32_t vsllink_swd_frequency(struct adiv5_dap *dap,
|
||||
int_least32_t hz);
|
||||
static int vsllink_swd_switch_seq(struct adiv5_dap *dap,
|
||||
enum swd_special_seq seq);
|
||||
static int_least32_t vsllink_swd_frequency(int_least32_t hz);
|
||||
static int vsllink_swd_switch_seq(enum swd_special_seq seq);
|
||||
|
||||
/* VSLLink lowlevel functions */
|
||||
struct vsllink {
|
||||
@@ -243,7 +241,7 @@ static int vsllink_execute_queue(void)
|
||||
static int vsllink_speed(int speed)
|
||||
{
|
||||
if (swd_mode) {
|
||||
vsllink_swd_frequency(NULL, speed * 1000);
|
||||
vsllink_swd_frequency(speed * 1000);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
@@ -349,8 +347,8 @@ static int vsllink_init(void)
|
||||
versaloon_interface.adaptors.gpio.config(0, GPIO_TRST, 0,
|
||||
GPIO_TRST, GPIO_TRST);
|
||||
versaloon_interface.adaptors.swd.init(0);
|
||||
vsllink_swd_frequency(NULL, jtag_get_speed_khz() * 1000);
|
||||
vsllink_swd_switch_seq(NULL, JTAG_TO_SWD);
|
||||
vsllink_swd_frequency(jtag_get_speed_khz() * 1000);
|
||||
vsllink_swd_switch_seq(JTAG_TO_SWD);
|
||||
|
||||
} else {
|
||||
/* malloc buffer size for tap */
|
||||
@@ -730,8 +728,7 @@ static int vsllink_swd_init(void)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int_least32_t vsllink_swd_frequency(struct adiv5_dap *dap,
|
||||
int_least32_t hz)
|
||||
static int_least32_t vsllink_swd_frequency(int_least32_t hz)
|
||||
{
|
||||
const int_least32_t delay2hz[] = {
|
||||
1850000, 235000, 130000, 102000, 85000, 72000
|
||||
@@ -764,8 +761,7 @@ static int_least32_t vsllink_swd_frequency(struct adiv5_dap *dap,
|
||||
return hz;
|
||||
}
|
||||
|
||||
static int vsllink_swd_switch_seq(struct adiv5_dap *dap,
|
||||
enum swd_special_seq seq)
|
||||
static int vsllink_swd_switch_seq(enum swd_special_seq seq)
|
||||
{
|
||||
switch (seq) {
|
||||
case LINE_RESET:
|
||||
@@ -791,19 +787,17 @@ static int vsllink_swd_switch_seq(struct adiv5_dap *dap,
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static void vsllink_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd,
|
||||
uint32_t *value)
|
||||
static void vsllink_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
|
||||
{
|
||||
versaloon_interface.adaptors.swd.transact(0, cmd, value, NULL);
|
||||
}
|
||||
|
||||
static void vsllink_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd,
|
||||
uint32_t value)
|
||||
static void vsllink_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
|
||||
{
|
||||
versaloon_interface.adaptors.swd.transact(0, cmd, &value, NULL);
|
||||
}
|
||||
|
||||
static int vsllink_swd_run_queue(struct adiv5_dap *dap)
|
||||
static int vsllink_swd_run_queue(void)
|
||||
{
|
||||
return versaloon_interface.adaptors.peripheral_commit();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user