aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/target/aarch64.c49
-rw-r--r--src/target/armv8.c2
-rw-r--r--src/target/armv8.h4
-rw-r--r--src/target/armv8_dpm.c21
-rw-r--r--src/target/armv8_dpm.h2
5 files changed, 22 insertions, 56 deletions
diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index e6eb2ca..612924f 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -988,25 +988,26 @@ static int aarch64_debug_entry(struct target *target)
/* Examine debug reason */
armv8_dpm_report_dscr(dpm, dscr);
- /* save address of instruction that triggered the watchpoint? */
+ /* save the memory address that triggered the watchpoint */
if (target->debug_reason == DBG_REASON_WATCHPOINT) {
uint32_t tmp;
- uint64_t wfar = 0;
retval = mem_ap_read_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_WFAR1,
- &tmp);
+ armv8->debug_base + CPUV8_DBG_EDWAR0, &tmp);
if (retval != ERROR_OK)
return retval;
- wfar = tmp;
- wfar = (wfar << 32);
- retval = mem_ap_read_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_WFAR0,
- &tmp);
- if (retval != ERROR_OK)
- return retval;
- wfar |= tmp;
- armv8_dpm_report_wfar(&armv8->dpm, wfar);
+ target_addr_t edwar = tmp;
+
+ /* EDWAR[63:32] has unknown content in aarch32 state */
+ if (core_state == ARM_STATE_AARCH64) {
+ retval = mem_ap_read_atomic_u32(armv8->debug_ap,
+ armv8->debug_base + CPUV8_DBG_EDWAR1, &tmp);
+ if (retval != ERROR_OK)
+ return retval;
+ edwar |= ((target_addr_t)tmp) << 32;
+ }
+
+ armv8->dpm.wp_addr = edwar;
}
retval = armv8_dpm_read_current_registers(&armv8->dpm);
@@ -1853,7 +1854,7 @@ int aarch64_hit_watchpoint(struct target *target,
struct armv8_common *armv8 = target_to_armv8(target);
- uint64_t exception_address;
+ target_addr_t exception_address;
struct watchpoint *wp;
exception_address = armv8->dpm.wp_addr;
@@ -1861,23 +1862,11 @@ int aarch64_hit_watchpoint(struct target *target,
if (exception_address == 0xFFFFFFFF)
return ERROR_FAIL;
- /**********************************************************/
- /* see if a watchpoint address matches a value read from */
- /* the EDWAR register. Testing shows that on some ARM CPUs*/
- /* the EDWAR value needs to have 8 added to it so we add */
- /* that check as well not sure if that is a core bug) */
- /**********************************************************/
- for (exception_address = armv8->dpm.wp_addr; exception_address <= (armv8->dpm.wp_addr + 8);
- exception_address += 8) {
- for (wp = target->watchpoints; wp; wp = wp->next) {
- if ((exception_address >= wp->address) && (exception_address < (wp->address + wp->length))) {
- *hit_watchpoint = wp;
- if (exception_address != armv8->dpm.wp_addr)
- LOG_DEBUG("watchpoint hit required EDWAR to be increased by 8");
- return ERROR_OK;
- }
+ for (wp = target->watchpoints; wp; wp = wp->next)
+ if (exception_address >= wp->address && exception_address < (wp->address + wp->length)) {
+ *hit_watchpoint = wp;
+ return ERROR_OK;
}
- }
return ERROR_FAIL;
}
diff --git a/src/target/armv8.c b/src/target/armv8.c
index e209e88..0c5cf34 100644
--- a/src/target/armv8.c
+++ b/src/target/armv8.c
@@ -1169,7 +1169,7 @@ int armv8_arch_state(struct target *target)
armv8_show_fault_registers(target);
if (target->debug_reason == DBG_REASON_WATCHPOINT)
- LOG_USER("Watchpoint triggered at PC " TARGET_ADDR_FMT, armv8->dpm.wp_addr);
+ LOG_USER("Watchpoint triggered at " TARGET_ADDR_FMT, armv8->dpm.wp_addr);
return ERROR_OK;
}
diff --git a/src/target/armv8.h b/src/target/armv8.h
index 978b2ad..f09f3ab 100644
--- a/src/target/armv8.h
+++ b/src/target/armv8.h
@@ -257,8 +257,8 @@ static inline bool is_armv8(struct armv8_common *armv8)
#define CPUV8_DBG_EDESR 0x20
#define CPUV8_DBG_EDECR 0x24
-#define CPUV8_DBG_WFAR0 0x30
-#define CPUV8_DBG_WFAR1 0x34
+#define CPUV8_DBG_EDWAR0 0x30
+#define CPUV8_DBG_EDWAR1 0x34
#define CPUV8_DBG_DSCR 0x088
#define CPUV8_DBG_DRCR 0x090
#define CPUV8_DBG_ECCR 0x098
diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c
index a7b4f1d..6ef8c33 100644
--- a/src/target/armv8_dpm.c
+++ b/src/target/armv8_dpm.c
@@ -1279,27 +1279,6 @@ static int dpmv8_remove_watchpoint(struct target *target, struct watchpoint *wp)
return retval;
}
-void armv8_dpm_report_wfar(struct arm_dpm *dpm, uint64_t addr)
-{
- switch (dpm->arm->core_state) {
- case ARM_STATE_ARM:
- case ARM_STATE_AARCH64:
- addr -= 8;
- break;
- case ARM_STATE_THUMB:
- case ARM_STATE_THUMB_EE:
- addr -= 4;
- break;
- case ARM_STATE_JAZELLE:
- /* ?? */
- break;
- default:
- LOG_DEBUG("Unknown core_state");
- break;
- }
- dpm->wp_addr = addr;
-}
-
/*
* Handle exceptions taken in debug state. This happens mostly for memory
* accesses that violated a MMU policy. Taking an exception while in debug
diff --git a/src/target/armv8_dpm.h b/src/target/armv8_dpm.h
index a6cade3..c30b04f 100644
--- a/src/target/armv8_dpm.h
+++ b/src/target/armv8_dpm.h
@@ -38,8 +38,6 @@ int armv8_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode);
int armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp);
-void armv8_dpm_report_wfar(struct arm_dpm *dpm, uint64_t wfar);
-
/* DSCR bits; see ARMv7a arch spec section C10.3.1.
* Not all v7 bits are valid in v6.
*/