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/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>
109 #include <asm/system.h>
110 #include <asm/signal.h>
111 #include <asm/kgdb.h>
112 #include <asm/pgtable.h>
113 #include <asm/ptrace.h>
115 void breakinst(void);
118 * BUFMAX defines the maximum number of characters in inbound/outbound buffers
119 * at least NUMREGBYTES*2 are needed for register packets
122 static char remcomInBuffer[BUFMAX];
123 static char remcomOutBuffer[BUFMAX];
125 static int initialized = 0;
126 static int kgdb_active = 0;
127 static int kgdb_started = 0;
128 static u_int fault_jmp_buf[100];
131 static const char hexchars[]="0123456789abcdef";
133 /* Place where we save old trap entries for restoration - sparc*/
134 /* struct tt_entry kgdb_savettable[256]; */
135 /* typedef void (*trapfunc_t)(void); */
138 /* Install an exception handler for kgdb */
139 static void exceptionHandler(int tnum, unsigned int *tfunc)
141 /* We are dorking with a live trap table, all irqs off */
146 kgdb_setjmp(long *buf)
148 asm ("mflr 0; stw 0,0(%0);"
149 "stw 1,4(%0); stw 2,8(%0);"
150 "mfcr 0; stw 0,12(%0);"
153 /* XXX should save fp regs as well */
157 kgdb_longjmp(long *buf, int val)
161 asm ("lmw 13,16(%0);"
162 "lwz 0,12(%0); mtcrf 0x38,0;"
163 "lwz 0,0(%0); lwz 1,4(%0); lwz 2,8(%0);"
165 : : "r" (buf), "r" (val));
167 /* Convert ch from a hex digit to an int */
169 hex(unsigned char ch)
171 if (ch >= 'a' && ch <= 'f')
173 if (ch >= '0' && ch <= '9')
175 if (ch >= 'A' && ch <= 'F')
180 /* Convert the memory pointed to by mem into hex, placing result in buf.
181 * Return a pointer to the last char put in buf (null), in case of mem fault,
184 static unsigned char *
185 mem2hex(char *mem, char *buf, int count)
189 if (kgdb_setjmp((long*)fault_jmp_buf) == 0) {
190 debugger_fault_handler = kgdb_fault_handler;
191 while (count-- > 0) {
193 *buf++ = hexchars[ch >> 4];
194 *buf++ = hexchars[ch & 0xf];
197 /* error condition */
199 debugger_fault_handler = 0;
204 /* convert the hex array pointed to by buf into binary to be placed in mem
205 * return a pointer to the character AFTER the last byte written.
208 hex2mem(char *buf, char *mem, int count)
213 if (kgdb_setjmp((long*)fault_jmp_buf) == 0) {
214 debugger_fault_handler = kgdb_fault_handler;
215 for (i=0; i<count; i++) {
216 ch = hex(*buf++) << 4;
220 flush_icache_range((int)mem, (int)mem+count);
222 /* error condition */
224 debugger_fault_handler = 0;
229 * While we find nice hex chars, build an int.
230 * Return number of chars processed.
233 hexToInt(char **ptr, int *intValue)
240 if (kgdb_setjmp((long*)fault_jmp_buf) == 0) {
241 debugger_fault_handler = kgdb_fault_handler;
243 hexValue = hex(**ptr);
247 *intValue = (*intValue << 4) | hexValue;
253 /* error condition */
255 debugger_fault_handler = 0;
260 /* scan for the sequence $<data>#<checksum> */
262 getpacket(char *buffer)
264 unsigned char checksum;
265 unsigned char xmitcsum;
271 /* wait around for the start character, ignore all other
273 while ((ch = (getDebugChar() & 0x7f)) != '$') ;
280 /* now, read until a # or end of buffer is found */
281 while (count < BUFMAX) {
282 ch = getDebugChar() & 0x7f;
285 checksum = checksum + ch;
296 xmitcsum = hex(getDebugChar() & 0x7f) << 4;
297 xmitcsum |= hex(getDebugChar() & 0x7f);
298 if (checksum != xmitcsum)
299 putDebugChar('-'); /* failed checksum */
301 putDebugChar('+'); /* successful transfer */
302 /* if a sequence char is present, reply the ID */
303 if (buffer[2] == ':') {
304 putDebugChar(buffer[0]);
305 putDebugChar(buffer[1]);
306 /* remove sequence chars from buffer */
307 count = strlen(buffer);
308 for (i=3; i <= count; i++)
309 buffer[i-3] = buffer[i];
313 } while (checksum != xmitcsum);
316 /* send the packet in buffer. */
317 static void putpacket(unsigned char *buffer)
319 unsigned char checksum;
321 unsigned char ch, recv;
323 /* $<packet info>#<checksum>. */
329 while ((ch = buffer[count])) {
336 putDebugChar(hexchars[checksum >> 4]);
337 putDebugChar(hexchars[checksum & 0xf]);
338 recv = getDebugChar();
339 } while ((recv & 0x7f) != '+');
342 static void kgdb_flush_cache_all(void)
344 flush_instruction_cache();
348 /* Set up exception handlers for tracing and breakpoints
349 * [could be called kgdb_init()]
351 void set_debug_traps(void)
358 /* In case GDB is started before us, ack any packets (presumably
359 * "$?#xx") sitting there.
361 * I've found this code causes more problems than it solves,
362 * so that's why it's commented out. GDB seems to work fine
363 * now starting either before or after the kernel -bwb
366 while((c = getDebugChar()) != '$');
367 while((c = getDebugChar()) != '#');
368 c = getDebugChar(); /* eat first csum byte */
369 c = getDebugChar(); /* eat second csum byte */
370 putDebugChar('+'); /* ack it */
373 debugger_bpt = kgdb_bpt;
374 debugger_sstep = kgdb_sstep;
375 debugger_iabr_match = kgdb_iabr_match;
376 debugger_dabr_match = kgdb_dabr_match;
381 static void kgdb_fault_handler(struct pt_regs *regs)
383 kgdb_longjmp((long*)fault_jmp_buf, 1);
386 int kgdb_bpt(struct pt_regs *regs)
388 handle_exception(regs);
392 int kgdb_sstep(struct pt_regs *regs)
394 handle_exception(regs);
398 void kgdb(struct pt_regs *regs)
400 handle_exception(regs);
403 int kgdb_iabr_match(struct pt_regs *regs)
405 printk("kgdb doesn't support iabr, what?!?\n");
406 handle_exception(regs);
410 int kgdb_dabr_match(struct pt_regs *regs)
412 printk("kgdb doesn't support dabr, what?!?\n");
413 handle_exception(regs);
417 /* Convert the SPARC hardware trap type code to a unix signal number. */
419 * This table contains the mapping between PowerPC hardware trap types, and
420 * signals, which are primarily what GDB understands.
422 static struct hard_trap_info
424 unsigned int tt; /* Trap type code for powerpc */
425 unsigned char signo; /* Signal that we map this trap into */
426 } hard_trap_info[] = {
427 { 0x200, SIGSEGV }, /* machine check */
428 { 0x300, SIGSEGV }, /* address error (store) */
429 { 0x400, SIGBUS }, /* instruction bus error */
430 { 0x500, SIGINT }, /* interrupt */
431 { 0x600, SIGBUS }, /* alingment */
432 { 0x700, SIGTRAP }, /* breakpoint trap */
433 { 0x800, SIGFPE }, /* fpu unavail */
434 { 0x900, SIGALRM }, /* decrementer */
435 { 0xa00, SIGILL }, /* reserved */
436 { 0xb00, SIGILL }, /* reserved */
437 { 0xc00, SIGCHLD }, /* syscall */
438 { 0xd00, SIGTRAP }, /* single-step/watch */
439 { 0xe00, SIGFPE }, /* fp assist */
440 { 0, 0} /* Must be last */
443 static int computeSignal(unsigned int tt)
445 struct hard_trap_info *ht;
447 for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
451 return SIGHUP; /* default for things we don't know about */
458 * This function does all command processing for interfacing to gdb.
461 handle_exception (struct pt_regs *regs)
469 if (debugger_fault_handler) {
470 debugger_fault_handler(regs);
471 panic("kgdb longjump failed!\n");
474 printk("interrupt while in kgdb, returning\n");
481 printk("kgdb: entering handle_exception; trap [0x%x]\n",
482 (unsigned int)regs->trap);
485 kgdb_interruptible(0);
488 set_msr(msr & ~MSR_EE); /* disable interrupts */
490 if (regs->nip == (unsigned long)breakinst) {
491 /* Skip over breakpoint trap insn */
495 /* reply to host that an exception has occurred */
496 sigval = computeSignal(regs->trap);
497 ptr = remcomOutBuffer;
501 *ptr++ = hexchars[sigval >> 4];
502 *ptr++ = hexchars[sigval & 0xf];
505 *ptr++ = hexchars[sigval >> 4];
506 *ptr++ = hexchars[sigval & 0xf];
507 *ptr++ = hexchars[PC_REGNUM >> 4];
508 *ptr++ = hexchars[PC_REGNUM & 0xf];
510 ptr = mem2hex((char *)®s->nip, ptr, 4);
512 *ptr++ = hexchars[SP_REGNUM >> 4];
513 *ptr++ = hexchars[SP_REGNUM & 0xf];
515 ptr = mem2hex(((char *)®s) + SP_REGNUM*4, ptr, 4);
521 putpacket(remcomOutBuffer);
523 /* XXX We may want to add some features dealing with poking the
524 * XXX page tables, ... (look at sparc-stub.c for more info)
525 * XXX also required hacking to the gdb sources directly...
529 remcomOutBuffer[0] = 0;
531 getpacket(remcomInBuffer);
532 switch (remcomInBuffer[0]) {
533 case '?': /* report most recent signal */
534 remcomOutBuffer[0] = 'S';
535 remcomOutBuffer[1] = hexchars[sigval >> 4];
536 remcomOutBuffer[2] = hexchars[sigval & 0xf];
537 remcomOutBuffer[3] = 0;
540 case 'q': /* this screws up gdb for some reason...*/
542 extern long _start, sdata, __bss_start;
544 ptr = &remcomInBuffer[1];
545 if (strncmp(ptr, "Offsets", 7) != 0)
548 ptr = remcomOutBuffer;
549 sprintf(ptr, "Text=%8.8x;Data=%8.8x;Bss=%8.8x",
550 &_start, &sdata, &__bss_start);
555 /* toggle debug flag */
559 case 'g': /* return the value of the CPU registers.
560 * some of them are non-PowerPC names :(
561 * they are stored in gdb like:
565 * u32 pc, ps, cnd, lr; (ps=msr)
571 ptr = remcomOutBuffer;
572 /* General Purpose Regs */
573 ptr = mem2hex((char *)regs, ptr, 32 * 4);
574 /* Floating Point Regs - FIXME */
575 /*ptr = mem2hex((char *), ptr, 32 * 8);*/
576 for(i=0; i<(32*8*2); i++) { /* 2chars/byte */
580 /* pc, msr, cr, lr, ctr, xer, (mq is unused) */
581 ptr = mem2hex((char *)®s->nip, ptr, 4);
582 ptr = mem2hex((char *)®s->msr, ptr, 4);
583 ptr = mem2hex((char *)®s->ccr, ptr, 4);
584 ptr = mem2hex((char *)®s->link, ptr, 4);
585 ptr = mem2hex((char *)®s->ctr, ptr, 4);
586 ptr = mem2hex((char *)®s->xer, ptr, 4);
590 case 'G': /* set the value of the CPU registers */
592 ptr = &remcomInBuffer[1];
595 * If the stack pointer has moved, you should pray.
596 * (cause only god can help you).
599 /* General Purpose Regs */
600 hex2mem(ptr, (char *)regs, 32 * 4);
602 /* Floating Point Regs - FIXME?? */
603 /*ptr = hex2mem(ptr, ??, 32 * 8);*/
606 /* pc, msr, cr, lr, ctr, xer, (mq is unused) */
607 ptr = hex2mem(ptr, (char *)®s->nip, 4);
608 ptr = hex2mem(ptr, (char *)®s->msr, 4);
609 ptr = hex2mem(ptr, (char *)®s->ccr, 4);
610 ptr = hex2mem(ptr, (char *)®s->link, 4);
611 ptr = hex2mem(ptr, (char *)®s->ctr, 4);
612 ptr = hex2mem(ptr, (char *)®s->xer, 4);
614 strcpy(remcomOutBuffer,"OK");
618 /* don't do anything, yet, just acknowledge */
619 hexToInt(&ptr, &addr);
620 strcpy(remcomOutBuffer,"OK");
623 case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
624 /* Try to read %x,%x. */
626 ptr = &remcomInBuffer[1];
628 if (hexToInt(&ptr, &addr)
630 && hexToInt(&ptr, &length)) {
631 if (mem2hex((char *)addr, remcomOutBuffer,length))
633 strcpy (remcomOutBuffer, "E03");
635 strcpy(remcomOutBuffer,"E01");
639 case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
640 /* Try to read '%x,%x:'. */
642 ptr = &remcomInBuffer[1];
644 if (hexToInt(&ptr, &addr)
646 && hexToInt(&ptr, &length)
648 if (hex2mem(ptr, (char *)addr, length)) {
649 strcpy(remcomOutBuffer, "OK");
651 strcpy(remcomOutBuffer, "E03");
653 flush_icache_range(addr, addr+length);
655 strcpy(remcomOutBuffer, "E02");
660 case 'k': /* kill the program, actually just continue */
661 case 'c': /* cAA..AA Continue; address AA..AA optional */
662 /* try to read optional parameter, pc unchanged if no parm */
664 ptr = &remcomInBuffer[1];
665 if (hexToInt(&ptr, &addr)) {
669 /* Need to flush the instruction cache here, as we may have deposited a
670 * breakpoint, and the icache probably has no way of knowing that a data ref to
671 * some location may have changed something that is in the instruction cache.
673 kgdb_flush_cache_all();
675 kgdb_interruptible(1);
681 kgdb_flush_cache_all();
684 set_msr(msr | MSR_SE);
690 case 'r': /* Reset (if user process..exit ???)*/
691 panic("kgdb reset.");
694 if (remcomOutBuffer[0] && kdebug) {
695 printk("remcomInBuffer: %s\n", remcomInBuffer);
696 printk("remcomOutBuffer: %s\n", remcomOutBuffer);
698 /* reply to the request */
699 putpacket(remcomOutBuffer);
703 /* This function will generate a breakpoint exception. It is used at the
704 beginning of a program to sync up with a debugger and can be used
705 otherwise as a quick means to stop program execution and "break" into
712 printk("breakpoint() called b4 kgdb init\n");
716 asm(" .globl breakinst
717 breakinst: .long 0x7d821008
721 /* Output string in GDB O-packet format if GDB has connected. If nothing
722 output, returns 0 (caller must then handle output). */
724 kgdb_output_string (const char* s, unsigned int count)
731 count = (count <= (sizeof(buffer) / 2 - 2))
732 ? count : (sizeof(buffer) / 2 - 2);
735 mem2hex (s, &buffer[1], count);