diff options
author | pierre Kuo <vichy.kuo@gmail.com> | 2015-04-23 14:44:27 -0700 |
---|---|---|
committer | Matthias Welwarsky <matthias.welwarsky@sysgo.com> | 2017-02-10 13:57:29 +0100 |
commit | 13d13b2e2a5ed12bcc8f2f0dc44bb2beface4946 (patch) | |
tree | e6052034c75078c1c250b42d474c74be68c0f325 | |
parent | 5ee67ce024fcbdb0292dce1384b41ac0d6f30426 (diff) | |
download | riscv-openocd-13d13b2e2a5ed12bcc8f2f0dc44bb2beface4946.zip riscv-openocd-13d13b2e2a5ed12bcc8f2f0dc44bb2beface4946.tar.gz riscv-openocd-13d13b2e2a5ed12bcc8f2f0dc44bb2beface4946.tar.bz2 |
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>
-rw-r--r-- | src/target/aarch64.c | 49 | ||||
-rw-r--r-- | src/target/armv8.h | 1 |
2 files changed, 14 insertions, 36 deletions
diff --git a/src/target/aarch64.c b/src/target/aarch64.c index c6354c2..276f4a3 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -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); - - /* 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); + retval = mem_ap_read_atomic_u32(armv8->debug_ap, + armv8->debug_base + CPUDBG_DECR, &tmp); + if (retval != ERROR_OK) + return retval; - 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"); diff --git a/src/target/armv8.h b/src/target/armv8.h index 080237d..58e4228 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_DECR 0x024 /* PCSR at 0x084 -or- 0x0a0 -or- both ... based on flags in DIDR */ #define CPUDBG_DSCR 0x088 #define CPUDBG_DRCR 0x090 |