mdebug

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 3491cb2bfc76504d2fe3c6ee2cb30528d4589c92
parent ae7e5259441321338769bacf0895af7fd604c474
Author: Brian Swetland <swetland@frotz.net>
Date:   Sun, 21 Jun 2015 02:29:19 -0700

debugger: attempt to auto-recover from swd errors

Diffstat:
Mtools/debugger-core.c | 15++++++++++++---
Mtools/rswdp.c | 30+++++++++++++++++++++++++++++-
Mtools/rswdp.h | 4++++
3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/tools/debugger-core.c b/tools/debugger-core.c @@ -67,6 +67,7 @@ static void m_event(const char *evt) { static void monitor(void) { u32 v; + if (swdp_clear_error()) return; if (swdp_ahb_read(DFSR, &v) == 0) { if (v & DFSR_MASK) { swdp_ahb_write(DFSR, DFSR_MASK); @@ -84,6 +85,10 @@ static pthread_t _dbg_thread; void debugger_lock() { pthread_mutex_lock(&_dbg_lock); + if (swdp_clear_error()) { + xprintf("SWD ERROR persists. Attempting link reset.\n"); + swdp_reset(); + } } void debugger_unlock() { @@ -105,9 +110,13 @@ void debugger_init() { #else -void debugger_lock() { } -void debugger_unlock() { } -void debugger_init() { } +void debugger_lock() { + swdp_clear_error(); +} +void debugger_unlock() { +} +void debugger_init() { +} #endif diff --git a/tools/rswdp.c b/tools/rswdp.c @@ -37,6 +37,8 @@ static u16 sequence = 1; static usb_handle *usb; +static int swd_error = 0; + #define MAXWORDS 512 struct txn { @@ -110,7 +112,15 @@ static int process_reply(struct txn *t, u32 *data, int count) { } continue; case CMD_STATUS: - return op ? -op : 0; + if (op) { + if (swd_error == 0) { + swd_error = -op; + fprintf(stderr, "SWD ERROR\n"); + } + return -op; + } else { + return 0; + } default: fprintf(stderr,"unknown command 0x%02x\n", RSWD_MSG_CMD(msg)); return -1; @@ -505,6 +515,7 @@ int swdp_reset(void) { struct txn t; u32 n, idcode; + swd_error = 0; q_init(&t); t.tx[t.txc++] = RSWD_MSG(CMD_ATTACH, 0, 0); t.tx[t.txc++] = SWD_RD(DP_IDCODE, 1); @@ -513,6 +524,7 @@ int swdp_reset(void) { fprintf(stderr,"IDCODE: %08x\n", idcode); + swd_error = 0; q_init(&t); /* clear any stale errors */ t.tx[t.txc++] = SWD_WR(DP_ABORT, 1); @@ -535,6 +547,22 @@ int swdp_reset(void) { return 0; } +int swdp_clear_error(void) { + if (swd_error == 0) { + return 0; + } else { + struct txn t; + swd_error = 0; + + q_init(&t); + t.tx[t.txc++] = SWD_WR(DP_ABORT, 1); + t.tx[t.txc++] = 0x1E; + q_exec(&t); + + return swd_error; + } +} + void swdp_enable_tracing(int yes) { struct txn t; q_init(&t); diff --git a/tools/rswdp.h b/tools/rswdp.h @@ -46,6 +46,10 @@ int swdp_watchpoint_rd(unsigned n, u32 addr); int swdp_watchpoint_wr(unsigned n, u32 addr); int swdp_watchpoint_rw(unsigned n, u32 addr); +/* attempt to clear any error state from previous transactions */ +/* return 0 if successful (or no error state existed) */ +int swdp_clear_error(void); + int swdp_reset(void); int swdp_open(void);