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
kgdb_send(type,bp,len)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
kgdb_recv(bp,lenp)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
computeSignal(type)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 */
kgdb_connect(verbose)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 */
kgdb_panic()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
kgdb_copy(src,dst,nbytes)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
regs_to_gdb(fp,regs)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 *)®s[GDB_SR], 2*4);
292 }
293
294 static inline void
gdb_to_regs(fp,regs)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 *)®s[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
kgdb_trap(type,frame)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 */
kgdb_acc(addr,len,rw)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