ARM DPM: share debug reason logic
authorDavid Brownell <dbrownell@users.sourceforge.net>
Fri, 4 Dec 2009 00:08:04 +0000 (16:08 -0800)
committerDavid Brownell <dbrownell@users.sourceforge.net>
Fri, 4 Dec 2009 00:08:04 +0000 (16:08 -0800)
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>
src/target/arm11.c
src/target/arm11.h
src/target/arm11_dbgtap.c
src/target/arm11_dbgtap.h
src/target/arm_dpm.c
src/target/arm_dpm.h
src/target/cortex_a8.c

index b01e33bd4c2d899add40520cf67de5d4ea3f1288..20ad22d50235dba2f23e5a670b6d0e720ed87749 100644 (file)
@@ -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));
 
index 5f78db5dfab966b81cf5782edff0d0081291b1f9..f3f0644b08b90af0569ea94f078baf0cdd99e3d8 100644 (file)
@@ -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,
index 3df1c65894e6cfadfb29f6baf2b2b1a9b43ec6e6..e5d3f8052cfb2dd19210e0ce72683e54661f067a 100644 (file)
@@ -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.
  *
index a6b9bbd8d7ba719dbddb723fd8cbcf14d5cd126a..2c586cc9fcc4bdc97bdd15d6ffaf04e9fb2de64a 100644 (file)
@@ -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);
index ca3930fca7e4fabfb6fdc3c4b6e18ebc46cb04c8..b02baa39780afe686250f85dc7fedf347ca11e49 100644 (file)
@@ -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.
  */
index 11213a36c7766641570a949e0f5ae13d8e1d6767..135e3db86decad962de8e66188c3954a4a4abd1c 100644 (file)
@@ -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 */
index 14cbb9d77b453614020b99b01d9019a869f94774..eb42a5d5ff7d604bb97850b556311aeac3bbf93c 100644 (file)
@@ -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 ... */