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>
This commit is contained in:
parent
a12c15e21f
commit
6b554b3b0e
|
@ -1063,6 +1063,7 @@ static int aarch64_debug_entry(struct target *target)
|
||||||
int retval = ERROR_OK;
|
int retval = ERROR_OK;
|
||||||
struct aarch64_common *aarch64 = target_to_aarch64(target);
|
struct aarch64_common *aarch64 = target_to_aarch64(target);
|
||||||
struct armv8_common *armv8 = target_to_armv8(target);
|
struct armv8_common *armv8 = target_to_armv8(target);
|
||||||
|
uint32_t tmp;
|
||||||
|
|
||||||
LOG_DEBUG("dscr = 0x%08" PRIx32, aarch64->cpudbg_dscr);
|
LOG_DEBUG("dscr = 0x%08" PRIx32, aarch64->cpudbg_dscr);
|
||||||
|
|
||||||
|
@ -1086,6 +1087,10 @@ static int aarch64_debug_entry(struct target *target)
|
||||||
|
|
||||||
/* Examine debug reason */
|
/* Examine debug reason */
|
||||||
arm_dpm_report_dscr(&armv8->dpm, aarch64->cpudbg_dscr);
|
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? */
|
/* save address of instruction that triggered the watchpoint? */
|
||||||
if (target->debug_reason == DBG_REASON_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)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
|
target->debug_reason = DBG_REASON_SINGLESTEP;
|
||||||
retval = aarch64_resume(target, 1, address, 0, 0);
|
retval = aarch64_resume(target, 1, address, 0, 0);
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
long long then = timeval_ms();
|
long long then = timeval_ms();
|
||||||
while (target->state != TARGET_HALTED) {
|
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);
|
retval = aarch64_poll(target);
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
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,
|
retval = mem_ap_write_atomic_u32(armv8->debug_ap,
|
||||||
armv8->debug_base + CPUDBG_DECR, (tmp&(~0x4)));
|
armv8->debug_base + CPUDBG_DECR, (tmp&(~0x4)));
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
if (target->state != TARGET_HALTED)
|
target_call_event_callbacks(target, TARGET_EVENT_HALTED);
|
||||||
|
if (target->state == TARGET_HALTED)
|
||||||
LOG_DEBUG("target stepped");
|
LOG_DEBUG("target stepped");
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
|
|
|
@ -161,6 +161,7 @@ target_to_armv8(struct target *target)
|
||||||
/* register offsets from armv8.debug_base */
|
/* register offsets from armv8.debug_base */
|
||||||
|
|
||||||
#define CPUDBG_WFAR 0x018
|
#define CPUDBG_WFAR 0x018
|
||||||
|
#define CPUDBG_DESR 0x020
|
||||||
#define CPUDBG_DECR 0x024
|
#define CPUDBG_DECR 0x024
|
||||||
/* PCSR at 0x084 -or- 0x0a0 -or- both ... based on flags in DIDR */
|
/* PCSR at 0x084 -or- 0x0a0 -or- both ... based on flags in DIDR */
|
||||||
#define CPUDBG_DSCR 0x088
|
#define CPUDBG_DSCR 0x088
|
||||||
|
|
Loading…
Reference in New Issue