sh: Bring kgdb back from the dead.
authorPaul Mundt <lethal@linux-sh.org>
Thu, 8 Mar 2007 08:27:37 +0000 (17:27 +0900)
committerPaul Mundt <lethal@hera.kernel.org>
Mon, 7 May 2007 02:10:51 +0000 (02:10 +0000)
This code has suffered quite a bit of bitrot, do some basic
tidying to get it to a reasonably functional state again.
This gets the basic support and the console working again.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
arch/sh/Kconfig.debug
arch/sh/Makefile
arch/sh/boards/se/7751/setup.c
arch/sh/kernel/kgdb_stub.c
arch/sh/kernel/setup.c
drivers/serial/sh-sci.c
include/asm-sh/kgdb.h
include/asm-sh/se7751.h

index 87902e0..6be2385 100644 (file)
@@ -77,16 +77,17 @@ config 4KSTACKS
          on the VM subsystem for higher order allocations. This option
          will also use IRQ stacks to compensate for the reduced stackspace.
 
          on the VM subsystem for higher order allocations. This option
          will also use IRQ stacks to compensate for the reduced stackspace.
 
-config KGDB
+config SH_KGDB
        bool "Include KGDB kernel debugger"
        select FRAME_POINTER
        bool "Include KGDB kernel debugger"
        select FRAME_POINTER
+       select DEBUG_INFO
        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"
        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 KGDB
+       depends on SH_KGDB
 
 config MORE_COMPILE_OPTIONS
        bool "Add any additional compile options"
 
 config MORE_COMPILE_OPTIONS
        bool "Add any additional compile options"
@@ -109,16 +110,14 @@ config KGDB_THREAD
 
 config SH_KGDB_CONSOLE
        bool "Console messages through GDB"
 
 config SH_KGDB_CONSOLE
        bool "Console messages through GDB"
+       depends on !SERIAL_SH_SCI_CONSOLE
+       select SERIAL_CORE_CONSOLE
        default n
 
 config KGDB_SYSRQ
        bool "Allow SysRq 'G' to enter KGDB"
        default y
 
        default n
 
 config KGDB_SYSRQ
        bool "Allow SysRq 'G' to enter KGDB"
        default y
 
-config KGDB_KERNEL_ASSERTS
-       bool "Include KGDB kernel assertions"
-       default n
-
 comment "Serial port setup"
 
 config KGDB_DEFPORT
 comment "Serial port setup"
 
 config KGDB_DEFPORT
@@ -131,7 +130,7 @@ config KGDB_DEFBAUD
 
 choice
        prompt "Parity"
 
 choice
        prompt "Parity"
-       depends on KGDB
+       depends on SH_KGDB
        default KGDB_DEFPARITY_N
 
 config KGDB_DEFPARITY_N
        default KGDB_DEFPARITY_N
 
 config KGDB_DEFPARITY_N
@@ -147,7 +146,7 @@ endchoice
 
 choice
        prompt "Data bits"
 
 choice
        prompt "Data bits"
-       depends on KGDB
+       depends on SH_KGDB
        default KGDB_DEFBITS_8
 
 config KGDB_DEFBITS_8
        default KGDB_DEFBITS_8
 
 config KGDB_DEFBITS_8
index bd9b172..0fadde2 100644 (file)
@@ -47,7 +47,6 @@ cflags-$(CONFIG_CPU_LITTLE_ENDIAN)    += -ml
 cflags-y       += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding
 
 cflags-$(CONFIG_SH_DSP)                        += -Wa,-dsp
 cflags-y       += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding
 
 cflags-$(CONFIG_SH_DSP)                        += -Wa,-dsp
-cflags-$(CONFIG_SH_KGDB)               += -g
 
 cflags-$(CONFIG_MORE_COMPILE_OPTIONS)  += \
        $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g')
 
 cflags-$(CONFIG_MORE_COMPILE_OPTIONS)  += \
        $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g')
index e3feae6..770defe 100644 (file)
 #include <asm/se7751.h>
 #include <asm/io.h>
 
 #include <asm/se7751.h>
 #include <asm/io.h>
 
-void init_7751se_IRQ(void);
-
-#ifdef CONFIG_SH_KGDB
-#include <asm/kgdb.h>
-static int kgdb_uart_setup(void);
-static struct kgdb_sermap kgdb_uart_sermap = 
-{ "ttyS", 0, kgdb_uart_setup, NULL };
-#endif
-/*
- * Initialize the board
- */
-static void __init sh7751se_setup(char **cmdline_p)
-{
-       /* Call init_smsc() replacement to set up SuperIO. */
-       /* XXX: RTC setting comes here */
-#ifdef CONFIG_SH_KGDB
-       kgdb_register_sermap(&kgdb_uart_sermap);
-#endif
-}
-
-/*********************************************************************
- * Currently a hack (e.g. does not interact well w/serial.c, lots of *
- * hardcoded stuff) but may be useful if SCI/F needs debugging.      *
- * Mostly copied from x86 code (see files asm-i386/kgdb_local.h and  *
- * arch/i386/lib/kgdb_serial.c).                                     *
- *********************************************************************/
-
-#ifdef CONFIG_SH_KGDB
-#include <linux/types.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-
-#define COM1_PORT 0x3f8  /* Base I/O address */
-#define COM1_IRQ  4      /* IRQ not used yet */
-#define COM2_PORT 0x2f8  /* Base I/O address */
-#define COM2_IRQ  3      /* IRQ not used yet */
-
-#define SB_CLOCK 1843200 /* Serial baud clock */
-#define SB_BASE (SB_CLOCK/16)
-#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS
-
-struct uart_port {
-       int base;
-};
-#define UART_NPORTS 2
-struct uart_port uart_ports[] = {
-       { COM1_PORT },
-       { COM2_PORT },
-};
-struct uart_port *kgdb_uart_port;
-
-#define UART_IN(reg)   inb_p(kgdb_uart_port->base + reg)
-#define UART_OUT(reg,v)        outb_p((v), kgdb_uart_port->base + reg)
-
-/* Basic read/write functions for the UART */
-#define UART_LSR_RXCERR    (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE)
-static int kgdb_uart_getchar(void)
-{
-       int lsr;
-       int c = -1;
-
-       while (c == -1) {
-               lsr = UART_IN(UART_LSR);
-               if (lsr & UART_LSR_DR) 
-                       c = UART_IN(UART_RX);
-               if ((lsr & UART_LSR_RXCERR))
-                       c = -1;
-       }
-       return c;
-}
-
-static void kgdb_uart_putchar(int c)
-{
-       while ((UART_IN(UART_LSR) & UART_LSR_THRE) == 0)
-               ;
-       UART_OUT(UART_TX, c);
-}
-
-/*
- * Initialize UART to configured/requested values.
- * (But we don't interrupts yet, or interact w/serial.c)
- */
-static int kgdb_uart_setup(void)
-{
-       int port;
-       int lcr = 0;
-       int bdiv = 0;
-
-       if (kgdb_portnum >= UART_NPORTS) {
-               KGDB_PRINTK("uart port %d invalid.\n", kgdb_portnum);
-               return -1;
-       }
-
-       kgdb_uart_port = &uart_ports[kgdb_portnum];
-
-       /* Init sequence from gdb_hook_interrupt */
-       UART_IN(UART_RX);
-       UART_OUT(UART_IER, 0);
-
-       UART_IN(UART_RX);       /* Serial driver comments say */
-       UART_IN(UART_IIR);      /* this clears interrupt regs */
-       UART_IN(UART_MSR);
-
-       /* Figure basic LCR values */
-       switch (kgdb_bits) {
-       case '7':
-               lcr |= UART_LCR_WLEN7;
-               break;
-       default: case '8': 
-               lcr |= UART_LCR_WLEN8;
-               break;
-       }
-       switch (kgdb_parity) {
-       case 'O':
-               lcr |= UART_LCR_PARITY;
-               break;
-       case 'E':
-               lcr |= (UART_LCR_PARITY | UART_LCR_EPAR);
-               break;
-       default: break;
-       }
-
-       /* Figure the baud rate divisor */
-       bdiv = (SB_BASE/kgdb_baud);
-       
-       /* Set the baud rate and LCR values */
-       UART_OUT(UART_LCR, (lcr | UART_LCR_DLAB));
-       UART_OUT(UART_DLL, (bdiv & 0xff));
-       UART_OUT(UART_DLM, ((bdiv >> 8) & 0xff));
-       UART_OUT(UART_LCR, lcr);
-
-       /* Set the MCR */
-       UART_OUT(UART_MCR, SB_MCR);
-
-       /* Turn off FIFOs for now */
-       UART_OUT(UART_FCR, 0);
-
-       /* Setup complete: initialize function pointers */
-       kgdb_getchar = kgdb_uart_getchar;
-       kgdb_putchar = kgdb_uart_putchar;
-
-       return 0;
-}
-#endif /* CONFIG_SH_KGDB */
-
 static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
 
 static struct resource heartbeat_resources[] = {
 static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
 
 static struct resource heartbeat_resources[] = {
@@ -197,7 +50,6 @@ __initcall(se7751_devices_setup);
  */
 struct sh_machine_vector mv_7751se __initmv = {
        .mv_name                = "7751 SolutionEngine",
  */
 struct sh_machine_vector mv_7751se __initmv = {
        .mv_name                = "7751 SolutionEngine",
-       .mv_setup               = sh7751se_setup,
        .mv_nr_irqs             = 72,
 
        .mv_inb                 = sh7751se_inb,
        .mv_nr_irqs             = 72,
 
        .mv_inb                 = sh7751se_inb,
index d8927d8..737eadc 100644 (file)
@@ -6,11 +6,11 @@
  * 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>.
  * 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>
  * 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. 
+ *
+ * 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
  *
  * To enable debugger support, two things need to happen. A call to
  * set_debug_traps() is necessary in order to allow any breakpoints
@@ -48,7 +48,7 @@
  *    k             kill (Detach GDB)
  *
  *    d             Toggle debug flag
  *    k             kill (Detach GDB)
  *
  *    d             Toggle debug flag
- *    D             Detach GDB 
+ *    D             Detach GDB
  *
  *    Hct           Set thread t for operations,           OK or ENN
  *                  c = 'c' (step, cont), c = 'g' (other
  *
  *    Hct           Set thread t for operations,           OK or ENN
  *                  c = 'c' (step, cont), c = 'g' (other
@@ -58,7 +58,7 @@
  *    qfThreadInfo  Get list of current threads (first)    m<id>
  *    qsThreadInfo   "    "  "     "      "   (subsequent)
  *    qOffsets      Get section offsets                  Text=x;Data=y;Bss=z
  *    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
  *    TXX           Find if thread XX is alive             OK or ENN
  *    ?             What was the last sigval ?             SNN   (signal NN)
  *    O             Output to GDB console
@@ -74,7 +74,7 @@
  *       '$' or '#'.  If <data> starts with two characters followed by
  *       ':', then the existing stubs interpret this as a sequence number.
  *
  *       '$' 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 
+ *       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.
  *
  *       checksum of <data>, the most significant nibble is sent first.
  *       the hex digits 0-9,a-f are used.
  *
@@ -86,8 +86,8 @@
  * 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 repititions of the character preceding the '*'.
  * 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 repititions 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. 
+ * 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".
  */
  *
  * So "0* " means the same as "0000".
  */
 #include <linux/delay.h>
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/linkage.h>
 #include <linux/init.h>
-
-#ifdef CONFIG_SH_KGDB_CONSOLE
 #include <linux/console.h>
 #include <linux/console.h>
-#endif
-
+#include <linux/sysrq.h>
 #include <asm/system.h>
 #include <asm/system.h>
+#include <asm/cacheflush.h>
 #include <asm/current.h>
 #include <asm/signal.h>
 #include <asm/pgtable.h>
 #include <asm/current.h>
 #include <asm/signal.h>
 #include <asm/pgtable.h>
@@ -153,7 +151,6 @@ 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) */
 int kgdb_enabled = 1;          /* Default to enabled, cmdline can disable */
 char in_nmi;                   /* Set during NMI to prevent reentry */
 int kgdb_nofault;              /* Boolean to ignore bus errs (i.e. in GDB) */
 int kgdb_enabled = 1;          /* Default to enabled, cmdline can disable */
-int kgdb_halt;
 
 /* Exposed for user access */
 struct task_struct *kgdb_current;
 
 /* Exposed for user access */
 struct task_struct *kgdb_current;
@@ -328,7 +325,7 @@ static int hex_to_int(char **ptr, int *int_value)
 }
 
 /*  Copy the binary array pointed to by buf into mem.  Fix $, #,
 }
 
 /*  Copy the binary array pointed to by buf into mem.  Fix $, #,
-    and 0x7d escaped with 0x7d.  Return a pointer to the character 
+    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)
 {
     after the last byte written. */
 static char *ebin_to_mem(const char *buf, char *mem, int count)
 {
@@ -452,7 +449,7 @@ static void get_packet(char *buffer, int buflen)
                                /* Ack successful transfer */
                                put_debug_char('+');
 
                                /* Ack successful transfer */
                                put_debug_char('+');
 
-                               /* If a sequence char is present, reply 
+                               /* If a sequence char is present, reply
                                   the sequence ID */
                                if (buffer[2] == ':') {
                                        put_debug_char(buffer[0]);
                                   the sequence ID */
                                if (buffer[2] == ':') {
                                        put_debug_char(buffer[0]);
@@ -759,7 +756,7 @@ static short *get_step_address(void)
        return (short *) addr;
 }
 
        return (short *) addr;
 }
 
-/* Set up a single-step.  Replace the instruction immediately after the 
+/* 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
    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
@@ -1002,10 +999,8 @@ void set_thread_msg(void)
        char *ptr;
 
        switch (in_buffer[1]) {
        char *ptr;
 
        switch (in_buffer[1]) {
-
-               /* To select which thread for gG etc messages, i.e. supported */
+       /* To select which thread for gG etc messages, i.e. supported */
        case 'g':
        case 'g':
-
                ptr = &in_buffer[2];
                hex_to_int(&ptr, &threadid);
                thread = get_thread(threadid);
                ptr = &in_buffer[2];
                hex_to_int(&ptr, &threadid);
                thread = get_thread(threadid);
@@ -1173,6 +1168,7 @@ static void query_msg(void)
 }
 #endif /* CONFIG_KGDB_THREAD */
 
 }
 #endif /* CONFIG_KGDB_THREAD */
 
+#ifdef CONFIG_SH_KGDB_CONSOLE
 /*
  * Bring up the ports..
  */
 /*
  * Bring up the ports..
  */
@@ -1185,6 +1181,9 @@ static int kgdb_serial_setup(void)
 
        return 0;
 }
 
        return 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)
 
 /* The command loop, read and act on requests */
 static void kgdb_command_loop(const int excep_code, const int trapa_value)
@@ -1193,7 +1192,7 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
 
        if (excep_code == NMI_VEC) {
 #ifndef CONFIG_KGDB_NMI
 
        if (excep_code == NMI_VEC) {
 #ifndef CONFIG_KGDB_NMI
-               KGDB_PRINTK("Ignoring unexpected NMI?\n");
+               printk(KERN_NOTICE "KGDB: Ignoring unexpected NMI?\n");
                return;
 #else /* CONFIG_KGDB_NMI */
                if (!kgdb_enabled) {
                return;
 #else /* CONFIG_KGDB_NMI */
                if (!kgdb_enabled) {
@@ -1216,10 +1215,7 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
        /* Enter GDB mode (e.g. after detach) */
        if (!kgdb_in_gdb_mode) {
                /* Do serial setup, notify user, issue preemptive ack */
        /* Enter GDB mode (e.g. after detach) */
        if (!kgdb_in_gdb_mode) {
                /* Do serial setup, notify user, issue preemptive ack */
-               kgdb_serial_setup();
-               KGDB_PRINTK("Waiting for GDB (on %s%d at %d baud)\n",
-                           (kgdb_porttype ? kgdb_porttype->name : ""),
-                           kgdb_portnum, kgdb_baud);
+               printk(KERN_NOTICE "KGDB: Waiting for GDB\n");
                kgdb_in_gdb_mode = 1;
                put_debug_char('+');
        }
                kgdb_in_gdb_mode = 1;
                put_debug_char('+');
        }
@@ -1233,21 +1229,18 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
           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) */
           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 != (0xff << 2))) {
+       if ((excep_code == TRAP_VEC) && (trapa_value != (0x3c << 2)))
                trap_registers.pc -= 2;
                trap_registers.pc -= 2;
-       }
 
        /* Undo any stepping we may have done */
        undo_single_step();
 
        while (1) {
 
        /* 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]) {
                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 '?':       /* Send which signal we've received */
                        send_signal_msg(sigval);
                        break;
@@ -1323,11 +1316,8 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
 }
 
 /* There has been an exception, most likely a breakpoint. */
 }
 
 /* There has been an exception, most likely a breakpoint. */
-asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
-                                     unsigned long r6, unsigned long r7,
-                                     struct pt_regs __regs)
+static void handle_exception(struct pt_regs *regs)
 {
 {
-       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        int excep_code, vbr_val;
        int count;
        int trapa_value = ctrl_inl(TRA);
        int excep_code, vbr_val;
        int count;
        int trapa_value = ctrl_inl(TRA);
@@ -1355,7 +1345,7 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
        kgdb_trapa_val = trapa_value;
 
        /* Act on the exception */
        kgdb_trapa_val = trapa_value;
 
        /* Act on the exception */
-       kgdb_command_loop(excep_code >> 5, trapa_value);
+       kgdb_command_loop(excep_code, trapa_value);
 
        kgdb_current = NULL;
 
 
        kgdb_current = NULL;
 
@@ -1373,14 +1363,12 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
        asm("ldc %0, vbr": :"r"(vbr_val));
 }
 
        asm("ldc %0, vbr": :"r"(vbr_val));
 }
 
-/* Trigger a breakpoint by function */
-void breakpoint(void)
+asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
+                                     unsigned long r6, unsigned long r7,
+                                     struct pt_regs __regs)
 {
 {
-       if (!kgdb_enabled) {
-               kgdb_enabled = 1;
-               kgdb_init();
-       }
-       BREAKPOINT();
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
+       handle_exception(regs);
 }
 
 /* Initialise the KGDB data structures and serial configuration */
 }
 
 /* Initialise the KGDB data structures and serial configuration */
@@ -1395,24 +1383,16 @@ int kgdb_init(void)
        kgdb_in_gdb_mode = 0;
 
        if (kgdb_serial_setup() != 0) {
        kgdb_in_gdb_mode = 0;
 
        if (kgdb_serial_setup() != 0) {
-               KGDB_PRINTK("serial setup error\n");
+               printk(KERN_NOTICE "KGDB: serial setup error\n");
                return -1;
        }
 
        /* Init ptr to exception handler */
                return -1;
        }
 
        /* Init ptr to exception handler */
-       kgdb_debug_hook = kgdb_handle_exception;
+       kgdb_debug_hook = handle_exception;
        kgdb_bus_err_hook = kgdb_handle_bus_error;
 
        /* Enter kgdb now if requested, or just report init done */
        kgdb_bus_err_hook = kgdb_handle_bus_error;
 
        /* Enter kgdb now if requested, or just report init done */
-       if (kgdb_halt) {
-               kgdb_in_gdb_mode = 1;
-               put_debug_char('+');
-               breakpoint();
-       }
-       else
-       {
-               KGDB_PRINTK("stub is initialized.\n");
-       }
+       printk(KERN_NOTICE "KGDB: stub is initialized.\n");
 
        return 0;
 }
 
        return 0;
 }
@@ -1437,7 +1417,7 @@ static void kgdb_msg_write(const char *s, unsigned count)
 
                /* Calculate how many this time */
                wcount = (count > MAXOUT) ? MAXOUT : count;
 
                /* 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]);
                /* Pack in hex chars */
                for (i = 0; i < wcount; i++)
                        bufptr = pack_hex_byte(bufptr, s[i]);
@@ -1467,3 +1447,25 @@ void kgdb_console_write(struct console *co, const char *s, unsigned count)
        kgdb_msg_write(s, count);
 }
 #endif
        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 98802ab..f964904 100644 (file)
 #include <asm/setup.h>
 #include <asm/clock.h>
 
 #include <asm/setup.h>
 #include <asm/clock.h>
 
-#ifdef CONFIG_SH_KGDB
-#include <asm/kgdb.h>
-static int kgdb_parse_options(char *options);
-#endif
 extern void * __rd_start, * __rd_end;
 extern void * __rd_start, * __rd_end;
+
 /*
  * Machine setup..
  */
 /*
  * Machine setup..
  */
@@ -499,92 +496,3 @@ struct seq_operations cpuinfo_op = {
        .show   = show_cpuinfo,
 };
 #endif /* CONFIG_PROC_FS */
        .show   = show_cpuinfo,
 };
 #endif /* CONFIG_PROC_FS */
-
-#ifdef CONFIG_SH_KGDB
-/*
- * Parse command-line kgdb options.  By default KGDB is enabled,
- * entered on error (or other action) using default serial info.
- * The command-line option can include a serial port specification
- * and an action to override default or configured behavior.
- */
-struct kgdb_sermap kgdb_sci_sermap =
-{ "ttySC", 5, kgdb_sci_setup, NULL };
-
-struct kgdb_sermap *kgdb_serlist = &kgdb_sci_sermap;
-struct kgdb_sermap *kgdb_porttype = &kgdb_sci_sermap;
-
-void kgdb_register_sermap(struct kgdb_sermap *map)
-{
-       struct kgdb_sermap *last;
-
-       for (last = kgdb_serlist; last->next; last = last->next)
-               ;
-       last->next = map;
-       if (!map->namelen) {
-               map->namelen = strlen(map->name);
-       }
-}
-
-static int __init kgdb_parse_options(char *options)
-{
-       char c;
-       int baud;
-
-       /* Check for port spec (or use default) */
-
-       /* Determine port type and instance */
-       if (!memcmp(options, "tty", 3)) {
-               struct kgdb_sermap *map = kgdb_serlist;
-
-               while (map && memcmp(options, map->name, map->namelen))
-                       map = map->next;
-
-               if (!map) {
-                       KGDB_PRINTK("unknown port spec in %s\n", options);
-                       return -1;
-               }
-
-               kgdb_porttype = map;
-               kgdb_serial_setup = map->setup_fn;
-               kgdb_portnum = options[map->namelen] - '0';
-               options += map->namelen + 1;
-
-               options = (*options == ',') ? options+1 : options;
-
-               /* Read optional parameters (baud/parity/bits) */
-               baud = simple_strtoul(options, &options, 10);
-               if (baud != 0) {
-                       kgdb_baud = baud;
-
-                       c = toupper(*options);
-                       if (c == 'E' || c == 'O' || c == 'N') {
-                               kgdb_parity = c;
-                               options++;
-                       }
-
-                       c = *options;
-                       if (c == '7' || c == '8') {
-                               kgdb_bits = c;
-                               options++;
-                       }
-                       options = (*options == ',') ? options+1 : options;
-               }
-       }
-
-       /* Check for action specification */
-       if (!memcmp(options, "halt", 4)) {
-               kgdb_halt = 1;
-               options += 4;
-       } else if (!memcmp(options, "disabled", 8)) {
-               kgdb_enabled = 0;
-               options += 8;
-       }
-
-       if (*options) {
-                KGDB_PRINTK("ignored unknown options: %s\n", options);
-               return 0;
-       }
-       return 1;
-}
-__setup("kgdb=", kgdb_parse_options);
-#endif /* CONFIG_SH_KGDB */
index 46c40bb..4b17f84 100644 (file)
@@ -46,6 +46,7 @@
 #endif
 
 #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
 #endif
 
 #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+#include <linux/ctype.h>
 #include <asm/clock.h>
 #include <asm/sh_bios.h>
 #include <asm/kgdb.h>
 #include <asm/clock.h>
 #include <asm/sh_bios.h>
 #include <asm/kgdb.h>
@@ -163,7 +164,7 @@ static void put_string(struct sci_port *sci_port, const char *buffer, int count)
        usegdb |= sh_bios_in_gdb_mode();
 #endif
 #ifdef CONFIG_SH_KGDB
        usegdb |= sh_bios_in_gdb_mode();
 #endif
 #ifdef CONFIG_SH_KGDB
-       usegdb |= (kgdb_in_gdb_mode && (port == kgdb_sci_port));
+       usegdb |= (kgdb_in_gdb_mode && (sci_port == kgdb_sci_port));
 #endif
 
        if (usegdb) {
 #endif
 
        if (usegdb) {
@@ -204,7 +205,7 @@ static int kgdb_sci_getchar(void)
         int c;
 
         /* Keep trying to read a character, this could be neater */
         int c;
 
         /* Keep trying to read a character, this could be neater */
-        while ((c = get_char(kgdb_sci_port)) < 0)
+        while ((c = get_char(&kgdb_sci_port->port)) < 0)
                cpu_relax();
 
         return c;
                cpu_relax();
 
         return c;
@@ -212,7 +213,7 @@ static int kgdb_sci_getchar(void)
 
 static inline void kgdb_sci_putchar(int c)
 {
 
 static inline void kgdb_sci_putchar(int c)
 {
-        put_char(kgdb_sci_port, c);
+        put_char(&kgdb_sci_port->port, c);
 }
 #endif /* CONFIG_SH_KGDB */
 
 }
 #endif /* CONFIG_SH_KGDB */
 
@@ -738,7 +739,7 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr)
 
 #ifdef CONFIG_SH_KGDB
        /* Break into the debugger if a break is detected */
 
 #ifdef CONFIG_SH_KGDB
        /* Break into the debugger if a break is detected */
-       BREAKPOINT();
+       breakpoint();
 #endif
 
        sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
 #endif
 
        sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
@@ -971,7 +972,6 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 {
        struct sci_port *s = &sci_ports[port->line];
        unsigned int status, baud, smr_val;
 {
        struct sci_port *s = &sci_ports[port->line];
        unsigned int status, baud, smr_val;
-       unsigned long flags;
        int t;
 
        baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
        int t;
 
        baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
@@ -989,12 +989,10 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 #else
                        t = SCBRR_VALUE(baud);
 #endif
 #else
                        t = SCBRR_VALUE(baud);
 #endif
-               }
                        break;
                        break;
+               }
        }
 
        }
 
-       spin_lock_irqsave(&port->lock, flags);
-
        do {
                status = sci_in(port, SCxSR);
        } while (!(status & SCxSR_TEND(port)));
        do {
                status = sci_in(port, SCxSR);
        } while (!(status & SCxSR_TEND(port)));
@@ -1038,8 +1036,6 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 
        if ((termios->c_cflag & CREAD) != 0)
               sci_start_rx(port,0);
 
        if ((termios->c_cflag & CREAD) != 0)
               sci_start_rx(port,0);
-
-       spin_unlock_irqrestore(&port->lock, flags);
 }
 
 static const char *sci_type(struct uart_port *port)
 }
 
 static const char *sci_type(struct uart_port *port)
@@ -1220,8 +1216,6 @@ static int __init serial_console_setup(struct console *co, char *options)
        if (!port->membase || !port->mapbase)
                return -ENODEV;
 
        if (!port->membase || !port->mapbase)
                return -ENODEV;
 
-       spin_lock_init(&port->lock);
-
        port->type = serial_console_port->type;
 
        if (port->flags & UPF_IOREMAP)
        port->type = serial_console_port->type;
 
        if (port->flags & UPF_IOREMAP)
@@ -1247,7 +1241,7 @@ static struct console serial_console = {
        .device         = uart_console_device,
        .write          = serial_console_write,
        .setup          = serial_console_setup,
        .device         = uart_console_device,
        .write          = serial_console_write,
        .setup          = serial_console_setup,
-       .flags          = CON_PRINTBUFFER, 
+       .flags          = CON_PRINTBUFFER,
        .index          = -1,
        .data           = &sci_uart_driver,
 };
        .index          = -1,
        .data           = &sci_uart_driver,
 };
@@ -1292,11 +1286,23 @@ int __init kgdb_console_setup(struct console *co, char *options)
        int parity = 'n';
        int flow = 'n';
 
        int parity = 'n';
        int flow = 'n';
 
-       spin_lock_init(&port->lock);
-
        if (co->index != kgdb_portnum)
                co->index = kgdb_portnum;
 
        if (co->index != kgdb_portnum)
                co->index = kgdb_portnum;
 
+       kgdb_sci_port = &sci_ports[co->index];
+       port = &kgdb_sci_port->port;
+
+       /*
+        * Also need to check port->type, we don't actually have any
+        * UPIO_PORT ports, but uart_report_port() handily misreports
+        * it anyways if we don't have a port available by the time this is
+        * called.
+        */
+       if (!port->type)
+               return -ENODEV;
+       if (!port->membase || !port->mapbase)
+               return -ENODEV;
+
        if (options)
                uart_parse_options(options, &baud, &parity, &bits, &flow);
        else
        if (options)
                uart_parse_options(options, &baud, &parity, &bits, &flow);
        else
@@ -1311,11 +1317,12 @@ int __init kgdb_console_setup(struct console *co, char *options)
 
 #ifdef CONFIG_SH_KGDB_CONSOLE
 static struct console kgdb_console = {
 
 #ifdef CONFIG_SH_KGDB_CONSOLE
 static struct console kgdb_console = {
-        .name          = "ttySC",
-        .write         = kgdb_console_write,
-        .setup         = kgdb_console_setup,
-        .flags         = CON_PRINTBUFFER | CON_ENABLED,
-        .index         = -1,
+       .name           = "ttySC",
+       .device         = uart_console_device,
+       .write          = kgdb_console_write,
+       .setup          = kgdb_console_setup,
+       .flags          = CON_PRINTBUFFER,
+       .index          = -1,
        .data           = &sci_uart_driver,
 };
 
        .data           = &sci_uart_driver,
 };
 
@@ -1386,6 +1393,12 @@ static int __devinit sci_probe(struct platform_device *dev)
                uart_add_one_port(&sci_uart_driver, &sciport->port);
        }
 
                uart_add_one_port(&sci_uart_driver, &sciport->port);
        }
 
+#if defined(CONFIG_SH_KGDB) && !defined(CONFIG_SH_KGDB_CONSOLE)
+       kgdb_sci_port   = &sci_ports[kgdb_portnum];
+       kgdb_getchar    = kgdb_sci_getchar;
+       kgdb_putchar    = kgdb_sci_putchar;
+#endif
+
 #ifdef CONFIG_CPU_FREQ
        cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER);
        dev_info(&dev->dev, "sci: CPU frequency notifier registered\n");
 #ifdef CONFIG_CPU_FREQ
        cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER);
        dev_info(&dev->dev, "sci: CPU frequency notifier registered\n");
index 0095c66..74bd095 100644 (file)
@@ -17,6 +17,7 @@
 #define __KGDB_H
 
 #include <asm/ptrace.h>
 #define __KGDB_H
 
 #include <asm/ptrace.h>
+#include <asm/cacheflush.h>
 
 struct console;
 
 
 struct console;
 
@@ -45,35 +46,21 @@ extern int kgdb_portnum;
 extern int kgdb_baud;
 extern char kgdb_parity;
 extern char kgdb_bits;
 extern int kgdb_baud;
 extern char kgdb_parity;
 extern char kgdb_bits;
-extern int kgdb_console_setup(struct console *, char *);
 
 /* Init and interface stuff */
 extern int kgdb_init(void);
 
 /* Init and interface stuff */
 extern int kgdb_init(void);
-extern int (*kgdb_serial_setup)(void);
 extern int (*kgdb_getchar)(void);
 extern void (*kgdb_putchar)(int);
 
 extern int (*kgdb_getchar)(void);
 extern void (*kgdb_putchar)(int);
 
-struct kgdb_sermap {
-       char *name;
-       int namelen;
-       int (*setup_fn)(struct console *, char *);
-       struct kgdb_sermap *next;
-};
-extern void kgdb_register_sermap(struct kgdb_sermap *map);
-extern struct kgdb_sermap *kgdb_porttype;
-
 /* Trap functions */
 /* Trap functions */
-typedef void (kgdb_debug_hook_t)(struct pt_regs *regs); 
+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;
 
 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;
 
-extern void breakpoint(void);
-
 /* Console */
 /* Console */
-struct console;
 void kgdb_console_write(struct console *co, const char *s, unsigned count);
 void kgdb_console_write(struct console *co, const char *s, unsigned count);
-void kgdb_console_init(void);
+extern int kgdb_console_setup(struct console *, char *);
 
 /* Prototypes for jmp fns */
 #define _JBLEN 9
 
 /* Prototypes for jmp fns */
 #define _JBLEN 9
@@ -81,11 +68,8 @@ typedef        int jmp_buf[_JBLEN];
 extern void    longjmp(jmp_buf __jmpb, int __retval);
 extern int     setjmp(jmp_buf __jmpb);
 
 extern void    longjmp(jmp_buf __jmpb, int __retval);
 extern int     setjmp(jmp_buf __jmpb);
 
-/* Variadic macro to print our own message to the console */
-#define KGDB_PRINTK(...) printk("KGDB: " __VA_ARGS__)
-
 /* Forced breakpoint */
 /* Forced breakpoint */
-#define BREAKPOINT()                                   \
+#define breakpoint()                                   \
 do {                                                   \
        if (kgdb_enabled)                               \
                __asm__ __volatile__("trapa   #0x3c");  \
 do {                                                   \
        if (kgdb_enabled)                               \
                __asm__ __volatile__("trapa   #0x3c");  \
@@ -95,7 +79,6 @@ do {                                                  \
 #if defined(CONFIG_CPU_SH4)
 #define kgdb_flush_icache_range(start, end) \
 {                                                                      \
 #if defined(CONFIG_CPU_SH4)
 #define kgdb_flush_icache_range(start, end) \
 {                                                                      \
-       extern void __flush_purge_region(void *, int);                  \
        __flush_purge_region((void*)(start), (int)(end) - (int)(start));\
        flush_icache_range((start), (end));                             \
 }
        __flush_purge_region((void*)(start), (int)(end) - (int)(start));\
        flush_icache_range((start), (end));                             \
 }
@@ -103,31 +86,6 @@ do {                                                        \
 #define kgdb_flush_icache_range(start, end)    do { } while (0)
 #endif
 
 #define kgdb_flush_icache_range(start, end)    do { } while (0)
 #endif
 
-/* Kernel assert macros */
-#ifdef CONFIG_KGDB_KERNEL_ASSERTS
-
-/* Predefined conditions */
-#define KA_VALID_ERRNO(errno) ((errno) > 0 && (errno) <= EMEDIUMTYPE)
-#define KA_VALID_PTR_ERR(ptr) KA_VALID_ERRNO(-PTR_ERR(ptr))
-#define KA_VALID_KPTR(ptr)  (!(ptr) || \
-              ((void *)(ptr) >= (void *)PAGE_OFFSET &&  \
-               (void *)(ptr) < ERR_PTR(-EMEDIUMTYPE)))
-#define KA_VALID_PTRORERR(errptr) \
-               (KA_VALID_KPTR(errptr) || KA_VALID_PTR_ERR(errptr))
-#define KA_HELD_GKL()  (current->lock_depth >= 0)
-
-/* The actual assert */
-#define KGDB_ASSERT(condition, message) do {                   \
-       if (!(condition) && (kgdb_enabled)) {                   \
-               KGDB_PRINTK("Assertion failed at %s:%d: %s\n",  \
-                                  __FILE__, __LINE__, message);\
-               BREAKPOINT();                                   \
-       }                                                       \
-} while (0)
-#else
-#define KGDB_ASSERT(condition, message)
-#endif
-
 /* Taken from sh-stub.c of GDB 4.18 */
 static const char hexchars[] = "0123456789abcdef";
 
 /* Taken from sh-stub.c of GDB 4.18 */
 static const char hexchars[] = "0123456789abcdef";
 
@@ -142,5 +100,4 @@ static inline char lowhex(const int x)
 {
        return hexchars[x & 0xf];
 }
 {
        return hexchars[x & 0xf];
 }
-
 #endif
 #endif
index 88cd379..02ca934 100644 (file)
@@ -65,6 +65,8 @@
 
 #define IRQ_79C973     13
 
 
 #define IRQ_79C973     13
 
+void init_7751se_IRQ(void);
+
 #define __IO_PREFIX    sh7751se
 #include <asm/io_generic.h>
 
 #define __IO_PREFIX    sh7751se
 #include <asm/io_generic.h>