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