diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c index f94fcc4e0..7c09e0645 100644 --- a/src/target/arm_dpm.c +++ b/src/target/arm_dpm.c @@ -736,6 +736,23 @@ static int dpm_remove_watchpoint(struct target *target, struct watchpoint *wp) return retval; } +void arm_dpm_report_wfar(struct arm_dpm *dpm, uint32_t addr) +{ + switch (dpm->arm->core_state) { + case ARMV4_5_STATE_ARM: + addr -= 8; + break; + case ARMV4_5_STATE_THUMB: + case ARM_STATE_THUMB_EE: + addr -= 4; + break; + case ARMV4_5_STATE_JAZELLE: + /* ?? */ + break; + } + dpm->wp_pc = addr; +} + /*----------------------------------------------------------------------*/ /* diff --git a/src/target/arm_dpm.h b/src/target/arm_dpm.h index 5d665a866..191f465a5 100644 --- a/src/target/arm_dpm.h +++ b/src/target/arm_dpm.h @@ -122,6 +122,9 @@ struct arm_dpm { struct dpm_bp *dbp; struct dpm_wp *dwp; + /** Address of the instruction which triggered a watchpoint. */ + uint32_t wp_pc; + // FIXME -- read/write DCSR methods and symbols }; @@ -131,4 +134,6 @@ int arm_dpm_reinitialize(struct arm_dpm *dpm); int arm_dpm_read_current_registers(struct arm_dpm *); int arm_dpm_write_dirty_registers(struct arm_dpm *, bool bpwp); +void arm_dpm_report_wfar(struct arm_dpm *, uint32_t wfar); + #endif /* __ARM_DPM_H */ diff --git a/src/target/armv7a.c b/src/target/armv7a.c index e23208f19..06bc74898 100644 --- a/src/target/armv7a.c +++ b/src/target/armv7a.c @@ -113,6 +113,9 @@ int armv7a_arch_state(struct target *target) if (armv4_5->core_mode == ARMV4_5_MODE_ABT) armv7a_show_fault_registers(target); + else if (target->debug_reason == DBG_REASON_WATCHPOINT) + LOG_USER("Watchpoint triggered at PC %#08x", + (unsigned) armv7a->dpm.wp_pc); return ERROR_OK; } diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c index a289d96a6..5f2de7658 100644 --- a/src/target/cortex_a8.c +++ b/src/target/cortex_a8.c @@ -772,7 +772,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], pc, cpsr, dscr; + uint32_t regfile[16], wfar, cpsr, dscr; int retval = ERROR_OK; struct working_area *regfile_working_area = NULL; struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target); @@ -811,9 +811,12 @@ static int cortex_a8_debug_entry(struct target *target) case 2: /* asynch watchpoint */ case 10: /* precise watchpoint */ target->debug_reason = DBG_REASON_WATCHPOINT; - /* REVISIT could collect WFAR later, to see just - * which instruction triggered the 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; @@ -841,7 +844,6 @@ static int cortex_a8_debug_entry(struct target *target) /* read Current PSR */ cortex_a8_dap_read_coreregister_u32(target, &cpsr, 16); - pc = regfile[15]; dap_ap_select(swjdp, swjdp_debugap); LOG_DEBUG("cpsr: %8.8" PRIx32, cpsr); @@ -892,10 +894,7 @@ static int cortex_a8_debug_entry(struct target *target) if (armv7a->post_debug_entry) armv7a->post_debug_entry(target); - - return retval; - } static void cortex_a8_post_debug_entry(struct target *target) @@ -1527,20 +1526,7 @@ static int cortex_a8_examine_first(struct target *target) cortex_a8->brp_list[i].BRPn = i; } - /* Setup Watchpoint Register Pairs */ - cortex_a8->wrp_num = ((didr >> 28) & 0x0F) + 1; - cortex_a8->wrp_num_available = cortex_a8->wrp_num; - cortex_a8->wrp_list = calloc(cortex_a8->wrp_num, sizeof(struct cortex_a8_wrp)); - for (i = 0; i < cortex_a8->wrp_num; i++) - { - cortex_a8->wrp_list[i].used = 0; - cortex_a8->wrp_list[i].type = 0; - cortex_a8->wrp_list[i].value = 0; - cortex_a8->wrp_list[i].control = 0; - cortex_a8->wrp_list[i].WRPn = i; - } - LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs", - cortex_a8->brp_num , cortex_a8->wrp_num); + LOG_DEBUG("Configured %i hw breakpoints", cortex_a8->brp_num); target_set_examined(target); return ERROR_OK; diff --git a/src/target/cortex_a8.h b/src/target/cortex_a8.h index 3b2c8b16d..87db23ec4 100644 --- a/src/target/cortex_a8.h +++ b/src/target/cortex_a8.h @@ -54,15 +54,6 @@ struct cortex_a8_brp uint8_t BRPn; }; -struct cortex_a8_wrp -{ - int used; - int type; - uint32_t value; - uint32_t control; - uint8_t WRPn; -}; - struct cortex_a8_common { int common_magic; @@ -70,29 +61,16 @@ struct cortex_a8_common /* Context information */ uint32_t cpudbg_dscr; - uint32_t nvic_dfsr; /* Debug Fault Status Register - shows reason for debug halt */ - uint32_t nvic_icsr; /* Interrupt Control State Register - shows active and pending IRQ */ /* Saved cp15 registers */ uint32_t cp15_control_reg; - uint32_t cp15_aux_control_reg; /* Breakpoint register pairs */ int brp_num_context; int brp_num; int brp_num_available; -// int brp_enabled; struct cortex_a8_brp *brp_list; - /* Watchpoint register pairs */ - int wrp_num; - int wrp_num_available; - struct cortex_a8_wrp *wrp_list; - - /* Interrupts */ - int intlinesnum; - uint32_t *intsetenable; - /* Use cortex_a8_read_regs_through_mem for fast register reads */ int fast_reg_read;