xref: /netbsd/sys/arch/x68k/x68k/kgdb_stub.c (revision bf9ec67e)
1 /*	$NetBSD: kgdb_stub.c,v 1.7 2001/11/20 08:43:42 lukem Exp $	*/
2 
3 /*
4  * Copyright (c) 1990, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
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.
10  *
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.
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
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. All advertising materials mentioning features or use of this software
25  *    must display the following acknowledgement:
26  *	This product includes software developed by the University of
27  *	California, Berkeley and its contributors.
28  * 4. Neither the name of the University nor the names of its contributors
29  *    may be used to endorse or promote products derived from this software
30  *    without specific prior written permission.
31  *
32  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
33  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
36  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42  * SUCH DAMAGE.
43  *
44  *	@(#)kgdb_stub.c	8.4 (Berkeley) 1/12/94
45  */
46 
47 /*
48  * "Stub" to allow remote cpu to debug over a serial line using gdb.
49  */
50 
51 #include "opt_kgdb.h"
52 
53 #ifdef KGDB
54 #ifndef lint
55 static char rcsid[] = "$NetBSD: kgdb_stub.c,v 1.7 2001/11/20 08:43:42 lukem Exp $";
56 #endif
57 
58 #include <sys/param.h>
59 #include <sys/systm.h>
60 
61 #include <machine/trap.h>
62 #include <machine/cpu.h>
63 #include <machine/psl.h>
64 #include <machine/reg.h>
65 #include <machine/frame.h>
66 
67 #include <sys/buf.h>
68 #include <dev/cons.h>
69 
70 #include <x68k/x68k/kgdb_proto.h>
71 #include <machine/remote-sl.h>
72 
73 extern int kernacc();
74 extern void chgkprot();
75 
76 #ifndef KGDB_DEV
77 #define KGDB_DEV NODEV
78 #endif
79 #ifndef KGDB_DEVRATE
80 #define KGDB_DEVRATE 9600
81 #endif
82 
83 dev_t kgdb_dev = KGDB_DEV;	/* remote debugging device (NODEV if none) */
84 int kgdb_rate = KGDB_DEVRATE;	/* remote debugging baud rate */
85 int kgdb_active = 0;            /* remote debugging active if != 0 */
86 int kgdb_debug_init = 0;	/* != 0 waits for remote at system init */
87 int kgdb_debug_panic = 1;	/* != 0 waits for remote on panic */
88 int kgdb_debug = 0;
89 
90 #define GETC	((*kgdb_getc)(kgdb_dev))
91 #define PUTC(c)	((*kgdb_putc)(kgdb_dev, c))
92 #define PUTESC(c) { \
93 	if (c == FRAME_END) { \
94 		PUTC(FRAME_ESCAPE); \
95 		c = TRANS_FRAME_END; \
96 	} else if (c == FRAME_ESCAPE) { \
97 		PUTC(FRAME_ESCAPE); \
98 		c = TRANS_FRAME_ESCAPE; \
99 	} else if (c == FRAME_START) { \
100 		PUTC(FRAME_ESCAPE); \
101 		c = TRANS_FRAME_START; \
102 	} \
103 	PUTC(c); \
104 }
105 static int (*kgdb_getc)();
106 static int (*kgdb_putc)();
107 
108 /*
109  * Send a message.  The host gets one chance to read it.
110  */
111 static void
112 kgdb_send(type, bp, len)
113 	register u_char type;
114 	register u_char *bp;
115 	register int len;
116 {
117 	register u_char csum;
118 	register u_char *ep = bp + len;
119 
120 	PUTC(FRAME_START);
121 	PUTESC(type);
122 
123 	csum = type;
124 	while (bp < ep) {
125 		type = *bp++;
126 		csum += type;
127 		PUTESC(type)
128 	}
129 	csum = -csum;
130 	PUTESC(csum)
131 	PUTC(FRAME_END);
132 }
133 
134 static int
135 kgdb_recv(bp, lenp)
136 	u_char *bp;
137 	int *lenp;
138 {
139 	register u_char c, csum;
140 	register int escape, len;
141 	register int type;
142 
143 restart:
144 	csum = len = escape = 0;
145 	type = -1;
146 	while (1) {
147 		c = GETC;
148 		switch (c) {
149 
150 		case FRAME_ESCAPE:
151 			escape = 1;
152 			continue;
153 
154 		case TRANS_FRAME_ESCAPE:
155 			if (escape)
156 				c = FRAME_ESCAPE;
157 			break;
158 
159 		case TRANS_FRAME_END:
160 			if (escape)
161 				c = FRAME_END;
162 			break;
163 
164 		case TRANS_FRAME_START:
165 			if (escape)
166 				c = FRAME_START;
167 			break;
168 
169 		case FRAME_START:
170 			goto restart;
171 
172 		case FRAME_END:
173 			if (type < 0 || --len < 0) {
174 				csum = len = escape = 0;
175 				type = -1;
176 				continue;
177 			}
178 			if (csum != 0) {
179 				return (0);
180 			}
181 			*lenp = len;
182 			return type;
183 		}
184 		csum += c;
185 		if (type < 0) {
186 			type = c;
187 			escape = 0;
188 			continue;
189 		}
190 		if (++len > SL_RPCSIZE) {
191 			while (GETC != FRAME_END)
192 				;
193 			return (0);
194 		}
195 		*bp++ = c;
196 		escape = 0;
197 	}
198 }
199 
200 /*
201  * Translate a trap number into a unix compatible signal value.
202  * (gdb only understands unix signal numbers).
203  */
204 static int
205 computeSignal(type)
206 	int type;
207 {
208 	int sigval;
209 
210 	switch (type) {
211 	case T_BUSERR:
212 	case T_ADDRERR:
213 		sigval = SIGBUS;
214 		break;
215 	case T_ILLINST:
216 	case T_PRIVINST:
217 		sigval = SIGILL;
218 		break;
219 	case T_ZERODIV:
220 	case T_CHKINST:
221 	case T_TRAPVINST:
222 		sigval = SIGFPE;
223 		break;
224 	case T_TRACE:
225 		sigval = SIGTRAP;
226 		break;
227 	case T_MMUFLT:
228 		sigval = SIGSEGV;
229 		break;
230 	case T_SSIR:
231 		sigval = SIGSEGV;
232 		break;
233 	case T_FMTERR:
234 		sigval = SIGILL;
235 		break;
236 	case T_FPERR:
237 	case T_COPERR:
238 		sigval = SIGFPE;
239 		break;
240 	case T_ASTFLT:
241 		sigval = SIGINT;
242 		break;
243 	case T_TRAP15:
244 		sigval = SIGTRAP;
245 		break;
246 	default:
247 		sigval = SIGEMT;
248 		break;
249 	}
250 	return (sigval);
251 }
252 
253 /*
254  * Trap into kgdb to wait for debugger to connect,
255  * noting on the console why nothing else is going on.
256  */
257 kgdb_connect(verbose)
258 	int verbose;
259 {
260 
261 	if (verbose)
262 		printf("kgdb waiting...");
263 	/* trap into kgdb */
264 	asm("trap #15;");
265 	if (verbose)
266 		printf("connected.\n");
267 }
268 
269 /*
270  * Decide what to do on panic.
271  */
272 kgdb_panic()
273 {
274 
275 	if (kgdb_active == 0 && kgdb_debug_panic && kgdb_dev != NODEV)
276 		kgdb_connect(1);
277 }
278 
279 /*
280  * Definitions exported from gdb.
281  */
282 #define NUM_REGS 18
283 #define REGISTER_BYTES ((16+2)*4)
284 #define REGISTER_BYTE(N)  ((N)*4)
285 
286 #define GDB_SR 16
287 #define GDB_PC 17
288 
289 static inline void
290 kgdb_copy(src, dst, nbytes)
291 	register u_char *src, *dst;
292 	register u_int nbytes;
293 {
294 	register u_char *ep = src + nbytes;
295 
296 	while (src < ep)
297 		*dst++ = *src++;
298 }
299 
300 /*
301  * There is a short pad word between SP (A7) and SR which keeps the
302  * kernel stack long word aligned (note that this is in addition to
303  * the stack adjust short that we treat as the upper half of a longword
304  * SR).  We must skip this when copying into and out of gdb.
305  */
306 static inline void
307 regs_to_gdb(fp, regs)
308 	struct frame *fp;
309 	u_long *regs;
310 {
311 	kgdb_copy((u_char *)fp->f_regs, (u_char *)regs, 16*4);
312 	kgdb_copy((u_char *)&fp->f_stackadj, (u_char *)&regs[GDB_SR], 2*4);
313 }
314 
315 static inline void
316 gdb_to_regs(fp, regs)
317 	struct frame *fp;
318 	u_long *regs;
319 {
320 	kgdb_copy((u_char *)regs, (u_char *)fp->f_regs, 16*4);
321 	kgdb_copy((u_char *)&regs[GDB_SR], (u_char *)&fp->f_stackadj, 2*4);
322 }
323 
324 static u_long reg_cache[NUM_REGS];
325 static u_char inbuffer[SL_RPCSIZE+1];
326 static u_char outbuffer[SL_RPCSIZE];
327 
328 /*
329  * This function does all command procesing for interfacing to
330  * a remote gdb.
331  */
332 int
333 kgdb_trap(type, frame)
334 	int type;
335 	struct frame *frame;
336 {
337 	register u_long len;
338 	u_char *addr;
339 	register u_char *cp;
340 	register u_char out, in;
341 	register int outlen;
342 	int inlen;
343 	u_long gdb_regs[NUM_REGS];
344 
345 	if ((int)kgdb_dev < 0) {
346 		/* not debugging */
347 		return (0);
348 	}
349 	if (kgdb_active == 0) {
350 		if (type != T_TRAP15) {
351 			/* No debugger active -- let trap handle this. */
352 			return (0);
353 		}
354 		kgdb_getc = 0;
355 		for (inlen = 0; constab[inlen].cn_probe; inlen++)
356 		    if (major(constab[inlen].cn_dev) == major(kgdb_dev)) {
357 			kgdb_getc = constab[inlen].cn_getc;
358 			kgdb_putc = constab[inlen].cn_putc;
359 			break;
360 		}
361 		if (kgdb_getc == 0 || kgdb_putc == 0)
362 			return (0);
363 		/*
364 		 * If the packet that woke us up isn't an exec packet,
365 		 * ignore it since there is no active debugger.  Also,
366 		 * we check that it's not an ack to be sure that the
367 		 * remote side doesn't send back a response after the
368 		 * local gdb has exited.  Otherwise, the local host
369 		 * could trap into gdb if it's running a gdb kernel too.
370 		 */
371 		in = GETC;
372 		/*
373 		 * If we came in asynchronously through the serial line,
374 		 * the framing character is eaten by the receive interrupt,
375 		 * but if we come in through a synchronous trap (i.e., via
376 		 * kgdb_connect()), we will see the extra character.
377 		 */
378 		if (in == FRAME_START)
379 			in = GETC;
380 
381 		/*
382 		 * Check that this is a debugger exec message.  If so,
383 		 * slurp up the entire message then ack it, and fall
384 		 * through to the recv loop.
385 		 */
386 		if (KGDB_CMD(in) != KGDB_EXEC || (in & KGDB_ACK) != 0)
387 			return (0);
388 		while (GETC != FRAME_END)
389 			;
390 		/*
391 		 * Do the printf *before* we ack the message.  This way
392 		 * we won't drop any inbound characters while we're
393 		 * doing the polling printf.
394 		 */
395 		printf("kgdb started from device %x\n", kgdb_dev);
396 		kgdb_send(in | KGDB_ACK, (u_char *)0, 0);
397 		kgdb_active = 1;
398 	}
399 	/*
400 	 * Stick frame regs into our reg cache then tell remote host
401 	 * that an exception has occurred.
402 	 */
403 	regs_to_gdb(frame, gdb_regs);
404 	if (type != T_TRAP15) {
405 		/*
406 		 * Only send an asynchronous SIGNAL message when we hit
407 		 * a breakpoint.  Otherwise, we will drop the incoming
408 		 * packet while we output this one (and on entry the other
409 		 * side isn't interested in the SIGNAL type -- if it is,
410 		 * it will have used a signal packet.)
411 		 */
412 		outbuffer[0] = computeSignal(type);
413 		kgdb_send(KGDB_SIGNAL, outbuffer, 1);
414 	}
415 
416 	while (1) {
417 		in = kgdb_recv(inbuffer, &inlen);
418 		if (in == 0 || (in & KGDB_ACK))
419 			/* Ignore inbound acks and error conditions. */
420 			continue;
421 
422 		out = in | KGDB_ACK;
423 		switch (KGDB_CMD(in)) {
424 
425 		case KGDB_SIGNAL:
426 			/*
427 			 * if this command came from a running gdb,
428 			 * answer it -- the other guy has no way of
429 			 * knowing if we're in or out of this loop
430 			 * when he issues a "remote-signal".  (Note
431 			 * that without the length check, we could
432 			 * loop here forever if the ourput line is
433 			 * looped back or the remote host is echoing.)
434 			 */
435 			if (inlen == 0) {
436 				outbuffer[0] = computeSignal(type);
437 				kgdb_send(KGDB_SIGNAL, outbuffer, 1);
438 			}
439 			continue;
440 
441 		case KGDB_REG_R:
442 		case KGDB_REG_R | KGDB_DELTA:
443 			cp = outbuffer;
444 			outlen = 0;
445 			for (len = inbuffer[0]; len < NUM_REGS; ++len) {
446 				if (reg_cache[len] != gdb_regs[len] ||
447 				    (in & KGDB_DELTA) == 0) {
448 					if (outlen + 5 > SL_MAXDATA) {
449 						out |= KGDB_MORE;
450 						break;
451 					}
452 					cp[outlen] = len;
453 					kgdb_copy((u_char *)&gdb_regs[len],
454 						  &cp[outlen + 1], 4);
455 					reg_cache[len] = gdb_regs[len];
456 					outlen += 5;
457 				}
458 			}
459 			break;
460 
461 		case KGDB_REG_W:
462 		case KGDB_REG_W | KGDB_DELTA:
463 			cp = inbuffer;
464 			for (len = 0; len < inlen; len += 5) {
465 				register int j = cp[len];
466 
467 				kgdb_copy(&cp[len + 1],
468 					  (u_char *)&gdb_regs[j], 4);
469 				reg_cache[j] = gdb_regs[j];
470 			}
471 			gdb_to_regs(frame, gdb_regs);
472 			outlen = 0;
473 			break;
474 
475 		case KGDB_MEM_R:
476 			len = inbuffer[0];
477 			kgdb_copy(&inbuffer[1], (u_char *)&addr, 4);
478 			if (len > SL_MAXDATA) {
479 				outlen = 1;
480 				outbuffer[0] = E2BIG;
481 			} else if (!kgdb_acc(addr, len, B_READ)) {
482 				outlen = 1;
483 				outbuffer[0] = EFAULT;
484 			} else {
485 				outlen = len + 1;
486 				outbuffer[0] = 0;
487 				kgdb_copy(addr, &outbuffer[1], len);
488 			}
489 			break;
490 
491 		case KGDB_MEM_W:
492 			len = inlen - 4;
493 			kgdb_copy(inbuffer, (u_char *)&addr, 4);
494 			outlen = 1;
495 			if (!kgdb_acc(addr, len, B_READ))
496 				outbuffer[0] = EFAULT;
497 			else {
498 				outbuffer[0] = 0;
499 				if (!kgdb_acc(addr, len, B_WRITE))
500 					chgkprot(addr, len, B_WRITE);
501 				kgdb_copy(&inbuffer[4], addr, len);
502 				ICIA();
503 			}
504 			break;
505 
506 		case KGDB_KILL:
507 			kgdb_active = 0;
508 			printf("kgdb detached\n");
509 			/* fall through */
510 		case KGDB_CONT:
511 			kgdb_send(out, 0, 0);
512 			frame->f_sr &=~ PSL_T;
513 			return (1);
514 
515 		case KGDB_STEP:
516 			kgdb_send(out, 0, 0);
517 			frame->f_sr |= PSL_T;
518 			return (1);
519 
520 		case KGDB_EXEC:
521 		default:
522 			/* Unknown command.  Ack with a null message. */
523 			outlen = 0;
524 			break;
525 		}
526 		/* Send the reply */
527 		kgdb_send(out, outbuffer, outlen);
528 	}
529 }
530 
531 /*
532  * XXX do kernacc call if safe, otherwise attempt
533  * to simulate by simple bounds-checking.
534  */
535 kgdb_acc(addr, len, rw)
536 	caddr_t addr;
537 	int len, rw;
538 {
539 	extern char proc0paddr[], kstack[];	/* XXX */
540 	extern char *kernel_map;		/* XXX! */
541 
542 	if (kernel_map != NULL)
543 		return (kernacc(addr, len, rw));
544 	if (addr < proc0paddr + USPACE  ||
545 	    kstack <= addr && addr < kstack + USPACE)
546 		return (1);
547 	return (0);
548 }
549 #endif /* KGDB */
550