aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Vanek <vanekt@fbl.cz>2024-02-17 13:14:01 +0100
committerAntonio Borneo <borneo.antonio@gmail.com>2024-03-16 14:37:26 +0000
commit31af18e9d1807d442885d0254ff5b13a66ea3a65 (patch)
treeea3d96191af350c75b64375d1801723032d91914
parentf7f4fa84f1466036ebec80b3143fdd32ce181344 (diff)
downloadriscv-openocd-31af18e9d1807d442885d0254ff5b13a66ea3a65.zip
riscv-openocd-31af18e9d1807d442885d0254ff5b13a66ea3a65.tar.gz
riscv-openocd-31af18e9d1807d442885d0254ff5b13a66ea3a65.tar.bz2
jtag/drivers/bitbang: limit SWD WAIT retries by timeout
The bitbang driver kept retrying a SWD command as long as the debugged device had been responding by SWD WAIT. If the DP stalled in WAIT permanently, OpenOCD hanged. Check 0.5 sec timeout in WAIT retry loop. While on it insert a short alive_sleep() if the command is retried 20 or more times. Signed-off-by: Tomas Vanek <vanekt@fbl.cz> Change-Id: I744e56e21a5a2dc2c4494cc0d7bbcb4be14ddb23 Reviewed-on: https://review.openocd.org/c/openocd/+/8153 Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Tested-by: jenkins
-rw-r--r--src/jtag/drivers/bitbang.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/jtag/drivers/bitbang.c b/src/jtag/drivers/bitbang.c
index f023684..3d839e6 100644
--- a/src/jtag/drivers/bitbang.c
+++ b/src/jtag/drivers/bitbang.c
@@ -20,6 +20,11 @@
#include <jtag/interface.h>
#include <jtag/commands.h>
+#include <helper/time_support.h>
+
+/* Timeout for retrying on SWD WAIT in msec */
+#define SWD_WAIT_TIMEOUT 500
+
/**
* Function bitbang_stableclocks
* issues a number of clock cycles while staying in a stable state.
@@ -474,6 +479,7 @@ static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay
return;
}
+ int64_t timeout = timeval_ms() + SWD_WAIT_TIMEOUT;
for (unsigned int retry = 0;; retry++) {
uint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)];
@@ -496,8 +502,11 @@ static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay
(cmd & SWD_CMD_A32) >> 1,
data);
- if (ack == SWD_ACK_WAIT) {
+ if (ack == SWD_ACK_WAIT && timeval_ms() <= timeout) {
swd_clear_sticky_errors();
+ if (retry > 20)
+ alive_sleep(1);
+
continue;
}
if (retry > 1)
@@ -530,6 +539,8 @@ static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay
return;
}
+ int64_t timeout = timeval_ms() + SWD_WAIT_TIMEOUT;
+
/* Devices do not reply to DP_TARGETSEL write cmd, ignore received ack */
bool check_ack = swd_cmd_returns_ack(cmd);
@@ -569,8 +580,11 @@ static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay
(cmd & SWD_CMD_A32) >> 1,
buf_get_u32(trn_ack_data_parity_trn, 1 + 3 + 1, 32));
- if (check_ack && ack == SWD_ACK_WAIT) {
+ if (check_ack && ack == SWD_ACK_WAIT && timeval_ms() <= timeout) {
swd_clear_sticky_errors();
+ if (retry > 20)
+ alive_sleep(1);
+
continue;
}