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;
 

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)