1 /* $Id: ppc-stub.c,v 1.4 1998/07/28 08:25:01 paulus Exp $
2 * ppc-stub.c: KGDB support for the Linux kernel.
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)
8 * Modifications to run under Linux
9 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
11 * This file originally came from the gdb sources, and the
12 * copyright notices have been retained below.
15 /****************************************************************************
17 THIS SOFTWARE IS NOT COPYRIGHTED
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.
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.
27 ****************************************************************************/
29 /****************************************************************************
30 * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
32 * Module name: remcom.c $
34 * Date: 91/03/09 12:29:49 $
35 * Contributor: Lake Stevens Instrument Division$
37 * Description: low level support for gdb debugger. $
39 * Considerations: only works on target hardware $
41 * Written by: Glenn Engel $
42 * ModuleState: Experimental $
46 * Modified for SPARC by Stu Grossman, Cygnus Support.
48 * This code has been extensively tested on the Fujitsu SPARClite demo board.
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.
59 * The following gdb commands are supported:
61 * command function Return value
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
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
70 * c Resume at current address SNN ( signal NN)
71 * cAA..AA Continue at address AA..AA SNN
73 * s Step one instruction SNN
74 * sAA..AA Step one instruction from AA..AA SNN
78 * ? What was the last sigval ? SNN (signal NN)
80 * bBB..BB Set baud rate to BB..BB OK or BNN, then sets
83 * All commands and responses are sent with a packet which includes a
84 * checksum. A packet consists of
86 * $<packet info>#<checksum>.
89 * <packet info> :: <characters representing the command or response>
90 * <checksum> :: <two hex digits computed as modulo 256 sum of <packetinfo>>
92 * When a packet is received, it is first acknowledged with either '+' or '-'.
93 * '+' indicates a successful transfer. '-' indicates a failed transfer.
98 * $m0,10#2a +$00010203040506070809101112131415#42
100 ****************************************************************************/
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>
108 #include <asm/system.h>
109 #include <asm/signal.h>
110 #include <asm/kgdb.h>
111 #include <asm/pgtable.h>
112 #include <asm/ptrace.h>
114 void breakinst(void);
117 * BUFMAX defines the maximum number of characters in inbound/outbound buffers
118 * at least NUMREGBYTES*2 are needed for register packets
121 static char remcomInBuffer
[BUFMAX
];
122 static char remcomOutBuffer
[BUFMAX
];
124 static int initialized
= 0;
125 static int kgdb_active
= 0;
126 static u_int fault_jmp_buf
[100];
129 static const char hexchars
[]="0123456789abcdef";
131 /* Place where we save old trap entries for restoration - sparc*/
132 /* struct tt_entry kgdb_savettable[256]; */
133 /* typedef void (*trapfunc_t)(void); */
136 /* Install an exception handler for kgdb */
137 static void exceptionHandler(int tnum
, unsigned int *tfunc
)
139 /* We are dorking with a live trap table, all irqs off */
144 kgdb_setjmp(long *buf
)
146 asm ("mflr 0; stw 0,0(%0);"
147 "stw 1,4(%0); stw 2,8(%0);"
148 "mfcr 0; stw 0,12(%0);"
151 /* XXX should save fp regs as well */
155 kgdb_longjmp(long *buf
, int val
)
159 asm ("lmw 13,16(%0);"
160 "lwz 0,12(%0); mtcrf 0x38,0;"
161 "lwz 0,0(%0); lwz 1,4(%0); lwz 2,8(%0);"
163 : : "r" (buf
), "r" (val
));
165 /* Convert ch from a hex digit to an int */
167 hex(unsigned char ch
)
169 if (ch
>= 'a' && ch
<= 'f')
171 if (ch
>= '0' && ch
<= '9')
173 if (ch
>= 'A' && ch
<= 'F')
178 /* Convert the memory pointed to by mem into hex, placing result in buf.
179 * Return a pointer to the last char put in buf (null), in case of mem fault,
182 static unsigned char *
183 mem2hex(char *mem
, char *buf
, int count
)
187 if (kgdb_setjmp((long*)fault_jmp_buf
) == 0) {
188 debugger_fault_handler
= kgdb_fault_handler
;
189 while (count
-- > 0) {
191 *buf
++ = hexchars
[ch
>> 4];
192 *buf
++ = hexchars
[ch
& 0xf];
195 /* error condition */
197 debugger_fault_handler
= 0;
202 /* convert the hex array pointed to by buf into binary to be placed in mem
203 * return a pointer to the character AFTER the last byte written.
206 hex2mem(char *buf
, char *mem
, int count
)
211 if (kgdb_setjmp((long*)fault_jmp_buf
) == 0) {
212 debugger_fault_handler
= kgdb_fault_handler
;
213 for (i
=0; i
<count
; i
++) {
214 ch
= hex(*buf
++) << 4;
218 flush_icache_range((int)mem
, (int)mem
+count
);
220 /* error condition */
222 debugger_fault_handler
= 0;
227 * While we find nice hex chars, build an int.
228 * Return number of chars processed.
231 hexToInt(char **ptr
, int *intValue
)
238 if (kgdb_setjmp((long*)fault_jmp_buf
) == 0) {
239 debugger_fault_handler
= kgdb_fault_handler
;
241 hexValue
= hex(**ptr
);
245 *intValue
= (*intValue
<< 4) | hexValue
;
251 /* error condition */
253 debugger_fault_handler
= 0;
258 /* scan for the sequence $<data>#<checksum> */
260 getpacket(char *buffer
)
262 unsigned char checksum
;
263 unsigned char xmitcsum
;
269 /* wait around for the start character, ignore all other
271 while ((ch
= (getDebugChar() & 0x7f)) != '$') ;
278 /* now, read until a # or end of buffer is found */
279 while (count
< BUFMAX
) {
280 ch
= getDebugChar() & 0x7f;
283 checksum
= checksum
+ ch
;
294 xmitcsum
= hex(getDebugChar() & 0x7f) << 4;
295 xmitcsum
|= hex(getDebugChar() & 0x7f);
296 if (checksum
!= xmitcsum
)
297 putDebugChar('-'); /* failed checksum */
299 putDebugChar('+'); /* successful transfer */
300 /* if a sequence char is present, reply the ID */
301 if (buffer
[2] == ':') {
302 putDebugChar(buffer
[0]);
303 putDebugChar(buffer
[1]);
304 /* remove sequence chars from buffer */
305 count
= strlen(buffer
);
306 for (i
=3; i
<= count
; i
++)
307 buffer
[i
-3] = buffer
[i
];
311 } while (checksum
!= xmitcsum
);
314 /* send the packet in buffer. */
315 static void putpacket(unsigned char *buffer
)
317 unsigned char checksum
;
319 unsigned char ch
, recv
;
321 /* $<packet info>#<checksum>. */
327 while ((ch
= buffer
[count
])) {
334 putDebugChar(hexchars
[checksum
>> 4]);
335 putDebugChar(hexchars
[checksum
& 0xf]);
336 recv
= getDebugChar();
337 } while ((recv
& 0x7f) != '+');
340 static void kgdb_flush_cache_all(void)
342 flush_instruction_cache();
345 static inline int get_msr()
348 asm volatile("mfmsr %0" : "=r" (msr
):);
352 static inline void set_msr(int msr
)
354 asm volatile("mfmsr %0" : : "r" (msr
));
357 /* Set up exception handlers for tracing and breakpoints
358 * [could be called kgdb_init()]
360 void set_debug_traps(void)
367 /* In case GDB is started before us, ack any packets (presumably
368 * "$?#xx") sitting there.
370 * I've found this code causes more problems than it solves,
371 * so that's why it's commented out. GDB seems to work fine
372 * now starting either before or after the kernel -bwb
375 while((c
= getDebugChar()) != '$');
376 while((c
= getDebugChar()) != '#');
377 c
= getDebugChar(); /* eat first csum byte */
378 c
= getDebugChar(); /* eat second csum byte */
379 putDebugChar('+'); /* ack it */
382 debugger_bpt
= kgdb_bpt
;
383 debugger_sstep
= kgdb_sstep
;
384 debugger_iabr_match
= kgdb_iabr_match
;
385 debugger_dabr_match
= kgdb_dabr_match
;
390 static void kgdb_fault_handler(struct pt_regs
*regs
)
392 kgdb_longjmp((long*)fault_jmp_buf
, 1);
395 int kgdb_bpt(struct pt_regs
*regs
)
397 handle_exception(regs
);
401 int kgdb_sstep(struct pt_regs
*regs
)
403 handle_exception(regs
);
407 void kgdb(struct pt_regs
*regs
)
409 handle_exception(regs
);
412 int kgdb_iabr_match(struct pt_regs
*regs
)
414 printk("kgdb doesn't support iabr, what?!?\n");
415 handle_exception(regs
);
419 int kgdb_dabr_match(struct pt_regs
*regs
)
421 printk("kgdb doesn't support dabr, what?!?\n");
422 handle_exception(regs
);
426 /* Convert the SPARC hardware trap type code to a unix signal number. */
428 * This table contains the mapping between PowerPC hardware trap types, and
429 * signals, which are primarily what GDB understands.
431 static struct hard_trap_info
433 unsigned int tt
; /* Trap type code for powerpc */
434 unsigned char signo
; /* Signal that we map this trap into */
435 } hard_trap_info
[] = {
436 { 0x200, SIGSEGV
}, /* machine check */
437 { 0x300, SIGSEGV
}, /* address error (store) */
438 { 0x400, SIGBUS
}, /* instruction bus error */
439 { 0x500, SIGINT
}, /* interrupt */
440 { 0x600, SIGBUS
}, /* alingment */
441 { 0x700, SIGILL
}, /* reserved instruction or sumpin' */
442 { 0x800, SIGFPE
}, /* fpu unavail */
443 { 0x900, SIGALRM
}, /* decrementer */
444 { 0xa00, SIGILL
}, /* reserved */
445 { 0xb00, SIGILL
}, /* reserved */
446 { 0xc00, SIGCHLD
}, /* syscall */
447 { 0xd00, SIGINT
}, /* watch */
448 { 0xe00, SIGFPE
}, /* fp assist */
449 { 0, 0} /* Must be last */
452 static int computeSignal(unsigned int tt
)
454 struct hard_trap_info
*ht
;
456 for (ht
= hard_trap_info
; ht
->tt
&& ht
->signo
; ht
++)
460 return SIGHUP
; /* default for things we don't know about */
464 * This function does all command processing for interfacing to gdb.
467 handle_exception (struct pt_regs
*regs
)
475 if (debugger_fault_handler
) {
476 debugger_fault_handler(regs
);
477 panic("kgdb longjump failed!\n");
480 printk("interrupt while in kgdb, returning\n");
485 printk("kgdb: entering handle_exception; trap [0x%x]\n",
486 (unsigned int)regs
->trap
);
488 kgdb_interruptible(0);
491 set_msr(msr
& ~MSR_EE
); /* disable interrupts */
493 if (regs
->nip
== (unsigned long)breakinst
) {
494 /* Skip over breakpoint trap insn */
498 /* reply to host that an exception has occurred */
499 sigval
= computeSignal(regs
->trap
);
500 ptr
= remcomOutBuffer
;
503 *ptr
++ = hexchars
[sigval
>> 4];
504 *ptr
++ = hexchars
[sigval
& 0xf];
508 putpacket(remcomOutBuffer
);
510 /* XXX We may want to add some features dealing with poking the
511 * XXX page tables, ... (look at sparc-stub.c for more info)
512 * XXX also required hacking to the gdb sources directly...
516 remcomOutBuffer
[0] = 0;
518 getpacket(remcomInBuffer
);
519 switch (remcomInBuffer
[0]) {
520 case '?': /* report most recent signal */
521 remcomOutBuffer
[0] = 'S';
522 remcomOutBuffer
[1] = hexchars
[sigval
>> 4];
523 remcomOutBuffer
[2] = hexchars
[sigval
& 0xf];
524 remcomOutBuffer
[3] = 0;
527 case 'q': /* this screws up gdb for some reason...*/
529 extern long _start
, sdata
, __bss_start
;
531 ptr
= &remcomInBuffer
[1];
532 if (strncmp(ptr
, "Offsets", 7) != 0)
535 ptr
= remcomOutBuffer
;
536 sprintf(ptr
, "Text=%8.8x;Data=%8.8x;Bss=%8.8x",
537 &_start
, &sdata
, &__bss_start
);
542 /* toggle debug flag */
546 case 'g': /* return the value of the CPU registers.
547 * some of them are non-PowerPC names :(
548 * they are stored in gdb like:
552 * u32 pc, ps, cnd, lr; (ps=msr)
558 ptr
= remcomOutBuffer
;
559 /* General Purpose Regs */
560 ptr
= mem2hex((char *)regs
, ptr
, 32 * 4);
561 /* Floating Point Regs - FIXME */
562 /*ptr = mem2hex((char *), ptr, 32 * 8);*/
563 for(i
=0; i
<(32*8*2); i
++) { /* 2chars/byte */
567 /* pc, msr, cr, lr, ctr, xer, (mq is unused) */
568 ptr
= mem2hex((char *)®s
->nip
, ptr
, 4);
569 ptr
= mem2hex((char *)®s
->msr
, ptr
, 4);
570 ptr
= mem2hex((char *)®s
->ccr
, ptr
, 4);
571 ptr
= mem2hex((char *)®s
->link
, ptr
, 4);
572 ptr
= mem2hex((char *)®s
->ctr
, ptr
, 4);
573 ptr
= mem2hex((char *)®s
->xer
, ptr
, 4);
577 case 'G': /* set the value of the CPU registers */
579 ptr
= &remcomInBuffer
[1];
582 * If the stack pointer has moved, you should pray.
583 * (cause only god can help you).
586 /* General Purpose Regs */
587 hex2mem(ptr
, (char *)regs
, 32 * 4);
589 /* Floating Point Regs - FIXME?? */
590 /*ptr = hex2mem(ptr, ??, 32 * 8);*/
593 /* pc, msr, cr, lr, ctr, xer, (mq is unused) */
594 ptr
= hex2mem(ptr
, (char *)®s
->nip
, 4);
595 ptr
= hex2mem(ptr
, (char *)®s
->msr
, 4);
596 ptr
= hex2mem(ptr
, (char *)®s
->ccr
, 4);
597 ptr
= hex2mem(ptr
, (char *)®s
->link
, 4);
598 ptr
= hex2mem(ptr
, (char *)®s
->ctr
, 4);
599 ptr
= hex2mem(ptr
, (char *)®s
->xer
, 4);
601 strcpy(remcomOutBuffer
,"OK");
605 /* don't do anything, yet, just acknowledge */
606 hexToInt(&ptr
, &addr
);
607 strcpy(remcomOutBuffer
,"OK");
610 case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
611 /* Try to read %x,%x. */
613 ptr
= &remcomInBuffer
[1];
615 if (hexToInt(&ptr
, &addr
)
617 && hexToInt(&ptr
, &length
)) {
618 if (mem2hex((char *)addr
, remcomOutBuffer
,length
))
620 strcpy (remcomOutBuffer
, "E03");
622 strcpy(remcomOutBuffer
,"E01");
626 case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
627 /* Try to read '%x,%x:'. */
629 ptr
= &remcomInBuffer
[1];
631 if (hexToInt(&ptr
, &addr
)
633 && hexToInt(&ptr
, &length
)
635 if (hex2mem(ptr
, (char *)addr
, length
)) {
636 strcpy(remcomOutBuffer
, "OK");
638 strcpy(remcomOutBuffer
, "E03");
641 strcpy(remcomOutBuffer
, "E02");
646 case 'k': /* kill the program, actually just continue */
647 case 'c': /* cAA..AA Continue; address AA..AA optional */
648 /* try to read optional parameter, pc unchanged if no parm */
650 ptr
= &remcomInBuffer
[1];
651 if (hexToInt(&ptr
, &addr
)) {
655 /* Need to flush the instruction cache here, as we may have deposited a
656 * breakpoint, and the icache probably has no way of knowing that a data ref to
657 * some location may have changed something that is in the instruction cache.
659 kgdb_flush_cache_all();
661 kgdb_interruptible(1);
667 kgdb_flush_cache_all();
669 set_msr(msr
| MSR_SE
);
674 case 'r': /* Reset (if user process..exit ???)*/
675 panic("kgdb reset.");
678 if (remcomOutBuffer
[0] && kdebug
) {
679 printk("remcomInBuffer: %s\n", remcomInBuffer
);
680 printk("remcomOutBuffer: %s\n", remcomOutBuffer
);
682 /* reply to the request */
683 putpacket(remcomOutBuffer
);
687 /* This function will generate a breakpoint exception. It is used at the
688 beginning of a program to sync up with a debugger and can be used
689 otherwise as a quick means to stop program execution and "break" into
696 printk("breakpoint() called b4 kgdb init\n");
700 asm(" .globl breakinst