Merge branch 'syscore' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspen...
[pandora-kernel.git] / arch / mn10300 / kernel / gdb-stub.c
index b169d99..538266b 100644 (file)
 #include <asm/system.h>
 #include <asm/gdb-stub.h>
 #include <asm/exceptions.h>
-#include <asm/cacheflush.h>
+#include <asm/debugger.h>
 #include <asm/serial-regs.h>
 #include <asm/busctl-regs.h>
 #include <unit/leds.h>
@@ -405,6 +405,7 @@ static int hexToInt(char **ptr, int *intValue)
        return (numChars);
 }
 
+#ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP
 /*
  * We single-step by setting breakpoints. When an exception
  * is handled, we need to restore the instructions hoisted
@@ -729,6 +730,7 @@ static int gdbstub_single_step(struct pt_regs *regs)
        __gdbstub_restore_bp();
        return -EFAULT;
 }
+#endif /* CONFIG_GDBSTUB_ALLOW_SINGLE_STEP */
 
 #ifdef CONFIG_GDBSTUB_CONSOLE
 
@@ -1171,7 +1173,7 @@ int gdbstub_clear_breakpoint(u8 *addr, int len)
 
 /*
  * This function does all command processing for interfacing to gdb
- * - returns 1 if the exception should be skipped, 0 otherwise.
+ * - returns 0 if the exception should be skipped, -ERROR otherwise.
  */
 static int gdbstub(struct pt_regs *regs, enum exception_code excep)
 {
@@ -1186,7 +1188,7 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
        int loop;
 
        if (excep == EXCEP_FPU_DISABLED)
-               return 0;
+               return -ENOTSUPP;
 
        gdbstub_flush_caches = 0;
 
@@ -1195,7 +1197,7 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
        asm volatile("mov mdr,%0" : "=d"(mdr));
        local_save_flags(epsw);
        arch_local_change_intr_mask_level(
-               NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
+               NUM2EPSW_IM(CONFIG_DEBUGGER_IRQ_LEVEL + 1));
 
        gdbstub_store_fpu();
 
@@ -1208,11 +1210,13 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
        /* if we were single stepping, restore the opcodes hoisted for the
         * breakpoint[s] */
        broke = 0;
+#ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP
        if ((step_bp[0].addr && step_bp[0].addr == (u8 *) regs->pc) ||
            (step_bp[1].addr && step_bp[1].addr == (u8 *) regs->pc))
                broke = 1;
 
        __gdbstub_restore_bp();
+#endif
 
        if (gdbstub_rx_unget) {
                sigval = SIGINT;
@@ -1548,17 +1552,21 @@ packet_waiting:
                         * Step to next instruction
                         */
                case 's':
-                       /*
-                        * using the T flag doesn't seem to perform single
+                       /* Using the T flag doesn't seem to perform single
                         * stepping (it seems to wind up being caught by the
                         * JTAG unit), so we have to use breakpoints and
                         * continue instead.
                         */
+#ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP
                        if (gdbstub_single_step(regs) < 0)
                                /* ignore any fault error for now */
                                gdbstub_printk("unable to set single-step"
                                               " bp\n");
                        goto done;
+#else
+                       gdbstub_strcpy(output_buffer, "E01");
+                       break;
+#endif
 
                        /*
                         * Set baud rate (bBB)
@@ -1657,7 +1665,7 @@ done:
         * NB: We flush both caches, just to be sure...
         */
        if (gdbstub_flush_caches)
-               gdbstub_purge_cache();
+               debugger_local_cache_flushinv();
 
        gdbstub_load_fpu();
        mn10300_set_gdbleds(0);
@@ -1667,14 +1675,23 @@ done:
        touch_softlockup_watchdog();
 
        local_irq_restore(epsw);
-       return 1;
+       return 0;
+}
+
+/*
+ * Determine if we hit a debugger special breakpoint that needs skipping over
+ * automatically.
+ */
+int at_debugger_breakpoint(struct pt_regs *regs)
+{
+       return 0;
 }
 
 /*
  * handle event interception
  */
-asmlinkage int gdbstub_intercept(struct pt_regs *regs,
-                                enum exception_code excep)
+asmlinkage int debugger_intercept(enum exception_code excep,
+                                 int signo, int si_code, struct pt_regs *regs)
 {
        static u8 notfirst = 1;
        int ret;
@@ -1688,7 +1705,7 @@ asmlinkage int gdbstub_intercept(struct pt_regs *regs,
                asm("mov mdr,%0" : "=d"(mdr));
 
                gdbstub_entry(
-                       "--> gdbstub_intercept(%p,%04x) [MDR=%lx PC=%lx]\n",
+                       "--> debugger_intercept(%p,%04x) [MDR=%lx PC=%lx]\n",
                        regs, excep, mdr, regs->pc);
 
                gdbstub_entry(
@@ -1722,7 +1739,7 @@ asmlinkage int gdbstub_intercept(struct pt_regs *regs,
 
        ret = gdbstub(regs, excep);
 
-       gdbstub_entry("<-- gdbstub_intercept()\n");
+       gdbstub_entry("<-- debugger_intercept()\n");
        gdbstub_busy = 0;
        return ret;
 }