diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/mips/kernel/gdb-stub.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/mips/kernel/gdb-stub.c')
-rw-r--r-- | arch/mips/kernel/gdb-stub.c | 1091 |
1 files changed, 1091 insertions, 0 deletions
diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c new file mode 100644 index 000000000000..269889302a27 --- /dev/null +++ b/arch/mips/kernel/gdb-stub.c | |||
@@ -0,0 +1,1091 @@ | |||
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/config.h> | ||
124 | #include <linux/string.h> | ||
125 | #include <linux/kernel.h> | ||
126 | #include <linux/signal.h> | ||
127 | #include <linux/sched.h> | ||
128 | #include <linux/mm.h> | ||
129 | #include <linux/console.h> | ||
130 | #include <linux/init.h> | ||
131 | #include <linux/smp.h> | ||
132 | #include <linux/spinlock.h> | ||
133 | #include <linux/slab.h> | ||
134 | #include <linux/reboot.h> | ||
135 | |||
136 | #include <asm/asm.h> | ||
137 | #include <asm/cacheflush.h> | ||
138 | #include <asm/mipsregs.h> | ||
139 | #include <asm/pgtable.h> | ||
140 | #include <asm/system.h> | ||
141 | #include <asm/gdb-stub.h> | ||
142 | #include <asm/inst.h> | ||
143 | |||
144 | /* | ||
145 | * external low-level support routines | ||
146 | */ | ||
147 | |||
148 | extern int putDebugChar(char c); /* write a single character */ | ||
149 | extern char getDebugChar(void); /* read and return a single char */ | ||
150 | extern void trap_low(void); | ||
151 | |||
152 | /* | ||
153 | * breakpoint and test functions | ||
154 | */ | ||
155 | extern void breakpoint(void); | ||
156 | extern void breakinst(void); | ||
157 | extern void async_breakpoint(void); | ||
158 | extern void async_breakinst(void); | ||
159 | extern void adel(void); | ||
160 | |||
161 | /* | ||
162 | * local prototypes | ||
163 | */ | ||
164 | |||
165 | static void getpacket(char *buffer); | ||
166 | static void putpacket(char *buffer); | ||
167 | static int computeSignal(int tt); | ||
168 | static int hex(unsigned char ch); | ||
169 | static int hexToInt(char **ptr, int *intValue); | ||
170 | static int hexToLong(char **ptr, long *longValue); | ||
171 | static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault); | ||
172 | void handle_exception(struct gdb_regs *regs); | ||
173 | |||
174 | int kgdb_enabled; | ||
175 | |||
176 | /* | ||
177 | * spin locks for smp case | ||
178 | */ | ||
179 | static spinlock_t kgdb_lock = SPIN_LOCK_UNLOCKED; | ||
180 | static spinlock_t kgdb_cpulock[NR_CPUS] = { [0 ... NR_CPUS-1] = SPIN_LOCK_UNLOCKED}; | ||
181 | |||
182 | /* | ||
183 | * BUFMAX defines the maximum number of characters in inbound/outbound buffers | ||
184 | * at least NUMREGBYTES*2 are needed for register packets | ||
185 | */ | ||
186 | #define BUFMAX 2048 | ||
187 | |||
188 | static char input_buffer[BUFMAX]; | ||
189 | static char output_buffer[BUFMAX]; | ||
190 | static int initialized; /* !0 means we've been initialized */ | ||
191 | static int kgdb_started; | ||
192 | static const char hexchars[]="0123456789abcdef"; | ||
193 | |||
194 | /* Used to prevent crashes in memory access. Note that they'll crash anyway if | ||
195 | we haven't set up fault handlers yet... */ | ||
196 | int kgdb_read_byte(unsigned char *address, unsigned char *dest); | ||
197 | int kgdb_write_byte(unsigned char val, unsigned char *dest); | ||
198 | |||
199 | /* | ||
200 | * Convert ch from a hex digit to an int | ||
201 | */ | ||
202 | static int hex(unsigned char ch) | ||
203 | { | ||
204 | if (ch >= 'a' && ch <= 'f') | ||
205 | return ch-'a'+10; | ||
206 | if (ch >= '0' && ch <= '9') | ||
207 | return ch-'0'; | ||
208 | if (ch >= 'A' && ch <= 'F') | ||
209 | return ch-'A'+10; | ||
210 | return -1; | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * scan for the sequence $<data>#<checksum> | ||
215 | */ | ||
216 | static void getpacket(char *buffer) | ||
217 | { | ||
218 | unsigned char checksum; | ||
219 | unsigned char xmitcsum; | ||
220 | int i; | ||
221 | int count; | ||
222 | unsigned char ch; | ||
223 | |||
224 | do { | ||
225 | /* | ||
226 | * wait around for the start character, | ||
227 | * ignore all other characters | ||
228 | */ | ||
229 | while ((ch = (getDebugChar() & 0x7f)) != '$') ; | ||
230 | |||
231 | checksum = 0; | ||
232 | xmitcsum = -1; | ||
233 | count = 0; | ||
234 | |||
235 | /* | ||
236 | * now, read until a # or end of buffer is found | ||
237 | */ | ||
238 | while (count < BUFMAX) { | ||
239 | ch = getDebugChar(); | ||
240 | if (ch == '#') | ||
241 | break; | ||
242 | checksum = checksum + ch; | ||
243 | buffer[count] = ch; | ||
244 | count = count + 1; | ||
245 | } | ||
246 | |||
247 | if (count >= BUFMAX) | ||
248 | continue; | ||
249 | |||
250 | buffer[count] = 0; | ||
251 | |||
252 | if (ch == '#') { | ||
253 | xmitcsum = hex(getDebugChar() & 0x7f) << 4; | ||
254 | xmitcsum |= hex(getDebugChar() & 0x7f); | ||
255 | |||
256 | if (checksum != xmitcsum) | ||
257 | putDebugChar('-'); /* failed checksum */ | ||
258 | else { | ||
259 | putDebugChar('+'); /* successful transfer */ | ||
260 | |||
261 | /* | ||
262 | * if a sequence char is present, | ||
263 | * reply the sequence ID | ||
264 | */ | ||
265 | if (buffer[2] == ':') { | ||
266 | putDebugChar(buffer[0]); | ||
267 | putDebugChar(buffer[1]); | ||
268 | |||
269 | /* | ||
270 | * remove sequence chars from buffer | ||
271 | */ | ||
272 | count = strlen(buffer); | ||
273 | for (i=3; i <= count; i++) | ||
274 | buffer[i-3] = buffer[i]; | ||
275 | } | ||
276 | } | ||
277 | } | ||
278 | } | ||
279 | while (checksum != xmitcsum); | ||
280 | } | ||
281 | |||
282 | /* | ||
283 | * send the packet in buffer. | ||
284 | */ | ||
285 | static void putpacket(char *buffer) | ||
286 | { | ||
287 | unsigned char checksum; | ||
288 | int count; | ||
289 | unsigned char ch; | ||
290 | |||
291 | /* | ||
292 | * $<packet info>#<checksum>. | ||
293 | */ | ||
294 | |||
295 | do { | ||
296 | putDebugChar('$'); | ||
297 | checksum = 0; | ||
298 | count = 0; | ||
299 | |||
300 | while ((ch = buffer[count]) != 0) { | ||
301 | if (!(putDebugChar(ch))) | ||
302 | return; | ||
303 | checksum += ch; | ||
304 | count += 1; | ||
305 | } | ||
306 | |||
307 | putDebugChar('#'); | ||
308 | putDebugChar(hexchars[checksum >> 4]); | ||
309 | putDebugChar(hexchars[checksum & 0xf]); | ||
310 | |||
311 | } | ||
312 | while ((getDebugChar() & 0x7f) != '+'); | ||
313 | } | ||
314 | |||
315 | |||
316 | /* | ||
317 | * Convert the memory pointed to by mem into hex, placing result in buf. | ||
318 | * Return a pointer to the last char put in buf (null), in case of mem fault, | ||
319 | * return 0. | ||
320 | * may_fault is non-zero if we are reading from arbitrary memory, but is currently | ||
321 | * not used. | ||
322 | */ | ||
323 | static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault) | ||
324 | { | ||
325 | unsigned char ch; | ||
326 | |||
327 | while (count-- > 0) { | ||
328 | if (kgdb_read_byte(mem++, &ch) != 0) | ||
329 | return 0; | ||
330 | *buf++ = hexchars[ch >> 4]; | ||
331 | *buf++ = hexchars[ch & 0xf]; | ||
332 | } | ||
333 | |||
334 | *buf = 0; | ||
335 | |||
336 | return buf; | ||
337 | } | ||
338 | |||
339 | /* | ||
340 | * convert the hex array pointed to by buf into binary to be placed in mem | ||
341 | * return a pointer to the character AFTER the last byte written | ||
342 | * may_fault is non-zero if we are reading from arbitrary memory, but is currently | ||
343 | * not used. | ||
344 | */ | ||
345 | static char *hex2mem(char *buf, char *mem, int count, int binary, int may_fault) | ||
346 | { | ||
347 | int i; | ||
348 | unsigned char ch; | ||
349 | |||
350 | for (i=0; i<count; i++) | ||
351 | { | ||
352 | if (binary) { | ||
353 | ch = *buf++; | ||
354 | if (ch == 0x7d) | ||
355 | ch = 0x20 ^ *buf++; | ||
356 | } | ||
357 | else { | ||
358 | ch = hex(*buf++) << 4; | ||
359 | ch |= hex(*buf++); | ||
360 | } | ||
361 | if (kgdb_write_byte(ch, mem++) != 0) | ||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | return mem; | ||
366 | } | ||
367 | |||
368 | /* | ||
369 | * This table contains the mapping between SPARC hardware trap types, and | ||
370 | * signals, which are primarily what GDB understands. It also indicates | ||
371 | * which hardware traps we need to commandeer when initializing the stub. | ||
372 | */ | ||
373 | static struct hard_trap_info { | ||
374 | unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */ | ||
375 | unsigned char signo; /* Signal that we map this trap into */ | ||
376 | } hard_trap_info[] = { | ||
377 | { 6, SIGBUS }, /* instruction bus error */ | ||
378 | { 7, SIGBUS }, /* data bus error */ | ||
379 | { 9, SIGTRAP }, /* break */ | ||
380 | { 10, SIGILL }, /* reserved instruction */ | ||
381 | /* { 11, SIGILL }, */ /* CPU unusable */ | ||
382 | { 12, SIGFPE }, /* overflow */ | ||
383 | { 13, SIGTRAP }, /* trap */ | ||
384 | { 14, SIGSEGV }, /* virtual instruction cache coherency */ | ||
385 | { 15, SIGFPE }, /* floating point exception */ | ||
386 | { 23, SIGSEGV }, /* watch */ | ||
387 | { 31, SIGSEGV }, /* virtual data cache coherency */ | ||
388 | { 0, 0} /* Must be last */ | ||
389 | }; | ||
390 | |||
391 | /* Save the normal trap handlers for user-mode traps. */ | ||
392 | void *saved_vectors[32]; | ||
393 | |||
394 | /* | ||
395 | * Set up exception handlers for tracing and breakpoints | ||
396 | */ | ||
397 | void set_debug_traps(void) | ||
398 | { | ||
399 | struct hard_trap_info *ht; | ||
400 | unsigned long flags; | ||
401 | unsigned char c; | ||
402 | |||
403 | local_irq_save(flags); | ||
404 | for (ht = hard_trap_info; ht->tt && ht->signo; ht++) | ||
405 | saved_vectors[ht->tt] = set_except_vector(ht->tt, trap_low); | ||
406 | |||
407 | putDebugChar('+'); /* 'hello world' */ | ||
408 | /* | ||
409 | * In case GDB is started before us, ack any packets | ||
410 | * (presumably "$?#xx") sitting there. | ||
411 | */ | ||
412 | while((c = getDebugChar()) != '$'); | ||
413 | while((c = getDebugChar()) != '#'); | ||
414 | c = getDebugChar(); /* eat first csum byte */ | ||
415 | c = getDebugChar(); /* eat second csum byte */ | ||
416 | putDebugChar('+'); /* ack it */ | ||
417 | |||
418 | initialized = 1; | ||
419 | local_irq_restore(flags); | ||
420 | } | ||
421 | |||
422 | void restore_debug_traps(void) | ||
423 | { | ||
424 | struct hard_trap_info *ht; | ||
425 | unsigned long flags; | ||
426 | |||
427 | local_irq_save(flags); | ||
428 | for (ht = hard_trap_info; ht->tt && ht->signo; ht++) | ||
429 | set_except_vector(ht->tt, saved_vectors[ht->tt]); | ||
430 | local_irq_restore(flags); | ||
431 | } | ||
432 | |||
433 | /* | ||
434 | * Convert the MIPS hardware trap type code to a Unix signal number. | ||
435 | */ | ||
436 | static int computeSignal(int tt) | ||
437 | { | ||
438 | struct hard_trap_info *ht; | ||
439 | |||
440 | for (ht = hard_trap_info; ht->tt && ht->signo; ht++) | ||
441 | if (ht->tt == tt) | ||
442 | return ht->signo; | ||
443 | |||
444 | return SIGHUP; /* default for things we don't know about */ | ||
445 | } | ||
446 | |||
447 | /* | ||
448 | * While we find nice hex chars, build an int. | ||
449 | * Return number of chars processed. | ||
450 | */ | ||
451 | static int hexToInt(char **ptr, int *intValue) | ||
452 | { | ||
453 | int numChars = 0; | ||
454 | int hexValue; | ||
455 | |||
456 | *intValue = 0; | ||
457 | |||
458 | while (**ptr) { | ||
459 | hexValue = hex(**ptr); | ||
460 | if (hexValue < 0) | ||
461 | break; | ||
462 | |||
463 | *intValue = (*intValue << 4) | hexValue; | ||
464 | numChars ++; | ||
465 | |||
466 | (*ptr)++; | ||
467 | } | ||
468 | |||
469 | return (numChars); | ||
470 | } | ||
471 | |||
472 | static int hexToLong(char **ptr, long *longValue) | ||
473 | { | ||
474 | int numChars = 0; | ||
475 | int hexValue; | ||
476 | |||
477 | *longValue = 0; | ||
478 | |||
479 | while (**ptr) { | ||
480 | hexValue = hex(**ptr); | ||
481 | if (hexValue < 0) | ||
482 | break; | ||
483 | |||
484 | *longValue = (*longValue << 4) | hexValue; | ||
485 | numChars ++; | ||
486 | |||
487 | (*ptr)++; | ||
488 | } | ||
489 | |||
490 | return numChars; | ||
491 | } | ||
492 | |||
493 | |||
494 | #if 0 | ||
495 | /* | ||
496 | * Print registers (on target console) | ||
497 | * Used only to debug the stub... | ||
498 | */ | ||
499 | void show_gdbregs(struct gdb_regs * regs) | ||
500 | { | ||
501 | /* | ||
502 | * Saved main processor registers | ||
503 | */ | ||
504 | printk("$0 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", | ||
505 | regs->reg0, regs->reg1, regs->reg2, regs->reg3, | ||
506 | regs->reg4, regs->reg5, regs->reg6, regs->reg7); | ||
507 | printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", | ||
508 | regs->reg8, regs->reg9, regs->reg10, regs->reg11, | ||
509 | regs->reg12, regs->reg13, regs->reg14, regs->reg15); | ||
510 | printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", | ||
511 | regs->reg16, regs->reg17, regs->reg18, regs->reg19, | ||
512 | regs->reg20, regs->reg21, regs->reg22, regs->reg23); | ||
513 | printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", | ||
514 | regs->reg24, regs->reg25, regs->reg26, regs->reg27, | ||
515 | regs->reg28, regs->reg29, regs->reg30, regs->reg31); | ||
516 | |||
517 | /* | ||
518 | * Saved cp0 registers | ||
519 | */ | ||
520 | printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\n", | ||
521 | regs->cp0_epc, regs->cp0_status, regs->cp0_cause); | ||
522 | } | ||
523 | #endif /* dead code */ | ||
524 | |||
525 | /* | ||
526 | * We single-step by setting breakpoints. When an exception | ||
527 | * is handled, we need to restore the instructions hoisted | ||
528 | * when the breakpoints were set. | ||
529 | * | ||
530 | * This is where we save the original instructions. | ||
531 | */ | ||
532 | static struct gdb_bp_save { | ||
533 | unsigned long addr; | ||
534 | unsigned int val; | ||
535 | } step_bp[2]; | ||
536 | |||
537 | #define BP 0x0000000d /* break opcode */ | ||
538 | |||
539 | /* | ||
540 | * Set breakpoint instructions for single stepping. | ||
541 | */ | ||
542 | static void single_step(struct gdb_regs *regs) | ||
543 | { | ||
544 | union mips_instruction insn; | ||
545 | unsigned long targ; | ||
546 | int is_branch, is_cond, i; | ||
547 | |||
548 | targ = regs->cp0_epc; | ||
549 | insn.word = *(unsigned int *)targ; | ||
550 | is_branch = is_cond = 0; | ||
551 | |||
552 | switch (insn.i_format.opcode) { | ||
553 | /* | ||
554 | * jr and jalr are in r_format format. | ||
555 | */ | ||
556 | case spec_op: | ||
557 | switch (insn.r_format.func) { | ||
558 | case jalr_op: | ||
559 | case jr_op: | ||
560 | targ = *(®s->reg0 + insn.r_format.rs); | ||
561 | is_branch = 1; | ||
562 | break; | ||
563 | } | ||
564 | break; | ||
565 | |||
566 | /* | ||
567 | * This group contains: | ||
568 | * bltz_op, bgez_op, bltzl_op, bgezl_op, | ||
569 | * bltzal_op, bgezal_op, bltzall_op, bgezall_op. | ||
570 | */ | ||
571 | case bcond_op: | ||
572 | is_branch = is_cond = 1; | ||
573 | targ += 4 + (insn.i_format.simmediate << 2); | ||
574 | break; | ||
575 | |||
576 | /* | ||
577 | * These are unconditional and in j_format. | ||
578 | */ | ||
579 | case jal_op: | ||
580 | case j_op: | ||
581 | is_branch = 1; | ||
582 | targ += 4; | ||
583 | targ >>= 28; | ||
584 | targ <<= 28; | ||
585 | targ |= (insn.j_format.target << 2); | ||
586 | break; | ||
587 | |||
588 | /* | ||
589 | * These are conditional. | ||
590 | */ | ||
591 | case beq_op: | ||
592 | case beql_op: | ||
593 | case bne_op: | ||
594 | case bnel_op: | ||
595 | case blez_op: | ||
596 | case blezl_op: | ||
597 | case bgtz_op: | ||
598 | case bgtzl_op: | ||
599 | case cop0_op: | ||
600 | case cop1_op: | ||
601 | case cop2_op: | ||
602 | case cop1x_op: | ||
603 | is_branch = is_cond = 1; | ||
604 | targ += 4 + (insn.i_format.simmediate << 2); | ||
605 | break; | ||
606 | } | ||
607 | |||
608 | if (is_branch) { | ||
609 | i = 0; | ||
610 | if (is_cond && targ != (regs->cp0_epc + 8)) { | ||
611 | step_bp[i].addr = regs->cp0_epc + 8; | ||
612 | step_bp[i++].val = *(unsigned *)(regs->cp0_epc + 8); | ||
613 | *(unsigned *)(regs->cp0_epc + 8) = BP; | ||
614 | } | ||
615 | step_bp[i].addr = targ; | ||
616 | step_bp[i].val = *(unsigned *)targ; | ||
617 | *(unsigned *)targ = BP; | ||
618 | } else { | ||
619 | step_bp[0].addr = regs->cp0_epc + 4; | ||
620 | step_bp[0].val = *(unsigned *)(regs->cp0_epc + 4); | ||
621 | *(unsigned *)(regs->cp0_epc + 4) = BP; | ||
622 | } | ||
623 | } | ||
624 | |||
625 | /* | ||
626 | * If asynchronously interrupted by gdb, then we need to set a breakpoint | ||
627 | * at the interrupted instruction so that we wind up stopped with a | ||
628 | * reasonable stack frame. | ||
629 | */ | ||
630 | static struct gdb_bp_save async_bp; | ||
631 | |||
632 | /* | ||
633 | * Swap the interrupted EPC with our asynchronous breakpoint routine. | ||
634 | * This is safer than stuffing the breakpoint in-place, since no cache | ||
635 | * flushes (or resulting smp_call_functions) are required. The | ||
636 | * assumption is that only one CPU will be handling asynchronous bp's, | ||
637 | * and only one can be active at a time. | ||
638 | */ | ||
639 | extern spinlock_t smp_call_lock; | ||
640 | void set_async_breakpoint(unsigned long *epc) | ||
641 | { | ||
642 | /* skip breaking into userland */ | ||
643 | if ((*epc & 0x80000000) == 0) | ||
644 | return; | ||
645 | |||
646 | /* avoid deadlock if someone is make IPC */ | ||
647 | if (spin_is_locked(&smp_call_lock)) | ||
648 | return; | ||
649 | |||
650 | async_bp.addr = *epc; | ||
651 | *epc = (unsigned long)async_breakpoint; | ||
652 | } | ||
653 | |||
654 | void kgdb_wait(void *arg) | ||
655 | { | ||
656 | unsigned flags; | ||
657 | int cpu = smp_processor_id(); | ||
658 | |||
659 | local_irq_save(flags); | ||
660 | |||
661 | spin_lock(&kgdb_cpulock[cpu]); | ||
662 | spin_unlock(&kgdb_cpulock[cpu]); | ||
663 | |||
664 | local_irq_restore(flags); | ||
665 | } | ||
666 | |||
667 | |||
668 | /* | ||
669 | * This function does all command processing for interfacing to gdb. It | ||
670 | * returns 1 if you should skip the instruction at the trap address, 0 | ||
671 | * otherwise. | ||
672 | */ | ||
673 | void handle_exception (struct gdb_regs *regs) | ||
674 | { | ||
675 | int trap; /* Trap type */ | ||
676 | int sigval; | ||
677 | long addr; | ||
678 | int length; | ||
679 | char *ptr; | ||
680 | unsigned long *stack; | ||
681 | int i; | ||
682 | int bflag = 0; | ||
683 | |||
684 | kgdb_started = 1; | ||
685 | |||
686 | /* | ||
687 | * acquire the big kgdb spinlock | ||
688 | */ | ||
689 | if (!spin_trylock(&kgdb_lock)) { | ||
690 | /* | ||
691 | * some other CPU has the lock, we should go back to | ||
692 | * receive the gdb_wait IPC | ||
693 | */ | ||
694 | return; | ||
695 | } | ||
696 | |||
697 | /* | ||
698 | * If we're in async_breakpoint(), restore the real EPC from | ||
699 | * the breakpoint. | ||
700 | */ | ||
701 | if (regs->cp0_epc == (unsigned long)async_breakinst) { | ||
702 | regs->cp0_epc = async_bp.addr; | ||
703 | async_bp.addr = 0; | ||
704 | } | ||
705 | |||
706 | /* | ||
707 | * acquire the CPU spinlocks | ||
708 | */ | ||
709 | for (i = num_online_cpus()-1; i >= 0; i--) | ||
710 | if (spin_trylock(&kgdb_cpulock[i]) == 0) | ||
711 | panic("kgdb: couldn't get cpulock %d\n", i); | ||
712 | |||
713 | /* | ||
714 | * force other cpus to enter kgdb | ||
715 | */ | ||
716 | smp_call_function(kgdb_wait, NULL, 0, 0); | ||
717 | |||
718 | /* | ||
719 | * If we're in breakpoint() increment the PC | ||
720 | */ | ||
721 | trap = (regs->cp0_cause & 0x7c) >> 2; | ||
722 | if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst) | ||
723 | regs->cp0_epc += 4; | ||
724 | |||
725 | /* | ||
726 | * If we were single_stepping, restore the opcodes hoisted | ||
727 | * for the breakpoint[s]. | ||
728 | */ | ||
729 | if (step_bp[0].addr) { | ||
730 | *(unsigned *)step_bp[0].addr = step_bp[0].val; | ||
731 | step_bp[0].addr = 0; | ||
732 | |||
733 | if (step_bp[1].addr) { | ||
734 | *(unsigned *)step_bp[1].addr = step_bp[1].val; | ||
735 | step_bp[1].addr = 0; | ||
736 | } | ||
737 | } | ||
738 | |||
739 | stack = (long *)regs->reg29; /* stack ptr */ | ||
740 | sigval = computeSignal(trap); | ||
741 | |||
742 | /* | ||
743 | * reply to host that an exception has occurred | ||
744 | */ | ||
745 | ptr = output_buffer; | ||
746 | |||
747 | /* | ||
748 | * Send trap type (converted to signal) | ||
749 | */ | ||
750 | *ptr++ = 'T'; | ||
751 | *ptr++ = hexchars[sigval >> 4]; | ||
752 | *ptr++ = hexchars[sigval & 0xf]; | ||
753 | |||
754 | /* | ||
755 | * Send Error PC | ||
756 | */ | ||
757 | *ptr++ = hexchars[REG_EPC >> 4]; | ||
758 | *ptr++ = hexchars[REG_EPC & 0xf]; | ||
759 | *ptr++ = ':'; | ||
760 | ptr = mem2hex((char *)®s->cp0_epc, ptr, sizeof(long), 0); | ||
761 | *ptr++ = ';'; | ||
762 | |||
763 | /* | ||
764 | * Send frame pointer | ||
765 | */ | ||
766 | *ptr++ = hexchars[REG_FP >> 4]; | ||
767 | *ptr++ = hexchars[REG_FP & 0xf]; | ||
768 | *ptr++ = ':'; | ||
769 | ptr = mem2hex((char *)®s->reg30, ptr, sizeof(long), 0); | ||
770 | *ptr++ = ';'; | ||
771 | |||
772 | /* | ||
773 | * Send stack pointer | ||
774 | */ | ||
775 | *ptr++ = hexchars[REG_SP >> 4]; | ||
776 | *ptr++ = hexchars[REG_SP & 0xf]; | ||
777 | *ptr++ = ':'; | ||
778 | ptr = mem2hex((char *)®s->reg29, ptr, sizeof(long), 0); | ||
779 | *ptr++ = ';'; | ||
780 | |||
781 | *ptr++ = 0; | ||
782 | putpacket(output_buffer); /* send it off... */ | ||
783 | |||
784 | /* | ||
785 | * Wait for input from remote GDB | ||
786 | */ | ||
787 | while (1) { | ||
788 | output_buffer[0] = 0; | ||
789 | getpacket(input_buffer); | ||
790 | |||
791 | switch (input_buffer[0]) | ||
792 | { | ||
793 | case '?': | ||
794 | output_buffer[0] = 'S'; | ||
795 | output_buffer[1] = hexchars[sigval >> 4]; | ||
796 | output_buffer[2] = hexchars[sigval & 0xf]; | ||
797 | output_buffer[3] = 0; | ||
798 | break; | ||
799 | |||
800 | /* | ||
801 | * Detach debugger; let CPU run | ||
802 | */ | ||
803 | case 'D': | ||
804 | putpacket(output_buffer); | ||
805 | goto finish_kgdb; | ||
806 | break; | ||
807 | |||
808 | case 'd': | ||
809 | /* toggle debug flag */ | ||
810 | break; | ||
811 | |||
812 | /* | ||
813 | * Return the value of the CPU registers | ||
814 | */ | ||
815 | case 'g': | ||
816 | ptr = output_buffer; | ||
817 | ptr = mem2hex((char *)®s->reg0, ptr, 32*sizeof(long), 0); /* r0...r31 */ | ||
818 | ptr = mem2hex((char *)®s->cp0_status, ptr, 6*sizeof(long), 0); /* cp0 */ | ||
819 | ptr = mem2hex((char *)®s->fpr0, ptr, 32*sizeof(long), 0); /* f0...31 */ | ||
820 | ptr = mem2hex((char *)®s->cp1_fsr, ptr, 2*sizeof(long), 0); /* cp1 */ | ||
821 | ptr = mem2hex((char *)®s->frame_ptr, ptr, 2*sizeof(long), 0); /* frp */ | ||
822 | ptr = mem2hex((char *)®s->cp0_index, ptr, 16*sizeof(long), 0); /* cp0 */ | ||
823 | break; | ||
824 | |||
825 | /* | ||
826 | * set the value of the CPU registers - return OK | ||
827 | */ | ||
828 | case 'G': | ||
829 | { | ||
830 | ptr = &input_buffer[1]; | ||
831 | hex2mem(ptr, (char *)®s->reg0, 32*sizeof(long), 0, 0); | ||
832 | ptr += 32*(2*sizeof(long)); | ||
833 | hex2mem(ptr, (char *)®s->cp0_status, 6*sizeof(long), 0, 0); | ||
834 | ptr += 6*(2*sizeof(long)); | ||
835 | hex2mem(ptr, (char *)®s->fpr0, 32*sizeof(long), 0, 0); | ||
836 | ptr += 32*(2*sizeof(long)); | ||
837 | hex2mem(ptr, (char *)®s->cp1_fsr, 2*sizeof(long), 0, 0); | ||
838 | ptr += 2*(2*sizeof(long)); | ||
839 | hex2mem(ptr, (char *)®s->frame_ptr, 2*sizeof(long), 0, 0); | ||
840 | ptr += 2*(2*sizeof(long)); | ||
841 | hex2mem(ptr, (char *)®s->cp0_index, 16*sizeof(long), 0, 0); | ||
842 | strcpy(output_buffer,"OK"); | ||
843 | } | ||
844 | break; | ||
845 | |||
846 | /* | ||
847 | * mAA..AA,LLLL Read LLLL bytes at address AA..AA | ||
848 | */ | ||
849 | case 'm': | ||
850 | ptr = &input_buffer[1]; | ||
851 | |||
852 | if (hexToLong(&ptr, &addr) | ||
853 | && *ptr++ == ',' | ||
854 | && hexToInt(&ptr, &length)) { | ||
855 | if (mem2hex((char *)addr, output_buffer, length, 1)) | ||
856 | break; | ||
857 | strcpy (output_buffer, "E03"); | ||
858 | } else | ||
859 | strcpy(output_buffer,"E01"); | ||
860 | break; | ||
861 | |||
862 | /* | ||
863 | * XAA..AA,LLLL: Write LLLL escaped binary bytes at address AA.AA | ||
864 | */ | ||
865 | case 'X': | ||
866 | bflag = 1; | ||
867 | /* fall through */ | ||
868 | |||
869 | /* | ||
870 | * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK | ||
871 | */ | ||
872 | case 'M': | ||
873 | ptr = &input_buffer[1]; | ||
874 | |||
875 | if (hexToLong(&ptr, &addr) | ||
876 | && *ptr++ == ',' | ||
877 | && hexToInt(&ptr, &length) | ||
878 | && *ptr++ == ':') { | ||
879 | if (hex2mem(ptr, (char *)addr, length, bflag, 1)) | ||
880 | strcpy(output_buffer, "OK"); | ||
881 | else | ||
882 | strcpy(output_buffer, "E03"); | ||
883 | } | ||
884 | else | ||
885 | strcpy(output_buffer, "E02"); | ||
886 | break; | ||
887 | |||
888 | /* | ||
889 | * cAA..AA Continue at address AA..AA(optional) | ||
890 | */ | ||
891 | case 'c': | ||
892 | /* try to read optional parameter, pc unchanged if no parm */ | ||
893 | |||
894 | ptr = &input_buffer[1]; | ||
895 | if (hexToLong(&ptr, &addr)) | ||
896 | regs->cp0_epc = addr; | ||
897 | |||
898 | goto exit_kgdb_exception; | ||
899 | break; | ||
900 | |||
901 | /* | ||
902 | * kill the program; let us try to restart the machine | ||
903 | * Reset the whole machine. | ||
904 | */ | ||
905 | case 'k': | ||
906 | case 'r': | ||
907 | machine_restart("kgdb restarts machine"); | ||
908 | break; | ||
909 | |||
910 | /* | ||
911 | * Step to next instruction | ||
912 | */ | ||
913 | case 's': | ||
914 | /* | ||
915 | * There is no single step insn in the MIPS ISA, so we | ||
916 | * use breakpoints and continue, instead. | ||
917 | */ | ||
918 | single_step(regs); | ||
919 | goto exit_kgdb_exception; | ||
920 | /* NOTREACHED */ | ||
921 | break; | ||
922 | |||
923 | /* | ||
924 | * Set baud rate (bBB) | ||
925 | * FIXME: Needs to be written | ||
926 | */ | ||
927 | case 'b': | ||
928 | { | ||
929 | #if 0 | ||
930 | int baudrate; | ||
931 | extern void set_timer_3(); | ||
932 | |||
933 | ptr = &input_buffer[1]; | ||
934 | if (!hexToInt(&ptr, &baudrate)) | ||
935 | { | ||
936 | strcpy(output_buffer,"B01"); | ||
937 | break; | ||
938 | } | ||
939 | |||
940 | /* Convert baud rate to uart clock divider */ | ||
941 | |||
942 | switch (baudrate) | ||
943 | { | ||
944 | case 38400: | ||
945 | baudrate = 16; | ||
946 | break; | ||
947 | case 19200: | ||
948 | baudrate = 33; | ||
949 | break; | ||
950 | case 9600: | ||
951 | baudrate = 65; | ||
952 | break; | ||
953 | default: | ||
954 | baudrate = 0; | ||
955 | strcpy(output_buffer,"B02"); | ||
956 | goto x1; | ||
957 | } | ||
958 | |||
959 | if (baudrate) { | ||
960 | putpacket("OK"); /* Ack before changing speed */ | ||
961 | set_timer_3(baudrate); /* Set it */ | ||
962 | } | ||
963 | #endif | ||
964 | } | ||
965 | break; | ||
966 | |||
967 | } /* switch */ | ||
968 | |||
969 | /* | ||
970 | * reply to the request | ||
971 | */ | ||
972 | |||
973 | putpacket(output_buffer); | ||
974 | |||
975 | } /* while */ | ||
976 | |||
977 | return; | ||
978 | |||
979 | finish_kgdb: | ||
980 | restore_debug_traps(); | ||
981 | |||
982 | exit_kgdb_exception: | ||
983 | /* release locks so other CPUs can go */ | ||
984 | for (i = num_online_cpus()-1; i >= 0; i--) | ||
985 | spin_unlock(&kgdb_cpulock[i]); | ||
986 | spin_unlock(&kgdb_lock); | ||
987 | |||
988 | __flush_cache_all(); | ||
989 | return; | ||
990 | } | ||
991 | |||
992 | /* | ||
993 | * This function will generate a breakpoint exception. It is used at the | ||
994 | * beginning of a program to sync up with a debugger and can be used | ||
995 | * otherwise as a quick means to stop program execution and "break" into | ||
996 | * the debugger. | ||
997 | */ | ||
998 | void breakpoint(void) | ||
999 | { | ||
1000 | if (!initialized) | ||
1001 | return; | ||
1002 | |||
1003 | __asm__ __volatile__( | ||
1004 | ".globl breakinst\n\t" | ||
1005 | ".set\tnoreorder\n\t" | ||
1006 | "nop\n" | ||
1007 | "breakinst:\tbreak\n\t" | ||
1008 | "nop\n\t" | ||
1009 | ".set\treorder" | ||
1010 | ); | ||
1011 | } | ||
1012 | |||
1013 | /* Nothing but the break; don't pollute any registers */ | ||
1014 | void async_breakpoint(void) | ||
1015 | { | ||
1016 | __asm__ __volatile__( | ||
1017 | ".globl async_breakinst\n\t" | ||
1018 | ".set\tnoreorder\n\t" | ||
1019 | "nop\n" | ||
1020 | "async_breakinst:\tbreak\n\t" | ||
1021 | "nop\n\t" | ||
1022 | ".set\treorder" | ||
1023 | ); | ||
1024 | } | ||
1025 | |||
1026 | void adel(void) | ||
1027 | { | ||
1028 | __asm__ __volatile__( | ||
1029 | ".globl\tadel\n\t" | ||
1030 | "lui\t$8,0x8000\n\t" | ||
1031 | "lw\t$9,1($8)\n\t" | ||
1032 | ); | ||
1033 | } | ||
1034 | |||
1035 | /* | ||
1036 | * malloc is needed by gdb client in "call func()", even a private one | ||
1037 | * will make gdb happy | ||
1038 | */ | ||
1039 | static void *malloc(size_t size) | ||
1040 | { | ||
1041 | return kmalloc(size, GFP_ATOMIC); | ||
1042 | } | ||
1043 | |||
1044 | static void free(void *where) | ||
1045 | { | ||
1046 | kfree(where); | ||
1047 | } | ||
1048 | |||
1049 | #ifdef CONFIG_GDB_CONSOLE | ||
1050 | |||
1051 | void gdb_putsn(const char *str, int l) | ||
1052 | { | ||
1053 | char outbuf[18]; | ||
1054 | |||
1055 | if (!kgdb_started) | ||
1056 | return; | ||
1057 | |||
1058 | outbuf[0]='O'; | ||
1059 | |||
1060 | while(l) { | ||
1061 | int i = (l>8)?8:l; | ||
1062 | mem2hex((char *)str, &outbuf[1], i, 0); | ||
1063 | outbuf[(i*2)+1]=0; | ||
1064 | putpacket(outbuf); | ||
1065 | str += i; | ||
1066 | l -= i; | ||
1067 | } | ||
1068 | } | ||
1069 | |||
1070 | static void gdb_console_write(struct console *con, const char *s, unsigned n) | ||
1071 | { | ||
1072 | gdb_putsn(s, n); | ||
1073 | } | ||
1074 | |||
1075 | static struct console gdb_console = { | ||
1076 | .name = "gdb", | ||
1077 | .write = gdb_console_write, | ||
1078 | .flags = CON_PRINTBUFFER, | ||
1079 | .index = -1 | ||
1080 | }; | ||
1081 | |||
1082 | static int __init register_gdb_console(void) | ||
1083 | { | ||
1084 | register_console(&gdb_console); | ||
1085 | |||
1086 | return 0; | ||
1087 | } | ||
1088 | |||
1089 | console_initcall(register_gdb_console); | ||
1090 | |||
1091 | #endif | ||