aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpierre Kuo <vichy.kuo@gmail.com>2015-04-23 14:44:27 -0700
committerMatthias Welwarsky <matthias.welwarsky@sysgo.com>2017-02-10 13:57:29 +0100
commit13d13b2e2a5ed12bcc8f2f0dc44bb2beface4946 (patch)
treee6052034c75078c1c250b42d474c74be68c0f325
parent5ee67ce024fcbdb0292dce1384b41ac0d6f30426 (diff)
downloadriscv-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.c49
-rw-r--r--src/target/armv8.h1
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