This is an automated email from Gerrit.

Eric Hoffman ([email protected]) just uploaded a new patch set to Gerrit, 
which you can find at http://openocd.zylin.com/4222

-- gerrit

commit 67815b44d675c3135d7f5713f7a31d607dd12f9f
Author: Eric Hoffman <[email protected]>
Date:   Mon Sep 11 00:45:56 2017 -0400

    mips32 - fixed GDB 'signal 0' sent when hitting breakpoint.
    
    On mips target, when the target halt, the halt reason is assessed
    and the reason is reported to GDB server.  In case of a hardware
    breakpoint or watchpoint, the proper reason was reported (i.e.
    DBG_REASON_BREAKPOINT or DBG_REASON_WATCHPOINT).  However, for
    software breakpoints (when the CPU goes to debug exception due
    to the SDBBP instruction, the 'software debug breakpoint'), the
    halt reason was not detected.  The code only checked if a hardware
    breakpoint or watchpoint was hit.  Thus, the reason reported to GDB
    was a leftover 'DBG_REASON_NOTHALTED', resulting in GDB server
    returning a 'signal 0' to the GDB client.
    
    This patch fixes 3 issues:
    
    - First, the proper debug request reason is detected on software
      breakpoint instruction.  The debug register is looked at when
      entering debug mode, and if the reason is due to software
      breakpoint or trap, we return DBG_REASON_BREAKPOINT.
    - Second, the code that check for hardware breakpoint or watchpoint
      had a wrong mask.  It was looking only if the break was due to
      one of the first 5 hardware breakpoints or watchpoints instead of
      a possibility of 15 (checked the break status registers with mask
      0x1F instead of 0x7FFF).  MIPS that I know of have less than 5,
      but the specs define that it's possible to have up to 15 hw
      breakpoints or watchpoints.
    - Third, minor, when both a breakpoint and data watchpoint occurred
      simultaneously, the watchpoint detection routine simply took
      priority (being last) and set the debug reason to
      DBG_REASON_WATCHPOINT.  Now, the code check if
      DBG_REASON_BREAKPOINT is previously set, and if so, set the debug
      reason to DBG_REASON_WPTANDBKPT, otherwise DBG_REASON_WATCHPOINT.
    
    Change-Id: I57601080d7087aa2d4cadcbd2989cca899685514
    Signed-off-by: Eric Hoffman <[email protected]>

diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h
index 71f5c1b..5e4a0e8 100644
--- a/src/target/mips_ejtag.h
+++ b/src/target/mips_ejtag.h
@@ -96,6 +96,33 @@
 #define EJTAG_DEBUG_DM                 (1 << 30)
 #define EJTAG_DEBUG_DBD                        (1 << 31)
 
+#define EJTAG_DEBUG_DEXCCODE_SHIFT     10
+#define EJTAG_DEBUG_DEXCCODE_MASK      0x1F
+
+/* Exception Codes */
+#define EJTAG_EXCCODE_INT              0
+#define EJTAG_EXCCODE_MOD              1
+#define EJTAG_EXCCODE_TLBL             2
+#define EJTAG_EXCCODE_TLBS             3
+#define EJTAG_EXCCODE_ADEL             4
+#define EJTAG_EXCCODE_ADES             5
+#define EJTAG_EXCCODE_IBE              6
+#define EJTAG_EXCCODE_DBE              7
+#define EJTAG_EXCCODE_SYS              8
+#define EJTAG_EXCCODE_BP               9
+#define EJTAG_EXCCODE_RI               10
+#define EJTAG_EXCCODE_CPU              11
+#define EJTAG_EXCCODE_OV               12
+#define EJTAG_EXCCODE_TR               13
+#define EJTAG_EXCCODE_FPE              15
+#define EJTAG_EXCCODE_CEU              17
+#define EJTAG_EXCCODE_C2E              18
+#define EJTAG_EXCCODE_MDMX             22
+#define EJTAG_EXCCODE_WATCH            23
+#define EJTAG_EXCCODE_MCHECK   24
+#define EJTAG_EXCCODE_DSP              26
+#define EJTAG_EXCCODE_CACHEERR 30
+
 /* implementation MIPS register bits.
  * Bits marked with V20 or v2.0 mean that, this registers supported only
  * by EJTAG v2.0. Bits marked with Lexra or BMIPS are different from the
diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c
index 7d1c06c..352398d 100644
--- a/src/target/mips_m4k.c
+++ b/src/target/mips_m4k.c
@@ -56,13 +56,29 @@ static int mips_m4k_examine_debug_reason(struct target 
*target)
 
        if ((target->debug_reason != DBG_REASON_DBGRQ)
                        && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
+               /* Check for software breakpoints */
+               uint32_t debug;
+               retval = mips32_cp0_read(ejtag_info, &debug, 23, 0);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               target->debug_reason = DBG_REASON_UNDEFINED; /* We must find 
proper reason */
+
+               uint32_t exc_code = (debug >> EJTAG_DEBUG_DEXCCODE_SHIFT) & 
EJTAG_DEBUG_DEXCCODE_MASK;
+               LOG_DEBUG("Debug register: 0x%08" PRIx32 ", Exception Code: 
0x%02" PRIx32,
+                                 debug, exc_code);
+               if ((exc_code == EJTAG_EXCCODE_BP) || /* Software breakpoint 
instruction */
+                       (exc_code == EJTAG_EXCCODE_TR)) { /* Trap (like 'teq') 
instruction */
+                       target->debug_reason = DBG_REASON_BREAKPOINT;
+               }
+
                if (ejtag_info->debug_caps & EJTAG_DCR_IB) {
                        /* get info about inst breakpoint support */
                        retval = target_read_u32(target,
                                ejtag_info->ejtag_ibs_addr, &break_status);
                        if (retval != ERROR_OK)
                                return retval;
-                       if (break_status & 0x1f) {
+                       if (break_status & 0x7fff) {
                                /* we have halted on a  breakpoint */
                                retval = target_write_u32(target,
                                        ejtag_info->ejtag_ibs_addr, 0);
@@ -78,13 +94,16 @@ static int mips_m4k_examine_debug_reason(struct target 
*target)
                                ejtag_info->ejtag_dbs_addr, &break_status);
                        if (retval != ERROR_OK)
                                return retval;
-                       if (break_status & 0x1f) {
+                       if (break_status & 0x7fff) {
                                /* we have halted on a  breakpoint */
                                retval = target_write_u32(target,
                                        ejtag_info->ejtag_dbs_addr, 0);
                                if (retval != ERROR_OK)
                                        return retval;
-                               target->debug_reason = DBG_REASON_WATCHPOINT;
+                               if (target->debug_reason == 
DBG_REASON_BREAKPOINT)
+                                       target->debug_reason = 
DBG_REASON_WPTANDBKPT;
+                               else
+                                       target->debug_reason = 
DBG_REASON_WATCHPOINT;
                        }
                }
        }

-- 

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to