Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfashe...
[deliverable/linux.git] / arch / ppc / kernel / ppc-stub.c
CommitLineData
1da177e4
LT
1/*
2 * ppc-stub.c: KGDB support for the Linux kernel.
3 *
4 * adapted from arch/sparc/kernel/sparc-stub.c for the PowerPC
5 * some stuff borrowed from Paul Mackerras' xmon
6 * Copyright (C) 1998 Michael AK Tesch (tesch@cs.wisc.edu)
7 *
8 * Modifications to run under Linux
9 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
10 *
11 * This file originally came from the gdb sources, and the
12 * copyright notices have been retained below.
13 */
14
15/****************************************************************************
16
17 THIS SOFTWARE IS NOT COPYRIGHTED
18
19 HP offers the following for use in the public domain. HP makes no
20 warranty with regard to the software or its performance and the
21 user accepts the software "AS IS" with all faults.
22
23 HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
24 TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
25 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26
27****************************************************************************/
28
29/****************************************************************************
30 * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
31 *
32 * Module name: remcom.c $
33 * Revision: 1.34 $
34 * Date: 91/03/09 12:29:49 $
35 * Contributor: Lake Stevens Instrument Division$
36 *
37 * Description: low level support for gdb debugger. $
38 *
39 * Considerations: only works on target hardware $
40 *
41 * Written by: Glenn Engel $
42 * ModuleState: Experimental $
43 *
44 * NOTES: See Below $
45 *
46 * Modified for SPARC by Stu Grossman, Cygnus Support.
47 *
48 * This code has been extensively tested on the Fujitsu SPARClite demo board.
49 *
50 * To enable debugger support, two things need to happen. One, a
51 * call to set_debug_traps() is necessary in order to allow any breakpoints
52 * or error conditions to be properly intercepted and reported to gdb.
53 * Two, a breakpoint needs to be generated to begin communication. This
54 * is most easily accomplished by a call to breakpoint(). Breakpoint()
55 * simulates a breakpoint by executing a trap #1.
56 *
57 *************
58 *
59 * The following gdb commands are supported:
60 *
61 * command function Return value
62 *
63 * g return the value of the CPU registers hex data or ENN
64 * G set the value of the CPU registers OK or ENN
65 * qOffsets Get section offsets. Reply is Text=xxx;Data=yyy;Bss=zzz
66 *
67 * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
68 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
69 *
70 * c Resume at current address SNN ( signal NN)
71 * cAA..AA Continue at address AA..AA SNN
72 *
73 * s Step one instruction SNN
74 * sAA..AA Step one instruction from AA..AA SNN
75 *
76 * k kill
77 *
78 * ? What was the last sigval ? SNN (signal NN)
79 *
80 * bBB..BB Set baud rate to BB..BB OK or BNN, then sets
81 * baud rate
82 *
83 * All commands and responses are sent with a packet which includes a
84 * checksum. A packet consists of
85 *
86 * $<packet info>#<checksum>.
87 *
88 * where
89 * <packet info> :: <characters representing the command or response>
90 * <checksum> :: <two hex digits computed as modulo 256 sum of <packetinfo>>
91 *
92 * When a packet is received, it is first acknowledged with either '+' or '-'.
93 * '+' indicates a successful transfer. '-' indicates a failed transfer.
94 *
95 * Example:
96 *
97 * Host: Reply:
98 * $m0,10#2a +$00010203040506070809101112131415#42
99 *
100 ****************************************************************************/
101
1da177e4
LT
102#include <linux/kernel.h>
103#include <linux/string.h>
104#include <linux/mm.h>
105#include <linux/smp.h>
106#include <linux/smp_lock.h>
107#include <linux/init.h>
108#include <linux/sysrq.h>
109
110#include <asm/cacheflush.h>
111#include <asm/system.h>
112#include <asm/signal.h>
113#include <asm/kgdb.h>
114#include <asm/pgtable.h>
115#include <asm/ptrace.h>
116
117void breakinst(void);
118
119/*
120 * BUFMAX defines the maximum number of characters in inbound/outbound buffers
121 * at least NUMREGBYTES*2 are needed for register packets
122 */
123#define BUFMAX 2048
124static char remcomInBuffer[BUFMAX];
125static char remcomOutBuffer[BUFMAX];
126
127static int initialized;
128static int kgdb_active;
129static int kgdb_started;
130static u_int fault_jmp_buf[100];
131static int kdebug;
132
133
134static const char hexchars[]="0123456789abcdef";
135
136/* Place where we save old trap entries for restoration - sparc*/
137/* struct tt_entry kgdb_savettable[256]; */
138/* typedef void (*trapfunc_t)(void); */
139
140static void kgdb_fault_handler(struct pt_regs *regs);
141static int handle_exception (struct pt_regs *regs);
142
143#if 0
144/* Install an exception handler for kgdb */
145static void exceptionHandler(int tnum, unsigned int *tfunc)
146{
147 /* We are dorking with a live trap table, all irqs off */
148}
149#endif
150
151int
152kgdb_setjmp(long *buf)
153{
154 asm ("mflr 0; stw 0,0(%0);"
155 "stw 1,4(%0); stw 2,8(%0);"
156 "mfcr 0; stw 0,12(%0);"
157 "stmw 13,16(%0)"
158 : : "r" (buf));
159 /* XXX should save fp regs as well */
160 return 0;
161}
162void
163kgdb_longjmp(long *buf, int val)
164{
165 if (val == 0)
166 val = 1;
167 asm ("lmw 13,16(%0);"
168 "lwz 0,12(%0); mtcrf 0x38,0;"
169 "lwz 0,0(%0); lwz 1,4(%0); lwz 2,8(%0);"
170 "mtlr 0; mr 3,%1"
171 : : "r" (buf), "r" (val));
172}
173/* Convert ch from a hex digit to an int */
174static int
175hex(unsigned char ch)
176{
177 if (ch >= 'a' && ch <= 'f')
178 return ch-'a'+10;
179 if (ch >= '0' && ch <= '9')
180 return ch-'0';
181 if (ch >= 'A' && ch <= 'F')
182 return ch-'A'+10;
183 return -1;
184}
185
186/* Convert the memory pointed to by mem into hex, placing result in buf.
187 * Return a pointer to the last char put in buf (null), in case of mem fault,
188 * return 0.
189 */
190static unsigned char *
191mem2hex(const char *mem, char *buf, int count)
192{
193 unsigned char ch;
194 unsigned short tmp_s;
195 unsigned long tmp_l;
196
197 if (kgdb_setjmp((long*)fault_jmp_buf) == 0) {
198 debugger_fault_handler = kgdb_fault_handler;
199
200 /* Accessing 16 bit and 32 bit objects in a single
201 ** load instruction is required to avoid bad side
202 ** effects for some IO registers.
203 */
204
205 if ((count == 2) && (((long)mem & 1) == 0)) {
206 tmp_s = *(unsigned short *)mem;
207 mem += 2;
208 *buf++ = hexchars[(tmp_s >> 12) & 0xf];
209 *buf++ = hexchars[(tmp_s >> 8) & 0xf];
210 *buf++ = hexchars[(tmp_s >> 4) & 0xf];
211 *buf++ = hexchars[tmp_s & 0xf];
212
213 } else if ((count == 4) && (((long)mem & 3) == 0)) {
214 tmp_l = *(unsigned int *)mem;
215 mem += 4;
216 *buf++ = hexchars[(tmp_l >> 28) & 0xf];
217 *buf++ = hexchars[(tmp_l >> 24) & 0xf];
218 *buf++ = hexchars[(tmp_l >> 20) & 0xf];
219 *buf++ = hexchars[(tmp_l >> 16) & 0xf];
220 *buf++ = hexchars[(tmp_l >> 12) & 0xf];
221 *buf++ = hexchars[(tmp_l >> 8) & 0xf];
222 *buf++ = hexchars[(tmp_l >> 4) & 0xf];
223 *buf++ = hexchars[tmp_l & 0xf];
224
225 } else {
226 while (count-- > 0) {
227 ch = *mem++;
228 *buf++ = hexchars[ch >> 4];
229 *buf++ = hexchars[ch & 0xf];
230 }
231 }
232
233 } else {
234 /* error condition */
235 }
236 debugger_fault_handler = NULL;
237 *buf = 0;
238 return buf;
239}
240
241/* convert the hex array pointed to by buf into binary to be placed in mem
242 * return a pointer to the character AFTER the last byte written.
243*/
244static char *
245hex2mem(char *buf, char *mem, int count)
246{
247 unsigned char ch;
248 int i;
249 char *orig_mem;
250 unsigned short tmp_s;
251 unsigned long tmp_l;
252
253 orig_mem = mem;
254
255 if (kgdb_setjmp((long*)fault_jmp_buf) == 0) {
256 debugger_fault_handler = kgdb_fault_handler;
257
258 /* Accessing 16 bit and 32 bit objects in a single
259 ** store instruction is required to avoid bad side
260 ** effects for some IO registers.
261 */
262
263 if ((count == 2) && (((long)mem & 1) == 0)) {
264 tmp_s = hex(*buf++) << 12;
265 tmp_s |= hex(*buf++) << 8;
266 tmp_s |= hex(*buf++) << 4;
267 tmp_s |= hex(*buf++);
268
269 *(unsigned short *)mem = tmp_s;
270 mem += 2;
271
272 } else if ((count == 4) && (((long)mem & 3) == 0)) {
273 tmp_l = hex(*buf++) << 28;
274 tmp_l |= hex(*buf++) << 24;
275 tmp_l |= hex(*buf++) << 20;
276 tmp_l |= hex(*buf++) << 16;
277 tmp_l |= hex(*buf++) << 12;
278 tmp_l |= hex(*buf++) << 8;
279 tmp_l |= hex(*buf++) << 4;
280 tmp_l |= hex(*buf++);
281
282 *(unsigned long *)mem = tmp_l;
283 mem += 4;
284
285 } else {
286 for (i=0; i<count; i++) {
287 ch = hex(*buf++) << 4;
288 ch |= hex(*buf++);
289 *mem++ = ch;
290 }
291 }
292
293
294 /*
295 ** Flush the data cache, invalidate the instruction cache.
296 */
297 flush_icache_range((int)orig_mem, (int)orig_mem + count - 1);
298
299 } else {
300 /* error condition */
301 }
302 debugger_fault_handler = NULL;
303 return mem;
304}
305
306/*
307 * While we find nice hex chars, build an int.
308 * Return number of chars processed.
309 */
310static int
311hexToInt(char **ptr, int *intValue)
312{
313 int numChars = 0;
314 int hexValue;
315
316 *intValue = 0;
317
318 if (kgdb_setjmp((long*)fault_jmp_buf) == 0) {
319 debugger_fault_handler = kgdb_fault_handler;
320 while (**ptr) {
321 hexValue = hex(**ptr);
322 if (hexValue < 0)
323 break;
324
325 *intValue = (*intValue << 4) | hexValue;
326 numChars ++;
327
328 (*ptr)++;
329 }
330 } else {
331 /* error condition */
332 }
333 debugger_fault_handler = NULL;
334
335 return (numChars);
336}
337
338/* scan for the sequence $<data>#<checksum> */
339static void
340getpacket(char *buffer)
341{
342 unsigned char checksum;
343 unsigned char xmitcsum;
344 int i;
345 int count;
346 unsigned char ch;
347
348 do {
349 /* wait around for the start character, ignore all other
350 * characters */
351 while ((ch = (getDebugChar() & 0x7f)) != '$') ;
352
353 checksum = 0;
354 xmitcsum = -1;
355
356 count = 0;
357
358 /* now, read until a # or end of buffer is found */
359 while (count < BUFMAX) {
360 ch = getDebugChar() & 0x7f;
361 if (ch == '#')
362 break;
363 checksum = checksum + ch;
364 buffer[count] = ch;
365 count = count + 1;
366 }
367
368 if (count >= BUFMAX)
369 continue;
370
371 buffer[count] = 0;
372
373 if (ch == '#') {
374 xmitcsum = hex(getDebugChar() & 0x7f) << 4;
375 xmitcsum |= hex(getDebugChar() & 0x7f);
376 if (checksum != xmitcsum)
377 putDebugChar('-'); /* failed checksum */
378 else {
379 putDebugChar('+'); /* successful transfer */
380 /* if a sequence char is present, reply the ID */
381 if (buffer[2] == ':') {
382 putDebugChar(buffer[0]);
383 putDebugChar(buffer[1]);
384 /* remove sequence chars from buffer */
385 count = strlen(buffer);
386 for (i=3; i <= count; i++)
387 buffer[i-3] = buffer[i];
388 }
389 }
390 }
391 } while (checksum != xmitcsum);
392}
393
394/* send the packet in buffer. */
395static void putpacket(unsigned char *buffer)
396{
397 unsigned char checksum;
398 int count;
399 unsigned char ch, recv;
400
401 /* $<packet info>#<checksum>. */
402 do {
403 putDebugChar('$');
404 checksum = 0;
405 count = 0;
406
407 while ((ch = buffer[count])) {
408 putDebugChar(ch);
409 checksum += ch;
410 count += 1;
411 }
412
413 putDebugChar('#');
414 putDebugChar(hexchars[checksum >> 4]);
415 putDebugChar(hexchars[checksum & 0xf]);
416 recv = getDebugChar();
417 } while ((recv & 0x7f) != '+');
418}
419
420static void kgdb_flush_cache_all(void)
421{
422 flush_instruction_cache();
423}
424
425/* Set up exception handlers for tracing and breakpoints
426 * [could be called kgdb_init()]
427 */
428void set_debug_traps(void)
429{
430#if 0
431 unsigned char c;
432
433 save_and_cli(flags);
434
435 /* In case GDB is started before us, ack any packets (presumably
436 * "$?#xx") sitting there.
437 *
438 * I've found this code causes more problems than it solves,
439 * so that's why it's commented out. GDB seems to work fine
440 * now starting either before or after the kernel -bwb
441 */
442
443 while((c = getDebugChar()) != '$');
444 while((c = getDebugChar()) != '#');
445 c = getDebugChar(); /* eat first csum byte */
446 c = getDebugChar(); /* eat second csum byte */
447 putDebugChar('+'); /* ack it */
448#endif
449 debugger = kgdb;
450 debugger_bpt = kgdb_bpt;
451 debugger_sstep = kgdb_sstep;
452 debugger_iabr_match = kgdb_iabr_match;
453 debugger_dabr_match = kgdb_dabr_match;
454
455 initialized = 1;
456}
457
458static void kgdb_fault_handler(struct pt_regs *regs)
459{
460 kgdb_longjmp((long*)fault_jmp_buf, 1);
461}
462
463int kgdb_bpt(struct pt_regs *regs)
464{
465 return handle_exception(regs);
466}
467
468int kgdb_sstep(struct pt_regs *regs)
469{
470 return handle_exception(regs);
471}
472
473void kgdb(struct pt_regs *regs)
474{
475 handle_exception(regs);
476}
477
478int kgdb_iabr_match(struct pt_regs *regs)
479{
480 printk(KERN_ERR "kgdb doesn't support iabr, what?!?\n");
481 return handle_exception(regs);
482}
483
484int kgdb_dabr_match(struct pt_regs *regs)
485{
486 printk(KERN_ERR "kgdb doesn't support dabr, what?!?\n");
487 return handle_exception(regs);
488}
489
490/* Convert the hardware trap type code to a unix signal number. */
491/*
492 * This table contains the mapping between PowerPC hardware trap types, and
493 * signals, which are primarily what GDB understands.
494 */
495static struct hard_trap_info
496{
497 unsigned int tt; /* Trap type code for powerpc */
498 unsigned char signo; /* Signal that we map this trap into */
499} hard_trap_info[] = {
500#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
501 { 0x100, SIGINT }, /* critical input interrupt */
502 { 0x200, SIGSEGV }, /* machine check */
503 { 0x300, SIGSEGV }, /* data storage */
504 { 0x400, SIGBUS }, /* instruction storage */
505 { 0x500, SIGINT }, /* interrupt */
506 { 0x600, SIGBUS }, /* alignment */
507 { 0x700, SIGILL }, /* program */
508 { 0x800, SIGILL }, /* reserved */
509 { 0x900, SIGILL }, /* reserved */
510 { 0xa00, SIGILL }, /* reserved */
511 { 0xb00, SIGILL }, /* reserved */
512 { 0xc00, SIGCHLD }, /* syscall */
513 { 0xd00, SIGILL }, /* reserved */
514 { 0xe00, SIGILL }, /* reserved */
515 { 0xf00, SIGILL }, /* reserved */
516 /*
517 ** 0x1000 PIT
518 ** 0x1010 FIT
519 ** 0x1020 watchdog
520 ** 0x1100 data TLB miss
521 ** 0x1200 instruction TLB miss
522 */
523 { 0x2002, SIGTRAP}, /* debug */
524#else
525 { 0x200, SIGSEGV }, /* machine check */
526 { 0x300, SIGSEGV }, /* address error (store) */
527 { 0x400, SIGBUS }, /* instruction bus error */
528 { 0x500, SIGINT }, /* interrupt */
529 { 0x600, SIGBUS }, /* alingment */
530 { 0x700, SIGTRAP }, /* breakpoint trap */
531 { 0x800, SIGFPE }, /* fpu unavail */
532 { 0x900, SIGALRM }, /* decrementer */
533 { 0xa00, SIGILL }, /* reserved */
534 { 0xb00, SIGILL }, /* reserved */
535 { 0xc00, SIGCHLD }, /* syscall */
536 { 0xd00, SIGTRAP }, /* single-step/watch */
537 { 0xe00, SIGFPE }, /* fp assist */
538#endif
539 { 0, 0} /* Must be last */
540
541};
542
543static int computeSignal(unsigned int tt)
544{
545 struct hard_trap_info *ht;
546
547 for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
548 if (ht->tt == tt)
549 return ht->signo;
550
551 return SIGHUP; /* default for things we don't know about */
552}
553
554#define PC_REGNUM 64
555#define SP_REGNUM 1
556
557/*
558 * This function does all command processing for interfacing to gdb.
559 */
560static int
561handle_exception (struct pt_regs *regs)
562{
563 int sigval;
564 int addr;
565 int length;
566 char *ptr;
567 unsigned int msr;
568
569 /* We don't handle user-mode breakpoints. */
570 if (user_mode(regs))
571 return 0;
572
573 if (debugger_fault_handler) {
574 debugger_fault_handler(regs);
575 panic("kgdb longjump failed!\n");
576 }
577 if (kgdb_active) {
578 printk(KERN_ERR "interrupt while in kgdb, returning\n");
579 return 0;
580 }
581
582 kgdb_active = 1;
583 kgdb_started = 1;
584
585#ifdef KGDB_DEBUG
586 printk("kgdb: entering handle_exception; trap [0x%x]\n",
587 (unsigned int)regs->trap);
588#endif
589
590 kgdb_interruptible(0);
591 lock_kernel();
592 msr = mfmsr();
593 mtmsr(msr & ~MSR_EE); /* disable interrupts */
594
595 if (regs->nip == (unsigned long)breakinst) {
596 /* Skip over breakpoint trap insn */
597 regs->nip += 4;
598 }
599
600 /* reply to host that an exception has occurred */
601 sigval = computeSignal(regs->trap);
602 ptr = remcomOutBuffer;
603
604 *ptr++ = 'T';
605 *ptr++ = hexchars[sigval >> 4];
606 *ptr++ = hexchars[sigval & 0xf];
607 *ptr++ = hexchars[PC_REGNUM >> 4];
608 *ptr++ = hexchars[PC_REGNUM & 0xf];
609 *ptr++ = ':';
610 ptr = mem2hex((char *)&regs->nip, ptr, 4);
611 *ptr++ = ';';
612 *ptr++ = hexchars[SP_REGNUM >> 4];
613 *ptr++ = hexchars[SP_REGNUM & 0xf];
614 *ptr++ = ':';
615 ptr = mem2hex(((char *)regs) + SP_REGNUM*4, ptr, 4);
616 *ptr++ = ';';
617 *ptr++ = 0;
618
619 putpacket(remcomOutBuffer);
620 if (kdebug)
621 printk("remcomOutBuffer: %s\n", remcomOutBuffer);
622
623 /* XXX We may want to add some features dealing with poking the
624 * XXX page tables, ... (look at sparc-stub.c for more info)
625 * XXX also required hacking to the gdb sources directly...
626 */
627
628 while (1) {
629 remcomOutBuffer[0] = 0;
630
631 getpacket(remcomInBuffer);
632 switch (remcomInBuffer[0]) {
633 case '?': /* report most recent signal */
634 remcomOutBuffer[0] = 'S';
635 remcomOutBuffer[1] = hexchars[sigval >> 4];
636 remcomOutBuffer[2] = hexchars[sigval & 0xf];
637 remcomOutBuffer[3] = 0;
638 break;
639#if 0
640 case 'q': /* this screws up gdb for some reason...*/
641 {
642 extern long _start, sdata, __bss_start;
643
644 ptr = &remcomInBuffer[1];
645 if (strncmp(ptr, "Offsets", 7) != 0)
646 break;
647
648 ptr = remcomOutBuffer;
649 sprintf(ptr, "Text=%8.8x;Data=%8.8x;Bss=%8.8x",
650 &_start, &sdata, &__bss_start);
651 break;
652 }
653#endif
654 case 'd':
655 /* toggle debug flag */
656 kdebug ^= 1;
657 break;
658
659 case 'g': /* return the value of the CPU registers.
660 * some of them are non-PowerPC names :(
661 * they are stored in gdb like:
662 * struct {
663 * u32 gpr[32];
664 * f64 fpr[32];
665 * u32 pc, ps, cnd, lr; (ps=msr)
666 * u32 cnt, xer, mq;
667 * }
668 */
669 {
670 int i;
671 ptr = remcomOutBuffer;
672 /* General Purpose Regs */
673 ptr = mem2hex((char *)regs, ptr, 32 * 4);
674 /* Floating Point Regs - FIXME */
675 /*ptr = mem2hex((char *), ptr, 32 * 8);*/
676 for(i=0; i<(32*8*2); i++) { /* 2chars/byte */
677 ptr[i] = '0';
678 }
679 ptr += 32*8*2;
680 /* pc, msr, cr, lr, ctr, xer, (mq is unused) */
681 ptr = mem2hex((char *)&regs->nip, ptr, 4);
682 ptr = mem2hex((char *)&regs->msr, ptr, 4);
683 ptr = mem2hex((char *)&regs->ccr, ptr, 4);
684 ptr = mem2hex((char *)&regs->link, ptr, 4);
685 ptr = mem2hex((char *)&regs->ctr, ptr, 4);
686 ptr = mem2hex((char *)&regs->xer, ptr, 4);
687 }
688 break;
689
690 case 'G': /* set the value of the CPU registers */
691 {
692 ptr = &remcomInBuffer[1];
693
694 /*
695 * If the stack pointer has moved, you should pray.
696 * (cause only god can help you).
697 */
698
699 /* General Purpose Regs */
700 hex2mem(ptr, (char *)regs, 32 * 4);
701
702 /* Floating Point Regs - FIXME?? */
703 /*ptr = hex2mem(ptr, ??, 32 * 8);*/
704 ptr += 32*8*2;
705
706 /* pc, msr, cr, lr, ctr, xer, (mq is unused) */
707 ptr = hex2mem(ptr, (char *)&regs->nip, 4);
708 ptr = hex2mem(ptr, (char *)&regs->msr, 4);
709 ptr = hex2mem(ptr, (char *)&regs->ccr, 4);
710 ptr = hex2mem(ptr, (char *)&regs->link, 4);
711 ptr = hex2mem(ptr, (char *)&regs->ctr, 4);
712 ptr = hex2mem(ptr, (char *)&regs->xer, 4);
713
714 strcpy(remcomOutBuffer,"OK");
715 }
716 break;
717 case 'H':
718 /* don't do anything, yet, just acknowledge */
719 hexToInt(&ptr, &addr);
720 strcpy(remcomOutBuffer,"OK");
721 break;
722
723 case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
724 /* Try to read %x,%x. */
725
726 ptr = &remcomInBuffer[1];
727
728 if (hexToInt(&ptr, &addr) && *ptr++ == ','
729 && hexToInt(&ptr, &length)) {
730 if (mem2hex((char *)addr, remcomOutBuffer,
731 length))
732 break;
733 strcpy(remcomOutBuffer, "E03");
734 } else
735 strcpy(remcomOutBuffer, "E01");
736 break;
737
738 case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
739 /* Try to read '%x,%x:'. */
740
741 ptr = &remcomInBuffer[1];
742
743 if (hexToInt(&ptr, &addr) && *ptr++ == ','
744 && hexToInt(&ptr, &length)
745 && *ptr++ == ':') {
746 if (hex2mem(ptr, (char *)addr, length))
747 strcpy(remcomOutBuffer, "OK");
748 else
749 strcpy(remcomOutBuffer, "E03");
750 flush_icache_range(addr, addr+length);
751 } else
752 strcpy(remcomOutBuffer, "E02");
753 break;
754
755
756 case 'k': /* kill the program, actually just continue */
757 case 'c': /* cAA..AA Continue; address AA..AA optional */
758 /* try to read optional parameter, pc unchanged if no parm */
759
760 ptr = &remcomInBuffer[1];
761 if (hexToInt(&ptr, &addr))
762 regs->nip = addr;
763
764/* Need to flush the instruction cache here, as we may have deposited a
765 * breakpoint, and the icache probably has no way of knowing that a data ref to
766 * some location may have changed something that is in the instruction cache.
767 */
768 kgdb_flush_cache_all();
769 mtmsr(msr);
770
771 kgdb_interruptible(1);
772 unlock_kernel();
773 kgdb_active = 0;
774 if (kdebug) {
775 printk("remcomInBuffer: %s\n", remcomInBuffer);
776 printk("remcomOutBuffer: %s\n", remcomOutBuffer);
777 }
778 return 1;
779
780 case 's':
781 kgdb_flush_cache_all();
782#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
783 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC);
784 regs->msr |= MSR_DE;
785#else
786 regs->msr |= MSR_SE;
787#endif
788 unlock_kernel();
789 kgdb_active = 0;
790 if (kdebug) {
791 printk("remcomInBuffer: %s\n", remcomInBuffer);
792 printk("remcomOutBuffer: %s\n", remcomOutBuffer);
793 }
794 return 1;
795
796 case 'r': /* Reset (if user process..exit ???)*/
797 panic("kgdb reset.");
798 break;
799 } /* switch */
800 if (remcomOutBuffer[0] && kdebug) {
801 printk("remcomInBuffer: %s\n", remcomInBuffer);
802 printk("remcomOutBuffer: %s\n", remcomOutBuffer);
803 }
804 /* reply to the request */
805 putpacket(remcomOutBuffer);
806 } /* while(1) */
807}
808
809/* This function will generate a breakpoint exception. It is used at the
810 beginning of a program to sync up with a debugger and can be used
811 otherwise as a quick means to stop program execution and "break" into
812 the debugger. */
813
814void
815breakpoint(void)
816{
817 if (!initialized) {
818 printk("breakpoint() called b4 kgdb init\n");
819 return;
820 }
821
822 asm(" .globl breakinst \n\
823 breakinst: .long 0x7d821008");
824}
825
826#ifdef CONFIG_KGDB_CONSOLE
827/* Output string in GDB O-packet format if GDB has connected. If nothing
828 output, returns 0 (caller must then handle output). */
829int
830kgdb_output_string (const char* s, unsigned int count)
831{
832 char buffer[512];
833
834 if (!kgdb_started)
835 return 0;
836
837 count = (count <= (sizeof(buffer) / 2 - 2))
838 ? count : (sizeof(buffer) / 2 - 2);
839
840 buffer[0] = 'O';
841 mem2hex (s, &buffer[1], count);
842 putpacket(buffer);
843
844 return 1;
845}
846#endif
847
848static void sysrq_handle_gdb(int key, struct pt_regs *pt_regs,
849 struct tty_struct *tty)
850{
851 printk("Entering GDB stub\n");
852 breakpoint();
853}
854static struct sysrq_key_op sysrq_gdb_op = {
855 .handler = sysrq_handle_gdb,
856 .help_msg = "Gdb",
857 .action_msg = "GDB",
858};
859
860static int gdb_register_sysrq(void)
861{
862 printk("Registering GDB sysrq handler\n");
863 register_sysrq_key('g', &sysrq_gdb_op);
864 return 0;
865}
866module_init(gdb_register_sysrq);
This page took 0.393787 seconds and 5 git commands to generate.