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