From ea7a49cb9b46ccc27daf6c9b306290c7e905a9fc Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 3 Dec 2009 16:08:04 -0800 Subject: [PATCH] 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 --- src/target/arm11.c | 24 +++++++-------------- src/target/arm11.h | 12 ----------- src/target/arm11_dbgtap.c | 44 --------------------------------------- src/target/arm11_dbgtap.h | 2 -- src/target/arm_dpm.c | 36 ++++++++++++++++++++++++++++++++ src/target/arm_dpm.h | 5 +++++ src/target/cortex_a8.c | 37 +++++++++++--------------------- 7 files changed, 60 insertions(+), 100 deletions(-) diff --git a/src/target/arm11.c b/src/target/arm11.c index b01e33bd4c..20ad22d502 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 5f78db5dfa..f3f0644b08 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 3df1c65894..e5d3f8052c 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 a6b9bbd8d7..2c586cc9fc 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 ca3930fca7..b02baa3978 100644 --- a/src/target/arm_dpm.c +++ b/src/target/arm_dpm.c @@ -755,6 +755,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 11213a36c7..135e3db86d 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 14cbb9d77b..eb42a5d5ff 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 ... */ -- 2.30.2