]> git.sur5r.net Git - openocd/commitdiff
ARMv7a/Cortex-A8: report watchpoint trigger insn
authorDavid Brownell <dbrownell@users.sourceforge.net>
Wed, 2 Dec 2009 19:31:32 +0000 (11:31 -0800)
committerDavid Brownell <dbrownell@users.sourceforge.net>
Wed, 2 Dec 2009 19:31:32 +0000 (11:31 -0800)
Save and display the address of the instruction which triggered the
watchpoint.  Because of pipelining, that's well behind the PC value
when debug entry completes.  (Example in a subroutine that had been
returned from...)

Remove unused A8 stuff, mostly watchpoint hooks from the header.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
src/target/arm_dpm.c
src/target/arm_dpm.h
src/target/armv7a.c
src/target/cortex_a8.c
src/target/cortex_a8.h

index f94fcc4e0962b900b68c367edb3def8cf1c93a43..7c09e0645ec37bc6d409f202628a3270b14bdbea 100644 (file)
@@ -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;
+}
+
 /*----------------------------------------------------------------------*/
 
 /*
index 5d665a866f29ae6ced8f992a343086acc0eb6b34..191f465a50f3ebe34edfaab6df93060252560f33 100644 (file)
@@ -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 */
index e23208f191c9b2fc3ae90cb715797859b39018f4..06bc748984c4c8eac129720dcca2fe810af94be7 100644 (file)
@@ -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;
 }
index a289d96a6e492a4717b37551dcc912951b4d934d..5f2de7658dd94014a7d5cff5dc3283ec1e3808d0 100644 (file)
@@ -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;
index 3b2c8b16d567007dc6e8a06971d8050d9a7ee4d1..87db23ec43b6b68e84bc08128ec52f51f9ebc85b 100644 (file)
@@ -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;