1 /* taken from arch/powerpc/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)
139 * We use the upper half of buf as an intermediate buffer for the
140 * raw memory copy. Hex conversion will work against this one.
143 longjmp_on_fault = 1;
145 memcpy(tmp, mem, count);
147 while (count-- > 0) {
149 *buf++ = hexchars[ch >> 4];
150 *buf++ = hexchars[ch & 0xf];
153 longjmp_on_fault = 0;
154 return (unsigned char *)buf;
157 /* convert the hex array pointed to by buf into binary to be placed in mem
158 * return a pointer to the character AFTER the last byte fetched from buf.
161 hex2mem(char *buf, char *mem, int count)
164 char *tmp_raw, *tmp_hex;
167 * We use the upper half of buf as an intermediate buffer for the
168 * raw memory that is converted from hex.
170 tmp_raw = buf + count * 2;
171 tmp_hex = tmp_raw - 1;
173 longjmp_on_fault = 1;
174 while (tmp_hex >= buf) {
176 hexValue = hex(*tmp_hex--);
178 kgdb_error(KGDBERR_NOTHEXDIG);
180 hexValue = hex(*tmp_hex--);
182 kgdb_error(KGDBERR_NOTHEXDIG);
183 *tmp_raw |= hexValue << 4;
187 memcpy(mem, tmp_raw, count);
189 kgdb_flush_cache_range((void *)mem, (void *)(mem+count));
190 longjmp_on_fault = 0;
196 * While we find nice hex chars, build an int.
197 * Return number of chars processed.
200 hexToInt(char **ptr, int *intValue)
207 longjmp_on_fault = 1;
209 hexValue = hex(**ptr);
213 *intValue = (*intValue << 4) | hexValue;
218 longjmp_on_fault = 0;
223 /* scan for the sequence $<data>#<checksum> */
225 getpacket(char *buffer)
227 unsigned char checksum;
228 unsigned char xmitcsum;
234 /* wait around for the start character, ignore all other
236 while ((ch = (getDebugChar() & 0x7f)) != '$') {
249 /* now, read until a # or end of buffer is found */
250 while (count < BUFMAX) {
251 ch = getDebugChar() & 0x7f;
254 checksum = checksum + ch;
265 xmitcsum = hex(getDebugChar() & 0x7f) << 4;
266 xmitcsum |= hex(getDebugChar() & 0x7f);
267 if (checksum != xmitcsum)
268 putDebugChar('-'); /* failed checksum */
270 putDebugChar('+'); /* successful transfer */
271 /* if a sequence char is present, reply the ID */
272 if (buffer[2] == ':') {
273 putDebugChar(buffer[0]);
274 putDebugChar(buffer[1]);
275 /* remove sequence chars from buffer */
276 count = strlen(buffer);
277 for (i=3; i <= count; i++)
278 buffer[i-3] = buffer[i];
282 } while (checksum != xmitcsum);
285 /* send the packet in buffer. */
287 putpacket(unsigned char *buffer)
289 unsigned char checksum;
291 unsigned char ch, recv;
293 /* $<packet info>#<checksum>. */
299 while ((ch = buffer[count])) {
306 putDebugChar(hexchars[checksum >> 4]);
307 putDebugChar(hexchars[checksum & 0xf]);
308 recv = getDebugChar();
309 } while ((recv & 0x7f) != '+');
313 * This function does all command processing for interfacing to gdb.
316 handle_exception (struct pt_regs *regs)
325 printf("kgdb: exception before kgdb is initialized! huh?\n");
329 /* probably should check which exception occured as well */
330 if (longjmp_on_fault) {
331 longjmp_on_fault = 0;
332 kgdb_longjmp(error_jmp_buf, KGDBERR_MEMFAULT);
333 panic("kgdb longjump failed!\n");
337 printf("kgdb: unexpected exception from within kgdb\n");
342 kgdb_interruptible(0);
344 printf("kgdb: handle_exception; trap [0x%x]\n", kgdb_trap(regs));
346 if (kgdb_setjmp(error_jmp_buf) != 0)
347 panic("kgdb: error or fault in entry init!\n");
349 kgdb_enter(regs, &kd);
353 * the first time we enter kgdb, we save the processor
354 * state so that we can return to the monitor if the
355 * remote end quits gdb (or at least, tells us to quit
356 * with the 'k' packet)
362 ptr = remcomOutBuffer;
366 *ptr++ = hexchars[kd.sigval >> 4];
367 *ptr++ = hexchars[kd.sigval & 0xf];
369 for (i = 0; i < kd.nregs; i++) {
370 kgdb_reg *rp = &kd.regs[i];
372 *ptr++ = hexchars[rp->num >> 4];
373 *ptr++ = hexchars[rp->num & 0xf];
375 ptr = (char *)mem2hex((char *)&rp->val, ptr, 4);
383 printf("kgdb: remcomOutBuffer: %s\n", remcomOutBuffer);
386 putpacket((unsigned char *)&remcomOutBuffer);
391 remcomOutBuffer[0] = 0;
393 getpacket(remcomInBuffer);
394 ptr = &remcomInBuffer[1];
398 printf("kgdb: remcomInBuffer: %s\n", remcomInBuffer);
401 errnum = kgdb_setjmp(error_jmp_buf);
403 if (errnum == 0) switch (remcomInBuffer[0]) {
405 case '?': /* report most recent signal */
406 remcomOutBuffer[0] = 'S';
407 remcomOutBuffer[1] = hexchars[kd.sigval >> 4];
408 remcomOutBuffer[2] = hexchars[kd.sigval & 0xf];
409 remcomOutBuffer[3] = 0;
414 /* toggle debug flag */
419 case 'g': /* return the value of the CPU registers. */
420 length = kgdb_getregs(regs, remcomRegBuffer, BUFMAX);
421 mem2hex(remcomRegBuffer, remcomOutBuffer, length);
424 case 'G': /* set the value of the CPU registers */
425 length = strlen(ptr);
426 if ((length & 1) != 0) kgdb_error(KGDBERR_BADPARAMS);
427 hex2mem(ptr, remcomRegBuffer, length/2);
428 kgdb_putregs(regs, remcomRegBuffer, length/2);
429 strcpy(remcomOutBuffer,"OK");
432 case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
433 /* Try to read %x,%x. */
435 if (hexToInt(&ptr, &addr)
437 && hexToInt(&ptr, &length)) {
438 mem2hex((char *)addr, remcomOutBuffer, length);
440 kgdb_error(KGDBERR_BADPARAMS);
444 case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
445 /* Try to read '%x,%x:'. */
447 if (hexToInt(&ptr, &addr)
449 && hexToInt(&ptr, &length)
451 hex2mem(ptr, (char *)addr, length);
452 strcpy(remcomOutBuffer, "OK");
454 kgdb_error(KGDBERR_BADPARAMS);
459 case 'k': /* kill the program, actually return to monitor */
460 kd.extype = KGDBEXIT_KILL;
465 case 'C': /* CSS continue with signal SS */
466 *ptr = '\0'; /* ignore the signal number for now */
469 case 'c': /* cAA..AA Continue; address AA..AA optional */
470 /* try to read optional parameter, pc unchanged if no parm */
471 kd.extype = KGDBEXIT_CONTINUE;
473 if (hexToInt(&ptr, &addr)) {
475 kd.extype |= KGDBEXIT_WITHADDR;
480 case 'S': /* SSS single step with signal SS */
481 *ptr = '\0'; /* ignore the signal number for now */
485 kd.extype = KGDBEXIT_SINGLE;
487 if (hexToInt(&ptr, &addr)) {
489 kd.extype |= KGDBEXIT_WITHADDR;
493 /* Need to flush the instruction cache here, as we may have deposited a
494 * breakpoint, and the icache probably has no way of knowing that a data ref to
495 * some location may have changed something that is in the instruction cache.
497 kgdb_flush_cache_all();
498 kgdb_exit(regs, &kd);
500 kgdb_interruptible(1);
503 case 'r': /* Reset (if user process..exit ???)*/
504 panic("kgdb reset.");
507 case 'P': /* Pr=v set reg r to value v (r and v are hex) */
508 if (hexToInt(&ptr, &addr)
510 && ((length = strlen(ptr)) & 1) == 0) {
511 hex2mem(ptr, remcomRegBuffer, length/2);
512 kgdb_putreg(regs, addr,
513 remcomRegBuffer, length/2);
514 strcpy(remcomOutBuffer,"OK");
516 kgdb_error(KGDBERR_BADPARAMS);
522 sprintf(remcomOutBuffer, "E%02d", errnum);
526 printf("kgdb: remcomOutBuffer: %s\n", remcomOutBuffer);
529 /* reply to the request */
530 putpacket((unsigned char *)&remcomOutBuffer);
536 * kgdb_init must be called *after* the
537 * monitor is relocated into ram
543 debugger_exception_handler = handle_exception;
546 putDebugStr("kgdb ready\n");
551 kgdb_error(int errnum)
553 longjmp_on_fault = 0;
554 kgdb_longjmp(error_jmp_buf, errnum);
555 panic("kgdb_error: longjmp failed!\n");
558 /* Output string in GDB O-packet format if GDB has connected. If nothing
559 output, returns 0 (caller must then handle output). */
561 kgdb_output_string (const char* s, unsigned int count)
565 count = (count <= (sizeof(buffer) / 2 - 2))
566 ? count : (sizeof(buffer) / 2 - 2);
569 mem2hex ((char *)s, &buffer[1], count);
570 putpacket((unsigned char *)&buffer);
579 printf("breakpoint() called b4 kgdb init\n");
583 kgdb_breakpoint(0, 0);
587 do_kgdb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
589 printf("Entering KGDB mode via exception handler...\n\n");
590 kgdb_breakpoint(argc - 1, argv + 1);
591 printf("\nReturned from KGDB mode\n");
596 kgdb, CONFIG_SYS_MAXARGS, 1, do_kgdb,
597 "enter gdb remote debug mode",
598 "[arg0 arg1 .. argN]\n"
599 " - executes a breakpoint so that kgdb mode is\n"
600 " entered via the exception handler. To return\n"
601 " to the monitor, the remote gdb debugger must\n"
602 " execute a \"continue\" or \"quit\" command.\n"
604 " if a program is loaded by the remote gdb, any args\n"
605 " passed to the kgdb command are given to the loaded\n"
606 " program if it is executed (see the \"hello_world\"\n"
607 " example program in the U-Boot examples directory)."