diff options
author | Jason Wessel <jason.wessel@windriver.com> | 2008-07-29 16:58:52 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-07-30 16:54:42 -0400 |
commit | 8d60a903d986ffa26c41f0092320a3b9da20bfaf (patch) | |
tree | f05a8ae48e275d55fcfd3acfb7b3b1b601da56ea /arch/mips/kernel/gdb-stub.c | |
parent | 8f8da9adebdf04bfb3b812a7de8706fbf179fd2c (diff) |
[MIPS] kgdb: Remove existing implementation
This patch explicitly removes the kgdb implementation, for mips which
is intended to be followed by a patch that adds a kgdb implementation
for MIPS that makes use of the kgdb core in the kernel.
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/gdb-stub.c')
-rw-r--r-- | arch/mips/kernel/gdb-stub.c | 1155 |
1 files changed, 0 insertions, 1155 deletions
diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c deleted file mode 100644 index 25f4eab8ea9c..000000000000 --- a/arch/mips/kernel/gdb-stub.c +++ /dev/null | |||
@@ -1,1155 +0,0 @@ | |||
1 | /* | ||
2 | * arch/mips/kernel/gdb-stub.c | ||
3 | * | ||
4 | * Originally written by Glenn Engel, Lake Stevens Instrument Division | ||
5 | * | ||
6 | * Contributed by HP Systems | ||
7 | * | ||
8 | * Modified for SPARC by Stu Grossman, Cygnus Support. | ||
9 | * | ||
10 | * Modified for Linux/MIPS (and MIPS in general) by Andreas Busse | ||
11 | * Send complaints, suggestions etc. to <andy@waldorf-gmbh.de> | ||
12 | * | ||
13 | * Copyright (C) 1995 Andreas Busse | ||
14 | * | ||
15 | * Copyright (C) 2003 MontaVista Software Inc. | ||
16 | * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net | ||
17 | */ | ||
18 | |||
19 | /* | ||
20 | * To enable debugger support, two things need to happen. One, a | ||
21 | * call to set_debug_traps() is necessary in order to allow any breakpoints | ||
22 | * or error conditions to be properly intercepted and reported to gdb. | ||
23 | * Two, a breakpoint needs to be generated to begin communication. This | ||
24 | * is most easily accomplished by a call to breakpoint(). Breakpoint() | ||
25 | * simulates a breakpoint by executing a BREAK instruction. | ||
26 | * | ||
27 | * | ||
28 | * The following gdb commands are supported: | ||
29 | * | ||
30 | * command function Return value | ||
31 | * | ||
32 | * g return the value of the CPU registers hex data or ENN | ||
33 | * G set the value of the CPU registers OK or ENN | ||
34 | * | ||
35 | * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN | ||
36 | * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN | ||
37 | * | ||
38 | * c Resume at current address SNN ( signal NN) | ||
39 | * cAA..AA Continue at address AA..AA SNN | ||
40 | * | ||
41 | * s Step one instruction SNN | ||
42 | * sAA..AA Step one instruction from AA..AA SNN | ||
43 | * | ||
44 | * k kill | ||
45 | * | ||
46 | * ? What was the last sigval ? SNN (signal NN) | ||
47 | * | ||
48 | * bBB..BB Set baud rate to BB..BB OK or BNN, then sets | ||
49 | * baud rate | ||
50 | * | ||
51 | * All commands and responses are sent with a packet which includes a | ||
52 | * checksum. A packet consists of | ||
53 | * | ||
54 | * $<packet info>#<checksum>. | ||
55 | * | ||
56 | * where | ||
57 | * <packet info> :: <characters representing the command or response> | ||
58 | * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>> | ||
59 | * | ||
60 | * When a packet is received, it is first acknowledged with either '+' or '-'. | ||
61 | * '+' indicates a successful transfer. '-' indicates a failed transfer. | ||
62 | * | ||
63 | * Example: | ||
64 | * | ||
65 | * Host: Reply: | ||
66 | * $m0,10#2a +$00010203040506070809101112131415#42 | ||
67 | * | ||
68 | * | ||
69 | * ============== | ||
70 | * MORE EXAMPLES: | ||
71 | * ============== | ||
72 | * | ||
73 | * For reference -- the following are the steps that one | ||
74 | * company took (RidgeRun Inc) to get remote gdb debugging | ||
75 | * going. In this scenario the host machine was a PC and the | ||
76 | * target platform was a Galileo EVB64120A MIPS evaluation | ||
77 | * board. | ||
78 | * | ||
79 | * Step 1: | ||
80 | * First download gdb-5.0.tar.gz from the internet. | ||
81 | * and then build/install the package. | ||
82 | * | ||
83 | * Example: | ||
84 | * $ tar zxf gdb-5.0.tar.gz | ||
85 | * $ cd gdb-5.0 | ||
86 | * $ ./configure --target=mips-linux-elf | ||
87 | * $ make | ||
88 | * $ install | ||
89 | * $ which mips-linux-elf-gdb | ||
90 | * /usr/local/bin/mips-linux-elf-gdb | ||
91 | * | ||
92 | * Step 2: | ||
93 | * Configure linux for remote debugging and build it. | ||
94 | * | ||
95 | * Example: | ||
96 | * $ cd ~/linux | ||
97 | * $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging> | ||
98 | * $ make | ||
99 | * | ||
100 | * Step 3: | ||
101 | * Download the kernel to the remote target and start | ||
102 | * the kernel running. It will promptly halt and wait | ||
103 | * for the host gdb session to connect. It does this | ||
104 | * since the "Kernel Hacking" option has defined | ||
105 | * CONFIG_KGDB which in turn enables your calls | ||
106 | * to: | ||
107 | * set_debug_traps(); | ||
108 | * breakpoint(); | ||
109 | * | ||
110 | * Step 4: | ||
111 | * Start the gdb session on the host. | ||
112 | * | ||
113 | * Example: | ||
114 | * $ mips-linux-elf-gdb vmlinux | ||
115 | * (gdb) set remotebaud 115200 | ||
116 | * (gdb) target remote /dev/ttyS1 | ||
117 | * ...at this point you are connected to | ||
118 | * the remote target and can use gdb | ||
119 | * in the normal fasion. Setting | ||
120 | * breakpoints, single stepping, | ||
121 | * printing variables, etc. | ||
122 | */ | ||
123 | #include <linux/string.h> | ||
124 | #include <linux/kernel.h> | ||
125 | #include <linux/signal.h> | ||
126 | #include <linux/sched.h> | ||
127 | #include <linux/mm.h> | ||
128 | #include <linux/console.h> | ||
129 | #include <linux/init.h> | ||
130 | #include <linux/smp.h> | ||
131 | #include <linux/spinlock.h> | ||
132 | #include <linux/slab.h> | ||
133 | #include <linux/reboot.h> | ||
134 | |||
135 | #include <asm/asm.h> | ||
136 | #include <asm/cacheflush.h> | ||
137 | #include <asm/mipsregs.h> | ||
138 | #include <asm/pgtable.h> | ||
139 | #include <asm/system.h> | ||
140 | #include <asm/gdb-stub.h> | ||
141 | #include <asm/inst.h> | ||
142 | |||
143 | /* | ||
144 | * external low-level support routines | ||
145 | */ | ||
146 | |||
147 | extern int putDebugChar(char c); /* write a single character */ | ||
148 | extern char getDebugChar(void); /* read and return a single char */ | ||
149 | extern void trap_low(void); | ||
150 | |||
151 | /* | ||
152 | * breakpoint and test functions | ||
153 | */ | ||
154 | extern void breakpoint(void); | ||
155 | extern void breakinst(void); | ||
156 | extern void async_breakpoint(void); | ||
157 | extern void async_breakinst(void); | ||
158 | extern void adel(void); | ||
159 | |||
160 | /* | ||
161 | * local prototypes | ||
162 | */ | ||
163 | |||
164 | static void getpacket(char *buffer); | ||
165 | static void putpacket(char *buffer); | ||
166 | static int computeSignal(int tt); | ||
167 | static int hex(unsigned char ch); | ||
168 | static int hexToInt(char **ptr, int *intValue); | ||
169 | static int hexToLong(char **ptr, long *longValue); | ||
170 | static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault); | ||
171 | void handle_exception(struct gdb_regs *regs); | ||
172 | |||
173 | int kgdb_enabled; | ||
174 | |||
175 | /* | ||
176 | * spin locks for smp case | ||
177 | */ | ||
178 | static DEFINE_SPINLOCK(kgdb_lock); | ||
179 | static raw_spinlock_t kgdb_cpulock[NR_CPUS] = { | ||
180 | [0 ... NR_CPUS-1] = __RAW_SPIN_LOCK_UNLOCKED, | ||
181 | }; | ||
182 | |||
183 | /* | ||
184 | * BUFMAX defines the maximum number of characters in inbound/outbound buffers | ||
185 | * at least NUMREGBYTES*2 are needed for register packets | ||
186 | */ | ||
187 | #define BUFMAX 2048 | ||
188 | |||
189 | static char input_buffer[BUFMAX]; | ||
190 | static char output_buffer[BUFMAX]; | ||
191 | static int initialized; /* !0 means we've been initialized */ | ||
192 | static int kgdb_started; | ||
193 | static const char hexchars[]="0123456789abcdef"; | ||
194 | |||
195 | /* Used to prevent crashes in memory access. Note that they'll crash anyway if | ||
196 | we haven't set up fault handlers yet... */ | ||
197 | int kgdb_read_byte(unsigned char *address, unsigned char *dest); | ||
198 | int kgdb_write_byte(unsigned char val, unsigned char *dest); | ||
199 | |||
200 | /* | ||
201 | * Convert ch from a hex digit to an int | ||
202 | */ | ||
203 | static int hex(unsigned char ch) | ||
204 | { | ||
205 | if (ch >= 'a' && ch <= 'f') | ||
206 | return ch-'a'+10; | ||
207 | if (ch >= '0' && ch <= '9') | ||
208 | return ch-'0'; | ||
209 | if (ch >= 'A' && ch <= 'F') | ||
210 | return ch-'A'+10; | ||
211 | return -1; | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * scan for the sequence $<data>#<checksum> | ||
216 | */ | ||
217 | static void getpacket(char *buffer) | ||
218 | { | ||
219 | unsigned char checksum; | ||
220 | unsigned char xmitcsum; | ||
221 | int i; | ||
222 | int count; | ||
223 | unsigned char ch; | ||
224 | |||
225 | do { | ||
226 | /* | ||
227 | * wait around for the start character, | ||
228 | * ignore all other characters | ||
229 | */ | ||
230 | while ((ch = (getDebugChar() & 0x7f)) != '$') ; | ||
231 | |||
232 | checksum = 0; | ||
233 | xmitcsum = -1; | ||
234 | count = 0; | ||
235 | |||
236 | /* | ||
237 | * now, read until a # or end of buffer is found | ||
238 | */ | ||
239 | while (count < BUFMAX) { | ||
240 | ch = getDebugChar(); | ||
241 | if (ch == '#') | ||
242 | break; | ||
243 | checksum = checksum + ch; | ||
244 | buffer[count] = ch; | ||
245 | count = count + 1; | ||
246 | } | ||
247 | |||
248 | if (count >= BUFMAX) | ||
249 | continue; | ||
250 | |||
251 | buffer[count] = 0; | ||
252 | |||
253 | if (ch == '#') { | ||
254 | xmitcsum = hex(getDebugChar() & 0x7f) << 4; | ||
255 | xmitcsum |= hex(getDebugChar() & 0x7f); | ||
256 | |||
257 | if (checksum != xmitcsum) | ||
258 | putDebugChar('-'); /* failed checksum */ | ||
259 | else { | ||
260 | putDebugChar('+'); /* successful transfer */ | ||
261 | |||
262 | /* | ||
263 | * if a sequence char is present, | ||
264 | * reply the sequence ID | ||
265 | */ | ||
266 | if (buffer[2] == ':') { | ||
267 | putDebugChar(buffer[0]); | ||
268 | putDebugChar(buffer[1]); | ||
269 | |||
270 | /* | ||
271 | * remove sequence chars from buffer | ||
272 | */ | ||
273 | count = strlen(buffer); | ||
274 | for (i=3; i <= count; i++) | ||
275 | buffer[i-3] = buffer[i]; | ||
276 | } | ||
277 | } | ||
278 | } | ||
279 | } | ||
280 | while (checksum != xmitcsum); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * send the packet in buffer. | ||
285 | */ | ||
286 | static void putpacket(char *buffer) | ||
287 | { | ||
288 | unsigned char checksum; | ||
289 | int count; | ||
290 | unsigned char ch; | ||
291 | |||
292 | /* | ||
293 | * $<packet info>#<checksum>. | ||
294 | */ | ||
295 | |||
296 | do { | ||
297 | putDebugChar('$'); | ||
298 | checksum = 0; | ||
299 | count = 0; | ||
300 | |||
301 | while ((ch = buffer[count]) != 0) { | ||
302 | if (!(putDebugChar(ch))) | ||
303 | return; | ||
304 | checksum += ch; | ||
305 | count += 1; | ||
306 | } | ||
307 | |||
308 | putDebugChar('#'); | ||
309 | putDebugChar(hexchars[checksum >> 4]); | ||
310 | putDebugChar(hexchars[checksum & 0xf]); | ||
311 | |||
312 | } | ||
313 | while ((getDebugChar() & 0x7f) != '+'); | ||
314 | } | ||
315 | |||
316 | |||
317 | /* | ||
318 | * Convert the memory pointed to by mem into hex, placing result in buf. | ||
319 | * Return a pointer to the last char put in buf (null), in case of mem fault, | ||
320 | * return 0. | ||
321 | * may_fault is non-zero if we are reading from arbitrary memory, but is currently | ||
322 | * not used. | ||
323 | */ | ||
324 | static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault) | ||
325 | { | ||
326 | unsigned char ch; | ||
327 | |||
328 | while (count-- > 0) { | ||
329 | if (kgdb_read_byte(mem++, &ch) != 0) | ||
330 | return 0; | ||
331 | *buf++ = hexchars[ch >> 4]; | ||
332 | *buf++ = hexchars[ch & 0xf]; | ||
333 | } | ||
334 | |||
335 | *buf = 0; | ||
336 | |||
337 | return buf; | ||
338 | } | ||
339 | |||
340 | /* | ||
341 | * convert the hex array pointed to by buf into binary to be placed in mem | ||
342 | * return a pointer to the character AFTER the last byte written | ||
343 | * may_fault is non-zero if we are reading from arbitrary memory, but is currently | ||
344 | * not used. | ||
345 | */ | ||
346 | static char *hex2mem(char *buf, char *mem, int count, int binary, int may_fault) | ||
347 | { | ||
348 | int i; | ||
349 | unsigned char ch; | ||
350 | |||
351 | for (i=0; i<count; i++) | ||
352 | { | ||
353 | if (binary) { | ||
354 | ch = *buf++; | ||
355 | if (ch == 0x7d) | ||
356 | ch = 0x20 ^ *buf++; | ||
357 | } | ||
358 | else { | ||
359 | ch = hex(*buf++) << 4; | ||
360 | ch |= hex(*buf++); | ||
361 | } | ||
362 | if (kgdb_write_byte(ch, mem++) != 0) | ||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | return mem; | ||
367 | } | ||
368 | |||
369 | /* | ||
370 | * This table contains the mapping between SPARC hardware trap types, and | ||
371 | * signals, which are primarily what GDB understands. It also indicates | ||
372 | * which hardware traps we need to commandeer when initializing the stub. | ||
373 | */ | ||
374 | static struct hard_trap_info { | ||
375 | unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */ | ||
376 | unsigned char signo; /* Signal that we map this trap into */ | ||
377 | } hard_trap_info[] = { | ||
378 | { 6, SIGBUS }, /* instruction bus error */ | ||
379 | { 7, SIGBUS }, /* data bus error */ | ||
380 | { 9, SIGTRAP }, /* break */ | ||
381 | { 10, SIGILL }, /* reserved instruction */ | ||
382 | /* { 11, SIGILL }, */ /* CPU unusable */ | ||
383 | { 12, SIGFPE }, /* overflow */ | ||
384 | { 13, SIGTRAP }, /* trap */ | ||
385 | { 14, SIGSEGV }, /* virtual instruction cache coherency */ | ||
386 | { 15, SIGFPE }, /* floating point exception */ | ||
387 | { 23, SIGSEGV }, /* watch */ | ||
388 | { 31, SIGSEGV }, /* virtual data cache coherency */ | ||
389 | { 0, 0} /* Must be last */ | ||
390 | }; | ||
391 | |||
392 | /* Save the normal trap handlers for user-mode traps. */ | ||
393 | void *saved_vectors[32]; | ||
394 | |||
395 | /* | ||
396 | * Set up exception handlers for tracing and breakpoints | ||
397 | */ | ||
398 | void set_debug_traps(void) | ||
399 | { | ||
400 | struct hard_trap_info *ht; | ||
401 | unsigned long flags; | ||
402 | unsigned char c; | ||
403 | |||
404 | local_irq_save(flags); | ||
405 | for (ht = hard_trap_info; ht->tt && ht->signo; ht++) | ||
406 | saved_vectors[ht->tt] = set_except_vector(ht->tt, trap_low); | ||
407 | |||
408 | putDebugChar('+'); /* 'hello world' */ | ||
409 | /* | ||
410 | * In case GDB is started before us, ack any packets | ||
411 | * (presumably "$?#xx") sitting there. | ||
412 | */ | ||
413 | while((c = getDebugChar()) != '$'); | ||
414 | while((c = getDebugChar()) != '#'); | ||
415 | c = getDebugChar(); /* eat first csum byte */ | ||
416 | c = getDebugChar(); /* eat second csum byte */ | ||
417 | putDebugChar('+'); /* ack it */ | ||
418 | |||
419 | initialized = 1; | ||
420 | local_irq_restore(flags); | ||
421 | } | ||
422 | |||
423 | void restore_debug_traps(void) | ||
424 | { | ||
425 | struct hard_trap_info *ht; | ||
426 | unsigned long flags; | ||
427 | |||
428 | local_irq_save(flags); | ||
429 | for (ht = hard_trap_info; ht->tt && ht->signo; ht++) | ||
430 | set_except_vector(ht->tt, saved_vectors[ht->tt]); | ||
431 | local_irq_restore(flags); | ||
432 | } | ||
433 | |||
434 | /* | ||
435 | * Convert the MIPS hardware trap type code to a Unix signal number. | ||
436 | */ | ||
437 | static int computeSignal(int tt) | ||
438 | { | ||
439 | struct hard_trap_info *ht; | ||
440 | |||
441 | for (ht = hard_trap_info; ht->tt && ht->signo; ht++) | ||
442 | if (ht->tt == tt) | ||
443 | return ht->signo; | ||
444 | |||
445 | return SIGHUP; /* default for things we don't know about */ | ||
446 | } | ||
447 | |||
448 | /* | ||
449 | * While we find nice hex chars, build an int. | ||
450 | * Return number of chars processed. | ||
451 | */ | ||
452 | static int hexToInt(char **ptr, int *intValue) | ||
453 | { | ||
454 | int numChars = 0; | ||
455 | int hexValue; | ||
456 | |||
457 | *intValue = 0; | ||
458 | |||
459 | while (**ptr) { | ||
460 | hexValue = hex(**ptr); | ||
461 | if (hexValue < 0) | ||
462 | break; | ||
463 | |||
464 | *intValue = (*intValue << 4) | hexValue; | ||
465 | numChars ++; | ||
466 | |||
467 | (*ptr)++; | ||
468 | } | ||
469 | |||
470 | return (numChars); | ||
471 | } | ||
472 | |||
473 | static int hexToLong(char **ptr, long *longValue) | ||
474 | { | ||
475 | int numChars = 0; | ||
476 | int hexValue; | ||
477 | |||
478 | *longValue = 0; | ||
479 | |||
480 | while (**ptr) { | ||
481 | hexValue = hex(**ptr); | ||
482 | if (hexValue < 0) | ||
483 | break; | ||
484 | |||
485 | *longValue = (*longValue << 4) | hexValue; | ||
486 | numChars ++; | ||
487 | |||
488 | (*ptr)++; | ||
489 | } | ||
490 | |||
491 | return numChars; | ||
492 | } | ||
493 | |||
494 | |||
495 | #if 0 | ||
496 | /* | ||
497 | * Print registers (on target console) | ||
498 | * Used only to debug the stub... | ||
499 | */ | ||
500 | void show_gdbregs(struct gdb_regs * regs) | ||
501 | { | ||
502 | /* | ||
503 | * Saved main processor registers | ||
504 | */ | ||
505 | printk("$0 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", | ||
506 | regs->reg0, regs->reg1, regs->reg2, regs->reg3, | ||
507 | regs->reg4, regs->reg5, regs->reg6, regs->reg7); | ||
508 | printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", | ||
509 | regs->reg8, regs->reg9, regs->reg10, regs->reg11, | ||
510 | regs->reg12, regs->reg13, regs->reg14, regs->reg15); | ||
511 | printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", | ||
512 | regs->reg16, regs->reg17, regs->reg18, regs->reg19, | ||
513 | regs->reg20, regs->reg21, regs->reg22, regs->reg23); | ||
514 | printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", | ||
515 | regs->reg24, regs->reg25, regs->reg26, regs->reg27, | ||
516 | regs->reg28, regs->reg29, regs->reg30, regs->reg31); | ||
517 | |||
518 | /* | ||
519 | * Saved cp0 registers | ||
520 | */ | ||
521 | printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\n", | ||
522 | regs->cp0_epc, regs->cp0_status, regs->cp0_cause); | ||
523 | } | ||
524 | #endif /* dead code */ | ||
525 | |||
526 | /* | ||
527 | * We single-step by setting breakpoints. When an exception | ||
528 | * is handled, we need to restore the instructions hoisted | ||
529 | * when the breakpoints were set. | ||
530 | * | ||
531 | * This is where we save the original instructions. | ||
532 | */ | ||
533 | static struct gdb_bp_save { | ||
534 | unsigned long addr; | ||
535 | unsigned int val; | ||
536 | } step_bp[2]; | ||
537 | |||
538 | #define BP 0x0000000d /* break opcode */ | ||
539 | |||
540 | /* | ||
541 | * Set breakpoint instructions for single stepping. | ||
542 | */ | ||
543 | static void single_step(struct gdb_regs *regs) | ||
544 | { | ||
545 | union mips_instruction insn; | ||
546 | unsigned long targ; | ||
547 | int is_branch, is_cond, i; | ||
548 | |||
549 | targ = regs->cp0_epc; | ||
550 | insn.word = *(unsigned int *)targ; | ||
551 | is_branch = is_cond = 0; | ||
552 | |||
553 | switch (insn.i_format.opcode) { | ||
554 | /* | ||
555 | * jr and jalr are in r_format format. | ||
556 | */ | ||
557 | case spec_op: | ||
558 | switch (insn.r_format.func) { | ||
559 | case jalr_op: | ||
560 | case jr_op: | ||
561 | targ = *(®s->reg0 + insn.r_format.rs); | ||
562 | is_branch = 1; | ||
563 | break; | ||
564 | } | ||
565 | break; | ||
566 | |||
567 | /* | ||
568 | * This group contains: | ||
569 | * bltz_op, bgez_op, bltzl_op, bgezl_op, | ||
570 | * bltzal_op, bgezal_op, bltzall_op, bgezall_op. | ||
571 | */ | ||
572 | case bcond_op: | ||
573 | is_branch = is_cond = 1; | ||
574 | targ += 4 + (insn.i_format.simmediate << 2); | ||
575 | break; | ||
576 | |||
577 | /* | ||
578 | * These are unconditional and in j_format. | ||
579 | */ | ||
580 | case jal_op: | ||
581 | case j_op: | ||
582 | is_branch = 1; | ||
583 | targ += 4; | ||
584 | targ >>= 28; | ||
585 | targ <<= 28; | ||
586 | targ |= (insn.j_format.target << 2); | ||
587 | break; | ||
588 | |||
589 | /* | ||
590 | * These are conditional. | ||
591 | */ | ||
592 | case beq_op: | ||
593 | case beql_op: | ||
594 | case bne_op: | ||
595 | case bnel_op: | ||
596 | case blez_op: | ||
597 | case blezl_op: | ||
598 | case bgtz_op: | ||
599 | case bgtzl_op: | ||
600 | case cop0_op: | ||
601 | case cop1_op: | ||
602 | case cop2_op: | ||
603 | case cop1x_op: | ||
604 | is_branch = is_cond = 1; | ||
605 | targ += 4 + (insn.i_format.simmediate << 2); | ||
606 | break; | ||
607 | } | ||
608 | |||
609 | if (is_branch) { | ||
610 | i = 0; | ||
611 | if (is_cond && targ != (regs->cp0_epc + 8)) { | ||
612 | step_bp[i].addr = regs->cp0_epc + 8; | ||
613 | step_bp[i++].val = *(unsigned *)(regs->cp0_epc + 8); | ||
614 | *(unsigned *)(regs->cp0_epc + 8) = BP; | ||
615 | } | ||
616 | step_bp[i].addr = targ; | ||
617 | step_bp[i].val = *(unsigned *)targ; | ||
618 | *(unsigned *)targ = BP; | ||
619 | } else { | ||
620 | step_bp[0].addr = regs->cp0_epc + 4; | ||
621 | step_bp[0].val = *(unsigned *)(regs->cp0_epc + 4); | ||
622 | *(unsigned *)(regs->cp0_epc + 4) = BP; | ||
623 | } | ||
624 | } | ||
625 | |||
626 | /* | ||
627 | * If asynchronously interrupted by gdb, then we need to set a breakpoint | ||
628 | * at the interrupted instruction so that we wind up stopped with a | ||
629 | * reasonable stack frame. | ||
630 | */ | ||
631 | static struct gdb_bp_save async_bp; | ||
632 | |||
633 | /* | ||
634 | * Swap the interrupted EPC with our asynchronous breakpoint routine. | ||
635 | * This is safer than stuffing the breakpoint in-place, since no cache | ||
636 | * flushes (or resulting smp_call_functions) are required. The | ||
637 | * assumption is that only one CPU will be handling asynchronous bp's, | ||
638 | * and only one can be active at a time. | ||
639 | */ | ||
640 | extern spinlock_t smp_call_lock; | ||
641 | |||
642 | void set_async_breakpoint(unsigned long *epc) | ||
643 | { | ||
644 | /* skip breaking into userland */ | ||
645 | if ((*epc & 0x80000000) == 0) | ||
646 | return; | ||
647 | |||
648 | #ifdef CONFIG_SMP | ||
649 | /* avoid deadlock if someone is make IPC */ | ||
650 | if (spin_is_locked(&smp_call_lock)) | ||
651 | return; | ||
652 | #endif | ||
653 | |||
654 | async_bp.addr = *epc; | ||
655 | *epc = (unsigned long)async_breakpoint; | ||
656 | } | ||
657 | |||
658 | #ifdef CONFIG_SMP | ||
659 | static void kgdb_wait(void *arg) | ||
660 | { | ||
661 | unsigned flags; | ||
662 | int cpu = smp_processor_id(); | ||
663 | |||
664 | local_irq_save(flags); | ||
665 | |||
666 | __raw_spin_lock(&kgdb_cpulock[cpu]); | ||
667 | __raw_spin_unlock(&kgdb_cpulock[cpu]); | ||
668 | |||
669 | local_irq_restore(flags); | ||
670 | } | ||
671 | #endif | ||
672 | |||
673 | /* | ||
674 | * GDB stub needs to call kgdb_wait on all processor with interrupts | ||
675 | * disabled, so it uses it's own special variant. | ||
676 | */ | ||
677 | static int kgdb_smp_call_kgdb_wait(void) | ||
678 | { | ||
679 | #ifdef CONFIG_SMP | ||
680 | cpumask_t mask = cpu_online_map; | ||
681 | struct call_data_struct data; | ||
682 | int cpu = smp_processor_id(); | ||
683 | int cpus; | ||
684 | |||
685 | /* | ||
686 | * Can die spectacularly if this CPU isn't yet marked online | ||
687 | */ | ||
688 | BUG_ON(!cpu_online(cpu)); | ||
689 | |||
690 | cpu_clear(cpu, mask); | ||
691 | cpus = cpus_weight(mask); | ||
692 | if (!cpus) | ||
693 | return 0; | ||
694 | |||
695 | if (spin_is_locked(&smp_call_lock)) { | ||
696 | /* | ||
697 | * Some other processor is trying to make us do something | ||
698 | * but we're not going to respond... give up | ||
699 | */ | ||
700 | return -1; | ||
701 | } | ||
702 | |||
703 | /* | ||
704 | * We will continue here, accepting the fact that | ||
705 | * the kernel may deadlock if another CPU attempts | ||
706 | * to call smp_call_function now... | ||
707 | */ | ||
708 | |||
709 | data.func = kgdb_wait; | ||
710 | data.info = NULL; | ||
711 | atomic_set(&data.started, 0); | ||
712 | data.wait = 0; | ||
713 | |||
714 | spin_lock(&smp_call_lock); | ||
715 | call_data = &data; | ||
716 | mb(); | ||
717 | |||
718 | core_send_ipi_mask(mask, SMP_CALL_FUNCTION); | ||
719 | |||
720 | /* Wait for response */ | ||
721 | /* FIXME: lock-up detection, backtrace on lock-up */ | ||
722 | while (atomic_read(&data.started) != cpus) | ||
723 | barrier(); | ||
724 | |||
725 | call_data = NULL; | ||
726 | spin_unlock(&smp_call_lock); | ||
727 | #endif | ||
728 | |||
729 | return 0; | ||
730 | } | ||
731 | |||
732 | /* | ||
733 | * This function does all command processing for interfacing to gdb. It | ||
734 | * returns 1 if you should skip the instruction at the trap address, 0 | ||
735 | * otherwise. | ||
736 | */ | ||
737 | void handle_exception(struct gdb_regs *regs) | ||
738 | { | ||
739 | int trap; /* Trap type */ | ||
740 | int sigval; | ||
741 | long addr; | ||
742 | int length; | ||
743 | char *ptr; | ||
744 | unsigned long *stack; | ||
745 | int i; | ||
746 | int bflag = 0; | ||
747 | |||
748 | kgdb_started = 1; | ||
749 | |||
750 | /* | ||
751 | * acquire the big kgdb spinlock | ||
752 | */ | ||
753 | if (!spin_trylock(&kgdb_lock)) { | ||
754 | /* | ||
755 | * some other CPU has the lock, we should go back to | ||
756 | * receive the gdb_wait IPC | ||
757 | */ | ||
758 | return; | ||
759 | } | ||
760 | |||
761 | /* | ||
762 | * If we're in async_breakpoint(), restore the real EPC from | ||
763 | * the breakpoint. | ||
764 | */ | ||
765 | if (regs->cp0_epc == (unsigned long)async_breakinst) { | ||
766 | regs->cp0_epc = async_bp.addr; | ||
767 | async_bp.addr = 0; | ||
768 | } | ||
769 | |||
770 | /* | ||
771 | * acquire the CPU spinlocks | ||
772 | */ | ||
773 | for_each_online_cpu(i) | ||
774 | if (__raw_spin_trylock(&kgdb_cpulock[i]) == 0) | ||
775 | panic("kgdb: couldn't get cpulock %d\n", i); | ||
776 | |||
777 | /* | ||
778 | * force other cpus to enter kgdb | ||
779 | */ | ||
780 | kgdb_smp_call_kgdb_wait(); | ||
781 | |||
782 | /* | ||
783 | * If we're in breakpoint() increment the PC | ||
784 | */ | ||
785 | trap = (regs->cp0_cause & 0x7c) >> 2; | ||
786 | if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst) | ||
787 | regs->cp0_epc += 4; | ||
788 | |||
789 | /* | ||
790 | * If we were single_stepping, restore the opcodes hoisted | ||
791 | * for the breakpoint[s]. | ||
792 | */ | ||
793 | if (step_bp[0].addr) { | ||
794 | *(unsigned *)step_bp[0].addr = step_bp[0].val; | ||
795 | step_bp[0].addr = 0; | ||
796 | |||
797 | if (step_bp[1].addr) { | ||
798 | *(unsigned *)step_bp[1].addr = step_bp[1].val; | ||
799 | step_bp[1].addr = 0; | ||
800 | } | ||
801 | } | ||
802 | |||
803 | stack = (long *)regs->reg29; /* stack ptr */ | ||
804 | sigval = computeSignal(trap); | ||
805 | |||
806 | /* | ||
807 | * reply to host that an exception has occurred | ||
808 | */ | ||
809 | ptr = output_buffer; | ||
810 | |||
811 | /* | ||
812 | * Send trap type (converted to signal) | ||
813 | */ | ||
814 | *ptr++ = 'T'; | ||
815 | *ptr++ = hexchars[sigval >> 4]; | ||
816 | *ptr++ = hexchars[sigval & 0xf]; | ||
817 | |||
818 | /* | ||
819 | * Send Error PC | ||
820 | */ | ||
821 | *ptr++ = hexchars[REG_EPC >> 4]; | ||
822 | *ptr++ = hexchars[REG_EPC & 0xf]; | ||
823 | *ptr++ = ':'; | ||
824 | ptr = mem2hex((char *)®s->cp0_epc, ptr, sizeof(long), 0); | ||
825 | *ptr++ = ';'; | ||
826 | |||
827 | /* | ||
828 | * Send frame pointer | ||
829 | */ | ||
830 | *ptr++ = hexchars[REG_FP >> 4]; | ||
831 | *ptr++ = hexchars[REG_FP & 0xf]; | ||
832 | *ptr++ = ':'; | ||
833 | ptr = mem2hex((char *)®s->reg30, ptr, sizeof(long), 0); | ||
834 | *ptr++ = ';'; | ||
835 | |||
836 | /* | ||
837 | * Send stack pointer | ||
838 | */ | ||
839 | *ptr++ = hexchars[REG_SP >> 4]; | ||
840 | *ptr++ = hexchars[REG_SP & 0xf]; | ||
841 | *ptr++ = ':'; | ||
842 | ptr = mem2hex((char *)®s->reg29, ptr, sizeof(long), 0); | ||
843 | *ptr++ = ';'; | ||
844 | |||
845 | *ptr++ = 0; | ||
846 | putpacket(output_buffer); /* send it off... */ | ||
847 | |||
848 | /* | ||
849 | * Wait for input from remote GDB | ||
850 | */ | ||
851 | while (1) { | ||
852 | output_buffer[0] = 0; | ||
853 | getpacket(input_buffer); | ||
854 | |||
855 | switch (input_buffer[0]) | ||
856 | { | ||
857 | case '?': | ||
858 | output_buffer[0] = 'S'; | ||
859 | output_buffer[1] = hexchars[sigval >> 4]; | ||
860 | output_buffer[2] = hexchars[sigval & 0xf]; | ||
861 | output_buffer[3] = 0; | ||
862 | break; | ||
863 | |||
864 | /* | ||
865 | * Detach debugger; let CPU run | ||
866 | */ | ||
867 | case 'D': | ||
868 | putpacket(output_buffer); | ||
869 | goto finish_kgdb; | ||
870 | break; | ||
871 | |||
872 | case 'd': | ||
873 | /* toggle debug flag */ | ||
874 | break; | ||
875 | |||
876 | /* | ||
877 | * Return the value of the CPU registers | ||
878 | */ | ||
879 | case 'g': | ||
880 | ptr = output_buffer; | ||
881 | ptr = mem2hex((char *)®s->reg0, ptr, 32*sizeof(long), 0); /* r0...r31 */ | ||
882 | ptr = mem2hex((char *)®s->cp0_status, ptr, 6*sizeof(long), 0); /* cp0 */ | ||
883 | ptr = mem2hex((char *)®s->fpr0, ptr, 32*sizeof(long), 0); /* f0...31 */ | ||
884 | ptr = mem2hex((char *)®s->cp1_fsr, ptr, 2*sizeof(long), 0); /* cp1 */ | ||
885 | ptr = mem2hex((char *)®s->frame_ptr, ptr, 2*sizeof(long), 0); /* frp */ | ||
886 | ptr = mem2hex((char *)®s->cp0_index, ptr, 16*sizeof(long), 0); /* cp0 */ | ||
887 | break; | ||
888 | |||
889 | /* | ||
890 | * set the value of the CPU registers - return OK | ||
891 | */ | ||
892 | case 'G': | ||
893 | { | ||
894 | ptr = &input_buffer[1]; | ||
895 | hex2mem(ptr, (char *)®s->reg0, 32*sizeof(long), 0, 0); | ||
896 | ptr += 32*(2*sizeof(long)); | ||
897 | hex2mem(ptr, (char *)®s->cp0_status, 6*sizeof(long), 0, 0); | ||
898 | ptr += 6*(2*sizeof(long)); | ||
899 | hex2mem(ptr, (char *)®s->fpr0, 32*sizeof(long), 0, 0); | ||
900 | ptr += 32*(2*sizeof(long)); | ||
901 | hex2mem(ptr, (char *)®s->cp1_fsr, 2*sizeof(long), 0, 0); | ||
902 | ptr += 2*(2*sizeof(long)); | ||
903 | hex2mem(ptr, (char *)®s->frame_ptr, 2*sizeof(long), 0, 0); | ||
904 | ptr += 2*(2*sizeof(long)); | ||
905 | hex2mem(ptr, (char *)®s->cp0_index, 16*sizeof(long), 0, 0); | ||
906 | strcpy(output_buffer, "OK"); | ||
907 | } | ||
908 | break; | ||
909 | |||
910 | /* | ||
911 | * mAA..AA,LLLL Read LLLL bytes at address AA..AA | ||
912 | */ | ||
913 | case 'm': | ||
914 | ptr = &input_buffer[1]; | ||
915 | |||
916 | if (hexToLong(&ptr, &addr) | ||
917 | && *ptr++ == ',' | ||
918 | && hexToInt(&ptr, &length)) { | ||
919 | if (mem2hex((char *)addr, output_buffer, length, 1)) | ||
920 | break; | ||
921 | strcpy(output_buffer, "E03"); | ||
922 | } else | ||
923 | strcpy(output_buffer, "E01"); | ||
924 | break; | ||
925 | |||
926 | /* | ||
927 | * XAA..AA,LLLL: Write LLLL escaped binary bytes at address AA.AA | ||
928 | */ | ||
929 | case 'X': | ||
930 | bflag = 1; | ||
931 | /* fall through */ | ||
932 | |||
933 | /* | ||
934 | * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK | ||
935 | */ | ||
936 | case 'M': | ||
937 | ptr = &input_buffer[1]; | ||
938 | |||
939 | if (hexToLong(&ptr, &addr) | ||
940 | && *ptr++ == ',' | ||
941 | && hexToInt(&ptr, &length) | ||
942 | && *ptr++ == ':') { | ||
943 | if (hex2mem(ptr, (char *)addr, length, bflag, 1)) | ||
944 | strcpy(output_buffer, "OK"); | ||
945 | else | ||
946 | strcpy(output_buffer, "E03"); | ||
947 | } | ||
948 | else | ||
949 | strcpy(output_buffer, "E02"); | ||
950 | break; | ||
951 | |||
952 | /* | ||
953 | * cAA..AA Continue at address AA..AA(optional) | ||
954 | */ | ||
955 | case 'c': | ||
956 | /* try to read optional parameter, pc unchanged if no parm */ | ||
957 | |||
958 | ptr = &input_buffer[1]; | ||
959 | if (hexToLong(&ptr, &addr)) | ||
960 | regs->cp0_epc = addr; | ||
961 | |||
962 | goto exit_kgdb_exception; | ||
963 | break; | ||
964 | |||
965 | /* | ||
966 | * kill the program; let us try to restart the machine | ||
967 | * Reset the whole machine. | ||
968 | */ | ||
969 | case 'k': | ||
970 | case 'r': | ||
971 | machine_restart("kgdb restarts machine"); | ||
972 | break; | ||
973 | |||
974 | /* | ||
975 | * Step to next instruction | ||
976 | */ | ||
977 | case 's': | ||
978 | /* | ||
979 | * There is no single step insn in the MIPS ISA, so we | ||
980 | * use breakpoints and continue, instead. | ||
981 | */ | ||
982 | single_step(regs); | ||
983 | goto exit_kgdb_exception; | ||
984 | /* NOTREACHED */ | ||
985 | break; | ||
986 | |||
987 | /* | ||
988 | * Set baud rate (bBB) | ||
989 | * FIXME: Needs to be written | ||
990 | */ | ||
991 | case 'b': | ||
992 | { | ||
993 | #if 0 | ||
994 | int baudrate; | ||
995 | extern void set_timer_3(); | ||
996 | |||
997 | ptr = &input_buffer[1]; | ||
998 | if (!hexToInt(&ptr, &baudrate)) | ||
999 | { | ||
1000 | strcpy(output_buffer, "B01"); | ||
1001 | break; | ||
1002 | } | ||
1003 | |||
1004 | /* Convert baud rate to uart clock divider */ | ||
1005 | |||
1006 | switch (baudrate) | ||
1007 | { | ||
1008 | case 38400: | ||
1009 | baudrate = 16; | ||
1010 | break; | ||
1011 | case 19200: | ||
1012 | baudrate = 33; | ||
1013 | break; | ||
1014 | case 9600: | ||
1015 | baudrate = 65; | ||
1016 | break; | ||
1017 | default: | ||
1018 | baudrate = 0; | ||
1019 | strcpy(output_buffer, "B02"); | ||
1020 | goto x1; | ||
1021 | } | ||
1022 | |||
1023 | if (baudrate) { | ||
1024 | putpacket("OK"); /* Ack before changing speed */ | ||
1025 | set_timer_3(baudrate); /* Set it */ | ||
1026 | } | ||
1027 | #endif | ||
1028 | } | ||
1029 | break; | ||
1030 | |||
1031 | } /* switch */ | ||
1032 | |||
1033 | /* | ||
1034 | * reply to the request | ||
1035 | */ | ||
1036 | |||
1037 | putpacket(output_buffer); | ||
1038 | |||
1039 | } /* while */ | ||
1040 | |||
1041 | return; | ||
1042 | |||
1043 | finish_kgdb: | ||
1044 | restore_debug_traps(); | ||
1045 | |||
1046 | exit_kgdb_exception: | ||
1047 | /* release locks so other CPUs can go */ | ||
1048 | for_each_online_cpu(i) | ||
1049 | __raw_spin_unlock(&kgdb_cpulock[i]); | ||
1050 | spin_unlock(&kgdb_lock); | ||
1051 | |||
1052 | __flush_cache_all(); | ||
1053 | return; | ||
1054 | } | ||
1055 | |||
1056 | /* | ||
1057 | * This function will generate a breakpoint exception. It is used at the | ||
1058 | * beginning of a program to sync up with a debugger and can be used | ||
1059 | * otherwise as a quick means to stop program execution and "break" into | ||
1060 | * the debugger. | ||
1061 | */ | ||
1062 | void breakpoint(void) | ||
1063 | { | ||
1064 | if (!initialized) | ||
1065 | return; | ||
1066 | |||
1067 | __asm__ __volatile__( | ||
1068 | ".globl breakinst\n\t" | ||
1069 | ".set\tnoreorder\n\t" | ||
1070 | "nop\n" | ||
1071 | "breakinst:\tbreak\n\t" | ||
1072 | "nop\n\t" | ||
1073 | ".set\treorder" | ||
1074 | ); | ||
1075 | } | ||
1076 | |||
1077 | /* Nothing but the break; don't pollute any registers */ | ||
1078 | void async_breakpoint(void) | ||
1079 | { | ||
1080 | __asm__ __volatile__( | ||
1081 | ".globl async_breakinst\n\t" | ||
1082 | ".set\tnoreorder\n\t" | ||
1083 | "nop\n" | ||
1084 | "async_breakinst:\tbreak\n\t" | ||
1085 | "nop\n\t" | ||
1086 | ".set\treorder" | ||
1087 | ); | ||
1088 | } | ||
1089 | |||
1090 | void adel(void) | ||
1091 | { | ||
1092 | __asm__ __volatile__( | ||
1093 | ".globl\tadel\n\t" | ||
1094 | "lui\t$8,0x8000\n\t" | ||
1095 | "lw\t$9,1($8)\n\t" | ||
1096 | ); | ||
1097 | } | ||
1098 | |||
1099 | /* | ||
1100 | * malloc is needed by gdb client in "call func()", even a private one | ||
1101 | * will make gdb happy | ||
1102 | */ | ||
1103 | static void __used *malloc(size_t size) | ||
1104 | { | ||
1105 | return kmalloc(size, GFP_ATOMIC); | ||
1106 | } | ||
1107 | |||
1108 | static void __used free(void *where) | ||
1109 | { | ||
1110 | kfree(where); | ||
1111 | } | ||
1112 | |||
1113 | #ifdef CONFIG_GDB_CONSOLE | ||
1114 | |||
1115 | void gdb_putsn(const char *str, int l) | ||
1116 | { | ||
1117 | char outbuf[18]; | ||
1118 | |||
1119 | if (!kgdb_started) | ||
1120 | return; | ||
1121 | |||
1122 | outbuf[0]='O'; | ||
1123 | |||
1124 | while(l) { | ||
1125 | int i = (l>8)?8:l; | ||
1126 | mem2hex((char *)str, &outbuf[1], i, 0); | ||
1127 | outbuf[(i*2)+1]=0; | ||
1128 | putpacket(outbuf); | ||
1129 | str += i; | ||
1130 | l -= i; | ||
1131 | } | ||
1132 | } | ||
1133 | |||
1134 | static void gdb_console_write(struct console *con, const char *s, unsigned n) | ||
1135 | { | ||
1136 | gdb_putsn(s, n); | ||
1137 | } | ||
1138 | |||
1139 | static struct console gdb_console = { | ||
1140 | .name = "gdb", | ||
1141 | .write = gdb_console_write, | ||
1142 | .flags = CON_PRINTBUFFER, | ||
1143 | .index = -1 | ||
1144 | }; | ||
1145 | |||
1146 | static int __init register_gdb_console(void) | ||
1147 | { | ||
1148 | register_console(&gdb_console); | ||
1149 | |||
1150 | return 0; | ||
1151 | } | ||
1152 | |||
1153 | console_initcall(register_gdb_console); | ||
1154 | |||
1155 | #endif | ||