xdebug

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

commit fc068d707ecc405ed27cc3d5044b270ec43147e3
parent 5b0bd390bb3272cd709b5f8c3d6ef6738d1bc47d
Author: Brian Swetland <swetland@frotz.net>
Date:   Fri,  3 Mar 2023 12:33:05 -0800

transport-dap: q_exec() clear sticky aborts after fault

Diffstat:
Msrc/transport-dap.c | 32++++++++++++++++++++++++--------
1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/src/transport-dap.c b/src/transport-dap.c @@ -12,7 +12,7 @@ #include "transport.h" #include "transport-private.h" -int dap_get_info(DC* dc, unsigned di, void *out, unsigned minlen, unsigned maxlen) { +static int dap_get_info(DC* dc, unsigned di, void *out, unsigned minlen, unsigned maxlen) { uint8_t buf[256 + 2]; buf[0] = DAP_Info; buf[1] = di; @@ -30,7 +30,7 @@ int dap_get_info(DC* dc, unsigned di, void *out, unsigned minlen, unsigned maxle return buf[1]; } -int dap_cmd(DC* dc, const void* tx, unsigned txlen, void* rx, unsigned rxlen) { +static int dap_cmd(DC* dc, const void* tx, unsigned txlen, void* rx, unsigned rxlen) { uint8_t cmd = ((const uint8_t*) tx)[0]; dump("TX>", tx, txlen); if (usb_write(dc->usb, tx, txlen) != txlen) { @@ -51,8 +51,8 @@ int dap_cmd(DC* dc, const void* tx, unsigned txlen, void* rx, unsigned rxlen) { return sz; } -int dap_cmd_std(DC* dc, const char* name, uint8_t* io, - unsigned txlen, unsigned rxlen) { +static int dap_cmd_std(DC* dc, const char* name, uint8_t* io, + unsigned txlen, unsigned rxlen) { int r = dap_cmd(dc, io, txlen, io, rxlen); if (r < 0) { return r; @@ -155,7 +155,10 @@ static int dc_decode_status(unsigned n) { return DC_OK; } -int dc_q_exec(DC* dc) { +// this internal version is called from the "public" dc_q_exec +// as well as when we need to flush outstanding txns before +// continuing to queue up more +static int _dc_q_exec(DC* dc) { // if we're already in error, don't generate more usb traffic if (dc->qerror) { int r = dc->qerror; @@ -200,13 +203,25 @@ int dc_q_exec(DC* dc) { return r; } +// the public dc_q_exec() is called from higher layers +int dc_q_exec(DC* dc) { + int r = _dc_q_exec(dc); + if (r == DC_ERR_SWD_FAULT) { + // clear all sticky errors + dc_dp_wr(dc, DP_ABORT, DP_ABORT_ALLCLR); + + } + return r; +} + // internal use only -- queue raw dp reads and writes // these do not check req for correctness static void dc_q_raw_rd(DC* dc, unsigned req, uint32_t* val) { if ((dc->txavail < 1) || (dc->rxavail < 4)) { // exec q to make space for more work, // but if there's an error, latch it - if ((dc->qerror = dc_q_exec(dc)) != DC_OK) { + // so we don't send any further txns + if ((dc->qerror = _dc_q_exec(dc)) != DC_OK) { return; } } @@ -223,7 +238,8 @@ static void dc_q_raw_wr(DC* dc, unsigned req, uint32_t val) { if (dc->txavail < 5) { // exec q to make space for more work, // but if there's an error, latch it - if ((dc->qerror = dc_q_exec(dc)) != DC_OK) { + // so we don't send any further txns + if ((dc->qerror = _dc_q_exec(dc)) != DC_OK) { return; } } @@ -402,7 +418,7 @@ static int _dc_attach(DC* dc, unsigned flags, uint32_t tgt, uint32_t* idcode) { // or line reset + target select dc_q_init(dc); dc_q_raw_rd(dc, XFER_DP | XFER_RD | XFER_00, idcode); - int r = dc_q_exec(dc); + int r = _dc_q_exec(dc); return r; }