aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Welwarsky <matthias.welwarsky@sysgo.com>2016-09-16 11:34:03 +0200
committerMatthias Welwarsky <matthias.welwarsky@sysgo.com>2017-02-10 14:01:38 +0100
commitd8abda4bd828f40fc76613f4d809d86f4c6f1c97 (patch)
treea78a2ffaf2a9d2039c4447f96252e758d9fed45e
parent391109505fff97772c70f7dda02865e7a9863007 (diff)
aarch64: fix entry into debug state
- armv8 EDSCR has no ITR_EN bit, ITR is always enabled. Writes to this bit are ignored but we should not do them anyway - use dpmv8 function to report the reason for debug entry - WFAR is a 64bit register Change-Id: I07b81ecf105ceb7c3ae2f764bb408eb973c1d1de Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com>
-rw-r--r--src/target/aarch64.c34
-rw-r--r--src/target/arm_dpm.h2
2 files changed, 16 insertions, 20 deletions
diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index 8ddc226..ef73afd 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -1140,49 +1140,45 @@ static int aarch64_resume(struct target *target, int current,
static int aarch64_debug_entry(struct target *target)
{
- uint32_t dscr;
int retval = ERROR_OK;
struct aarch64_common *aarch64 = target_to_aarch64(target);
struct armv8_common *armv8 = target_to_armv8(target);
- uint32_t tmp;
LOG_DEBUG("dscr = 0x%08" PRIx32, aarch64->cpudbg_dscr);
- /* REVISIT surely we should not re-read DSCR !! */
- retval = mem_ap_read_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
- if (retval != ERROR_OK)
- return retval;
-
/* REVISIT see A8 TRM 12.11.4 steps 2..3 -- make sure that any
* imprecise data aborts get discarded by issuing a Data
* Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
*/
- /* Enable the ITR execution once we are in debug mode */
- dscr |= DSCR_ITR_EN;
+ /* make sure to clear all sticky errors */
retval = mem_ap_write_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_DSCR, dscr);
+ armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
if (retval != ERROR_OK)
return retval;
/* Examine debug reason */
- arm_dpm_report_dscr(&armv8->dpm, aarch64->cpudbg_dscr);
- mem_ap_read_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_EDESR, &tmp);
- if ((tmp & 0x7) == 0x4)
- target->debug_reason = DBG_REASON_SINGLESTEP;
+ armv8_dpm_report_dscr(&armv8->dpm, aarch64->cpudbg_dscr);
/* save address of instruction that triggered the watchpoint? */
if (target->debug_reason == DBG_REASON_WATCHPOINT) {
- uint32_t wfar;
+ uint32_t tmp;
+ uint64_t wfar = 0;
retval = mem_ap_read_atomic_u32(armv8->debug_ap,
+ armv8->debug_base + CPUV8_DBG_WFAR1,
+ &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,
- &wfar);
+ &tmp);
if (retval != ERROR_OK)
return retval;
- arm_dpm_report_wfar(&armv8->dpm, wfar);
+ wfar |= tmp;
+ armv8_dpm_report_wfar(&armv8->dpm, wfar);
}
retval = armv8_dpm_read_current_registers(&armv8->dpm);
diff --git a/src/target/arm_dpm.h b/src/target/arm_dpm.h
index ad49b8c..27badf4 100644
--- a/src/target/arm_dpm.h
+++ b/src/target/arm_dpm.h
@@ -138,7 +138,7 @@ struct arm_dpm {
struct dpm_wp *dwp;
/** Address of the instruction which triggered a watchpoint. */
- uint32_t wp_pc;
+ target_addr_t wp_pc;
/** Recent value of DSCR. */
uint32_t dscr;