1 /* $NetBSD: kgdb_stub.c,v 1.22 2005/12/07 05:53:24 thorpej Exp $ */
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratories.
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
44 * "Stub" to allow remote CPU to debug over a serial line using gdb.
47 #include <sys/cdefs.h>
48 __KERNEL_RCSID(0, "$NetBSD: kgdb_stub.c,v 1.22 2005/12/07 05:53:24 thorpej Exp $");
52 #include <sys/param.h>
53 #include <sys/systm.h>
59 #define DPRINTF(x) printf x
64 /* XXX: Maybe these should be in the MD files? */
66 #define KGDB_DEV NODEV
69 #define KGDB_DEVRATE 19200
72 dev_t kgdb_dev
= KGDB_DEV
; /* remote debugging device (NODEV if none) */
73 int kgdb_rate
= KGDB_DEVRATE
; /* remote debugging baud rate */
74 int kgdb_active
= 0; /* remote debugging active if != 0 */
75 int kgdb_debug_init
= 0; /* != 0 waits for remote at system init */
76 int kgdb_debug_panic
= 0; /* != 0 waits for remote on panic */
77 label_t
*kgdb_recover
= 0;
79 static int (*kgdb_getc
)(void *);
80 static void (*kgdb_putc
)(void *, int);
81 static void *kgdb_ioarg
;
83 /* KGDB_BUFLEN must be at least (2*KGDB_NUMREGS*sizeof(kgdb_reg_t)+1) */
84 static u_char buffer
[KGDB_BUFLEN
];
85 static kgdb_reg_t gdb_regs
[KGDB_NUMREGS
];
87 #define GETC() ((*kgdb_getc)(kgdb_ioarg))
88 #define PUTC(c) ((*kgdb_putc)(kgdb_ioarg, c))
91 * db_trap_callback can be hooked by MD port code to handle special
92 * cases such as disabling hardware watchdogs while in kgdb. Name
95 void (*db_trap_callback
)(int);
98 * This little routine exists simply so that bcopy() can be debugged.
101 kgdb_copy(void *vsrc
, void *vdst
, int len
)
111 /* ditto for bzero */
113 kgdb_zero(void *vptr
, int len
)
123 * Convert a hex digit into an integer.
124 * This returns -1 if the argument passed is no
130 if (c
>= '0' && c
<= '9')
132 else if (c
>= 'a' && c
<= 'f')
133 return (c
- 'a' + 10);
134 else if (c
>= 'A' && c
<= 'F')
136 return (c
- 'A' + 10);
142 * Convert the low 4 bits of an integer into
148 return (hexdigits
[n
& 0x0f]);
152 * Convert a byte array into an hex string.
155 mem2hex(void *vdst
, void *vsrc
, int len
)
161 *dst
++ = i2digit(*src
>> 4);
162 *dst
++ = i2digit(*src
++);
168 * Convert an hex string into a byte array.
169 * This returns a pointer to the character following
170 * the last valid hex digit. If the string ends in
171 * the middle of a byte, NULL is returned.
174 hex2mem(void *vdst
, u_char
*src
, int maxlen
)
179 while (*src
&& maxlen
--) {
180 msb
= digit2i(*src
++);
183 lsb
= digit2i(*src
++);
186 *dst
++ = (msb
<< 4) | lsb
;
192 * Convert an hex string into an integer.
193 * This returns a pointer to the character following
194 * the last valid hex digit.
203 while ((nibble
= digit2i(*src
)) >= 0) {
216 kgdb_send(const u_char
*bp
)
221 DPRINTF(("kgdb_send: %s\n", bp
));
225 for (csum
= 0; (c
= *p
); p
++) {
230 PUTC(i2digit(csum
>> 4));
232 } while ((c
= GETC() & 0x7f) == KGDB_BADP
);
239 kgdb_recv(u_char
*bp
, int maxlen
)
242 int c
, csum
, tmpcsum
;
245 DPRINTF(("kgdb_recv: "));
249 while ((c
= GETC()) != KGDB_START
)
251 DPRINTF(("%c Start ",c
));
253 while ((c
= GETC()) != KGDB_END
&& len
< maxlen
) {
262 DPRINTF(("%c End ", c
));
273 csum
-= digit2i(c
) * 16;
281 /* Sequence present? */
283 DPRINTF(("Seq %c%c ", bp
[0], bp
[1]));
287 kgdb_copy(bp
+ 3, bp
, len
);
291 DPRINTF((" Bad(wanted %x, off by %d)- ", tmpcsum
, csum
));
294 DPRINTF(("kgdb_recv: %s\n", bp
));
299 * This is called by the appropriate tty driver.
302 kgdb_attach(int (*getfn
)(void *), void (*putfn
)(void *, int), void *ioarg
)
310 * This function does all command processing for interfacing to
311 * a remote gdb. Note that the error codes are ignored by gdb
312 * at present, but might eventually become meaningful. (XXX)
313 * It might makes sense to use POSIX errno values, because
314 * that is what the gdb/remote.c functions want to return.
317 kgdb_trap(int type
, db_regs_t
*regs
)
324 if (kgdb_dev
== NODEV
|| kgdb_getc
== NULL
) {
329 db_clear_single_step(regs
);
331 if (db_trap_callback
) db_trap_callback(1);
333 /* Detect and recover from unexpected traps. */
334 if (kgdb_recover
!= 0) {
335 printf("kgdb: caught trap 0x%x at %p\n",
336 type
, (void*)PC_REGS(regs
));
337 kgdb_send("E0E"); /* 14==EFAULT */
338 longjmp(kgdb_recover
);
342 * The first entry to this function is normally through
343 * a breakpoint trap in kgdb_connect(), in which case we
344 * must advance past the breakpoint because gdb will not.
346 * Machines vary as to where they leave the PC after a
347 * breakpoint trap. Those that leave the PC set to the
348 * address of the trap instruction (i.e. pc532) will not
349 * define FIXUP_PC_AFTER_BREAK(), and therefore will just
350 * advance the PC. On machines that leave the PC set to
351 * the instruction after the trap, FIXUP_PC_AFTER_BREAK
352 * will be defined to back-up the PC, so that after the
353 * "first-time" part of the if statement below has run,
354 * the PC will be the same as it was on entry.
356 * On the first entry here, we expect that gdb is not yet
357 * listening to us, so just enter the interaction loop.
358 * After the debugger is "active" (connected) it will be
359 * waiting for a "signaled" message from us.
361 if (kgdb_active
== 0) {
362 if (!IS_BREAKPOINT_TRAP(type
, 0)) {
363 /* No debugger active -- let trap handle this. */
364 if (db_trap_callback
) db_trap_callback(0);
367 /* Make the PC point at the breakpoint... */
368 #ifdef FIXUP_PC_AFTER_BREAK
369 FIXUP_PC_AFTER_BREAK(regs
);
371 /* ... and then advance past it. */
375 PC_REGS(regs
) += BKPT_SIZE
;
379 /* Tell remote host that an exception has occurred. */
380 snprintf(buffer
, sizeof(buffer
), "S%02x", kgdb_signal(type
));
384 /* Stick frame regs into our reg cache. */
385 kgdb_getregs(regs
, gdb_regs
);
388 * Interact with gdb until it lets us go.
389 * If we cause a trap, resume here.
391 (void)setjmp((kgdb_recover
= &jmpbuf
));
393 kgdb_recv(buffer
, sizeof(buffer
));
397 /* Unknown command. */
403 * if this command came from a running gdb,
404 * answer it -- the other guy has no way of
405 * knowing if we're in or out of this loop
406 * when he issues a "remote-signal".
408 snprintf(buffer
, sizeof(buffer
), "S%02x",
414 mem2hex(buffer
, gdb_regs
, sizeof(gdb_regs
));
419 p
= hex2mem(gdb_regs
, buffer
+ 1, sizeof(gdb_regs
));
420 if (p
== NULL
|| *p
!= '\0')
423 kgdb_setregs(regs
, gdb_regs
);
440 if (len
> sizeof(buffer
) / 2) {
444 if (kgdb_acc(addr
, len
) == 0) {
448 db_read_bytes(addr
, (size_t)len
,
449 (char *)buffer
+ sizeof(buffer
) / 2);
450 mem2hex(buffer
, buffer
+ sizeof(buffer
) / 2, len
);
466 if (len
> (sizeof(buffer
) - (p
- buffer
))) {
470 p
= hex2mem(buffer
, p
, sizeof(buffer
));
475 if (kgdb_acc(addr
, len
) == 0) {
479 db_write_bytes(addr
, (size_t)len
, (char *)buffer
);
486 printf("kgdb detached\n");
487 db_clear_single_step(regs
);
499 PC_REGS(regs
) = addr
;
500 DPRINTF(("kgdb: continuing at %08lx\n", addr
));
504 "kgdb: continuing at old address %08lx\n",
505 (vaddr_t
)PC_REGS(regs
)));
508 db_clear_single_step(regs
);
519 PC_REGS(regs
) = addr
;
521 db_set_single_step(regs
);
526 if (db_trap_callback
) db_trap_callback(0);