aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2007-03-08 03:27:37 -0500
committerPaul Mundt <lethal@hera.kernel.org>2007-05-06 22:10:51 -0400
commitfa5da2f7bdcf885efe65a37df13907c7d72296f6 (patch)
tree54104d5f660a1ec824505b28540eb2c5e4be390a /arch/sh
parent15700770ef7c5d12e2f1659d2ddbeb3f658d9f37 (diff)
sh: Bring kgdb back from the dead.
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>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/Kconfig.debug15
-rw-r--r--arch/sh/Makefile1
-rw-r--r--arch/sh/boards/se/7751/setup.c148
-rw-r--r--arch/sh/kernel/kgdb_stub.c106
-rw-r--r--arch/sh/kernel/setup.c94
5 files changed, 62 insertions, 302 deletions
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index 87902e0298e2..6be2385c1ad2 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -77,16 +77,17 @@ config 4KSTACKS
77 on the VM subsystem for higher order allocations. This option 77 on the VM subsystem for higher order allocations. This option
78 will also use IRQ stacks to compensate for the reduced stackspace. 78 will also use IRQ stacks to compensate for the reduced stackspace.
79 79
80config KGDB 80config SH_KGDB
81 bool "Include KGDB kernel debugger" 81 bool "Include KGDB kernel debugger"
82 select FRAME_POINTER 82 select FRAME_POINTER
83 select DEBUG_INFO
83 help 84 help
84 Include in-kernel hooks for kgdb, the Linux kernel source level 85 Include in-kernel hooks for kgdb, the Linux kernel source level
85 debugger. See <http://kgdb.sourceforge.net/> for more information. 86 debugger. See <http://kgdb.sourceforge.net/> for more information.
86 Unless you are intending to debug the kernel, say N here. 87 Unless you are intending to debug the kernel, say N here.
87 88
88menu "KGDB configuration options" 89menu "KGDB configuration options"
89 depends on KGDB 90 depends on SH_KGDB
90 91
91config MORE_COMPILE_OPTIONS 92config MORE_COMPILE_OPTIONS
92 bool "Add any additional compile options" 93 bool "Add any additional compile options"
@@ -109,16 +110,14 @@ config KGDB_THREAD
109 110
110config SH_KGDB_CONSOLE 111config SH_KGDB_CONSOLE
111 bool "Console messages through GDB" 112 bool "Console messages through GDB"
113 depends on !SERIAL_SH_SCI_CONSOLE
114 select SERIAL_CORE_CONSOLE
112 default n 115 default n
113 116
114config KGDB_SYSRQ 117config KGDB_SYSRQ
115 bool "Allow SysRq 'G' to enter KGDB" 118 bool "Allow SysRq 'G' to enter KGDB"
116 default y 119 default y
117 120
118config KGDB_KERNEL_ASSERTS
119 bool "Include KGDB kernel assertions"
120 default n
121
122comment "Serial port setup" 121comment "Serial port setup"
123 122
124config KGDB_DEFPORT 123config KGDB_DEFPORT
@@ -131,7 +130,7 @@ config KGDB_DEFBAUD
131 130
132choice 131choice
133 prompt "Parity" 132 prompt "Parity"
134 depends on KGDB 133 depends on SH_KGDB
135 default KGDB_DEFPARITY_N 134 default KGDB_DEFPARITY_N
136 135
137config KGDB_DEFPARITY_N 136config KGDB_DEFPARITY_N
@@ -147,7 +146,7 @@ endchoice
147 146
148choice 147choice
149 prompt "Data bits" 148 prompt "Data bits"
150 depends on KGDB 149 depends on SH_KGDB
151 default KGDB_DEFBITS_8 150 default KGDB_DEFBITS_8
152 151
153config KGDB_DEFBITS_8 152config KGDB_DEFBITS_8
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index bd9b1729f8b8..0fadde283368 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -47,7 +47,6 @@ cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml
47cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding 47cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding
48 48
49cflags-$(CONFIG_SH_DSP) += -Wa,-dsp 49cflags-$(CONFIG_SH_DSP) += -Wa,-dsp
50cflags-$(CONFIG_SH_KGDB) += -g
51 50
52cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \ 51cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \
53 $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g') 52 $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g')
diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c
index e3feae6ec0bf..770defed9c4a 100644
--- a/arch/sh/boards/se/7751/setup.c
+++ b/arch/sh/boards/se/7751/setup.c
@@ -14,153 +14,6 @@
14#include <asm/se7751.h> 14#include <asm/se7751.h>
15#include <asm/io.h> 15#include <asm/io.h>
16 16
17void init_7751se_IRQ(void);
18
19#ifdef CONFIG_SH_KGDB
20#include <asm/kgdb.h>
21static int kgdb_uart_setup(void);
22static struct kgdb_sermap kgdb_uart_sermap =
23{ "ttyS", 0, kgdb_uart_setup, NULL };
24#endif
25
26/*
27 * Initialize the board
28 */
29static void __init sh7751se_setup(char **cmdline_p)
30{
31 /* Call init_smsc() replacement to set up SuperIO. */
32 /* XXX: RTC setting comes here */
33#ifdef CONFIG_SH_KGDB
34 kgdb_register_sermap(&kgdb_uart_sermap);
35#endif
36}
37
38/*********************************************************************
39 * Currently a hack (e.g. does not interact well w/serial.c, lots of *
40 * hardcoded stuff) but may be useful if SCI/F needs debugging. *
41 * Mostly copied from x86 code (see files asm-i386/kgdb_local.h and *
42 * arch/i386/lib/kgdb_serial.c). *
43 *********************************************************************/
44
45#ifdef CONFIG_SH_KGDB
46#include <linux/types.h>
47#include <linux/serial.h>
48#include <linux/serialP.h>
49#include <linux/serial_reg.h>
50
51#define COM1_PORT 0x3f8 /* Base I/O address */
52#define COM1_IRQ 4 /* IRQ not used yet */
53#define COM2_PORT 0x2f8 /* Base I/O address */
54#define COM2_IRQ 3 /* IRQ not used yet */
55
56#define SB_CLOCK 1843200 /* Serial baud clock */
57#define SB_BASE (SB_CLOCK/16)
58#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS
59
60struct uart_port {
61 int base;
62};
63#define UART_NPORTS 2
64struct uart_port uart_ports[] = {
65 { COM1_PORT },
66 { COM2_PORT },
67};
68struct uart_port *kgdb_uart_port;
69
70#define UART_IN(reg) inb_p(kgdb_uart_port->base + reg)
71#define UART_OUT(reg,v) outb_p((v), kgdb_uart_port->base + reg)
72
73/* Basic read/write functions for the UART */
74#define UART_LSR_RXCERR (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE)
75static int kgdb_uart_getchar(void)
76{
77 int lsr;
78 int c = -1;
79
80 while (c == -1) {
81 lsr = UART_IN(UART_LSR);
82 if (lsr & UART_LSR_DR)
83 c = UART_IN(UART_RX);
84 if ((lsr & UART_LSR_RXCERR))
85 c = -1;
86 }
87 return c;
88}
89
90static void kgdb_uart_putchar(int c)
91{
92 while ((UART_IN(UART_LSR) & UART_LSR_THRE) == 0)
93 ;
94 UART_OUT(UART_TX, c);
95}
96
97/*
98 * Initialize UART to configured/requested values.
99 * (But we don't interrupts yet, or interact w/serial.c)
100 */
101static int kgdb_uart_setup(void)
102{
103 int port;
104 int lcr = 0;
105 int bdiv = 0;
106
107 if (kgdb_portnum >= UART_NPORTS) {
108 KGDB_PRINTK("uart port %d invalid.\n", kgdb_portnum);
109 return -1;
110 }
111
112 kgdb_uart_port = &uart_ports[kgdb_portnum];
113
114 /* Init sequence from gdb_hook_interrupt */
115 UART_IN(UART_RX);
116 UART_OUT(UART_IER, 0);
117
118 UART_IN(UART_RX); /* Serial driver comments say */
119 UART_IN(UART_IIR); /* this clears interrupt regs */
120 UART_IN(UART_MSR);
121
122 /* Figure basic LCR values */
123 switch (kgdb_bits) {
124 case '7':
125 lcr |= UART_LCR_WLEN7;
126 break;
127 default: case '8':
128 lcr |= UART_LCR_WLEN8;
129 break;
130 }
131 switch (kgdb_parity) {
132 case 'O':
133 lcr |= UART_LCR_PARITY;
134 break;
135 case 'E':
136 lcr |= (UART_LCR_PARITY | UART_LCR_EPAR);
137 break;
138 default: break;
139 }
140
141 /* Figure the baud rate divisor */
142 bdiv = (SB_BASE/kgdb_baud);
143
144 /* Set the baud rate and LCR values */
145 UART_OUT(UART_LCR, (lcr | UART_LCR_DLAB));
146 UART_OUT(UART_DLL, (bdiv & 0xff));
147 UART_OUT(UART_DLM, ((bdiv >> 8) & 0xff));
148 UART_OUT(UART_LCR, lcr);
149
150 /* Set the MCR */
151 UART_OUT(UART_MCR, SB_MCR);
152
153 /* Turn off FIFOs for now */
154 UART_OUT(UART_FCR, 0);
155
156 /* Setup complete: initialize function pointers */
157 kgdb_getchar = kgdb_uart_getchar;
158 kgdb_putchar = kgdb_uart_putchar;
159
160 return 0;
161}
162#endif /* CONFIG_SH_KGDB */
163
164static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; 17static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
165 18
166static struct resource heartbeat_resources[] = { 19static struct resource heartbeat_resources[] = {
@@ -197,7 +50,6 @@ __initcall(se7751_devices_setup);
197 */ 50 */
198struct sh_machine_vector mv_7751se __initmv = { 51struct sh_machine_vector mv_7751se __initmv = {
199 .mv_name = "7751 SolutionEngine", 52 .mv_name = "7751 SolutionEngine",
200 .mv_setup = sh7751se_setup,
201 .mv_nr_irqs = 72, 53 .mv_nr_irqs = 72,
202 54
203 .mv_inb = sh7751se_inb, 55 .mv_inb = sh7751se_inb,
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
index d8927d85492e..737eadc8ce0f 100644
--- a/arch/sh/kernel/kgdb_stub.c
+++ b/arch/sh/kernel/kgdb_stub.c
@@ -6,11 +6,11 @@
6 * David Grothe <dave@gcom.com>, Tigran Aivazian <tigran@sco.com>, 6 * David Grothe <dave@gcom.com>, Tigran Aivazian <tigran@sco.com>,
7 * Amit S. Kale <akale@veritas.com>, William Gatliff <bgat@open-widgets.com>, 7 * Amit S. Kale <akale@veritas.com>, William Gatliff <bgat@open-widgets.com>,
8 * Ben Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com>. 8 * Ben Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com>.
9 * 9 *
10 * This version by Henry Bell <henry.bell@st.com> 10 * This version by Henry Bell <henry.bell@st.com>
11 * Minor modifications by Jeremy Siegel <jsiegel@mvista.com> 11 * Minor modifications by Jeremy Siegel <jsiegel@mvista.com>
12 * 12 *
13 * Contains low-level support for remote debug using GDB. 13 * Contains low-level support for remote debug using GDB.
14 * 14 *
15 * To enable debugger support, two things need to happen. A call to 15 * To enable debugger support, two things need to happen. A call to
16 * set_debug_traps() is necessary in order to allow any breakpoints 16 * set_debug_traps() is necessary in order to allow any breakpoints
@@ -48,7 +48,7 @@
48 * k kill (Detach GDB) 48 * k kill (Detach GDB)
49 * 49 *
50 * d Toggle debug flag 50 * d Toggle debug flag
51 * D Detach GDB 51 * D Detach GDB
52 * 52 *
53 * Hct Set thread t for operations, OK or ENN 53 * Hct Set thread t for operations, OK or ENN
54 * c = 'c' (step, cont), c = 'g' (other 54 * c = 'c' (step, cont), c = 'g' (other
@@ -58,7 +58,7 @@
58 * qfThreadInfo Get list of current threads (first) m<id> 58 * qfThreadInfo Get list of current threads (first) m<id>
59 * qsThreadInfo " " " " " (subsequent) 59 * qsThreadInfo " " " " " (subsequent)
60 * qOffsets Get section offsets Text=x;Data=y;Bss=z 60 * qOffsets Get section offsets Text=x;Data=y;Bss=z
61 * 61 *
62 * TXX Find if thread XX is alive OK or ENN 62 * TXX Find if thread XX is alive OK or ENN
63 * ? What was the last sigval ? SNN (signal NN) 63 * ? What was the last sigval ? SNN (signal NN)
64 * O Output to GDB console 64 * O Output to GDB console
@@ -74,7 +74,7 @@
74 * '$' or '#'. If <data> starts with two characters followed by 74 * '$' or '#'. If <data> starts with two characters followed by
75 * ':', then the existing stubs interpret this as a sequence number. 75 * ':', then the existing stubs interpret this as a sequence number.
76 * 76 *
77 * CSUM1 and CSUM2 are ascii hex representation of an 8-bit 77 * CSUM1 and CSUM2 are ascii hex representation of an 8-bit
78 * checksum of <data>, the most significant nibble is sent first. 78 * checksum of <data>, the most significant nibble is sent first.
79 * the hex digits 0-9,a-f are used. 79 * the hex digits 0-9,a-f are used.
80 * 80 *
@@ -86,8 +86,8 @@
86 * Responses can be run-length encoded to save space. A '*' means that 86 * Responses can be run-length encoded to save space. A '*' means that
87 * the next character is an ASCII encoding giving a repeat count which 87 * the next character is an ASCII encoding giving a repeat count which
88 * stands for that many repititions of the character preceding the '*'. 88 * stands for that many repititions of the character preceding the '*'.
89 * The encoding is n+29, yielding a printable character where n >=3 89 * The encoding is n+29, yielding a printable character where n >=3
90 * (which is where RLE starts to win). Don't use an n > 126. 90 * (which is where RLE starts to win). Don't use an n > 126.
91 * 91 *
92 * So "0* " means the same as "0000". 92 * So "0* " means the same as "0000".
93 */ 93 */
@@ -100,12 +100,10 @@
100#include <linux/delay.h> 100#include <linux/delay.h>
101#include <linux/linkage.h> 101#include <linux/linkage.h>
102#include <linux/init.h> 102#include <linux/init.h>
103
104#ifdef CONFIG_SH_KGDB_CONSOLE
105#include <linux/console.h> 103#include <linux/console.h>
106#endif 104#include <linux/sysrq.h>
107
108#include <asm/system.h> 105#include <asm/system.h>
106#include <asm/cacheflush.h>
109#include <asm/current.h> 107#include <asm/current.h>
110#include <asm/signal.h> 108#include <asm/signal.h>
111#include <asm/pgtable.h> 109#include <asm/pgtable.h>
@@ -153,7 +151,6 @@ char kgdb_in_gdb_mode;
153char in_nmi; /* Set during NMI to prevent reentry */ 151char in_nmi; /* Set during NMI to prevent reentry */
154int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */ 152int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */
155int kgdb_enabled = 1; /* Default to enabled, cmdline can disable */ 153int kgdb_enabled = 1; /* Default to enabled, cmdline can disable */
156int kgdb_halt;
157 154
158/* Exposed for user access */ 155/* Exposed for user access */
159struct task_struct *kgdb_current; 156struct task_struct *kgdb_current;
@@ -328,7 +325,7 @@ static int hex_to_int(char **ptr, int *int_value)
328} 325}
329 326
330/* Copy the binary array pointed to by buf into mem. Fix $, #, 327/* Copy the binary array pointed to by buf into mem. Fix $, #,
331 and 0x7d escaped with 0x7d. Return a pointer to the character 328 and 0x7d escaped with 0x7d. Return a pointer to the character
332 after the last byte written. */ 329 after the last byte written. */
333static char *ebin_to_mem(const char *buf, char *mem, int count) 330static char *ebin_to_mem(const char *buf, char *mem, int count)
334{ 331{
@@ -452,7 +449,7 @@ static void get_packet(char *buffer, int buflen)
452 /* Ack successful transfer */ 449 /* Ack successful transfer */
453 put_debug_char('+'); 450 put_debug_char('+');
454 451
455 /* If a sequence char is present, reply 452 /* If a sequence char is present, reply
456 the sequence ID */ 453 the sequence ID */
457 if (buffer[2] == ':') { 454 if (buffer[2] == ':') {
458 put_debug_char(buffer[0]); 455 put_debug_char(buffer[0]);
@@ -759,7 +756,7 @@ static short *get_step_address(void)
759 return (short *) addr; 756 return (short *) addr;
760} 757}
761 758
762/* Set up a single-step. Replace the instruction immediately after the 759/* Set up a single-step. Replace the instruction immediately after the
763 current instruction (i.e. next in the expected flow of control) with a 760 current instruction (i.e. next in the expected flow of control) with a
764 trap instruction, so that returning will cause only a single instruction 761 trap instruction, so that returning will cause only a single instruction
765 to be executed. Note that this model is slightly broken for instructions 762 to be executed. Note that this model is slightly broken for instructions
@@ -1002,10 +999,8 @@ void set_thread_msg(void)
1002 char *ptr; 999 char *ptr;
1003 1000
1004 switch (in_buffer[1]) { 1001 switch (in_buffer[1]) {
1005 1002 /* To select which thread for gG etc messages, i.e. supported */
1006 /* To select which thread for gG etc messages, i.e. supported */
1007 case 'g': 1003 case 'g':
1008
1009 ptr = &in_buffer[2]; 1004 ptr = &in_buffer[2];
1010 hex_to_int(&ptr, &threadid); 1005 hex_to_int(&ptr, &threadid);
1011 thread = get_thread(threadid); 1006 thread = get_thread(threadid);
@@ -1173,6 +1168,7 @@ static void query_msg(void)
1173} 1168}
1174#endif /* CONFIG_KGDB_THREAD */ 1169#endif /* CONFIG_KGDB_THREAD */
1175 1170
1171#ifdef CONFIG_SH_KGDB_CONSOLE
1176/* 1172/*
1177 * Bring up the ports.. 1173 * Bring up the ports..
1178 */ 1174 */
@@ -1185,6 +1181,9 @@ static int kgdb_serial_setup(void)
1185 1181
1186 return 0; 1182 return 0;
1187} 1183}
1184#else
1185#define kgdb_serial_setup() 0
1186#endif
1188 1187
1189/* The command loop, read and act on requests */ 1188/* The command loop, read and act on requests */
1190static void kgdb_command_loop(const int excep_code, const int trapa_value) 1189static 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)
1193 1192
1194 if (excep_code == NMI_VEC) { 1193 if (excep_code == NMI_VEC) {
1195#ifndef CONFIG_KGDB_NMI 1194#ifndef CONFIG_KGDB_NMI
1196 KGDB_PRINTK("Ignoring unexpected NMI?\n"); 1195 printk(KERN_NOTICE "KGDB: Ignoring unexpected NMI?\n");
1197 return; 1196 return;
1198#else /* CONFIG_KGDB_NMI */ 1197#else /* CONFIG_KGDB_NMI */
1199 if (!kgdb_enabled) { 1198 if (!kgdb_enabled) {
@@ -1216,10 +1215,7 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
1216 /* Enter GDB mode (e.g. after detach) */ 1215 /* Enter GDB mode (e.g. after detach) */
1217 if (!kgdb_in_gdb_mode) { 1216 if (!kgdb_in_gdb_mode) {
1218 /* Do serial setup, notify user, issue preemptive ack */ 1217 /* Do serial setup, notify user, issue preemptive ack */
1219 kgdb_serial_setup(); 1218 printk(KERN_NOTICE "KGDB: Waiting for GDB\n");
1220 KGDB_PRINTK("Waiting for GDB (on %s%d at %d baud)\n",
1221 (kgdb_porttype ? kgdb_porttype->name : ""),
1222 kgdb_portnum, kgdb_baud);
1223 kgdb_in_gdb_mode = 1; 1219 kgdb_in_gdb_mode = 1;
1224 put_debug_char('+'); 1220 put_debug_char('+');
1225 } 1221 }
@@ -1233,21 +1229,18 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
1233 will later be replaced by its original one. Do NOT do this for 1229 will later be replaced by its original one. Do NOT do this for
1234 trap 0xff, since that indicates a compiled-in breakpoint which 1230 trap 0xff, since that indicates a compiled-in breakpoint which
1235 will not be replaced (and we would retake the trap forever) */ 1231 will not be replaced (and we would retake the trap forever) */
1236 if ((excep_code == TRAP_VEC) && (trapa_value != (0xff << 2))) { 1232 if ((excep_code == TRAP_VEC) && (trapa_value != (0x3c << 2)))
1237 trap_registers.pc -= 2; 1233 trap_registers.pc -= 2;
1238 }
1239 1234
1240 /* Undo any stepping we may have done */ 1235 /* Undo any stepping we may have done */
1241 undo_single_step(); 1236 undo_single_step();
1242 1237
1243 while (1) { 1238 while (1) {
1244
1245 out_buffer[0] = 0; 1239 out_buffer[0] = 0;
1246 get_packet(in_buffer, BUFMAX); 1240 get_packet(in_buffer, BUFMAX);
1247 1241
1248 /* Examine first char of buffer to see what we need to do */ 1242 /* Examine first char of buffer to see what we need to do */
1249 switch (in_buffer[0]) { 1243 switch (in_buffer[0]) {
1250
1251 case '?': /* Send which signal we've received */ 1244 case '?': /* Send which signal we've received */
1252 send_signal_msg(sigval); 1245 send_signal_msg(sigval);
1253 break; 1246 break;
@@ -1323,11 +1316,8 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
1323} 1316}
1324 1317
1325/* There has been an exception, most likely a breakpoint. */ 1318/* There has been an exception, most likely a breakpoint. */
1326asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5, 1319static void handle_exception(struct pt_regs *regs)
1327 unsigned long r6, unsigned long r7,
1328 struct pt_regs __regs)
1329{ 1320{
1330 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
1331 int excep_code, vbr_val; 1321 int excep_code, vbr_val;
1332 int count; 1322 int count;
1333 int trapa_value = ctrl_inl(TRA); 1323 int trapa_value = ctrl_inl(TRA);
@@ -1355,7 +1345,7 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
1355 kgdb_trapa_val = trapa_value; 1345 kgdb_trapa_val = trapa_value;
1356 1346
1357 /* Act on the exception */ 1347 /* Act on the exception */
1358 kgdb_command_loop(excep_code >> 5, trapa_value); 1348 kgdb_command_loop(excep_code, trapa_value);
1359 1349
1360 kgdb_current = NULL; 1350 kgdb_current = NULL;
1361 1351
@@ -1373,14 +1363,12 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
1373 asm("ldc %0, vbr": :"r"(vbr_val)); 1363 asm("ldc %0, vbr": :"r"(vbr_val));
1374} 1364}
1375 1365
1376/* Trigger a breakpoint by function */ 1366asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
1377void breakpoint(void) 1367 unsigned long r6, unsigned long r7,
1368 struct pt_regs __regs)
1378{ 1369{
1379 if (!kgdb_enabled) { 1370 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
1380 kgdb_enabled = 1; 1371 handle_exception(regs);
1381 kgdb_init();
1382 }
1383 BREAKPOINT();
1384} 1372}
1385 1373
1386/* Initialise the KGDB data structures and serial configuration */ 1374/* Initialise the KGDB data structures and serial configuration */
@@ -1395,24 +1383,16 @@ int kgdb_init(void)
1395 kgdb_in_gdb_mode = 0; 1383 kgdb_in_gdb_mode = 0;
1396 1384
1397 if (kgdb_serial_setup() != 0) { 1385 if (kgdb_serial_setup() != 0) {
1398 KGDB_PRINTK("serial setup error\n"); 1386 printk(KERN_NOTICE "KGDB: serial setup error\n");
1399 return -1; 1387 return -1;
1400 } 1388 }
1401 1389
1402 /* Init ptr to exception handler */ 1390 /* Init ptr to exception handler */
1403 kgdb_debug_hook = kgdb_handle_exception; 1391 kgdb_debug_hook = handle_exception;
1404 kgdb_bus_err_hook = kgdb_handle_bus_error; 1392 kgdb_bus_err_hook = kgdb_handle_bus_error;
1405 1393
1406 /* Enter kgdb now if requested, or just report init done */ 1394 /* Enter kgdb now if requested, or just report init done */
1407 if (kgdb_halt) { 1395 printk(KERN_NOTICE "KGDB: stub is initialized.\n");
1408 kgdb_in_gdb_mode = 1;
1409 put_debug_char('+');
1410 breakpoint();
1411 }
1412 else
1413 {
1414 KGDB_PRINTK("stub is initialized.\n");
1415 }
1416 1396
1417 return 0; 1397 return 0;
1418} 1398}
@@ -1437,7 +1417,7 @@ static void kgdb_msg_write(const char *s, unsigned count)
1437 1417
1438 /* Calculate how many this time */ 1418 /* Calculate how many this time */
1439 wcount = (count > MAXOUT) ? MAXOUT : count; 1419 wcount = (count > MAXOUT) ? MAXOUT : count;
1440 1420
1441 /* Pack in hex chars */ 1421 /* Pack in hex chars */
1442 for (i = 0; i < wcount; i++) 1422 for (i = 0; i < wcount; i++)
1443 bufptr = pack_hex_byte(bufptr, s[i]); 1423 bufptr = pack_hex_byte(bufptr, s[i]);
@@ -1467,3 +1447,25 @@ void kgdb_console_write(struct console *co, const char *s, unsigned count)
1467 kgdb_msg_write(s, count); 1447 kgdb_msg_write(s, count);
1468} 1448}
1469#endif 1449#endif
1450
1451#ifdef CONFIG_KGDB_SYSRQ
1452static void sysrq_handle_gdb(int key, struct tty_struct *tty)
1453{
1454 printk("Entering GDB stub\n");
1455 breakpoint();
1456}
1457
1458static struct sysrq_key_op sysrq_gdb_op = {
1459 .handler = sysrq_handle_gdb,
1460 .help_msg = "Gdb",
1461 .action_msg = "GDB",
1462};
1463
1464static int gdb_register_sysrq(void)
1465{
1466 printk("Registering GDB sysrq handler\n");
1467 register_sysrq_key('g', &sysrq_gdb_op);
1468 return 0;
1469}
1470module_init(gdb_register_sysrq);
1471#endif
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 98802ab28211..f96490419768 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -25,11 +25,8 @@
25#include <asm/setup.h> 25#include <asm/setup.h>
26#include <asm/clock.h> 26#include <asm/clock.h>
27 27
28#ifdef CONFIG_SH_KGDB
29#include <asm/kgdb.h>
30static int kgdb_parse_options(char *options);
31#endif
32extern void * __rd_start, * __rd_end; 28extern void * __rd_start, * __rd_end;
29
33/* 30/*
34 * Machine setup.. 31 * Machine setup..
35 */ 32 */
@@ -499,92 +496,3 @@ struct seq_operations cpuinfo_op = {
499 .show = show_cpuinfo, 496 .show = show_cpuinfo,
500}; 497};
501#endif /* CONFIG_PROC_FS */ 498#endif /* CONFIG_PROC_FS */
502
503#ifdef CONFIG_SH_KGDB
504/*
505 * Parse command-line kgdb options. By default KGDB is enabled,
506 * entered on error (or other action) using default serial info.
507 * The command-line option can include a serial port specification
508 * and an action to override default or configured behavior.
509 */
510struct kgdb_sermap kgdb_sci_sermap =
511{ "ttySC", 5, kgdb_sci_setup, NULL };
512
513struct kgdb_sermap *kgdb_serlist = &kgdb_sci_sermap;
514struct kgdb_sermap *kgdb_porttype = &kgdb_sci_sermap;
515
516void kgdb_register_sermap(struct kgdb_sermap *map)
517{
518 struct kgdb_sermap *last;
519
520 for (last = kgdb_serlist; last->next; last = last->next)
521 ;
522 last->next = map;
523 if (!map->namelen) {
524 map->namelen = strlen(map->name);
525 }
526}
527
528static int __init kgdb_parse_options(char *options)
529{
530 char c;
531 int baud;
532
533 /* Check for port spec (or use default) */
534
535 /* Determine port type and instance */
536 if (!memcmp(options, "tty", 3)) {
537 struct kgdb_sermap *map = kgdb_serlist;
538
539 while (map && memcmp(options, map->name, map->namelen))
540 map = map->next;
541
542 if (!map) {
543 KGDB_PRINTK("unknown port spec in %s\n", options);
544 return -1;
545 }
546
547 kgdb_porttype = map;
548 kgdb_serial_setup = map->setup_fn;
549 kgdb_portnum = options[map->namelen] - '0';
550 options += map->namelen + 1;
551
552 options = (*options == ',') ? options+1 : options;
553
554 /* Read optional parameters (baud/parity/bits) */
555 baud = simple_strtoul(options, &options, 10);
556 if (baud != 0) {
557 kgdb_baud = baud;
558
559 c = toupper(*options);
560 if (c == 'E' || c == 'O' || c == 'N') {
561 kgdb_parity = c;
562 options++;
563 }
564
565 c = *options;
566 if (c == '7' || c == '8') {
567 kgdb_bits = c;
568 options++;
569 }
570 options = (*options == ',') ? options+1 : options;
571 }
572 }
573
574 /* Check for action specification */
575 if (!memcmp(options, "halt", 4)) {
576 kgdb_halt = 1;
577 options += 4;
578 } else if (!memcmp(options, "disabled", 8)) {
579 kgdb_enabled = 0;
580 options += 8;
581 }
582
583 if (*options) {
584 KGDB_PRINTK("ignored unknown options: %s\n", options);
585 return 0;
586 }
587 return 1;
588}
589__setup("kgdb=", kgdb_parse_options);
590#endif /* CONFIG_SH_KGDB */