xref: /original-bsd/sys/sparc/sparc/kgdb_stub.c (revision a6d8c59f)
1 /*
2  * Copyright (c) 1992 The Regents of the University of California.
3  * 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	7.3 (Berkeley) 10/11/92
17  *
18  * from: $Header: kgdb_stub.c,v 1.11 92/06/17 05:22:07 torek Exp $
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 /* from LBL version: */
27 static char rcsid[] = "$Header: kgdb_stub.c,v 1.11 92/06/17 05:22:07 torek Exp $";
28 #endif
29 
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/buf.h>
33 
34 #include <machine/psl.h>
35 #include <machine/pte.h>
36 #include <machine/reg.h>
37 #include <machine/trap.h>
38 
39 #include <sparc/sparc/asm.h>
40 #include <sparc/sparc/ctlreg.h>
41 #include <sparc/sparc/kgdb_proto.h>
42 #include <machine/remote-sl.h>
43 
44 #ifndef KGDBDEV
45 #define KGDBDEV -1
46 #endif
47 #ifndef KGDBRATE
48 #define KGDBRATE 38400
49 #endif
50 
51 int kgdb_dev = KGDBDEV;		/* remote debugging device (-1 if none) */
52 int kgdb_rate = KGDBRATE;	/* remote debugging baud rate */
53 int kgdb_active = 0;		/* remote debugging active if != 0 */
54 int kgdb_debug_panic = 0;	/* != 0 waits for remote on panic */
55 
56 #define	getpte(va)	lda(va, ASI_PTE)
57 #define	setpte(va, pte)	sta(va, ASI_PTE, pte)
58 
59 /*
60  * This little routine exists simply so that bcopy() can be debugged.
61  */
62 kgdb_copy(src, dst, len)
63 	register char *src, *dst;
64 	register int len;
65 {
66 
67 	while (--len >= 0)
68 		*dst++ = *src++;
69 }
70 
71 static int (*kgdb_getc) __P((void *));
72 static void (*kgdb_putc) __P((void *, int));
73 static void *kgdb_ioarg;
74 
75 #define GETC()	((*kgdb_getc)(kgdb_ioarg))
76 #define PUTC(c)	((*kgdb_putc)(kgdb_ioarg, c))
77 #define PUTESC(c) { \
78 	if (c == FRAME_END) { \
79 		PUTC(FRAME_ESCAPE); \
80 		c = TRANS_FRAME_END; \
81 	} else if (c == FRAME_ESCAPE) { \
82 		PUTC(FRAME_ESCAPE); \
83 		c = TRANS_FRAME_ESCAPE; \
84 	} else if (c == FRAME_START) { \
85 		PUTC(FRAME_ESCAPE); \
86 		c = TRANS_FRAME_START; \
87 	} \
88 	PUTC(c); \
89 }
90 
91 kgdb_attach(getfn, putfn, ioarg)
92 	int (*getfn) __P((void *));
93 	void (*putfn) __P((void *, int));
94 	void *ioarg;
95 {
96 
97 	kgdb_getc = getfn;
98 	kgdb_putc = putfn;
99 	kgdb_ioarg = ioarg;
100 }
101 
102 /*
103  * Send a message.  The host gets one chance to read it.
104  */
105 static void
106 kgdb_send(type, bp, len)
107 	register u_char type;
108 	register u_char *bp;
109 	register int len;
110 {
111 	register u_char csum;
112 	register u_char *ep = bp + len;
113 
114 	PUTC(FRAME_START);
115 	PUTESC(type);
116 
117 	csum = type;
118 	while (bp < ep) {
119 		type = *bp++;
120 		csum += type;
121 		PUTESC(type);
122 	}
123 	csum = -csum;
124 	PUTESC(csum);
125 	PUTC(FRAME_END);
126 }
127 
128 static int
129 kgdb_recv(bp, lenp)
130 	u_char *bp;
131 	int *lenp;
132 {
133 	register u_char c, csum;
134 	register int escape, len;
135 	register int type;
136 
137 restart:
138 	csum = len = escape = 0;
139 	type = -1;
140 	while (1) {
141 		c = GETC();
142 		switch (c) {
143 
144 		case FRAME_ESCAPE:
145 			escape = 1;
146 			continue;
147 
148 		case TRANS_FRAME_ESCAPE:
149 			if (escape)
150 				c = FRAME_ESCAPE;
151 			break;
152 
153 		case TRANS_FRAME_END:
154 			if (escape)
155 				c = FRAME_END;
156 			break;
157 
158 		case TRANS_FRAME_START:
159 			if (escape)
160 				c = FRAME_START;
161 			break;
162 
163 		case FRAME_START:
164 			goto restart;
165 
166 		case FRAME_END:
167 			if (type < 0 || --len < 0) {
168 				csum = len = escape = 0;
169 				type = -1;
170 				continue;
171 			}
172 			if (csum != 0)
173 				return (0);
174 			*lenp = len;
175 			return (type);
176 		}
177 		csum += c;
178 		if (type < 0) {
179 			type = c;
180 			escape = 0;
181 			continue;
182 		}
183 		if (++len > SL_RPCSIZE) {
184 			while (GETC() != FRAME_END)
185 				continue;
186 			return (0);
187 		}
188 		*bp++ = c;
189 		escape = 0;
190 	}
191 }
192 
193 /*
194  * Translate a trap number into a unix compatible signal value.
195  * (gdb only understands unix signal numbers).
196  * ### should this be done at the other end?
197  */
198 static int
199 computeSignal(type)
200 	int type;
201 {
202 	int sigval;
203 
204 	switch (type) {
205 
206 	case T_AST:
207 		sigval = SIGINT;
208 		break;
209 
210 	case T_TEXTFAULT:
211 	case T_DATAFAULT:
212 		sigval = SIGSEGV;
213 		break;
214 
215 	case T_ALIGN:
216 		sigval = SIGBUS;
217 		break;
218 
219 	case T_ILLINST:
220 	case T_PRIVINST:
221 	case T_DIV0:
222 		sigval = SIGILL;
223 		break;
224 
225 	case T_FPE:
226 		sigval = SIGFPE;
227 		break;
228 
229 	case T_BREAKPOINT:
230 		sigval = SIGTRAP;
231 		break;
232 
233 	case T_KGDB_EXEC:
234 		sigval = SIGIOT;
235 		break;
236 
237 	default:
238 		sigval = SIGEMT;
239 		break;
240 	}
241 	return (sigval);
242 }
243 
244 /*
245  * Trap into kgdb to wait for debugger to connect,
246  * noting on the console why nothing else is going on.
247  */
248 kgdb_connect(verbose)
249 	int verbose;
250 {
251 
252 	if (kgdb_dev < 0 || kgdb_getc == NULL)
253 		return;
254 	fb_unblank();
255 	if (verbose)
256 		printf("kgdb waiting...");
257 	__asm("ta %0" :: "n" (T_KGDB_EXEC));	/* trap into kgdb */
258 }
259 
260 /*
261  * Decide what to do on panic.
262  */
263 kgdb_panic()
264 {
265 
266 	if (kgdb_dev >= 0 && kgdb_getc != NULL &&
267 	    kgdb_active == 0 && kgdb_debug_panic)
268 		kgdb_connect(1);
269 }
270 
271 /*
272  * Definitions exported from gdb (& then made prettier).
273  */
274 #define	GDB_G0		0
275 #define	GDB_O0		8
276 #define	GDB_L0		16
277 #define	GDB_I0		24
278 #define	GDB_FP0		32
279 #define	GDB_Y		64
280 #define	GDB_PSR		65
281 #define	GDB_WIM		66
282 #define	GDB_TBR		67
283 #define	GDB_PC		68
284 #define	GDB_NPC		69
285 #define	GDB_FSR		70
286 #define	GDB_CSR		71
287 
288 #define NUM_REGS 72
289 
290 #define REGISTER_BYTES		(NUM_REGS * 4)
291 #define REGISTER_BYTE(n)	((n) * 4)
292 
293 /*
294  * Translate the values stored in the kernel regs struct to the format
295  * understood by gdb.
296  */
297 void
298 regs_to_gdb(tf, gdb_regs)
299 	struct trapframe *tf;
300 	u_long *gdb_regs;
301 {
302 
303 	/* %g0..%g7 and %o0..%o7: from trapframe */
304 	gdb_regs[0] = 0;
305 	kgdb_copy((caddr_t)&tf->tf_global[1], (caddr_t)&gdb_regs[1], 15 * 4);
306 
307 	/* %l0..%l7 and %i0..%i7: from stack */
308 	kgdb_copy((caddr_t)tf->tf_out[6], (caddr_t)&gdb_regs[GDB_L0], 16 * 4);
309 
310 	/* %f0..%f31 -- fake, kernel does not use FP */
311 	bzero((caddr_t)&gdb_regs[GDB_FP0], 32 * 4);
312 
313 	/* %y, %psr, %wim, %tbr, %pc, %npc, %fsr, %csr */
314 	gdb_regs[GDB_Y] = tf->tf_y;
315 	gdb_regs[GDB_PSR] = tf->tf_psr;
316 	gdb_regs[GDB_WIM] = tf->tf_global[0];	/* input only! */
317 	gdb_regs[GDB_TBR] = 0;			/* fake */
318 	gdb_regs[GDB_PC] = tf->tf_pc;
319 	gdb_regs[GDB_NPC] = tf->tf_npc;
320 	gdb_regs[GDB_FSR] = 0;			/* fake */
321 	gdb_regs[GDB_CSR] = 0;			/* fake */
322 }
323 
324 /*
325  * Reverse the above.
326  */
327 void
328 gdb_to_regs(tf, gdb_regs)
329 	struct trapframe *tf;
330 	u_long *gdb_regs;
331 {
332 
333 	kgdb_copy((caddr_t)&gdb_regs[1], (caddr_t)&tf->tf_global[1], 15 * 4);
334 	kgdb_copy((caddr_t)&gdb_regs[GDB_L0], (caddr_t)tf->tf_out[6]);
335 	tf->tf_y = gdb_regs[GDB_Y];
336 	tf->tf_psr = gdb_regs[GDB_PSR];
337 	tf->tf_pc = gdb_regs[GDB_PC];
338 	tf->tf_npc = gdb_regs[GDB_NPC];
339 }
340 
341 static u_long reg_cache[NUM_REGS];
342 static u_char inbuffer[SL_RPCSIZE];
343 static u_char outbuffer[SL_RPCSIZE];
344 
345 /*
346  * This function does all command procesing for interfacing to
347  * a remote gdb.
348  */
349 int
350 kgdb_trap(type, tf)
351 	int type;
352 	register struct trapframe *tf;
353 {
354 	register u_long len;
355 	caddr_t addr;
356 	register u_char *cp;
357 	register u_char out, in;
358 	register int outlen;
359 	int inlen;
360 	u_long gdb_regs[NUM_REGS];
361 
362 	if (kgdb_dev < 0 || kgdb_getc == NULL) {
363 		/* not debugging */
364 		return (0);
365 	}
366 	if (kgdb_active == 0) {
367 		if (type != T_KGDB_EXEC) {
368 			/* No debugger active -- let trap handle this. */
369 			return (0);
370 		}
371 
372 		/*
373 		 * If the packet that woke us up isn't an exec packet,
374 		 * ignore it since there is no active debugger.  Also,
375 		 * we check that it's not an ack to be sure that the
376 		 * remote side doesn't send back a response after the
377 		 * local gdb has exited.  Otherwise, the local host
378 		 * could trap into gdb if it's running a gdb kernel too.
379 		 */
380 		in = GETC();
381 		/*
382 		 * If we came in asynchronously through the serial line,
383 		 * the framing character is eaten by the receive interrupt,
384 		 * but if we come in through a synchronous trap (i.e., via
385 		 * kgdb_connect()), we will see the extra character.
386 		 */
387 		if (in == FRAME_START)
388 			in = GETC();
389 
390 		if (KGDB_CMD(in) != KGDB_EXEC || (in & KGDB_ACK) != 0)
391 			return (0);
392 		while (GETC() != FRAME_END)
393 			continue;
394 		/*
395 		 * Do the printf *before* we ack the message.  This way
396 		 * we won't drop any inbound characters while we're
397 		 * doing the polling printf.
398 		 */
399 		printf("kgdb started from device %x\n", kgdb_dev);
400 		kgdb_send(in | KGDB_ACK, (u_char *)0, 0);
401 		kgdb_active = 1;
402 	}
403 	if (type == T_KGDB_EXEC) {
404 		/* bypass the trap instruction that got us here */
405 		tf->tf_pc = tf->tf_npc;
406 		tf->tf_npc += 4;
407 	} else {
408 		/*
409 		 * Only send an asynchronous SIGNAL message when we hit
410 		 * a breakpoint.  Otherwise, we will drop the incoming
411 		 * packet while we output this one (and on entry the other
412 		 * side isn't interested in the SIGNAL type -- if it is,
413 		 * it will have used a signal packet.)
414 		 */
415 		outbuffer[0] = computeSignal(type);
416 		kgdb_send(KGDB_SIGNAL, outbuffer, 1);
417 	}
418 	/*
419 	 * Stick frame regs into our reg cache then tell remote host
420 	 * that an exception has occured.
421 	 */
422 	regs_to_gdb(tf, gdb_regs);
423 
424 	for (;;) {
425 		in = kgdb_recv(inbuffer, &inlen);
426 		if (in == 0 || (in & KGDB_ACK))
427 			/* Ignore inbound acks and error conditions. */
428 			continue;
429 
430 		out = in | KGDB_ACK;
431 		switch (KGDB_CMD(in)) {
432 
433 		case KGDB_SIGNAL:
434 			/*
435 			 * if this command came from a running gdb,
436 			 * answer it -- the other guy has no way of
437 			 * knowing if we're in or out of this loop
438 			 * when he issues a "remote-signal".  (Note
439 			 * that without the length check, we could
440 			 * loop here forever if the output line is
441 			 * looped back or the remote host is echoing.)
442 			 */
443 			if (inlen == 0) {
444 				outbuffer[0] = computeSignal(type);
445 				kgdb_send(KGDB_SIGNAL, outbuffer, 1);
446 			}
447 			continue;
448 
449 		case KGDB_REG_R:
450 		case KGDB_REG_R | KGDB_DELTA:
451 			cp = outbuffer;
452 			outlen = 0;
453 			for (len = inbuffer[0]; len < NUM_REGS; ++len) {
454 				if (reg_cache[len] != gdb_regs[len] ||
455 				    (in & KGDB_DELTA) == 0) {
456 					if (outlen + 5 > SL_MAXDATA) {
457 						out |= KGDB_MORE;
458 						break;
459 					}
460 					cp[outlen] = len;
461 					kgdb_copy((caddr_t)&gdb_regs[len],
462 					    (caddr_t)&cp[outlen + 1], 4);
463 					reg_cache[len] = gdb_regs[len];
464 					outlen += 5;
465 				}
466 			}
467 			break;
468 
469 		case KGDB_REG_W:
470 		case KGDB_REG_W | KGDB_DELTA:
471 			cp = inbuffer;
472 			for (len = 0; len < inlen; len += 5) {
473 				register int j = cp[len];
474 
475 				kgdb_copy((caddr_t)&cp[len + 1],
476 				    (caddr_t)&gdb_regs[j], 4);
477 				reg_cache[j] = gdb_regs[j];
478 			}
479 			gdb_to_regs(tf, gdb_regs);
480 			outlen = 0;
481 			break;
482 
483 		case KGDB_MEM_R:
484 			len = inbuffer[0];
485 			kgdb_copy((caddr_t)&inbuffer[1], (caddr_t)&addr, 4);
486 			if (len > SL_MAXDATA) {
487 				outlen = 1;
488 				outbuffer[0] = E2BIG;
489 			} else if (!kgdb_acc(addr, len, B_READ, 1)) {
490 				outlen = 1;
491 				outbuffer[0] = EFAULT;
492 			} else {
493 				outlen = len + 1;
494 				outbuffer[0] = 0;
495 				kgdb_copy(addr, (caddr_t)&outbuffer[1], len);
496 			}
497 			break;
498 
499 		case KGDB_MEM_W:
500 			len = inlen - 4;
501 			kgdb_copy((caddr_t)inbuffer, (caddr_t)&addr, 4);
502 			outlen = 1;
503 			if (!kgdb_acc(addr, len, B_READ, 0))
504 				outbuffer[0] = EFAULT;
505 			else {
506 				outbuffer[0] = 0;
507 				if (!kgdb_acc(addr, len, B_WRITE, 0))
508 					kdb_mkwrite(addr, len);
509 				kgdb_copy((caddr_t)&inbuffer[4], addr, len);
510 			}
511 			break;
512 
513 		case KGDB_KILL:
514 			kgdb_active = 0;
515 			printf("kgdb detached\n");
516 			/* FALLTHROUGH */
517 
518 		case KGDB_CONT:
519 			kgdb_send(out, 0, 0);
520 			return (1);
521 
522 		case KGDB_EXEC:
523 		default:
524 			/* Unknown command.  Ack with a null message. */
525 			outlen = 0;
526 			break;
527 		}
528 		/* Send the reply */
529 		kgdb_send(out, outbuffer, outlen);
530 	}
531 }
532 
533 extern int kernacc();
534 extern void chgkprot();
535 extern char *kernel_map;			/* XXX! */
536 extern char *curproc;				/* XXX! */
537 
538 /*
539  * XXX do kernacc and useracc calls if safe, otherwise use PTE protections.
540  */
541 kgdb_acc(addr, len, rw, usertoo)
542 	caddr_t addr;
543 	int len, rw, usertoo;
544 {
545 	extern char end[];
546 	int pte;
547 
548 	/* XXX icky: valid address but causes timeout */
549 	if (addr >= (caddr_t)0xfffff000)
550 		return (0);
551 	if (kernel_map != NULL) {
552 		if (kernacc(addr, len, rw))
553 			return (1);
554 		if (usertoo && curproc && useracc(addr, len, rw))
555 			return (1);
556 	}
557 	addr = (caddr_t)((int)addr & ~PGOFSET);
558 	for (; len > 0; len -= NBPG, addr += NBPG) {
559 		if (((int)addr >> PG_VSHIFT) != 0 &&
560 		    ((int)addr >> PG_VSHIFT) != -1)
561 			return (0);
562 		pte = getpte(addr);
563 		if ((pte & PG_V) == 0 || rw == B_WRITE && (pte & PG_W) == 0)
564 			return (0);
565 	}
566 	return (1);
567 }
568 
569 kdb_mkwrite(addr, len)
570 	register caddr_t addr;
571 	register int len;
572 {
573 
574 	if (kernel_map != NULL) {
575 		chgkprot(addr, len, B_WRITE);
576 		return;
577 	}
578 	addr = (caddr_t)((int)addr & ~PGOFSET);
579 	for (; len > 0; len -= NBPG, addr += NBPG)
580 		setpte(addr, getpte(addr) | PG_W);
581 }
582 #endif
583