1 /* taken from arch/ppc/kernel/ppc-stub.c */
3 /****************************************************************************
5 THIS SOFTWARE IS NOT COPYRIGHTED
7 HP offers the following for use in the public domain. HP makes no
8 warranty with regard to the software or its performance and the
9 user accepts the software "AS IS" with all faults.
11 HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
12 TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
13 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15 ****************************************************************************/
17 /****************************************************************************
18 * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
20 * Module name: remcom.c $
22 * Date: 91/03/09 12:29:49 $
23 * Contributor: Lake Stevens Instrument Division$
25 * Description: low level support for gdb debugger. $
27 * Considerations: only works on target hardware $
29 * Written by: Glenn Engel $
30 * ModuleState: Experimental $
34 * Modified for SPARC by Stu Grossman, Cygnus Support.
36 * This code has been extensively tested on the Fujitsu SPARClite demo board.
38 * To enable debugger support, two things need to happen. One, a
39 * call to set_debug_traps() is necessary in order to allow any breakpoints
40 * or error conditions to be properly intercepted and reported to gdb.
41 * Two, a breakpoint needs to be generated to begin communication. This
42 * is most easily accomplished by a call to breakpoint(). Breakpoint()
43 * simulates a breakpoint by executing a trap #1.
47 * The following gdb commands are supported:
49 * command function Return value
51 * g return the value of the CPU registers hex data or ENN
52 * G set the value of the CPU registers OK or ENN
53 * qOffsets Get section offsets. Reply is Text=xxx;Data=yyy;Bss=zzz
55 * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
56 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
58 * c Resume at current address SNN ( signal NN)
59 * cAA..AA Continue at address AA..AA SNN
61 * s Step one instruction SNN
62 * sAA..AA Step one instruction from AA..AA SNN
66 * ? What was the last sigval ? SNN (signal NN)
68 * bBB..BB Set baud rate to BB..BB OK or BNN, then sets
71 * All commands and responses are sent with a packet which includes a
72 * checksum. A packet consists of
74 * $<packet info>#<checksum>.
77 * <packet info> :: <characters representing the command or response>
78 * <checksum> :: <two hex digits computed as modulo 256 sum of <packetinfo>>
80 * When a packet is received, it is first acknowledged with either '+' or '-'.
81 * '+' indicates a successful transfer. '-' indicates a failed transfer.
86 * $m0,10#2a +$00010203040506070809101112131415#42
88 ****************************************************************************/
98 * BUFMAX defines the maximum number of characters in inbound/outbound buffers
101 static char remcomInBuffer[BUFMAX];
102 static char remcomOutBuffer[BUFMAX];
103 static char remcomRegBuffer[BUFMAX];
105 static int initialized = 0;
106 static int kgdb_active = 0, first_entry = 1;
107 static struct pt_regs entry_regs;
108 static long error_jmp_buf[BUFMAX/2];
109 static int longjmp_on_fault = 0;
111 static int kdebug = 1;
114 static const char hexchars[]="0123456789abcdef";
116 /* Convert ch from a hex digit to an int */
118 hex(unsigned char ch)
120 if (ch >= 'a' && ch <= 'f')
122 if (ch >= '0' && ch <= '9')
124 if (ch >= 'A' && ch <= 'F')
129 /* Convert the memory pointed to by mem into hex, placing result in buf.
130 * Return a pointer to the last char put in buf (null).
132 static unsigned char *
133 mem2hex(char *mem, char *buf, int count)
137 longjmp_on_fault = 1;
138 while (count-- > 0) {
140 *buf++ = hexchars[ch >> 4];
141 *buf++ = hexchars[ch & 0xf];
144 longjmp_on_fault = 0;
145 return (unsigned char *)buf;
148 /* convert the hex array pointed to by buf into binary to be placed in mem
149 * return a pointer to the character AFTER the last byte fetched from buf.
152 hex2mem(char *buf, char *mem, int count)
156 char *mem_start = mem;
158 longjmp_on_fault = 1;
159 for (i=0; i<count; i++) {
160 if ((hexValue = hex(*buf++)) < 0)
161 kgdb_error(KGDBERR_NOTHEXDIG);
163 if ((hexValue = hex(*buf++)) < 0)
164 kgdb_error(KGDBERR_NOTHEXDIG);
168 kgdb_flush_cache_range((void *)mem_start, (void *)(mem - 1));
169 longjmp_on_fault = 0;
175 * While we find nice hex chars, build an int.
176 * Return number of chars processed.
179 hexToInt(char **ptr, int *intValue)
186 longjmp_on_fault = 1;
188 hexValue = hex(**ptr);
192 *intValue = (*intValue << 4) | hexValue;
197 longjmp_on_fault = 0;
202 /* scan for the sequence $<data>#<checksum> */
204 getpacket(char *buffer)
206 unsigned char checksum;
207 unsigned char xmitcsum;
213 /* wait around for the start character, ignore all other
215 while ((ch = (getDebugChar() & 0x7f)) != '$') {
228 /* now, read until a # or end of buffer is found */
229 while (count < BUFMAX) {
230 ch = getDebugChar() & 0x7f;
233 checksum = checksum + ch;
244 xmitcsum = hex(getDebugChar() & 0x7f) << 4;
245 xmitcsum |= hex(getDebugChar() & 0x7f);
246 if (checksum != xmitcsum)
247 putDebugChar('-'); /* failed checksum */
249 putDebugChar('+'); /* successful transfer */
250 /* if a sequence char is present, reply the ID */
251 if (buffer[2] == ':') {
252 putDebugChar(buffer[0]);
253 putDebugChar(buffer[1]);
254 /* remove sequence chars from buffer */
255 count = strlen(buffer);
256 for (i=3; i <= count; i++)
257 buffer[i-3] = buffer[i];
261 } while (checksum != xmitcsum);
264 /* send the packet in buffer. */
266 putpacket(unsigned char *buffer)
268 unsigned char checksum;
270 unsigned char ch, recv;
272 /* $<packet info>#<checksum>. */
278 while ((ch = buffer[count])) {
285 putDebugChar(hexchars[checksum >> 4]);
286 putDebugChar(hexchars[checksum & 0xf]);
287 recv = getDebugChar();
288 } while ((recv & 0x7f) != '+');
292 * This function does all command processing for interfacing to gdb.
295 handle_exception (struct pt_regs *regs)
304 printf("kgdb: exception before kgdb is initialized! huh?\n");
308 /* probably should check which exception occured as well */
309 if (longjmp_on_fault) {
310 longjmp_on_fault = 0;
311 kgdb_longjmp(error_jmp_buf, KGDBERR_MEMFAULT);
312 panic("kgdb longjump failed!\n");
316 printf("kgdb: unexpected exception from within kgdb\n");
321 kgdb_interruptible(0);
323 printf("kgdb: handle_exception; trap [0x%x]\n", kgdb_trap(regs));
325 if (kgdb_setjmp(error_jmp_buf) != 0)
326 panic("kgdb: error or fault in entry init!\n");
328 kgdb_enter(regs, &kd);
332 * the first time we enter kgdb, we save the processor
333 * state so that we can return to the monitor if the
334 * remote end quits gdb (or at least, tells us to quit
335 * with the 'k' packet)
341 ptr = remcomOutBuffer;
345 *ptr++ = hexchars[kd.sigval >> 4];
346 *ptr++ = hexchars[kd.sigval & 0xf];
348 for (i = 0; i < kd.nregs; i++) {
349 kgdb_reg *rp = &kd.regs[i];
351 *ptr++ = hexchars[rp->num >> 4];
352 *ptr++ = hexchars[rp->num & 0xf];
354 ptr = (char *)mem2hex((char *)&rp->val, ptr, 4);
362 printf("kgdb: remcomOutBuffer: %s\n", remcomOutBuffer);
365 putpacket((unsigned char *)&remcomOutBuffer);
370 remcomOutBuffer[0] = 0;
372 getpacket(remcomInBuffer);
373 ptr = &remcomInBuffer[1];
377 printf("kgdb: remcomInBuffer: %s\n", remcomInBuffer);
380 errnum = kgdb_setjmp(error_jmp_buf);
382 if (errnum == 0) switch (remcomInBuffer[0]) {
384 case '?': /* report most recent signal */
385 remcomOutBuffer[0] = 'S';
386 remcomOutBuffer[1] = hexchars[kd.sigval >> 4];
387 remcomOutBuffer[2] = hexchars[kd.sigval & 0xf];
388 remcomOutBuffer[3] = 0;
393 /* toggle debug flag */
398 case 'g': /* return the value of the CPU registers. */
399 length = kgdb_getregs(regs, remcomRegBuffer, BUFMAX);
400 mem2hex(remcomRegBuffer, remcomOutBuffer, length);
403 case 'G': /* set the value of the CPU registers */
404 length = strlen(ptr);
405 if ((length & 1) != 0) kgdb_error(KGDBERR_BADPARAMS);
406 hex2mem(ptr, remcomRegBuffer, length/2);
407 kgdb_putregs(regs, remcomRegBuffer, length/2);
408 strcpy(remcomOutBuffer,"OK");
411 case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
412 /* Try to read %x,%x. */
414 if (hexToInt(&ptr, &addr)
416 && hexToInt(&ptr, &length)) {
417 mem2hex((char *)addr, remcomOutBuffer, length);
419 kgdb_error(KGDBERR_BADPARAMS);
423 case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
424 /* Try to read '%x,%x:'. */
426 if (hexToInt(&ptr, &addr)
428 && hexToInt(&ptr, &length)
430 hex2mem(ptr, (char *)addr, length);
431 strcpy(remcomOutBuffer, "OK");
433 kgdb_error(KGDBERR_BADPARAMS);
438 case 'k': /* kill the program, actually return to monitor */
439 kd.extype = KGDBEXIT_KILL;
444 case 'C': /* CSS continue with signal SS */
445 *ptr = '\0'; /* ignore the signal number for now */
448 case 'c': /* cAA..AA Continue; address AA..AA optional */
449 /* try to read optional parameter, pc unchanged if no parm */
450 kd.extype = KGDBEXIT_CONTINUE;
452 if (hexToInt(&ptr, &addr)) {
454 kd.extype |= KGDBEXIT_WITHADDR;
459 case 'S': /* SSS single step with signal SS */
460 *ptr = '\0'; /* ignore the signal number for now */
464 kd.extype = KGDBEXIT_SINGLE;
466 if (hexToInt(&ptr, &addr)) {
468 kd.extype |= KGDBEXIT_WITHADDR;
472 /* Need to flush the instruction cache here, as we may have deposited a
473 * breakpoint, and the icache probably has no way of knowing that a data ref to
474 * some location may have changed something that is in the instruction cache.
476 kgdb_flush_cache_all();
477 kgdb_exit(regs, &kd);
479 kgdb_interruptible(1);
482 case 'r': /* Reset (if user process..exit ???)*/
483 panic("kgdb reset.");
486 case 'P': /* Pr=v set reg r to value v (r and v are hex) */
487 if (hexToInt(&ptr, &addr)
489 && ((length = strlen(ptr)) & 1) == 0) {
490 hex2mem(ptr, remcomRegBuffer, length/2);
491 kgdb_putreg(regs, addr,
492 remcomRegBuffer, length/2);
493 strcpy(remcomOutBuffer,"OK");
495 kgdb_error(KGDBERR_BADPARAMS);
501 sprintf(remcomOutBuffer, "E%02d", errnum);
505 printf("kgdb: remcomOutBuffer: %s\n", remcomOutBuffer);
508 /* reply to the request */
509 putpacket((unsigned char *)&remcomOutBuffer);
515 * kgdb_init must be called *after* the
516 * monitor is relocated into ram
522 debugger_exception_handler = handle_exception;
525 putDebugStr("kgdb ready\n");
530 kgdb_error(int errnum)
532 longjmp_on_fault = 0;
533 kgdb_longjmp(error_jmp_buf, errnum);
534 panic("kgdb_error: longjmp failed!\n");
537 /* Output string in GDB O-packet format if GDB has connected. If nothing
538 output, returns 0 (caller must then handle output). */
540 kgdb_output_string (const char* s, unsigned int count)
544 count = (count <= (sizeof(buffer) / 2 - 2))
545 ? count : (sizeof(buffer) / 2 - 2);
548 mem2hex ((char *)s, &buffer[1], count);
549 putpacket((unsigned char *)&buffer);
558 printf("breakpoint() called b4 kgdb init\n");
562 kgdb_breakpoint(0, 0);
566 do_kgdb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
568 printf("Entering KGDB mode via exception handler...\n\n");
569 kgdb_breakpoint(argc - 1, argv + 1);
570 printf("\nReturned from KGDB mode\n");
575 kgdb, CONFIG_SYS_MAXARGS, 1, do_kgdb,
576 "enter gdb remote debug mode",
577 "[arg0 arg1 .. argN]\n"
578 " - executes a breakpoint so that kgdb mode is\n"
579 " entered via the exception handler. To return\n"
580 " to the monitor, the remote gdb debugger must\n"
581 " execute a \"continue\" or \"quit\" command.\n"
583 " if a program is loaded by the remote gdb, any args\n"
584 " passed to the kgdb command are given to the loaded\n"
585 " program if it is executed (see the \"hello_world\"\n"
586 " example program in the U-Boot examples directory)."