]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
sh: Generic kgdb stub support.
authorPaul Mundt <lethal@linux-sh.org>
Thu, 11 Dec 2008 09:46:46 +0000 (18:46 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Mon, 22 Dec 2008 09:44:04 +0000 (18:44 +0900)
This migrates from the old bitrotted kgdb stub implementation and moves
to the generic stub. In the process support for SH-2/SH-2A is also added,
which the old stub never provided.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
15 files changed:
arch/sh/Kconfig
arch/sh/Kconfig.debug
arch/sh/include/asm/kgdb.h
arch/sh/include/asm/system.h
arch/sh/kernel/Makefile_32
arch/sh/kernel/cpu/sh3/entry.S
arch/sh/kernel/cpu/sh3/ex.S
arch/sh/kernel/debugtraps.S
arch/sh/kernel/entry-common.S
arch/sh/kernel/kgdb.c [new file with mode: 0644]
arch/sh/kernel/kgdb_jmp.S [deleted file]
arch/sh/kernel/kgdb_stub.c [deleted file]
arch/sh/kernel/time_32.c
arch/sh/kernel/traps_32.c
arch/sh/mm/fault_32.c

index ff7a1f358a364b0721d3e4b659b4e862703cccdc..ff3c137deac3b4ba5dd4080d685520e732cd9e40 100644 (file)
@@ -27,6 +27,7 @@ config SUPERH32
        select HAVE_FUNCTION_TRACER
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_DYNAMIC_FTRACE
+       select HAVE_ARCH_KGDB
 
 config SUPERH64
        def_bool y if CPU_SH5
index 8f0c1fbd51a69d957b08061acf9f5c084a3c59fe..834a2d24342ba23a57c420ef882a58c1b6893e3d 100644 (file)
@@ -98,19 +98,6 @@ config IRQSTACKS
          for handling hard and soft interrupts.  This can help avoid
          overflowing the process kernel stacks.
 
-config SH_KGDB
-       bool "Include KGDB kernel debugger"
-       select FRAME_POINTER
-       select DEBUG_INFO
-       depends on CPU_SH3 || CPU_SH4
-       help
-         Include in-kernel hooks for kgdb, the Linux kernel source level
-         debugger.  See <http://kgdb.sourceforge.net/> for more information.
-         Unless you are intending to debug the kernel, say N here.
-
-menu "KGDB configuration options"
-       depends on SH_KGDB
-
 config MORE_COMPILE_OPTIONS
        bool "Add any additional compile options"
        help
@@ -122,62 +109,6 @@ config COMPILE_OPTIONS
        string "Additional compile arguments"
        depends on MORE_COMPILE_OPTIONS
 
-config KGDB_NMI
-       def_bool n
-       prompt "Enter KGDB on NMI"
-
-config SH_KGDB_CONSOLE
-       def_bool n
-       prompt "Console messages through GDB"
-       depends on !SERIAL_SH_SCI_CONSOLE && SERIAL_SH_SCI=y
-       select SERIAL_CORE_CONSOLE
-
-config KGDB_SYSRQ
-       def_bool y
-       prompt "Allow SysRq 'G' to enter KGDB"
-       depends on MAGIC_SYSRQ
-
-comment "Serial port setup"
-
-config KGDB_DEFPORT
-       int "Port number (ttySCn)"
-       default "1"
-
-config KGDB_DEFBAUD
-       int "Baud rate"
-       default "115200"
-
-choice
-       prompt "Parity"
-       depends on SH_KGDB
-       default KGDB_DEFPARITY_N
-
-config KGDB_DEFPARITY_N
-       bool "None"
-
-config KGDB_DEFPARITY_E
-       bool "Even"
-
-config KGDB_DEFPARITY_O
-       bool "Odd"
-
-endchoice
-
-choice
-       prompt "Data bits"
-       depends on SH_KGDB
-       default KGDB_DEFBITS_8
-
-config KGDB_DEFBITS_8
-       bool "8"
-
-config KGDB_DEFBITS_7
-       bool "7"
-
-endchoice
-
-endmenu
-
 if SUPERH64
 
 config SH64_SR_WATCH
index 24e42078f36fa80e780cebd92204bacb62ab3e5e..72704ed725e550586b730e843a1a47b5c433c922 100644 (file)
@@ -1,21 +1,7 @@
-/*
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * Based on original code by Glenn Engel, Jim Kingdon,
- * David Grothe <dave@gcom.com>, Tigran Aivazian, <tigran@sco.com> and
- * Amit S. Kale <akale@veritas.com>
- * 
- * Super-H port based on sh-stub.c (Ben Lee and Steve Chamberlain) by
- * Henry Bell <henry.bell@st.com>
- * 
- * Header file for low-level support for remote debug using GDB. 
- *
- */
-
-#ifndef __KGDB_H
-#define __KGDB_H
+#ifndef __ASM_SH_KGDB_H
+#define __ASM_SH_KGDB_H
 
+#include <asm/cacheflush.h>
 #include <asm/ptrace.h>
 
 /* Same as pt_regs but has vbr in place of syscall_nr */
@@ -30,40 +16,26 @@ struct kgdb_regs {
         unsigned long vbr;
 };
 
-/* State info */
-extern char kgdb_in_gdb_mode;
-extern int kgdb_nofault;       /* Ignore bus errors (in gdb mem access) */
-extern char in_nmi;            /* Debounce flag to prevent NMI reentry*/
+enum regnames {
+       GDB_R0, GDB_R1, GDB_R2, GDB_R3, GDB_R4, GDB_R5, GDB_R6, GDB_R7,
+       GDB_R8, GDB_R9, GDB_R10, GDB_R11, GDB_R12, GDB_R13, GDB_R14, GDB_R15,
 
-/* SCI */
-extern int kgdb_portnum;
-extern int kgdb_baud;
-extern char kgdb_parity;
-extern char kgdb_bits;
+       GDB_PC, GDB_PR, GDB_SR, GDB_GBR, GDB_MACH, GDB_MACL, GDB_VBR,
+};
 
-/* Init and interface stuff */
-extern int kgdb_init(void);
-extern int (*kgdb_getchar)(void);
-extern void (*kgdb_putchar)(int);
+#define NUMREGBYTES    ((GDB_VBR + 1) * 4)
 
-/* Trap functions */
-typedef void (kgdb_debug_hook_t)(struct pt_regs *regs);
-typedef void (kgdb_bus_error_hook_t)(void);
-extern kgdb_debug_hook_t  *kgdb_debug_hook;
-extern kgdb_bus_error_hook_t *kgdb_bus_err_hook;
+static inline void arch_kgdb_breakpoint(void)
+{
+       __asm__ __volatile__ ("trapa #0x3c\n");
+}
 
-/* Console */
-struct console;
-void kgdb_console_write(struct console *co, const char *s, unsigned count);
-extern int kgdb_console_setup(struct console *, char *);
+/* State info */
+extern char in_nmi;            /* Debounce flag to prevent NMI reentry*/
 
-/* Prototypes for jmp fns */
-#define _JBLEN 9
-typedef        int jmp_buf[_JBLEN];
-extern void    longjmp(jmp_buf __jmpb, int __retval);
-extern int     setjmp(jmp_buf __jmpb);
+#define BUFMAX                 2048
 
-/* Forced breakpoint */
-#define breakpoint()   __asm__ __volatile__("trapa   #0x3c")
+#define CACHE_FLUSH_IS_SAFE    1
+#define BREAK_INSTR_SIZE       2
 
-#endif
+#endif /* __ASM_SH_KGDB_H */
index 6160fe445161e12071f6daeabbca709350563da2..c9ec6af8e7456a387063bae8eecdbab52342f401 100644 (file)
@@ -175,6 +175,8 @@ asmlinkage void name##_trap_handler(unsigned int vec, struct pt_regs *regs)
 BUILD_TRAP_HANDLER(address_error);
 BUILD_TRAP_HANDLER(debug);
 BUILD_TRAP_HANDLER(bug);
+BUILD_TRAP_HANDLER(breakpoint);
+BUILD_TRAP_HANDLER(singlestep);
 BUILD_TRAP_HANDLER(fpu_error);
 BUILD_TRAP_HANDLER(fpu_state_restore);
 
index 10a34c3ae64755f5b46c47a87df57f2bd687e5e4..df25304ad7806d59a947f590488ba13df55b95fd 100644 (file)
@@ -19,7 +19,7 @@ obj-$(CONFIG_VSYSCALL)                += vsyscall/
 obj-$(CONFIG_SMP)              += smp.o
 obj-$(CONFIG_CF_ENABLER)       += cf-enabler.o
 obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
-obj-$(CONFIG_SH_KGDB)          += kgdb_stub.o kgdb_jmp.o
+obj-$(CONFIG_KGDB)             += kgdb.o
 obj-$(CONFIG_SH_CPU_FREQ)      += cpufreq.o
 obj-$(CONFIG_MODULES)          += sh_ksyms_32.o module.o
 obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
index f112faa219c372beb7f6b0f533165d2d77a1811e..b4106d0c68ec0e0c8fc3db9365b5c289b15a961d 100644 (file)
@@ -52,7 +52,7 @@
  *     syscall #
  *
  */
-#if defined(CONFIG_KGDB_NMI)
+#if defined(CONFIG_KGDB)
 NMI_VEC = 0x1c0                        ! Must catch early for debounce
 #endif
 
@@ -307,7 +307,7 @@ skip_restore:
 6:     or      k0, k2                  ! Set the IMASK-bits
        ldc     k2, ssr
        !
-#if defined(CONFIG_KGDB_NMI)
+#if defined(CONFIG_KGDB)
        ! Clear in_nmi
        mov.l   6f, k0
        mov     #0, k1
@@ -320,7 +320,7 @@ skip_restore:
 
        .align  2
 5:     .long   0x00001000      ! DSP
-#ifdef CONFIG_KGDB_NMI
+#ifdef CONFIG_KGDB
 6:     .long   in_nmi
 #endif
 7:     .long   0x30000000
@@ -377,7 +377,7 @@ tlb_miss:
        .balign         512,0,512
 interrupt:
        mov.l   3f, k3
-#if defined(CONFIG_KGDB_NMI)
+#if defined(CONFIG_KGDB)
        mov.l   2f, k2
        ! Debounce (filter nested NMI)
        mov.l   @k2, k0
@@ -394,7 +394,7 @@ interrupt:
 5:     .long   NMI_VEC
 6:     .long   in_nmi
 0:
-#endif /* defined(CONFIG_KGDB_NMI) */
+#endif /* defined(CONFIG_KGDB) */
        bra     handle_exception
         mov    #-1, k2         ! interrupt exception marker
 
index dac42972689932b00100fd1c3a654a26aa61d1e9..e5a0de39a2dbab62054d9714b4fd420e7efb29a2 100644 (file)
@@ -26,7 +26,7 @@
 #define        fpu_error_trap_handler          exception_error
 #endif
 
-#if !defined(CONFIG_KGDB_NMI)
+#if !defined(CONFIG_KGDB)
 #define kgdb_handle_exception          exception_error
 #endif
 
index 13b66746410ac249f69800936cc1849a1e5ca52f..591741383ee6addd2fe537aa800d869b24ac26c0 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Debug trap jump tables for SuperH
  *
- *  Copyright (C) 2006  Paul Mundt
+ *  Copyright (C) 2006 - 2008  Paul Mundt
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
 #include <linux/sys.h>
 #include <linux/linkage.h>
 
-#if !defined(CONFIG_SH_KGDB)
-#define kgdb_handle_exception  debug_trap_handler
+#if !defined(CONFIG_KGDB)
+#define breakpoint_trap_handler                debug_trap_handler
+#define singlestep_trap_handler                debug_trap_handler
 #endif
 
 #if !defined(CONFIG_SH_STANDARD_BIOS)
-#define sh_bios_handler                debug_trap_handler
+#define sh_bios_handler                        debug_trap_handler
 #endif
 
        .data
@@ -35,7 +36,7 @@ ENTRY(debug_trap_table)
        .long debug_trap_handler        /* 0x39 */
        .long debug_trap_handler        /* 0x3a */
        .long debug_trap_handler        /* 0x3b */
-       .long kgdb_handle_exception     /* 0x3c */
-       .long debug_trap_handler        /* 0x3d */
+       .long breakpoint_trap_handler   /* 0x3c */
+       .long singlestep_trap_handler   /* 0x3d */
        .long bug_trap_handler          /* 0x3e */
        .long sh_bios_handler           /* 0x3f */
index efbb4268875e3a2b1fc43de0789b08b834cf2b3e..d62359cfbbe20723e39a7b304b02446dc78c686d 100644 (file)
@@ -308,15 +308,19 @@ ENTRY(system_call)
        mov.l   1f, r9
        mov.l   @r9, r8         ! Read from TRA (Trap Address) Register
 #endif
+
+       mov     #OFF_TRA, r10
+       add     r15, r10
+       mov.l   r8, @r10                ! set TRA value to tra
+
        /*
         * Check the trap type
         */
        mov     #((0x20 << 2) - 1), r9
        cmp/hi  r9, r8
        bt/s    debug_trap              ! it's a debug trap..
-        mov    #OFF_TRA, r9
-       add     r15, r9
-       mov.l   r8, @r9                 ! set TRA value to tra
+        nop
+
 #ifdef CONFIG_TRACE_IRQFLAGS
        mov.l   5f, r10
        jsr     @r10
diff --git a/arch/sh/kernel/kgdb.c b/arch/sh/kernel/kgdb.c
new file mode 100644 (file)
index 0000000..7c747e7
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * SuperH KGDB support
+ *
+ * Copyright (C) 2008  Paul Mundt
+ *
+ * Single stepping taken from the old stub by Henry Bell and Jeremy Siegel.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kgdb.h>
+#include <linux/kdebug.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/cacheflush.h>
+
+char in_nmi = 0;       /* Set during NMI to prevent re-entry */
+
+/* Macros for single step instruction identification */
+#define OPCODE_BT(op)          (((op) & 0xff00) == 0x8900)
+#define OPCODE_BF(op)          (((op) & 0xff00) == 0x8b00)
+#define OPCODE_BTF_DISP(op)    (((op) & 0x80) ? (((op) | 0xffffff80) << 1) : \
+                                (((op) & 0x7f ) << 1))
+#define OPCODE_BFS(op)         (((op) & 0xff00) == 0x8f00)
+#define OPCODE_BTS(op)         (((op) & 0xff00) == 0x8d00)
+#define OPCODE_BRA(op)         (((op) & 0xf000) == 0xa000)
+#define OPCODE_BRA_DISP(op)    (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
+                                (((op) & 0x7ff) << 1))
+#define OPCODE_BRAF(op)                (((op) & 0xf0ff) == 0x0023)
+#define OPCODE_BRAF_REG(op)    (((op) & 0x0f00) >> 8)
+#define OPCODE_BSR(op)         (((op) & 0xf000) == 0xb000)
+#define OPCODE_BSR_DISP(op)    (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
+                                (((op) & 0x7ff) << 1))
+#define OPCODE_BSRF(op)                (((op) & 0xf0ff) == 0x0003)
+#define OPCODE_BSRF_REG(op)    (((op) >> 8) & 0xf)
+#define OPCODE_JMP(op)         (((op) & 0xf0ff) == 0x402b)
+#define OPCODE_JMP_REG(op)     (((op) >> 8) & 0xf)
+#define OPCODE_JSR(op)         (((op) & 0xf0ff) == 0x400b)
+#define OPCODE_JSR_REG(op)     (((op) >> 8) & 0xf)
+#define OPCODE_RTS(op)         ((op) == 0xb)
+#define OPCODE_RTE(op)         ((op) == 0x2b)
+
+#define SR_T_BIT_MASK           0x1
+#define STEP_OPCODE             0xc33d
+
+/* Calculate the new address for after a step */
+static short *get_step_address(struct pt_regs *linux_regs)
+{
+       opcode_t op = __raw_readw(linux_regs->pc);
+       long addr;
+
+       /* BT */
+       if (OPCODE_BT(op)) {
+               if (linux_regs->sr & SR_T_BIT_MASK)
+                       addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
+               else
+                       addr = linux_regs->pc + 2;
+       }
+
+       /* BTS */
+       else if (OPCODE_BTS(op)) {
+               if (linux_regs->sr & SR_T_BIT_MASK)
+                       addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
+               else
+                       addr = linux_regs->pc + 4;      /* Not in delay slot */
+       }
+
+       /* BF */
+       else if (OPCODE_BF(op)) {
+               if (!(linux_regs->sr & SR_T_BIT_MASK))
+                       addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
+               else
+                       addr = linux_regs->pc + 2;
+       }
+
+       /* BFS */
+       else if (OPCODE_BFS(op)) {
+               if (!(linux_regs->sr & SR_T_BIT_MASK))
+                       addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
+               else
+                       addr = linux_regs->pc + 4;      /* Not in delay slot */
+       }
+
+       /* BRA */
+       else if (OPCODE_BRA(op))
+               addr = linux_regs->pc + 4 + OPCODE_BRA_DISP(op);
+
+       /* BRAF */
+       else if (OPCODE_BRAF(op))
+               addr = linux_regs->pc + 4
+                   + linux_regs->regs[OPCODE_BRAF_REG(op)];
+
+       /* BSR */
+       else if (OPCODE_BSR(op))
+               addr = linux_regs->pc + 4 + OPCODE_BSR_DISP(op);
+
+       /* BSRF */
+       else if (OPCODE_BSRF(op))
+               addr = linux_regs->pc + 4
+                   + linux_regs->regs[OPCODE_BSRF_REG(op)];
+
+       /* JMP */
+       else if (OPCODE_JMP(op))
+               addr = linux_regs->regs[OPCODE_JMP_REG(op)];
+
+       /* JSR */
+       else if (OPCODE_JSR(op))
+               addr = linux_regs->regs[OPCODE_JSR_REG(op)];
+
+       /* RTS */
+       else if (OPCODE_RTS(op))
+               addr = linux_regs->pr;
+
+       /* RTE */
+       else if (OPCODE_RTE(op))
+               addr = linux_regs->regs[15];
+
+       /* Other */
+       else
+               addr = linux_regs->pc + instruction_size(op);
+
+       flush_icache_range(addr, addr + instruction_size(op));
+       return (short *)addr;
+}
+
+/*
+ * Replace the instruction immediately after the current instruction
+ * (i.e. next in the expected flow of control) with a trap instruction,
+ * so that returning will cause only a single instruction to be executed.
+ * Note that this model is slightly broken for instructions with delay
+ * slots (e.g. B[TF]S, BSR, BRA etc), where both the branch and the
+ * instruction in the delay slot will be executed.
+ */
+
+static unsigned long stepped_address;
+static opcode_t stepped_opcode;
+
+static void do_single_step(struct pt_regs *linux_regs)
+{
+       /* Determine where the target instruction will send us to */
+       unsigned short *addr = get_step_address(linux_regs);
+
+       stepped_address = (int)addr;
+
+       /* Replace it */
+       stepped_opcode = __raw_readw((long)addr);
+       *addr = STEP_OPCODE;
+
+       /* Flush and return */
+       flush_icache_range((long)addr, (long)addr +
+                          instruction_size(stepped_opcode));
+}
+
+/* Undo a single step */
+static void undo_single_step(struct pt_regs *linux_regs)
+{
+       /* If we have stepped, put back the old instruction */
+       /* Use stepped_address in case we stopped elsewhere */
+       if (stepped_opcode != 0) {
+               __raw_writew(stepped_opcode, stepped_address);
+               flush_icache_range(stepped_address, stepped_address + 2);
+       }
+
+       stepped_opcode = 0;
+}
+
+void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+       int i;
+
+       for (i = 0; i < 16; i++)
+               gdb_regs[GDB_R0 + i] = regs->regs[i];
+
+       gdb_regs[GDB_PC] = regs->pc;
+       gdb_regs[GDB_PR] = regs->pr;
+       gdb_regs[GDB_SR] = regs->sr;
+       gdb_regs[GDB_GBR] = regs->gbr;
+       gdb_regs[GDB_MACH] = regs->mach;
+       gdb_regs[GDB_MACL] = regs->macl;
+
+       __asm__ __volatile__ ("stc vbr, %0" : "=r" (gdb_regs[GDB_VBR]));
+}
+
+void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+       int i;
+
+       for (i = 0; i < 16; i++)
+               regs->regs[GDB_R0 + i] = gdb_regs[GDB_R0 + i];
+
+       regs->pc = gdb_regs[GDB_PC];
+       regs->pr = gdb_regs[GDB_PR];
+       regs->sr = gdb_regs[GDB_SR];
+       regs->gbr = gdb_regs[GDB_GBR];
+       regs->mach = gdb_regs[GDB_MACH];
+       regs->macl = gdb_regs[GDB_MACL];
+
+       __asm__ __volatile__ ("ldc %0, vbr" : : "r" (gdb_regs[GDB_VBR]));
+}
+
+void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
+{
+       gdb_regs[GDB_R15] = p->thread.sp;
+       gdb_regs[GDB_PC] = p->thread.pc;
+}
+
+int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
+                              char *remcomInBuffer, char *remcomOutBuffer,
+                              struct pt_regs *linux_regs)
+{
+       unsigned long addr;
+       char *ptr;
+
+       /* Undo any stepping we may have done */
+       undo_single_step(linux_regs);
+
+       switch (remcomInBuffer[0]) {
+       case 'c':
+       case 's':
+               /* try to read optional parameter, pc unchanged if no parm */
+               ptr = &remcomInBuffer[1];
+               if (kgdb_hex2long(&ptr, &addr))
+                       linux_regs->pc = addr;
+       case 'D':
+       case 'k':
+               atomic_set(&kgdb_cpu_doing_single_step, -1);
+
+               if (remcomInBuffer[0] == 's') {
+                       do_single_step(linux_regs);
+                       kgdb_single_step = 1;
+
+                       atomic_set(&kgdb_cpu_doing_single_step,
+                                  raw_smp_processor_id());
+               }
+
+               return 0;
+       }
+
+       /* this means that we do not want to exit from the handler: */
+       return -1;
+}
+
+/*
+ * The primary entry points for the kgdb debug trap table entries.
+ */
+BUILD_TRAP_HANDLER(singlestep)
+{
+       unsigned long flags;
+       TRAP_HANDLER_DECL;
+
+       local_irq_save(flags);
+       regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
+       kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs);
+       local_irq_restore(flags);
+}
+
+
+BUILD_TRAP_HANDLER(breakpoint)
+{
+       unsigned long flags;
+       TRAP_HANDLER_DECL;
+
+       local_irq_save(flags);
+       kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs);
+       local_irq_restore(flags);
+}
+
+int kgdb_arch_init(void)
+{
+       return 0;
+}
+
+void kgdb_arch_exit(void)
+{
+}
+
+struct kgdb_arch arch_kgdb_ops = {
+       /* Breakpoint instruction: trapa #0x3c */
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+       .gdb_bpt_instr          = { 0x3c, 0xc3 },
+#else
+       .gdb_bpt_instr          = { 0xc3, 0x3c },
+#endif
+};
diff --git a/arch/sh/kernel/kgdb_jmp.S b/arch/sh/kernel/kgdb_jmp.S
deleted file mode 100644 (file)
index 339bb1d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <linux/linkage.h>
-
-ENTRY(setjmp)
-       add     #(9*4), r4
-       sts.l   pr, @-r4
-       mov.l   r15, @-r4
-       mov.l   r14, @-r4
-       mov.l   r13, @-r4
-       mov.l   r12, @-r4
-       mov.l   r11, @-r4
-       mov.l   r10, @-r4
-       mov.l   r9, @-r4
-       mov.l   r8, @-r4
-       rts
-        mov    #0, r0
-
-ENTRY(longjmp)
-       mov.l   @r4+, r8
-       mov.l   @r4+, r9
-       mov.l   @r4+, r10
-       mov.l   @r4+, r11
-       mov.l   @r4+, r12
-       mov.l   @r4+, r13
-       mov.l   @r4+, r14
-       mov.l   @r4+, r15
-       lds.l   @r4+, pr
-       mov     r5, r0
-       tst     r0, r0
-       bf      1f
-       mov     #1, r0  ! in case val==0
-1:     rts
-        nop
-
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
deleted file mode 100644 (file)
index bf8ac4c..0000000
+++ /dev/null
@@ -1,1052 +0,0 @@
-/*
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * Contains extracts from code by Glenn Engel, Jim Kingdon,
- * David Grothe <dave@gcom.com>, Tigran Aivazian <tigran@sco.com>,
- * Amit S. Kale <akale@veritas.com>,  William Gatliff <bgat@open-widgets.com>,
- * Ben Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com>.
- *
- * This version by Henry Bell <henry.bell@st.com>
- * Minor modifications by Jeremy Siegel <jsiegel@mvista.com>
- *
- * Contains low-level support for remote debug using GDB.
- *
- * To enable debugger support, two things need to happen. A call to
- * set_debug_traps() is necessary in order to allow any breakpoints
- * or error conditions to be properly intercepted and reported to gdb.
- * A breakpoint also needs to be generated to begin communication.  This
- * is most easily accomplished by a call to breakpoint() which does
- * a trapa if the initialisation phase has been successfully completed.
- *
- * In this case, set_debug_traps() is not used to "take over" exceptions;
- * other kernel code is modified instead to enter the kgdb functions here
- * when appropriate (see entry.S for breakpoint traps and NMI interrupts,
- * see traps.c for kernel error exceptions).
- *
- * The following gdb commands are supported:
- *
- *    Command       Function                               Return value
- *
- *    g             return the value of the CPU registers  hex data or ENN
- *    G             set the value of the CPU registers     OK or ENN
- *
- *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
- *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
- *    XAA..AA,LLLL: Same, but data is binary (not hex)     OK or ENN
- *
- *    c             Resume at current address              SNN   ( signal NN)
- *    cAA..AA       Continue at address AA..AA             SNN
- *    CNN;          Resume at current address with signal  SNN
- *    CNN;AA..AA    Resume at address AA..AA with signal   SNN
- *
- *    s             Step one instruction                   SNN
- *    sAA..AA       Step one instruction from AA..AA       SNN
- *    SNN;          Step one instruction with signal       SNN
- *    SNNAA..AA     Step one instruction from AA..AA w/NN  SNN
- *
- *    k             kill (Detach GDB)
- *
- *    d             Toggle debug flag
- *    D             Detach GDB
- *
- *    Hct           Set thread t for operations,           OK or ENN
- *                  c = 'c' (step, cont), c = 'g' (other
- *                  operations)
- *
- *    qC            Query current thread ID                QCpid
- *    qfThreadInfo  Get list of current threads (first)    m<id>
- *    qsThreadInfo   "    "  "     "      "   (subsequent)
- *    qOffsets      Get section offsets                  Text=x;Data=y;Bss=z
- *
- *    TXX           Find if thread XX is alive             OK or ENN
- *    ?             What was the last sigval ?             SNN   (signal NN)
- *    O             Output to GDB console
- *
- * Remote communication protocol.
- *
- *    A debug packet whose contents are <data> is encapsulated for
- *    transmission in the form:
- *
- *       $ <data> # CSUM1 CSUM2
- *
- *       <data> must be ASCII alphanumeric and cannot include characters
- *       '$' or '#'.  If <data> starts with two characters followed by
- *       ':', then the existing stubs interpret this as a sequence number.
- *
- *       CSUM1 and CSUM2 are ascii hex representation of an 8-bit
- *       checksum of <data>, the most significant nibble is sent first.
- *       the hex digits 0-9,a-f are used.
- *
- *    Receiver responds with:
- *
- *       +       - if CSUM is correct and ready for next packet
- *       -       - if CSUM is incorrect
- *
- * Responses can be run-length encoded to save space.  A '*' means that
- * the next character is an ASCII encoding giving a repeat count which
- * stands for that many repetitions of the character preceding the '*'.
- * The encoding is n+29, yielding a printable character where n >=3
- * (which is where RLE starts to win).  Don't use an n > 126.
- *
- * So "0* " means the same as "0000".
- */
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/sysrq.h>
-#include <linux/module.h>
-#include <asm/system.h>
-#include <asm/cacheflush.h>
-#include <asm/current.h>
-#include <asm/signal.h>
-#include <asm/pgtable.h>
-#include <asm/ptrace.h>
-#include <asm/kgdb.h>
-#include <asm/io.h>
-
-/* Function pointers for linkage */
-kgdb_debug_hook_t *kgdb_debug_hook;
-kgdb_bus_error_hook_t *kgdb_bus_err_hook;
-
-int (*kgdb_getchar)(void);
-EXPORT_SYMBOL_GPL(kgdb_getchar);
-void (*kgdb_putchar)(int);
-EXPORT_SYMBOL_GPL(kgdb_putchar);
-
-static void put_debug_char(int c)
-{
-       if (!kgdb_putchar)
-               return;
-       (*kgdb_putchar)(c);
-}
-static int get_debug_char(void)
-{
-       if (!kgdb_getchar)
-               return -1;
-       return (*kgdb_getchar)();
-}
-
-/* Num chars in in/out bound buffers, register packets need NUMREGBYTES * 2 */
-#define BUFMAX 1024
-#define NUMREGBYTES (MAXREG*4)
-#define OUTBUFMAX (NUMREGBYTES*2+512)
-
-enum {
-       R0 = 0, R1,  R2,  R3,   R4,   R5,  R6, R7,
-       R8, R9, R10, R11, R12,  R13,  R14, R15,
-       PC, PR, GBR, VBR, MACH, MACL, SR,
-       /*  */
-       MAXREG
-};
-
-static unsigned int registers[MAXREG];
-struct kgdb_regs trap_registers;
-
-char kgdb_in_gdb_mode;
-char in_nmi;                   /* Set during NMI to prevent reentry */
-int kgdb_nofault;              /* Boolean to ignore bus errs (i.e. in GDB) */
-
-/* Default values for SCI (can override via kernel args in setup.c) */
-#ifndef CONFIG_KGDB_DEFPORT
-#define CONFIG_KGDB_DEFPORT 1
-#endif
-
-#ifndef CONFIG_KGDB_DEFBAUD
-#define CONFIG_KGDB_DEFBAUD 115200
-#endif
-
-#if defined(CONFIG_KGDB_DEFPARITY_E)
-#define CONFIG_KGDB_DEFPARITY 'E'
-#elif defined(CONFIG_KGDB_DEFPARITY_O)
-#define CONFIG_KGDB_DEFPARITY 'O'
-#else /* CONFIG_KGDB_DEFPARITY_N */
-#define CONFIG_KGDB_DEFPARITY 'N'
-#endif
-
-#ifdef CONFIG_KGDB_DEFBITS_7
-#define CONFIG_KGDB_DEFBITS '7'
-#else /* CONFIG_KGDB_DEFBITS_8 */
-#define CONFIG_KGDB_DEFBITS '8'
-#endif
-
-/* SCI/UART settings, used in kgdb_console_setup() */
-int  kgdb_portnum = CONFIG_KGDB_DEFPORT;
-EXPORT_SYMBOL_GPL(kgdb_portnum);
-int  kgdb_baud = CONFIG_KGDB_DEFBAUD;
-EXPORT_SYMBOL_GPL(kgdb_baud);
-char kgdb_parity = CONFIG_KGDB_DEFPARITY;
-EXPORT_SYMBOL_GPL(kgdb_parity);
-char kgdb_bits = CONFIG_KGDB_DEFBITS;
-EXPORT_SYMBOL_GPL(kgdb_bits);
-
-/* Jump buffer for setjmp/longjmp */
-static jmp_buf rem_com_env;
-
-/* TRA differs sh3/4 */
-#if defined(CONFIG_CPU_SH3)
-#define TRA 0xffffffd0
-#elif defined(CONFIG_CPU_SH4)
-#define TRA 0xff000020
-#endif
-
-/* Macros for single step instruction identification */
-#define OPCODE_BT(op)         (((op) & 0xff00) == 0x8900)
-#define OPCODE_BF(op)         (((op) & 0xff00) == 0x8b00)
-#define OPCODE_BTF_DISP(op)   (((op) & 0x80) ? (((op) | 0xffffff80) << 1) : \
-                             (((op) & 0x7f ) << 1))
-#define OPCODE_BFS(op)        (((op) & 0xff00) == 0x8f00)
-#define OPCODE_BTS(op)        (((op) & 0xff00) == 0x8d00)
-#define OPCODE_BRA(op)        (((op) & 0xf000) == 0xa000)
-#define OPCODE_BRA_DISP(op)   (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
-                             (((op) & 0x7ff) << 1))
-#define OPCODE_BRAF(op)       (((op) & 0xf0ff) == 0x0023)
-#define OPCODE_BRAF_REG(op)   (((op) & 0x0f00) >> 8)
-#define OPCODE_BSR(op)        (((op) & 0xf000) == 0xb000)
-#define OPCODE_BSR_DISP(op)   (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
-                             (((op) & 0x7ff) << 1))
-#define OPCODE_BSRF(op)       (((op) & 0xf0ff) == 0x0003)
-#define OPCODE_BSRF_REG(op)   (((op) >> 8) & 0xf)
-#define OPCODE_JMP(op)        (((op) & 0xf0ff) == 0x402b)
-#define OPCODE_JMP_REG(op)    (((op) >> 8) & 0xf)
-#define OPCODE_JSR(op)        (((op) & 0xf0ff) == 0x400b)
-#define OPCODE_JSR_REG(op)    (((op) >> 8) & 0xf)
-#define OPCODE_RTS(op)        ((op) == 0xb)
-#define OPCODE_RTE(op)        ((op) == 0x2b)
-
-#define SR_T_BIT_MASK           0x1
-#define STEP_OPCODE             0xc320
-#define BIOS_CALL_TRAP          0x3f
-
-/* Exception codes as per SH-4 core manual */
-#define ADDRESS_ERROR_LOAD_VEC   7
-#define ADDRESS_ERROR_STORE_VEC  8
-#define TRAP_VEC                 11
-#define INVALID_INSN_VEC         12
-#define INVALID_SLOT_VEC         13
-#define NMI_VEC                  14
-#define USER_BREAK_VEC           15
-#define SERIAL_BREAK_VEC         58
-
-/* Misc static */
-static int stepped_address;
-static short stepped_opcode;
-static char in_buffer[BUFMAX];
-static char out_buffer[OUTBUFMAX];
-
-static void kgdb_to_gdb(const char *s);
-
-/* Convert ch to hex */
-static int hex(const char ch)
-{
-       if ((ch >= 'a') && (ch <= 'f'))
-               return (ch - 'a' + 10);
-       if ((ch >= '0') && (ch <= '9'))
-               return (ch - '0');
-       if ((ch >= 'A') && (ch <= 'F'))
-               return (ch - 'A' + 10);
-       return (-1);
-}
-
-/* Convert the memory pointed to by mem into hex, placing result in buf.
-   Returns a pointer to the last char put in buf (null) */
-static char *mem_to_hex(const char *mem, char *buf, const int count)
-{
-       int i;
-       int ch;
-       unsigned short s_val;
-       unsigned long l_val;
-
-       /* Check for 16 or 32 */
-       if (count == 2 && ((long) mem & 1) == 0) {
-               s_val = *(unsigned short *) mem;
-               mem = (char *) &s_val;
-       } else if (count == 4 && ((long) mem & 3) == 0) {
-               l_val = *(unsigned long *) mem;
-               mem = (char *) &l_val;
-       }
-       for (i = 0; i < count; i++) {
-               ch = *mem++;
-               buf = pack_hex_byte(buf, ch);
-       }
-       *buf = 0;
-       return (buf);
-}
-
-/* Convert the hex array pointed to by buf into binary, to be placed in mem.
-   Return a pointer to the character after the last byte written */
-static char *hex_to_mem(const char *buf, char *mem, const int count)
-{
-       int i;
-       unsigned char ch;
-
-       for (i = 0; i < count; i++) {
-               ch = hex(*buf++) << 4;
-               ch = ch + hex(*buf++);
-               *mem++ = ch;
-       }
-       return (mem);
-}
-
-/* While finding valid hex chars, convert to an integer, then return it */
-static int hex_to_int(char **ptr, int *int_value)
-{
-       int num_chars = 0;
-       int hex_value;
-
-       *int_value = 0;
-
-       while (**ptr) {
-               hex_value = hex(**ptr);
-               if (hex_value >= 0) {
-                       *int_value = (*int_value << 4) | hex_value;
-                       num_chars++;
-               } else
-                       break;
-               (*ptr)++;
-       }
-       return num_chars;
-}
-
-/*  Copy the binary array pointed to by buf into mem.  Fix $, #,
-    and 0x7d escaped with 0x7d.  Return a pointer to the character
-    after the last byte written. */
-static char *ebin_to_mem(const char *buf, char *mem, int count)
-{
-       for (; count > 0; count--, buf++) {
-               if (*buf == 0x7d)
-                       *mem++ = *(++buf) ^ 0x20;
-               else
-                       *mem++ = *buf;
-       }
-       return mem;
-}
-
-/* Scan for the start char '$', read the packet and check the checksum */
-static void get_packet(char *buffer, int buflen)
-{
-       unsigned char checksum;
-       unsigned char xmitcsum;
-       int i;
-       int count;
-       char ch;
-
-       do {
-               /* Ignore everything until the start character */
-               while ((ch = get_debug_char()) != '$');
-
-               checksum = 0;
-               xmitcsum = -1;
-               count = 0;
-
-               /* Now, read until a # or end of buffer is found */
-               while (count < (buflen - 1)) {
-                       ch = get_debug_char();
-
-                       if (ch == '#')
-                               break;
-
-                       checksum = checksum + ch;
-                       buffer[count] = ch;
-                       count = count + 1;
-               }
-
-               buffer[count] = 0;
-
-               /* Continue to read checksum following # */
-               if (ch == '#') {
-                       xmitcsum = hex(get_debug_char()) << 4;
-                       xmitcsum += hex(get_debug_char());
-
-                       /* Checksum */
-                       if (checksum != xmitcsum)
-                               put_debug_char('-');    /* Failed checksum */
-                       else {
-                               /* Ack successful transfer */
-                               put_debug_char('+');
-
-                               /* If a sequence char is present, reply
-                                  the sequence ID */
-                               if (buffer[2] == ':') {
-                                       put_debug_char(buffer[0]);
-                                       put_debug_char(buffer[1]);
-
-                                       /* Remove sequence chars from buffer */
-                                       count = strlen(buffer);
-                                       for (i = 3; i <= count; i++)
-                                               buffer[i - 3] = buffer[i];
-                               }
-                       }
-               }
-       }
-       while (checksum != xmitcsum);   /* Keep trying while we fail */
-}
-
-/* Send the packet in the buffer with run-length encoding */
-static void put_packet(char *buffer)
-{
-       int checksum;
-       char *src;
-       int runlen;
-       int encode;
-
-       do {
-               src = buffer;
-               put_debug_char('$');
-               checksum = 0;
-
-               /* Continue while we still have chars left */
-               while (*src) {
-                       /* Check for runs up to 99 chars long */
-                       for (runlen = 1; runlen < 99; runlen++) {
-                               if (src[0] != src[runlen])
-                                       break;
-                       }
-
-                       if (runlen > 3) {
-                               /* Got a useful amount, send encoding */
-                               encode = runlen + ' ' - 4;
-                               put_debug_char(*src);   checksum += *src;
-                               put_debug_char('*');    checksum += '*';
-                               put_debug_char(encode); checksum += encode;
-                               src += runlen;
-                       } else {
-                               /* Otherwise just send the current char */
-                               put_debug_char(*src);   checksum += *src;
-                               src += 1;
-                       }
-               }
-
-               /* '#' Separator, put high and low components of checksum */
-               put_debug_char('#');
-               put_debug_char(hex_asc_hi(checksum));
-               put_debug_char(hex_asc_lo(checksum));
-       }
-       while ((get_debug_char()) != '+');      /* While no ack */
-}
-
-/* A bus error has occurred - perform a longjmp to return execution and
-   allow handling of the error */
-static void kgdb_handle_bus_error(void)
-{
-       longjmp(rem_com_env, 1);
-}
-
-/* Translate SH-3/4 exception numbers to unix-like signal values */
-static int compute_signal(const int excep_code)
-{
-       int sigval;
-
-       switch (excep_code) {
-
-       case INVALID_INSN_VEC:
-       case INVALID_SLOT_VEC:
-               sigval = SIGILL;
-               break;
-       case ADDRESS_ERROR_LOAD_VEC:
-       case ADDRESS_ERROR_STORE_VEC:
-               sigval = SIGSEGV;
-               break;
-
-       case SERIAL_BREAK_VEC:
-       case NMI_VEC:
-               sigval = SIGINT;
-               break;
-
-       case USER_BREAK_VEC:
-       case TRAP_VEC:
-               sigval = SIGTRAP;
-               break;
-
-       default:
-               sigval = SIGBUS;        /* "software generated" */
-               break;
-       }
-
-       return (sigval);
-}
-
-/* Make a local copy of the registers passed into the handler (bletch) */
-static void kgdb_regs_to_gdb_regs(const struct kgdb_regs *regs,
-                                 int *gdb_regs)
-{
-       gdb_regs[R0] = regs->regs[R0];
-       gdb_regs[R1] = regs->regs[R1];
-       gdb_regs[R2] = regs->regs[R2];
-       gdb_regs[R3] = regs->regs[R3];
-       gdb_regs[R4] = regs->regs[R4];
-       gdb_regs[R5] = regs->regs[R5];
-       gdb_regs[R6] = regs->regs[R6];
-       gdb_regs[R7] = regs->regs[R7];
-       gdb_regs[R8] = regs->regs[R8];
-       gdb_regs[R9] = regs->regs[R9];
-       gdb_regs[R10] = regs->regs[R10];
-       gdb_regs[R11] = regs->regs[R11];
-       gdb_regs[R12] = regs->regs[R12];
-       gdb_regs[R13] = regs->regs[R13];
-       gdb_regs[R14] = regs->regs[R14];
-       gdb_regs[R15] = regs->regs[R15];
-       gdb_regs[PC] = regs->pc;
-       gdb_regs[PR] = regs->pr;
-       gdb_regs[GBR] = regs->gbr;
-       gdb_regs[MACH] = regs->mach;
-       gdb_regs[MACL] = regs->macl;
-       gdb_regs[SR] = regs->sr;
-       gdb_regs[VBR] = regs->vbr;
-}
-
-/* Copy local gdb registers back to kgdb regs, for later copy to kernel */
-static void gdb_regs_to_kgdb_regs(const int *gdb_regs,
-                                 struct kgdb_regs *regs)
-{
-       regs->regs[R0] = gdb_regs[R0];
-       regs->regs[R1] = gdb_regs[R1];
-       regs->regs[R2] = gdb_regs[R2];
-       regs->regs[R3] = gdb_regs[R3];
-       regs->regs[R4] = gdb_regs[R4];
-       regs->regs[R5] = gdb_regs[R5];
-       regs->regs[R6] = gdb_regs[R6];
-       regs->regs[R7] = gdb_regs[R7];
-       regs->regs[R8] = gdb_regs[R8];
-       regs->regs[R9] = gdb_regs[R9];
-       regs->regs[R10] = gdb_regs[R10];
-       regs->regs[R11] = gdb_regs[R11];
-       regs->regs[R12] = gdb_regs[R12];
-       regs->regs[R13] = gdb_regs[R13];
-       regs->regs[R14] = gdb_regs[R14];
-       regs->regs[R15] = gdb_regs[R15];
-       regs->pc = gdb_regs[PC];
-       regs->pr = gdb_regs[PR];
-       regs->gbr = gdb_regs[GBR];
-       regs->mach = gdb_regs[MACH];
-       regs->macl = gdb_regs[MACL];
-       regs->sr = gdb_regs[SR];
-       regs->vbr = gdb_regs[VBR];
-}
-
-/* Calculate the new address for after a step */
-static short *get_step_address(void)
-{
-       short op = *(short *) trap_registers.pc;
-       long addr;
-
-       /* BT */
-       if (OPCODE_BT(op)) {
-               if (trap_registers.sr & SR_T_BIT_MASK)
-                       addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
-               else
-                       addr = trap_registers.pc + 2;
-       }
-
-       /* BTS */
-       else if (OPCODE_BTS(op)) {
-               if (trap_registers.sr & SR_T_BIT_MASK)
-                       addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
-               else
-                       addr = trap_registers.pc + 4;   /* Not in delay slot */
-       }
-
-       /* BF */
-       else if (OPCODE_BF(op)) {
-               if (!(trap_registers.sr & SR_T_BIT_MASK))
-                       addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
-               else
-                       addr = trap_registers.pc + 2;
-       }
-
-       /* BFS */
-       else if (OPCODE_BFS(op)) {
-               if (!(trap_registers.sr & SR_T_BIT_MASK))
-                       addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
-               else
-                       addr = trap_registers.pc + 4;   /* Not in delay slot */
-       }
-
-       /* BRA */
-       else if (OPCODE_BRA(op))
-               addr = trap_registers.pc + 4 + OPCODE_BRA_DISP(op);
-
-       /* BRAF */
-       else if (OPCODE_BRAF(op))
-               addr = trap_registers.pc + 4
-                   + trap_registers.regs[OPCODE_BRAF_REG(op)];
-
-       /* BSR */
-       else if (OPCODE_BSR(op))
-               addr = trap_registers.pc + 4 + OPCODE_BSR_DISP(op);
-
-       /* BSRF */
-       else if (OPCODE_BSRF(op))
-               addr = trap_registers.pc + 4
-                   + trap_registers.regs[OPCODE_BSRF_REG(op)];
-
-       /* JMP */
-       else if (OPCODE_JMP(op))
-               addr = trap_registers.regs[OPCODE_JMP_REG(op)];
-
-       /* JSR */
-       else if (OPCODE_JSR(op))
-               addr = trap_registers.regs[OPCODE_JSR_REG(op)];
-
-       /* RTS */
-       else if (OPCODE_RTS(op))
-               addr = trap_registers.pr;
-
-       /* RTE */
-       else if (OPCODE_RTE(op))
-               addr = trap_registers.regs[15];
-
-       /* Other */
-       else
-               addr = trap_registers.pc + 2;
-
-       flush_icache_range(addr, addr + 2);
-       return (short *) addr;
-}
-
-/* Set up a single-step.  Replace the instruction immediately after the
-   current instruction (i.e. next in the expected flow of control) with a
-   trap instruction, so that returning will cause only a single instruction
-   to be executed. Note that this model is slightly broken for instructions
-   with delay slots (e.g. B[TF]S, BSR, BRA etc), where both the branch
-   and the instruction in the delay slot will be executed. */
-static void do_single_step(void)
-{
-       unsigned short *addr = 0;
-
-       /* Determine where the target instruction will send us to */
-       addr = get_step_address();
-       stepped_address = (int)addr;
-
-       /* Replace it */
-       stepped_opcode = *(short *)addr;
-       *addr = STEP_OPCODE;
-
-       /* Flush and return */
-       flush_icache_range((long) addr, (long) addr + 2);
-}
-
-/* Undo a single step */
-static void undo_single_step(void)
-{
-       /* If we have stepped, put back the old instruction */
-       /* Use stepped_address in case we stopped elsewhere */
-       if (stepped_opcode != 0) {
-               *(short*)stepped_address = stepped_opcode;
-               flush_icache_range(stepped_address, stepped_address + 2);
-       }
-       stepped_opcode = 0;
-}
-
-/* Send a signal message */
-static void send_signal_msg(const int signum)
-{
-       out_buffer[0] = 'S';
-       out_buffer[1] = hex_asc_hi(signum);
-       out_buffer[2] = hex_asc_lo(signum);
-       out_buffer[3] = 0;
-       put_packet(out_buffer);
-}
-
-/* Reply that all was well */
-static void send_ok_msg(void)
-{
-       strcpy(out_buffer, "OK");
-       put_packet(out_buffer);
-}
-
-/* Reply that an error occurred */
-static void send_err_msg(void)
-{
-       strcpy(out_buffer, "E01");
-       put_packet(out_buffer);
-}
-
-/* Empty message indicates unrecognised command */
-static void send_empty_msg(void)
-{
-       put_packet("");
-}
-
-/* Read memory due to 'm' message */
-static void read_mem_msg(void)
-{
-       char *ptr;
-       int addr;
-       int length;
-
-       /* Jmp, disable bus error handler */
-       if (setjmp(rem_com_env) == 0) {
-
-               kgdb_nofault = 1;
-
-               /* Walk through, have m<addr>,<length> */
-               ptr = &in_buffer[1];
-               if (hex_to_int(&ptr, &addr) && (*ptr++ == ','))
-                       if (hex_to_int(&ptr, &length)) {
-                               ptr = 0;
-                               if (length * 2 > OUTBUFMAX)
-                                       length = OUTBUFMAX / 2;
-                               mem_to_hex((char *) addr, out_buffer, length);
-                       }
-               if (ptr)
-                       send_err_msg();
-               else
-                       put_packet(out_buffer);
-       } else
-               send_err_msg();
-
-       /* Restore bus error handler */
-       kgdb_nofault = 0;
-}
-
-/* Write memory due to 'M' or 'X' message */
-static void write_mem_msg(int binary)
-{
-       char *ptr;
-       int addr;
-       int length;
-
-       if (setjmp(rem_com_env) == 0) {
-
-               kgdb_nofault = 1;
-
-               /* Walk through, have M<addr>,<length>:<data> */
-               ptr = &in_buffer[1];
-               if (hex_to_int(&ptr, &addr) && (*ptr++ == ','))
-                       if (hex_to_int(&ptr, &length) && (*ptr++ == ':')) {
-                               if (binary)
-                                       ebin_to_mem(ptr, (char*)addr, length);
-                               else
-                                       hex_to_mem(ptr, (char*)addr, length);
-                               flush_icache_range(addr, addr + length);
-                               ptr = 0;
-                               send_ok_msg();
-                       }
-               if (ptr)
-                       send_err_msg();
-       } else
-               send_err_msg();
-
-       /* Restore bus error handler */
-       kgdb_nofault = 0;
-}
-
-/* Continue message  */
-static void continue_msg(void)
-{
-       /* Try to read optional parameter, PC unchanged if none */
-       char *ptr = &in_buffer[1];
-       int addr;
-
-       if (hex_to_int(&ptr, &addr))
-               trap_registers.pc = addr;
-}
-
-/* Continue message with signal */
-static void continue_with_sig_msg(void)
-{
-       int signal;
-       char *ptr = &in_buffer[1];
-       int addr;
-
-       /* Report limitation */
-       kgdb_to_gdb("Cannot force signal in kgdb, continuing anyway.\n");
-
-       /* Signal */
-       hex_to_int(&ptr, &signal);
-       if (*ptr == ';')
-               ptr++;
-
-       /* Optional address */
-       if (hex_to_int(&ptr, &addr))
-               trap_registers.pc = addr;
-}
-
-/* Step message */
-static void step_msg(void)
-{
-       continue_msg();
-       do_single_step();
-}
-
-/* Step message with signal */
-static void step_with_sig_msg(void)
-{
-       continue_with_sig_msg();
-       do_single_step();
-}
-
-/* Send register contents */
-static void send_regs_msg(void)
-{
-       kgdb_regs_to_gdb_regs(&trap_registers, registers);
-       mem_to_hex((char *) registers, out_buffer, NUMREGBYTES);
-       put_packet(out_buffer);
-}
-
-/* Set register contents - currently can't set other thread's registers */
-static void set_regs_msg(void)
-{
-       kgdb_regs_to_gdb_regs(&trap_registers, registers);
-       hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES);
-       gdb_regs_to_kgdb_regs(registers, &trap_registers);
-       send_ok_msg();
-}
-
-#ifdef CONFIG_SH_KGDB_CONSOLE
-/*
- * Bring up the ports..
- */
-static int __init kgdb_serial_setup(void)
-{
-       struct console dummy;
-       return kgdb_console_setup(&dummy, 0);
-}
-#else
-#define kgdb_serial_setup()    0
-#endif
-
-/* The command loop, read and act on requests */
-static void kgdb_command_loop(const int excep_code, const int trapa_value)
-{
-       int sigval;
-
-       /* Enter GDB mode (e.g. after detach) */
-       if (!kgdb_in_gdb_mode) {
-               /* Do serial setup, notify user, issue preemptive ack */
-               printk(KERN_NOTICE "KGDB: Waiting for GDB\n");
-               kgdb_in_gdb_mode = 1;
-               put_debug_char('+');
-       }
-
-       /* Reply to host that an exception has occurred */
-       sigval = compute_signal(excep_code);
-       send_signal_msg(sigval);
-
-       /* TRAP_VEC exception indicates a software trap inserted in place of
-          code by GDB so back up PC by one instruction, as this instruction
-          will later be replaced by its original one.  Do NOT do this for
-          trap 0xff, since that indicates a compiled-in breakpoint which
-          will not be replaced (and we would retake the trap forever) */
-       if ((excep_code == TRAP_VEC) && (trapa_value != (0x3c << 2)))
-               trap_registers.pc -= 2;
-
-       /* Undo any stepping we may have done */
-       undo_single_step();
-
-       while (1) {
-               out_buffer[0] = 0;
-               get_packet(in_buffer, BUFMAX);
-
-               /* Examine first char of buffer to see what we need to do */
-               switch (in_buffer[0]) {
-               case '?':       /* Send which signal we've received */
-                       send_signal_msg(sigval);
-                       break;
-
-               case 'g':       /* Return the values of the CPU registers */
-                       send_regs_msg();
-                       break;
-
-               case 'G':       /* Set the value of the CPU registers */
-                       set_regs_msg();
-                       break;
-
-               case 'm':       /* Read LLLL bytes address AA..AA */
-                       read_mem_msg();
-                       break;
-
-               case 'M':       /* Write LLLL bytes address AA..AA, ret OK */
-                       write_mem_msg(0);       /* 0 = data in hex */
-                       break;
-
-               case 'X':       /* Write LLLL bytes esc bin address AA..AA */
-                       if (kgdb_bits == '8')
-                               write_mem_msg(1); /* 1 = data in binary */
-                       else
-                               send_empty_msg();
-                       break;
-
-               case 'C':       /* Continue, signum included, we ignore it */
-                       continue_with_sig_msg();
-                       return;
-
-               case 'c':       /* Continue at address AA..AA (optional) */
-                       continue_msg();
-                       return;
-
-               case 'S':       /* Step, signum included, we ignore it */
-                       step_with_sig_msg();
-                       return;
-
-               case 's':       /* Step one instruction from AA..AA */
-                       step_msg();
-                       return;
-
-               case 'k':       /* 'Kill the program' with a kernel ? */
-                       break;
-
-               case 'D':       /* Detach from program, send reply OK */
-                       kgdb_in_gdb_mode = 0;
-                       send_ok_msg();
-                       get_debug_char();
-                       return;
-
-               default:
-                       send_empty_msg();
-                       break;
-               }
-       }
-}
-
-/* There has been an exception, most likely a breakpoint. */
-static void handle_exception(struct pt_regs *regs)
-{
-       int excep_code, vbr_val;
-       int count;
-       int trapa_value = ctrl_inl(TRA);
-
-       /* Copy kernel regs (from stack) */
-       for (count = 0; count < 16; count++)
-               trap_registers.regs[count] = regs->regs[count];
-       trap_registers.pc = regs->pc;
-       trap_registers.pr = regs->pr;
-       trap_registers.sr = regs->sr;
-       trap_registers.gbr = regs->gbr;
-       trap_registers.mach = regs->mach;
-       trap_registers.macl = regs->macl;
-
-       asm("stc vbr, %0":"=r"(vbr_val));
-       trap_registers.vbr = vbr_val;
-
-       /* Get excode for command loop call, user access */
-       asm("stc r2_bank, %0":"=r"(excep_code));
-
-       /* Act on the exception */
-       kgdb_command_loop(excep_code, trapa_value);
-
-       /* Copy back the (maybe modified) registers */
-       for (count = 0; count < 16; count++)
-               regs->regs[count] = trap_registers.regs[count];
-       regs->pc = trap_registers.pc;
-       regs->pr = trap_registers.pr;
-       regs->sr = trap_registers.sr;
-       regs->gbr = trap_registers.gbr;
-       regs->mach = trap_registers.mach;
-       regs->macl = trap_registers.macl;
-
-       vbr_val = trap_registers.vbr;
-       asm("ldc %0, vbr": :"r"(vbr_val));
-}
-
-asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
-                                     unsigned long r6, unsigned long r7,
-                                     struct pt_regs __regs)
-{
-       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
-       handle_exception(regs);
-}
-
-/* Initialise the KGDB data structures and serial configuration */
-int __init kgdb_init(void)
-{
-       in_nmi = 0;
-       kgdb_nofault = 0;
-       stepped_opcode = 0;
-       kgdb_in_gdb_mode = 0;
-
-       if (kgdb_serial_setup() != 0) {
-               printk(KERN_NOTICE "KGDB: serial setup error\n");
-               return -1;
-       }
-
-       /* Init ptr to exception handler */
-       kgdb_debug_hook = handle_exception;
-       kgdb_bus_err_hook = kgdb_handle_bus_error;
-
-       /* Enter kgdb now if requested, or just report init done */
-       printk(KERN_NOTICE "KGDB: stub is initialized.\n");
-
-       return 0;
-}
-
-/* Make function available for "user messages"; console will use it too. */
-
-char gdbmsgbuf[BUFMAX];
-#define MAXOUT ((BUFMAX-2)/2)
-
-static void kgdb_msg_write(const char *s, unsigned count)
-{
-       int i;
-       int wcount;
-       char *bufptr;
-
-       /* 'O'utput */
-       gdbmsgbuf[0] = 'O';
-
-       /* Fill and send buffers... */
-       while (count > 0) {
-               bufptr = gdbmsgbuf + 1;
-
-               /* Calculate how many this time */
-               wcount = (count > MAXOUT) ? MAXOUT : count;
-
-               /* Pack in hex chars */
-               for (i = 0; i < wcount; i++)
-                       bufptr = pack_hex_byte(bufptr, s[i]);
-               *bufptr = '\0';
-
-               /* Move up */
-               s += wcount;
-               count -= wcount;
-
-               /* Write packet */
-               put_packet(gdbmsgbuf);
-       }
-}
-
-static void kgdb_to_gdb(const char *s)
-{
-       kgdb_msg_write(s, strlen(s));
-}
-
-#ifdef CONFIG_SH_KGDB_CONSOLE
-void kgdb_console_write(struct console *co, const char *s, unsigned count)
-{
-       /* Bail if we're not talking to GDB */
-       if (!kgdb_in_gdb_mode)
-               return;
-
-       kgdb_msg_write(s, count);
-}
-#endif
-
-#ifdef CONFIG_KGDB_SYSRQ
-static void sysrq_handle_gdb(int key, struct tty_struct *tty)
-{
-       printk("Entering GDB stub\n");
-       breakpoint();
-}
-
-static struct sysrq_key_op sysrq_gdb_op = {
-        .handler        = sysrq_handle_gdb,
-        .help_msg       = "Gdb",
-        .action_msg     = "GDB",
-};
-
-static int gdb_register_sysrq(void)
-{
-       printk("Registering GDB sysrq handler\n");
-       register_sysrq_key('g', &sysrq_gdb_op);
-       return 0;
-}
-module_init(gdb_register_sysrq);
-#endif
index 23ca711c27d2af9e6e15106a17bcdb8e92bea47c..1336f275326c70d70b3cf31e0a5c3e531ef59750 100644 (file)
@@ -277,11 +277,4 @@ void __init time_init(void)
                       ((sh_hpt_frequency + 500) / 1000) / 1000,
                       ((sh_hpt_frequency + 500) / 1000) % 1000);
 
-#if defined(CONFIG_SH_KGDB)
-       /*
-        * Set up kgdb as requested. We do it here because the serial
-        * init uses the timer vars we just set up for figuring baud.
-        */
-       kgdb_init();
-#endif
 }
index 6094fc13beea919bb0553d52795dcb06cfaf3fd7..88807a2aacc32c583d7b5d1e2392ad0961a87181 100644 (file)
 #include <asm/fpu.h>
 #include <asm/kprobes.h>
 
-#ifdef CONFIG_SH_KGDB
-#include <asm/kgdb.h>
-#define CHK_REMOTE_DEBUG(regs)                 \
-{                                              \
-       if (kgdb_debug_hook && !user_mode(regs))\
-               (*kgdb_debug_hook)(regs);       \
-}
-#else
-#define CHK_REMOTE_DEBUG(regs)
-#endif
-
 #ifdef CONFIG_CPU_SH2
 # define TRAP_RESERVED_INST    4
 # define TRAP_ILLEGAL_SLOT_INST        6
@@ -94,7 +83,6 @@ void die(const char * str, struct pt_regs * regs, long err)
 
        printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
 
-       CHK_REMOTE_DEBUG(regs);
        print_modules();
        show_regs(regs);
 
@@ -683,7 +671,6 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
        error_code = lookup_exception_vector();
 
        local_irq_enable();
-       CHK_REMOTE_DEBUG(regs);
        force_sig(SIGILL, tsk);
        die_if_no_fixup("reserved instruction", regs, error_code);
 }
@@ -761,7 +748,6 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
        inst = lookup_exception_vector();
 
        local_irq_enable();
-       CHK_REMOTE_DEBUG(regs);
        force_sig(SIGILL, tsk);
        die_if_no_fixup("illegal slot instruction", regs, inst);
 }
index e58726892b5ff5b57c358e075a35d49fa821b8ce..31a33ebdef6f8ca18d379c89cfa91fc995ce5eec 100644 (file)
@@ -20,7 +20,6 @@
 #include <asm/system.h>
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
-#include <asm/kgdb.h>
 
 /*
  * This routine handles page faults.  It determines the address,
@@ -282,11 +281,6 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
        if (notify_page_fault(regs, lookup_exception_vector()))
                goto out;
 
-#ifdef CONFIG_SH_KGDB
-       if (kgdb_nofault && kgdb_bus_err_hook)
-               kgdb_bus_err_hook();
-#endif
-
        ret = 1;
 
        /*