aarch64: Add instruction stepping support using hardware step

Use AARCH64's hardware step event to do stepping.

Change-Id: I2d029ceeadd381913d0c3355c8787b11dacff7f7
Signed-off-by: pierre Kuo <vichy.kuo@gmail.com>
Signed-off-by: David Ung <david.ung.42@gmail.com>
Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com>
This commit is contained in:
pierre Kuo 2015-04-23 14:44:27 -07:00 committed by Matthias Welwarsky
parent 5ee67ce024
commit 13d13b2e2a
2 changed files with 14 additions and 36 deletions

View File

@ -1150,45 +1150,23 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres
int handle_breakpoints)
{
struct armv8_common *armv8 = target_to_armv8(target);
struct arm *arm = &armv8->arm;
struct breakpoint *breakpoint = NULL;
struct breakpoint stepbreakpoint;
struct reg *r;
int retval;
uint32_t tmp;
if (target->state != TARGET_HALTED) {
LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED;
}
/* current = 1: continue on current pc, otherwise continue at <address> */
r = arm->pc;
if (!current)
buf_set_u64(r->value, 0, 64, address);
else
address = buf_get_u64(r->value, 0, 64);
retval = mem_ap_read_atomic_u32(armv8->debug_ap,
armv8->debug_base + CPUDBG_DECR, &tmp);
if (retval != ERROR_OK)
return retval;
/* The front-end may request us not to handle breakpoints.
* But since Cortex-A8 uses breakpoint for single step,
* we MUST handle breakpoints.
*/
handle_breakpoints = 1;
if (handle_breakpoints) {
breakpoint = breakpoint_find(target, address);
if (breakpoint)
aarch64_unset_breakpoint(target, breakpoint);
}
/* Setup single step breakpoint */
stepbreakpoint.address = address;
stepbreakpoint.length = 4;
stepbreakpoint.type = BKPT_HARD;
stepbreakpoint.set = 0;
/* Break on IVA mismatch */
aarch64_set_breakpoint(target, &stepbreakpoint, 0x04);
target->debug_reason = DBG_REASON_SINGLESTEP;
retval = mem_ap_write_atomic_u32(armv8->debug_ap,
armv8->debug_base + CPUDBG_DECR, (tmp|0x4));
if (retval != ERROR_OK)
return retval;
retval = aarch64_resume(target, 1, address, 0, 0);
if (retval != ERROR_OK)
@ -1205,12 +1183,11 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres
}
}
aarch64_unset_breakpoint(target, &stepbreakpoint);
target->debug_reason = DBG_REASON_BREAKPOINT;
if (breakpoint)
aarch64_set_breakpoint(target, breakpoint, 0);
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)
LOG_DEBUG("target stepped");

View File

@ -161,6 +161,7 @@ target_to_armv8(struct target *target)
/* register offsets from armv8.debug_base */
#define CPUDBG_WFAR 0x018
#define CPUDBG_DECR 0x024
/* PCSR at 0x084 -or- 0x0a0 -or- both ... based on flags in DIDR */
#define CPUDBG_DSCR 0x088
#define CPUDBG_DRCR 0x090