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