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.
This commit is contained in:
Gareth McMullin 2015-02-28 20:53:25 -08:00
parent fa046601a5
commit d6225eec76
4 changed files with 23 additions and 18 deletions

View File

@ -91,8 +91,8 @@ static uint32_t adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
ack = response & 0x07; ack = response & 0x07;
} while(--tries && (ack == JTAGDP_ACK_WAIT)); } while(--tries && (ack == JTAGDP_ACK_WAIT));
if (dp->allow_timeout && (ack == JTAGDP_ACK_WAIT)) if (ack == JTAGDP_ACK_WAIT)
return 0; raise_exception(EXCEPTION_TIMEOUT, "JTAG-DP ACK timeout");
if((ack != JTAGDP_ACK_OK)) if((ack != JTAGDP_ACK_OK))
raise_exception(EXCEPTION_ERROR, "JTAG-DP invalid ACK"); raise_exception(EXCEPTION_ERROR, "JTAG-DP invalid ACK");

View File

@ -136,8 +136,8 @@ static uint32_t adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
ack = swdptap_seq_in(3); ack = swdptap_seq_in(3);
} while(--tries && ack == SWDP_ACK_WAIT); } while(--tries && ack == SWDP_ACK_WAIT);
if (dp->allow_timeout && (ack == SWDP_ACK_WAIT)) if (ack == SWDP_ACK_WAIT)
return 0; raise_exception(EXCEPTION_TIMEOUT, "SWDP ACK timeout");
if(ack == SWDP_ACK_FAULT) { if(ack == SWDP_ACK_FAULT) {
dp->fault = 1; dp->fault = 1;

View File

@ -29,6 +29,7 @@
* There are way too many magic numbers used here. * There are way too many magic numbers used here.
*/ */
#include "general.h" #include "general.h"
#include "exception.h"
#include "jtagtap.h" #include "jtagtap.h"
#include "jtag_scan.h" #include "jtag_scan.h"
#include "adiv5.h" #include "adiv5.h"
@ -467,12 +468,15 @@ cortexm_reset(struct target_s *target)
static void static void
cortexm_halt_request(struct target_s *target) cortexm_halt_request(struct target_s *target)
{ {
ADIv5_AP_t *ap = adiv5_target_ap(target); volatile struct exception e;
TRY_CATCH (e, EXCEPTION_TIMEOUT) {
ap->dp->allow_timeout = false; target_mem_write32(target, CORTEXM_DHCSR, CORTEXM_DHCSR_DBGKEY |
target_mem_write32(target, CORTEXM_DHCSR, CORTEXM_DHCSR_C_HALT |
CORTEXM_DHCSR_DBGKEY | CORTEXM_DHCSR_C_HALT | CORTEXM_DHCSR_C_DEBUGEN);
CORTEXM_DHCSR_C_DEBUGEN); }
if (e.type) {
gdb_out("Timeout sending interrupt, is target in WFI?\n");
}
} }
static int static int
@ -480,10 +484,16 @@ cortexm_halt_wait(struct target_s *target)
{ {
ADIv5_AP_t *ap = adiv5_target_ap(target); ADIv5_AP_t *ap = adiv5_target_ap(target);
struct cortexm_priv *priv = ap->priv; 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. */ /* We've halted. Let's find out why. */
uint32_t dfsr = target_mem_read32(target, CORTEXM_DFSR); 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); target_mem_write32(target, CORTEXM_DHCSR, dhcsr);
ap->dp->allow_timeout = true;
} }
static int cortexm_fault_unwind(struct target_s *target) static int cortexm_fault_unwind(struct target_s *target)

View File

@ -107,12 +107,8 @@ typedef struct ADIv5_DP_s {
uint32_t idcode; uint32_t idcode;
bool allow_timeout;
uint32_t (*dp_read)(struct ADIv5_DP_s *dp, uint16_t addr); uint32_t (*dp_read)(struct ADIv5_DP_s *dp, uint16_t addr);
uint32_t (*error)(struct ADIv5_DP_s *dp); uint32_t (*error)(struct ADIv5_DP_s *dp);
uint32_t (*low_access)(struct ADIv5_DP_s *dp, uint8_t RnW, uint32_t (*low_access)(struct ADIv5_DP_s *dp, uint8_t RnW,
uint16_t addr, uint32_t value); uint16_t addr, uint32_t value);