aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGareth McMullin2015-02-28 20:53:25 -0800
committerGareth McMullin2015-03-22 12:26:45 -0700
commitd6225eec763bd49ef3cb8edac5138df9e524a073 (patch)
tree7db158a0e0adf742238a69b9e7ec6d2cfcc0192d
parentfa046601a54ddf2137048f11594ed7d72ede995a (diff)
Raise timeout exception when target is in WFI.
Ignore the exception when polling for halt, and report the exception to the user if halting the target fails. Remove old allow_timeout flag in DP struct that's no longer needed.
-rw-r--r--src/adiv5_jtagdp.c4
-rw-r--r--src/adiv5_swdp.c4
-rw-r--r--src/cortexm.c29
-rw-r--r--src/include/adiv5.h4
4 files changed, 23 insertions, 18 deletions
diff --git a/src/adiv5_jtagdp.c b/src/adiv5_jtagdp.c
index bb478d1..a460113 100644
--- a/src/adiv5_jtagdp.c
+++ b/src/adiv5_jtagdp.c
@@ -91,8 +91,8 @@ static uint32_t adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
ack = response & 0x07;
} while(--tries && (ack == JTAGDP_ACK_WAIT));
- if (dp->allow_timeout && (ack == JTAGDP_ACK_WAIT))
- return 0;
+ if (ack == JTAGDP_ACK_WAIT)
+ raise_exception(EXCEPTION_TIMEOUT, "JTAG-DP ACK timeout");
if((ack != JTAGDP_ACK_OK))
raise_exception(EXCEPTION_ERROR, "JTAG-DP invalid ACK");
diff --git a/src/adiv5_swdp.c b/src/adiv5_swdp.c
index d5193ac..1a6b158 100644
--- a/src/adiv5_swdp.c
+++ b/src/adiv5_swdp.c
@@ -136,8 +136,8 @@ static uint32_t adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
ack = swdptap_seq_in(3);
} while(--tries && ack == SWDP_ACK_WAIT);
- if (dp->allow_timeout && (ack == SWDP_ACK_WAIT))
- return 0;
+ if (ack == SWDP_ACK_WAIT)
+ raise_exception(EXCEPTION_TIMEOUT, "SWDP ACK timeout");
if(ack == SWDP_ACK_FAULT) {
dp->fault = 1;
diff --git a/src/cortexm.c b/src/cortexm.c
index a129a3c..f20f282 100644
--- a/src/cortexm.c
+++ b/src/cortexm.c
@@ -29,6 +29,7 @@
* There are way too many magic numbers used here.
*/
#include "general.h"
+#include "exception.h"
#include "jtagtap.h"
#include "jtag_scan.h"
#include "adiv5.h"
@@ -467,12 +468,15 @@ cortexm_reset(struct target_s *target)
static void
cortexm_halt_request(struct target_s *target)
{
- ADIv5_AP_t *ap = adiv5_target_ap(target);
-
- ap->dp->allow_timeout = false;
- target_mem_write32(target, CORTEXM_DHCSR,
- CORTEXM_DHCSR_DBGKEY | CORTEXM_DHCSR_C_HALT |
- CORTEXM_DHCSR_C_DEBUGEN);
+ volatile struct exception e;
+ TRY_CATCH (e, EXCEPTION_TIMEOUT) {
+ target_mem_write32(target, CORTEXM_DHCSR, CORTEXM_DHCSR_DBGKEY |
+ CORTEXM_DHCSR_C_HALT |
+ CORTEXM_DHCSR_C_DEBUGEN);
+ }
+ if (e.type) {
+ gdb_out("Timeout sending interrupt, is target in WFI?\n");
+ }
}
static int
@@ -480,10 +484,16 @@ cortexm_halt_wait(struct target_s *target)
{
ADIv5_AP_t *ap = adiv5_target_ap(target);
struct cortexm_priv *priv = ap->priv;
- if (!(target_mem_read32(target, CORTEXM_DHCSR) & CORTEXM_DHCSR_S_HALT))
- return 0;
- ap->dp->allow_timeout = false;
+ uint32_t dhcsr = 0;
+ volatile struct exception e;
+ TRY_CATCH (e, EXCEPTION_TIMEOUT) {
+ /* If this times out because the target is in WFI then
+ * the target is still running. */
+ dhcsr = target_mem_read32(target, CORTEXM_DHCSR);
+ }
+ if (e.type || !(dhcsr & CORTEXM_DHCSR_S_HALT))
+ return 0;
/* We've halted. Let's find out why. */
uint32_t dfsr = target_mem_read32(target, CORTEXM_DFSR);
@@ -543,7 +553,6 @@ void cortexm_halt_resume(struct target_s *target, bool step)
}
target_mem_write32(target, CORTEXM_DHCSR, dhcsr);
- ap->dp->allow_timeout = true;
}
static int cortexm_fault_unwind(struct target_s *target)
diff --git a/src/include/adiv5.h b/src/include/adiv5.h
index 6896f6d..12d3bf4 100644
--- a/src/include/adiv5.h
+++ b/src/include/adiv5.h
@@ -107,12 +107,8 @@ typedef struct ADIv5_DP_s {
uint32_t idcode;
- bool allow_timeout;
-
uint32_t (*dp_read)(struct ADIv5_DP_s *dp, uint16_t addr);
-
uint32_t (*error)(struct ADIv5_DP_s *dp);
-
uint32_t (*low_access)(struct ADIv5_DP_s *dp, uint8_t RnW,
uint16_t addr, uint32_t value);