aarch64: Add instruction stepping support using hardware step
authorpierre Kuo <vichy.kuo@gmail.com>
Thu, 23 Apr 2015 21:44:27 +0000 (14:44 -0700)
committerMatthias Welwarsky <matthias.welwarsky@sysgo.com>
Fri, 10 Feb 2017 12:57:29 +0000 (13:57 +0100)
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>
src/target/aarch64.c
src/target/armv8.h

index c6354c2c973bfae9733c899fa6ef599726e3d7cb..276f4a3ab6beb9e68193afb559bcde97854bccd4 100644 (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);
-
-       /* 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");
index 080237d4ef65789175aae9d81eef95d4f71a3ab7..58e4228c562394cb62324a20dc9514ad3db84268 100644 (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