aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Ung <davidu@nvidia.com>2015-04-20 13:14:43 -0700
committerMatthias Welwarsky <matthias.welwarsky@sysgo.com>2017-02-10 13:59:15 +0100
commit6b554b3b0e34fe0a1d37a1584baf3c3e32a76b57 (patch)
treed24136825f66a84297b97af0c4ac88a4842875b2
parenta12c15e21f663550de518595e606633bf82b5d04 (diff)
aarch64: Correct target state for hardware step
When using hardware step for doing stepping, the existing DSCR records the event as external debug request. This will generate a SIGINT event to GDB and causes it to stop the stepping process. For aarch64, read DESR to check if the event is a hardware step and set state to DBG_REASON_SINGLESTEP. With this patch, GDB can now do source level stepping. Change-Id: I1d06f819578c74b3ac17376c67f882adddea1f52 Signed-off-by: David Ung <david.ung.42@gmail.com> Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com>
-rw-r--r--src/target/aarch64.c13
-rw-r--r--src/target/armv8.h1
2 files changed, 12 insertions, 2 deletions
diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index a2b020bf..78d19731 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -1063,6 +1063,7 @@ static int aarch64_debug_entry(struct target *target)
int retval = ERROR_OK;
struct aarch64_common *aarch64 = target_to_aarch64(target);
struct armv8_common *armv8 = target_to_armv8(target);
+ uint32_t tmp;
LOG_DEBUG("dscr = 0x%08" PRIx32, aarch64->cpudbg_dscr);
@@ -1086,6 +1087,10 @@ static int aarch64_debug_entry(struct target *target)
/* Examine debug reason */
arm_dpm_report_dscr(&armv8->dpm, aarch64->cpudbg_dscr);
+ mem_ap_read_atomic_u32(armv8->debug_ap,
+ armv8->debug_base + CPUDBG_DESR, &tmp);
+ if ((tmp & 0x7) == 0x4)
+ target->debug_reason = DBG_REASON_SINGLESTEP;
/* save address of instruction that triggered the watchpoint? */
if (target->debug_reason == DBG_REASON_WATCHPOINT) {
@@ -1164,12 +1169,16 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres
if (retval != ERROR_OK)
return retval;
+ target->debug_reason = DBG_REASON_SINGLESTEP;
retval = aarch64_resume(target, 1, address, 0, 0);
if (retval != ERROR_OK)
return retval;
long long then = timeval_ms();
while (target->state != TARGET_HALTED) {
+ mem_ap_read_atomic_u32(armv8->debug_ap,
+ armv8->debug_base + CPUDBG_DESR, &tmp);
+ LOG_DEBUG("DESR = %#x", tmp);
retval = aarch64_poll(target);
if (retval != ERROR_OK)
return retval;
@@ -1179,13 +1188,13 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres
}
}
- target->debug_reason = DBG_REASON_BREAKPOINT;
retval = mem_ap_write_atomic_u32(armv8->debug_ap,
armv8->debug_base + CPUDBG_DECR, (tmp&(~0x4)));
if (retval != ERROR_OK)
return retval;
- if (target->state != TARGET_HALTED)
+ target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+ if (target->state == TARGET_HALTED)
LOG_DEBUG("target stepped");
return ERROR_OK;
diff --git a/src/target/armv8.h b/src/target/armv8.h
index 58e4228c..47e36680 100644
--- a/src/target/armv8.h
+++ b/src/target/armv8.h
@@ -161,6 +161,7 @@ target_to_armv8(struct target *target)
/* register offsets from armv8.debug_base */
#define CPUDBG_WFAR 0x018
+#define CPUDBG_DESR 0x020
#define CPUDBG_DECR 0x024
/* PCSR at 0x084 -or- 0x0a0 -or- both ... based on flags in DIDR */
#define CPUDBG_DSCR 0x088