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