aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/kgdb_stub.c
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/kernel/kgdb_stub.c
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/kernel/kgdb_stub.c')
-rw-r--r--arch/sh/kernel/kgdb_stub.c106
1 files changed, 54 insertions, 52 deletions
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