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 ****************************************************************************/
95 #if defined(CONFIG_CMD_KGDB)
100 * BUFMAX defines the maximum number of characters in inbound/outbound buffers
103 static char remcomInBuffer[BUFMAX];
104 static char remcomOutBuffer[BUFMAX];
105 static char remcomRegBuffer[BUFMAX];
107 static int initialized = 0;
108 static int kgdb_active = 0, first_entry = 1;
109 static struct pt_regs entry_regs;
110 static u_int error_jmp_buf[BUFMAX/2];
111 static int longjmp_on_fault = 0;
113 static int kdebug = 1;
116 static const char hexchars[]="0123456789abcdef";
118 /* Convert ch from a hex digit to an int */
120 hex(unsigned char ch)
122 if (ch >= 'a' && ch <= 'f')
124 if (ch >= '0' && ch <= '9')
126 if (ch >= 'A' && ch <= 'F')
131 /* Convert the memory pointed to by mem into hex, placing result in buf.
132 * Return a pointer to the last char put in buf (null).
134 static unsigned char *
135 mem2hex(char *mem, char *buf, int count)
139 longjmp_on_fault = 1;
140 while (count-- > 0) {
142 *buf++ = hexchars[ch >> 4];
143 *buf++ = hexchars[ch & 0xf];
146 longjmp_on_fault = 0;
147 return (unsigned char *)buf;
150 /* convert the hex array pointed to by buf into binary to be placed in mem
151 * return a pointer to the character AFTER the last byte fetched from buf.
154 hex2mem(char *buf, char *mem, int count)
158 char *mem_start = mem;
160 longjmp_on_fault = 1;
161 for (i=0; i<count; i++) {
162 if ((hexValue = hex(*buf++)) < 0)
163 kgdb_error(KGDBERR_NOTHEXDIG);
165 if ((hexValue = hex(*buf++)) < 0)
166 kgdb_error(KGDBERR_NOTHEXDIG);
170 kgdb_flush_cache_range((void *)mem_start, (void *)(mem - 1));
171 longjmp_on_fault = 0;
177 * While we find nice hex chars, build an int.
178 * Return number of chars processed.
181 hexToInt(char **ptr, int *intValue)
188 longjmp_on_fault = 1;
190 hexValue = hex(**ptr);
194 *intValue = (*intValue << 4) | hexValue;
199 longjmp_on_fault = 0;
204 /* scan for the sequence $<data>#<checksum> */
206 getpacket(char *buffer)
208 unsigned char checksum;
209 unsigned char xmitcsum;
215 /* wait around for the start character, ignore all other
217 while ((ch = (getDebugChar() & 0x7f)) != '$') {
230 /* now, read until a # or end of buffer is found */
231 while (count < BUFMAX) {
232 ch = getDebugChar() & 0x7f;
235 checksum = checksum + ch;
246 xmitcsum = hex(getDebugChar() & 0x7f) << 4;
247 xmitcsum |= hex(getDebugChar() & 0x7f);
248 if (checksum != xmitcsum)
249 putDebugChar('-'); /* failed checksum */
251 putDebugChar('+'); /* successful transfer */
252 /* if a sequence char is present, reply the ID */
253 if (buffer[2] == ':') {
254 putDebugChar(buffer[0]);
255 putDebugChar(buffer[1]);
256 /* remove sequence chars from buffer */
257 count = strlen(buffer);
258 for (i=3; i <= count; i++)
259 buffer[i-3] = buffer[i];
263 } while (checksum != xmitcsum);
266 /* send the packet in buffer. */
268 putpacket(unsigned char *buffer)
270 unsigned char checksum;
272 unsigned char ch, recv;
274 /* $<packet info>#<checksum>. */
280 while ((ch = buffer[count])) {
287 putDebugChar(hexchars[checksum >> 4]);
288 putDebugChar(hexchars[checksum & 0xf]);
289 recv = getDebugChar();
290 } while ((recv & 0x7f) != '+');
294 * This function does all command processing for interfacing to gdb.
297 handle_exception (struct pt_regs *regs)
306 printf("kgdb: exception before kgdb is initialized! huh?\n");
310 /* probably should check which exception occured as well */
311 if (longjmp_on_fault) {
312 longjmp_on_fault = 0;
313 kgdb_longjmp((long*)error_jmp_buf, KGDBERR_MEMFAULT);
314 panic("kgdb longjump failed!\n");
318 printf("kgdb: unexpected exception from within kgdb\n");
323 kgdb_interruptible(0);
325 printf("kgdb: handle_exception; trap [0x%x]\n", kgdb_trap(regs));
327 if (kgdb_setjmp((long*)error_jmp_buf) != 0)
328 panic("kgdb: error or fault in entry init!\n");
330 kgdb_enter(regs, &kd);
334 * the first time we enter kgdb, we save the processor
335 * state so that we can return to the monitor if the
336 * remote end quits gdb (or at least, tells us to quit
337 * with the 'k' packet)
343 ptr = remcomOutBuffer;
347 *ptr++ = hexchars[kd.sigval >> 4];
348 *ptr++ = hexchars[kd.sigval & 0xf];
350 for (i = 0; i < kd.nregs; i++) {
351 kgdb_reg *rp = &kd.regs[i];
353 *ptr++ = hexchars[rp->num >> 4];
354 *ptr++ = hexchars[rp->num & 0xf];
356 ptr = (char *)mem2hex((char *)&rp->val, ptr, 4);
364 printf("kgdb: remcomOutBuffer: %s\n", remcomOutBuffer);
367 putpacket((unsigned char *)&remcomOutBuffer);
372 remcomOutBuffer[0] = 0;
374 getpacket(remcomInBuffer);
375 ptr = &remcomInBuffer[1];
379 printf("kgdb: remcomInBuffer: %s\n", remcomInBuffer);
382 errnum = kgdb_setjmp((long*)error_jmp_buf);
384 if (errnum == 0) switch (remcomInBuffer[0]) {
386 case '?': /* report most recent signal */
387 remcomOutBuffer[0] = 'S';
388 remcomOutBuffer[1] = hexchars[kd.sigval >> 4];
389 remcomOutBuffer[2] = hexchars[kd.sigval & 0xf];
390 remcomOutBuffer[3] = 0;
395 /* toggle debug flag */
400 case 'g': /* return the value of the CPU registers. */
401 length = kgdb_getregs(regs, remcomRegBuffer, BUFMAX);
402 mem2hex(remcomRegBuffer, remcomOutBuffer, length);
405 case 'G': /* set the value of the CPU registers */
406 length = strlen(ptr);
407 if ((length & 1) != 0) kgdb_error(KGDBERR_BADPARAMS);
408 hex2mem(ptr, remcomRegBuffer, length/2);
409 kgdb_putregs(regs, remcomRegBuffer, length/2);
410 strcpy(remcomOutBuffer,"OK");
413 case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
414 /* Try to read %x,%x. */
416 if (hexToInt(&ptr, &addr)
418 && hexToInt(&ptr, &length)) {
419 mem2hex((char *)addr, remcomOutBuffer, length);
421 kgdb_error(KGDBERR_BADPARAMS);
425 case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
426 /* Try to read '%x,%x:'. */
428 if (hexToInt(&ptr, &addr)
430 && hexToInt(&ptr, &length)
432 hex2mem(ptr, (char *)addr, length);
433 strcpy(remcomOutBuffer, "OK");
435 kgdb_error(KGDBERR_BADPARAMS);
440 case 'k': /* kill the program, actually return to monitor */
441 kd.extype = KGDBEXIT_KILL;
446 case 'C': /* CSS continue with signal SS */
447 *ptr = '\0'; /* ignore the signal number for now */
450 case 'c': /* cAA..AA Continue; address AA..AA optional */
451 /* try to read optional parameter, pc unchanged if no parm */
452 kd.extype = KGDBEXIT_CONTINUE;
454 if (hexToInt(&ptr, &addr)) {
456 kd.extype |= KGDBEXIT_WITHADDR;
461 case 'S': /* SSS single step with signal SS */
462 *ptr = '\0'; /* ignore the signal number for now */
466 kd.extype = KGDBEXIT_SINGLE;
468 if (hexToInt(&ptr, &addr)) {
470 kd.extype |= KGDBEXIT_WITHADDR;
474 /* Need to flush the instruction cache here, as we may have deposited a
475 * breakpoint, and the icache probably has no way of knowing that a data ref to
476 * some location may have changed something that is in the instruction cache.
478 kgdb_flush_cache_all();
479 kgdb_exit(regs, &kd);
481 kgdb_interruptible(1);
484 case 'r': /* Reset (if user process..exit ???)*/
485 panic("kgdb reset.");
488 case 'P': /* Pr=v set reg r to value v (r and v are hex) */
489 if (hexToInt(&ptr, &addr)
491 && ((length = strlen(ptr)) & 1) == 0) {
492 hex2mem(ptr, remcomRegBuffer, length/2);
493 kgdb_putreg(regs, addr,
494 remcomRegBuffer, length/2);
495 strcpy(remcomOutBuffer,"OK");
497 kgdb_error(KGDBERR_BADPARAMS);
503 sprintf(remcomOutBuffer, "E%02d", errnum);
507 printf("kgdb: remcomOutBuffer: %s\n", remcomOutBuffer);
510 /* reply to the request */
511 putpacket((unsigned char *)&remcomOutBuffer);
517 * kgdb_init must be called *after* the
518 * monitor is relocated into ram
524 debugger_exception_handler = handle_exception;
527 putDebugStr("kgdb ready\n");
532 kgdb_error(int errnum)
534 longjmp_on_fault = 0;
535 kgdb_longjmp((long*)error_jmp_buf, errnum);
536 panic("kgdb_error: longjmp failed!\n");
539 /* Output string in GDB O-packet format if GDB has connected. If nothing
540 output, returns 0 (caller must then handle output). */
542 kgdb_output_string (const char* s, unsigned int count)
546 count = (count <= (sizeof(buffer) / 2 - 2))
547 ? count : (sizeof(buffer) / 2 - 2);
550 mem2hex ((char *)s, &buffer[1], count);
551 putpacket((unsigned char *)&buffer);
560 printf("breakpoint() called b4 kgdb init\n");
564 kgdb_breakpoint(0, 0);
568 do_kgdb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
570 printf("Entering KGDB mode via exception handler...\n\n");
571 kgdb_breakpoint(argc - 1, argv + 1);
572 printf("\nReturned from KGDB mode\n");
577 kgdb, CFG_MAXARGS, 1, do_kgdb,
578 "kgdb - enter gdb remote debug mode\n",
579 "[arg0 arg1 .. argN]\n"
580 " - executes a breakpoint so that kgdb mode is\n"
581 " entered via the exception handler. To return\n"
582 " to the monitor, the remote gdb debugger must\n"
583 " execute a \"continue\" or \"quit\" command.\n"
585 " if a program is loaded by the remote gdb, any args\n"
586 " passed to the kgdb command are given to the loaded\n"
587 " program if it is executed (see the \"hello_world\"\n"
588 " example program in the U-Boot examples directory)."
592 int kgdb_not_configured = 1;