summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2009-12-03 16:08:04 -0800
committerDavid Brownell <dbrownell@users.sourceforge.net>2009-12-03 16:08:04 -0800
commitea7a49cb9b46ccc27daf6c9b306290c7e905a9fc (patch)
tree24c67ceb5f9a185a0e3220a3121d366c74b28aef
parent6eee0729d79eab496d1d4368a2bae7e4e2d19876 (diff)
downloadopenocd+libswd-ea7a49cb9b46ccc27daf6c9b306290c7e905a9fc.tar.gz
openocd+libswd-ea7a49cb9b46ccc27daf6c9b306290c7e905a9fc.tar.bz2
openocd+libswd-ea7a49cb9b46ccc27daf6c9b306290c7e905a9fc.tar.xz
openocd+libswd-ea7a49cb9b46ccc27daf6c9b306290c7e905a9fc.zip
ARM DPM: share debug reason logic
No point in both ARM11 and Cortex-A8 having private copies of the logic sorting out e.g. DBG_REASON_WATCHPOINT. Add and use a shared routine for this ... there's actually a bunch more debug entry logic that could be shared, this is just a start on that. Note that this routine fixes a bug observed in the ARM11 code, where some abort mode quirks were displayed as being an unknown debug reason; and also silences needless ARM11 chatter. Likewise with private copies of DSCR ... add one to the DPM struct. Save it as part of setting DBG_REASON_* so later patches can switch over to using that copy. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-rw-r--r--src/target/arm11.c24
-rw-r--r--src/target/arm11.h12
-rw-r--r--src/target/arm11_dbgtap.c44
-rw-r--r--src/target/arm11_dbgtap.h2
-rw-r--r--src/target/arm_dpm.c36
-rw-r--r--src/target/arm_dpm.h5
-rw-r--r--src/target/cortex_a8.c37
7 files changed, 60 insertions, 100 deletions
diff --git a/src/target/arm11.c b/src/target/arm11.c
index b01e33bd..20ad22d5 100644
--- a/src/target/arm11.c
+++ b/src/target/arm11.c
@@ -83,8 +83,7 @@ static int arm11_check_init(struct arm11_common *arm11)
*/
arm11->arm.target->state = TARGET_HALTED;
- arm11->arm.target->debug_reason =
- arm11_get_DSCR_debug_reason(arm11->dscr);
+ arm_dpm_report_dscr(arm11->arm.dpm, arm11->dscr);
}
else
{
@@ -108,8 +107,7 @@ static int arm11_debug_entry(struct arm11_common *arm11)
int retval;
arm11->arm.target->state = TARGET_HALTED;
- arm11->arm.target->debug_reason =
- arm11_get_DSCR_debug_reason(arm11->dscr);
+ arm_dpm_report_dscr(arm11->arm.dpm, arm11->dscr);
/* REVISIT entire cache should already be invalid !!! */
register_cache_invalidate(arm11->arm.core_cache);
@@ -551,20 +549,12 @@ static int arm11_resume(struct target *target, int current,
i++;
}
+ target->debug_reason = DBG_REASON_NOTHALTED;
if (!debug_execution)
- {
- target->state = TARGET_RUNNING;
- target->debug_reason = DBG_REASON_NOTHALTED;
-
- CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));
- }
+ target->state = TARGET_RUNNING;
else
- {
- target->state = TARGET_DEBUG_RUNNING;
- target->debug_reason = DBG_REASON_NOTHALTED;
-
- CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));
- }
+ target->state = TARGET_DEBUG_RUNNING;
+ CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));
return ERROR_OK;
}
@@ -728,7 +718,7 @@ static int arm11_step(struct target *target, int current,
}
- target->debug_reason = DBG_REASON_SINGLESTEP;
+ target->debug_reason = DBG_REASON_SINGLESTEP;
CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED));
diff --git a/src/target/arm11.h b/src/target/arm11.h
index 5f78db5d..f3f0644b 100644
--- a/src/target/arm11.h
+++ b/src/target/arm11.h
@@ -94,18 +94,6 @@ enum arm11_instructions
ARM11_BYPASS = 0x1F,
};
-enum arm11_dscr
-{
-
- ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_MASK = 0x0F << 2,
- ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_HALT = 0x00 << 2,
- ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BREAKPOINT = 0x01 << 2,
- ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_WATCHPOINT = 0x02 << 2,
- ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BKPT_INSTRUCTION = 0x03 << 2,
- ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_EDBGRQ = 0x04 << 2,
- ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_VECTOR_CATCH = 0x05 << 2,
-};
-
enum arm11_sc7
{
ARM11_SC7_NULL = 0,
diff --git a/src/target/arm11_dbgtap.c b/src/target/arm11_dbgtap.c
index 3df1c658..e5d3f805 100644
--- a/src/target/arm11_dbgtap.c
+++ b/src/target/arm11_dbgtap.c
@@ -288,50 +288,6 @@ int arm11_write_DSCR(struct arm11_common * arm11, uint32_t dscr)
return ERROR_OK;
}
-
-
-/** Get the debug reason from Debug Status and Control Register (DSCR)
- *
- * \param dscr DSCR value to analyze
- * \return Debug reason
- *
- */
-enum target_debug_reason arm11_get_DSCR_debug_reason(uint32_t dscr)
-{
- switch (dscr & ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_MASK)
- {
- case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_HALT:
- LOG_INFO("Debug entry: JTAG HALT");
- return DBG_REASON_DBGRQ;
-
- case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BREAKPOINT:
- LOG_INFO("Debug entry: breakpoint");
- return DBG_REASON_BREAKPOINT;
-
- case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_WATCHPOINT:
- LOG_INFO("Debug entry: watchpoint");
- return DBG_REASON_WATCHPOINT;
-
- case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BKPT_INSTRUCTION:
- LOG_INFO("Debug entry: BKPT instruction");
- return DBG_REASON_BREAKPOINT;
-
- case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_EDBGRQ:
- LOG_INFO("Debug entry: EDBGRQ signal");
- return DBG_REASON_DBGRQ;
-
- case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_VECTOR_CATCH:
- LOG_INFO("Debug entry: VCR vector catch");
- return DBG_REASON_BREAKPOINT;
-
- default:
- LOG_INFO("Debug entry: unknown");
- return DBG_REASON_DBGRQ;
- }
-};
-
-
-
/** Prepare the stage for ITR/DTR operations
* from the arm11_run_instr... group of functions.
*
diff --git a/src/target/arm11_dbgtap.h b/src/target/arm11_dbgtap.h
index a6b9bbd8..2c586cc9 100644
--- a/src/target/arm11_dbgtap.h
+++ b/src/target/arm11_dbgtap.h
@@ -14,8 +14,6 @@ int arm11_add_debug_SCAN_N(struct arm11_common *arm11,
int arm11_read_DSCR(struct arm11_common *arm11);
int arm11_write_DSCR(struct arm11_common *arm11, uint32_t dscr);
-enum target_debug_reason arm11_get_DSCR_debug_reason(uint32_t dscr);
-
int arm11_run_instr_data_prepare(struct arm11_common *arm11);
int arm11_run_instr_data_finish(struct arm11_common *arm11);
int arm11_run_instr_no_data1(struct arm11_common *arm11, uint32_t opcode);
diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c
index ca3930fc..b02baa39 100644
--- a/src/target/arm_dpm.c
+++ b/src/target/arm_dpm.c
@@ -756,6 +756,42 @@ void arm_dpm_report_wfar(struct arm_dpm *dpm, uint32_t addr)
/*----------------------------------------------------------------------*/
/*
+ * Other debug and support utilities
+ */
+
+void arm_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr)
+{
+ struct target *target = dpm->arm->target;
+
+ dpm->dscr = dscr;
+
+ /* Examine debug reason */
+ switch (DSCR_ENTRY(dscr)) {
+ case 6: /* Data abort (v6 only) */
+ case 7: /* Prefetch abort (v6 only) */
+ /* FALL THROUGH -- assume a v6 core in abort mode */
+ case 0: /* HALT request from debugger */
+ case 4: /* EDBGRQ */
+ target->debug_reason = DBG_REASON_DBGRQ;
+ break;
+ case 1: /* HW breakpoint */
+ case 3: /* SW BKPT */
+ case 5: /* vector catch */
+ target->debug_reason = DBG_REASON_BREAKPOINT;
+ break;
+ case 2: /* asynch watchpoint */
+ case 10: /* precise watchpoint */
+ target->debug_reason = DBG_REASON_WATCHPOINT;
+ break;
+ default:
+ target->debug_reason = DBG_REASON_UNDEFINED;
+ break;
+ }
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
* Setup and management support.
*/
diff --git a/src/target/arm_dpm.h b/src/target/arm_dpm.h
index 11213a36..135e3db8 100644
--- a/src/target/arm_dpm.h
+++ b/src/target/arm_dpm.h
@@ -125,6 +125,9 @@ struct arm_dpm {
/** Address of the instruction which triggered a watchpoint. */
uint32_t wp_pc;
+ /** Recent value of DSCR. */
+ uint32_t dscr;
+
// FIXME -- read/write DCSR methods and symbols
};
@@ -151,4 +154,6 @@ void arm_dpm_report_wfar(struct arm_dpm *, uint32_t wfar);
#define DSCR_ENTRY(dscr) (((dscr) >> 2) & 0xf)
+void arm_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dcsr);
+
#endif /* __ARM_DPM_H */
diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c
index 14cbb9d7..eb42a5d5 100644
--- a/src/target/cortex_a8.c
+++ b/src/target/cortex_a8.c
@@ -782,7 +782,7 @@ static int cortex_a8_resume(struct target *target, int current,
static int cortex_a8_debug_entry(struct target *target)
{
int i;
- uint32_t regfile[16], wfar, cpsr, dscr;
+ uint32_t regfile[16], cpsr, dscr;
int retval = ERROR_OK;
struct working_area *regfile_working_area = NULL;
struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
@@ -793,6 +793,7 @@ static int cortex_a8_debug_entry(struct target *target)
LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a8->cpudbg_dscr);
+ /* REVISIT surely we should not re-read DSCR !! */
mem_ap_read_atomic_u32(swjdp,
armv7a->debug_base + CPUDBG_DSCR, &dscr);
@@ -807,30 +808,16 @@ static int cortex_a8_debug_entry(struct target *target)
armv7a->debug_base + CPUDBG_DSCR, dscr);
/* Examine debug reason */
- switch (DSCR_ENTRY(cortex_a8->cpudbg_dscr))
- {
- case 0: /* DRCR[0] write */
- case 4: /* EDBGRQ */
- target->debug_reason = DBG_REASON_DBGRQ;
- break;
- case 1: /* HW breakpoint */
- case 3: /* SW BKPT */
- case 5: /* vector catch */
- target->debug_reason = DBG_REASON_BREAKPOINT;
- break;
- case 2: /* asynch watchpoint */
- case 10: /* precise watchpoint */
- target->debug_reason = DBG_REASON_WATCHPOINT;
-
- /* save address of faulting instruction */
- retval = mem_ap_read_atomic_u32(swjdp,
- armv7a->debug_base + CPUDBG_WFAR,
- &wfar);
- arm_dpm_report_wfar(&armv7a->dpm, wfar);
- break;
- default:
- target->debug_reason = DBG_REASON_UNDEFINED;
- break;
+ arm_dpm_report_dscr(&armv7a->dpm, cortex_a8->cpudbg_dscr);
+
+ /* save address of instruction that triggered the watchpoint? */
+ if (target->debug_reason == DBG_REASON_WATCHPOINT) {
+ uint32_t wfar;
+
+ retval = mem_ap_read_atomic_u32(swjdp,
+ armv7a->debug_base + CPUDBG_WFAR,
+ &wfar);
+ arm_dpm_report_wfar(&armv7a->dpm, wfar);
}
/* REVISIT fast_reg_read is never set ... */