xref: /csrg-svn/sys/hp300/hp300/kgdb_stub.c (revision 65700)
141475Smckusick /*
263157Sbostic  * Copyright (c) 1990, 1993
363157Sbostic  *	The Regents of the University of California.  All rights reserved.
441475Smckusick  *
557149Smckusick  * This software was developed by the Computer Systems Engineering group
657149Smckusick  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
757149Smckusick  * contributed to Berkeley.
855673Smckusick  *
957149Smckusick  * All advertising materials mentioning features or use of this software
1057149Smckusick  * must display the following acknowledgement:
1157149Smckusick  *	This product includes software developed by the University of
1257149Smckusick  *	California, Lawrence Berkeley Laboratories.
1357149Smckusick  *
1441475Smckusick  * %sccs.include.redist.c%
1541475Smckusick  *
16*65700Shibler  *	@(#)kgdb_stub.c	8.4 (Berkeley) 01/12/94
1741475Smckusick  */
1855673Smckusick 
1941475Smckusick /*
2047211Skarels  * "Stub" to allow remote cpu to debug over a serial line using gdb.
2147211Skarels  */
2241475Smckusick #ifdef KGDB
2347211Skarels #ifndef lint
2457339Shibler static char rcsid[] = "$Header: /usr/src/sys/hp300/hp300/RCS/kgdb_stub.c,v 1.5 92/12/20 15:49:01 mike Exp $";
2547211Skarels #endif
2641475Smckusick 
2756508Sbostic #include <sys/param.h>
2856508Sbostic #include <sys/systm.h>
2947211Skarels 
3056508Sbostic #include <machine/trap.h>
3156508Sbostic #include <machine/cpu.h>
3256508Sbostic #include <machine/psl.h>
3356508Sbostic #include <machine/reg.h>
3456508Sbostic #include <machine/frame.h>
3547211Skarels 
3656508Sbostic #include <sys/buf.h>
3756508Sbostic #include <hp/dev/cons.h>
3856508Sbostic 
3956508Sbostic #include <hp300/hp300/kgdb_proto.h>
4056508Sbostic #include <machine/remote-sl.h>
4156508Sbostic 
4241475Smckusick extern int kernacc();
4341475Smckusick extern void chgkprot();
4441475Smckusick 
4542367Smckusick #ifndef KGDBDEV
4650225Skarels #define KGDBDEV NODEV
4742367Smckusick #endif
4842367Smckusick #ifndef KGDBRATE
4942367Smckusick #define KGDBRATE 9600
5042367Smckusick #endif
5142367Smckusick 
5250225Skarels dev_t kgdb_dev = KGDBDEV;	/* remote debugging device (NODEV if none) */
5342367Smckusick int kgdb_rate = KGDBRATE;	/* remote debugging baud rate */
5447211Skarels int kgdb_active = 0;            /* remote debugging active if != 0 */
5541475Smckusick int kgdb_debug_init = 0;	/* != 0 waits for remote at system init */
5647471Skarels int kgdb_debug_panic = 1;	/* != 0 waits for remote on panic */
5747211Skarels int kgdb_debug = 0;
5841475Smckusick 
5947211Skarels #define GETC	((*kgdb_getc)(kgdb_dev))
6047211Skarels #define PUTC(c)	((*kgdb_putc)(kgdb_dev, c))
6147211Skarels #define PUTESC(c) { \
6247211Skarels 	if (c == FRAME_END) { \
6347211Skarels 		PUTC(FRAME_ESCAPE); \
6447211Skarels 		c = TRANS_FRAME_END; \
6547211Skarels 	} else if (c == FRAME_ESCAPE) { \
6647211Skarels 		PUTC(FRAME_ESCAPE); \
6747211Skarels 		c = TRANS_FRAME_ESCAPE; \
6855673Smckusick 	} else if (c == FRAME_START) { \
6955673Smckusick 		PUTC(FRAME_ESCAPE); \
7055673Smckusick 		c = TRANS_FRAME_START; \
7147211Skarels 	} \
7247211Skarels 	PUTC(c); \
7342367Smckusick }
7447211Skarels static int (*kgdb_getc)();
7547211Skarels static int (*kgdb_putc)();
7641475Smckusick 
7741475Smckusick /*
7847211Skarels  * Send a message.  The host gets one chance to read it.
7941475Smckusick  */
8047211Skarels static void
kgdb_send(type,bp,len)8147211Skarels kgdb_send(type, bp, len)
8247211Skarels 	register u_char type;
8347211Skarels 	register u_char *bp;
8447211Skarels 	register int len;
8541475Smckusick {
8647211Skarels 	register u_char csum;
8747211Skarels 	register u_char *ep = bp + len;
8841475Smckusick 
8955673Smckusick 	PUTC(FRAME_START);
9055673Smckusick 	PUTESC(type);
9155673Smckusick 
9247211Skarels 	csum = type;
9347211Skarels 	while (bp < ep) {
9447211Skarels 		type = *bp++;
9547211Skarels 		csum += type;
9647211Skarels 		PUTESC(type)
9747211Skarels 	}
9847211Skarels 	csum = -csum;
9947211Skarels 	PUTESC(csum)
10047211Skarels 	PUTC(FRAME_END);
10141475Smckusick }
10241475Smckusick 
10347211Skarels static int
kgdb_recv(bp,lenp)10447211Skarels kgdb_recv(bp, lenp)
10547211Skarels 	u_char *bp;
10647211Skarels 	int *lenp;
10741475Smckusick {
10847211Skarels 	register u_char c, csum;
10947211Skarels 	register int escape, len;
11047211Skarels 	register int type;
11141475Smckusick 
11255673Smckusick restart:
11347211Skarels 	csum = len = escape = 0;
11447211Skarels 	type = -1;
11547211Skarels 	while (1) {
11647211Skarels 		c = GETC;
11747211Skarels 		switch (c) {
11841475Smckusick 
11947211Skarels 		case FRAME_ESCAPE:
12047211Skarels 			escape = 1;
12147211Skarels 			continue;
12241475Smckusick 
12347211Skarels 		case TRANS_FRAME_ESCAPE:
12447211Skarels 			if (escape)
12547211Skarels 				c = FRAME_ESCAPE;
12647211Skarels 			break;
12741475Smckusick 
12847211Skarels 		case TRANS_FRAME_END:
12947211Skarels 			if (escape)
13047211Skarels 				c = FRAME_END;
13141475Smckusick 			break;
13241475Smckusick 
13355673Smckusick 		case TRANS_FRAME_START:
13455673Smckusick 			if (escape)
13555673Smckusick 				c = FRAME_START;
13655673Smckusick 			break;
13755673Smckusick 
13855673Smckusick 		case FRAME_START:
13955673Smckusick 			goto restart;
14055673Smckusick 
14147211Skarels 		case FRAME_END:
14247211Skarels 			if (type < 0 || --len < 0) {
14347211Skarels 				csum = len = escape = 0;
14447211Skarels 				type = -1;
14547211Skarels 				continue;
14647211Skarels 			}
14747211Skarels 			if (csum != 0) {
14847211Skarels 				return (0);
14947211Skarels 			}
15047211Skarels 			*lenp = len;
15147211Skarels 			return type;
15241475Smckusick 		}
15347211Skarels 		csum += c;
15447211Skarels 		if (type < 0) {
15547211Skarels 			type = c;
15647211Skarels 			escape = 0;
15747211Skarels 			continue;
15841475Smckusick 		}
15955673Smckusick 		if (++len > SL_RPCSIZE) {
16047211Skarels 			while (GETC != FRAME_END)
16147211Skarels 				;
16247211Skarels 			return (0);
16347211Skarels 		}
16447211Skarels 		*bp++ = c;
16547211Skarels 		escape = 0;
16641475Smckusick 	}
16741475Smckusick }
16841475Smckusick 
16941475Smckusick /*
17041475Smckusick  * Translate a trap number into a unix compatible signal value.
17141475Smckusick  * (gdb only understands unix signal numbers).
17241475Smckusick  */
17341475Smckusick static int
computeSignal(type)17447211Skarels computeSignal(type)
17547211Skarels 	int type;
17641475Smckusick {
17741475Smckusick 	int sigval;
17841475Smckusick 
17947262Skarels 	switch (type) {
18041475Smckusick 	case T_BUSERR:
18141475Smckusick 		sigval = SIGBUS;
18247211Skarels 		break;
18341475Smckusick 	case T_ADDRERR:
18441475Smckusick 		sigval = SIGBUS;
18547211Skarels 		break;
18641475Smckusick 	case T_ILLINST:
18741475Smckusick 		sigval = SIGILL;
18847211Skarels 		break;
18941475Smckusick 	case T_ZERODIV:
19041475Smckusick 		sigval = SIGFPE;
19147211Skarels 		break;
19241475Smckusick 	case T_CHKINST:
19341475Smckusick 		sigval = SIGFPE;
19447211Skarels 		break;
19541475Smckusick 	case T_TRAPVINST:
19641475Smckusick 		sigval = SIGFPE;
19747211Skarels 		break;
19841475Smckusick 	case T_PRIVINST:
19941475Smckusick 		sigval = SIGILL;
20047211Skarels 		break;
20141475Smckusick 	case T_TRACE:
20241475Smckusick 		sigval = SIGTRAP;
20347211Skarels 		break;
20441475Smckusick 	case T_MMUFLT:
20541475Smckusick 		sigval = SIGSEGV;
20641475Smckusick 		break;
20741475Smckusick 	case T_SSIR:
20841475Smckusick 		sigval = SIGSEGV;
20941475Smckusick 		break;
21041475Smckusick 	case T_FMTERR:
21141475Smckusick 		sigval = SIGILL;
21241475Smckusick 		break;
21341475Smckusick 	case T_FPERR:
21441475Smckusick 		sigval = SIGFPE;
21541475Smckusick 		break;
21641475Smckusick 	case T_COPERR:
21741475Smckusick 		sigval = SIGFPE;
21841475Smckusick 		break;
21943413Shibler 	case T_ASTFLT:
22041475Smckusick 		sigval = SIGINT;
22141475Smckusick 		break;
22241475Smckusick 	case T_TRAP15:
22347211Skarels 		sigval = SIGTRAP;
22441475Smckusick 		break;
22541475Smckusick 	default:
22641475Smckusick 		sigval = SIGEMT;
22741475Smckusick 		break;
22841475Smckusick 	}
22941475Smckusick 	return (sigval);
23041475Smckusick }
23141475Smckusick 
23247211Skarels /*
23348473Skarels  * Trap into kgdb to wait for debugger to connect,
23447471Skarels  * noting on the console why nothing else is going on.
23547471Skarels  */
kgdb_connect(verbose)23647471Skarels kgdb_connect(verbose)
23747471Skarels 	int verbose;
23847471Skarels {
23947471Skarels 
24047471Skarels 	if (verbose)
24147471Skarels 		printf("kgdb waiting...");
24247471Skarels 	/* trap into kgdb */
24347471Skarels 	asm("trap #15;");
24447471Skarels 	if (verbose)
24547471Skarels 		printf("connected.\n");
24647471Skarels }
24747471Skarels 
24847471Skarels /*
24947471Skarels  * Decide what to do on panic.
25047471Skarels  */
kgdb_panic()25147471Skarels kgdb_panic()
25247471Skarels {
25347471Skarels 
25450225Skarels 	if (kgdb_active == 0 && kgdb_debug_panic && kgdb_dev != NODEV)
25547471Skarels 		kgdb_connect(1);
25647471Skarels }
25747471Skarels 
25847471Skarels /*
25947211Skarels  * Definitions exported from gdb.
26047211Skarels  */
26147211Skarels #define NUM_REGS 18
26247211Skarels #define REGISTER_BYTES ((16+2)*4)
26347211Skarels #define REGISTER_BYTE(N)  ((N)*4)
26441475Smckusick 
26547211Skarels #define GDB_SR 16
26647211Skarels #define GDB_PC 17
26747211Skarels 
26847262Skarels static inline void
kgdb_copy(src,dst,nbytes)26965628Sbostic kgdb_copy(src, dst, nbytes)
27065628Sbostic 	register u_char *src, *dst;
27165628Sbostic 	register u_int nbytes;
27247211Skarels {
27347262Skarels 	register u_char *ep = src + nbytes;
27447211Skarels 
27547262Skarels 	while (src < ep)
27647262Skarels 		*dst++ = *src++;
27747211Skarels }
27847211Skarels 
27957339Shibler /*
28057339Shibler  * There is a short pad word between SP (A7) and SR which keeps the
28157339Shibler  * kernel stack long word aligned (note that this is in addition to
28257339Shibler  * the stack adjust short that we treat as the upper half of a longword
28357339Shibler  * SR).  We must skip this when copying into and out of gdb.
28457339Shibler  */
28557339Shibler static inline void
regs_to_gdb(fp,regs)28665628Sbostic regs_to_gdb(fp, regs)
28765628Sbostic 	struct frame *fp;
28865628Sbostic 	u_long *regs;
28957339Shibler {
29057339Shibler 	kgdb_copy((u_char *)fp->f_regs, (u_char *)regs, 16*4);
29157339Shibler 	kgdb_copy((u_char *)&fp->f_stackadj, (u_char *)&regs[GDB_SR], 2*4);
29257339Shibler }
29347262Skarels 
29457339Shibler static inline void
gdb_to_regs(fp,regs)29565628Sbostic gdb_to_regs(fp, regs)
29665628Sbostic 	struct frame *fp;
29765647Sbostic 	u_long *regs;
29857339Shibler {
29957339Shibler 	kgdb_copy((u_char *)regs, (u_char *)fp->f_regs, 16*4);
30057339Shibler 	kgdb_copy((u_char *)&regs[GDB_SR], (u_char *)&fp->f_stackadj, 2*4);
30157339Shibler }
30247262Skarels 
30347211Skarels static u_long reg_cache[NUM_REGS];
30455673Smckusick static u_char inbuffer[SL_RPCSIZE+1];
30555673Smckusick static u_char outbuffer[SL_RPCSIZE];
30647211Skarels 
30747211Skarels /*
30841475Smckusick  * This function does all command procesing for interfacing to
30941475Smckusick  * a remote gdb.
31041475Smckusick  */
31141475Smckusick int
kgdb_trap(type,frame)31265628Sbostic kgdb_trap(type, frame)
31365628Sbostic 	int type;
31465628Sbostic 	struct frame *frame;
31541475Smckusick {
31647262Skarels 	register u_long len;
31747262Skarels 	u_char *addr;
31847262Skarels 	register u_char *cp;
31947262Skarels 	register u_char out, in;
32047262Skarels 	register int outlen;
32147262Skarels 	int inlen;
32247211Skarels 	u_long gdb_regs[NUM_REGS];
32341475Smckusick 
324*65700Shibler 	if ((int)kgdb_dev < 0) {
32541475Smckusick 		/* not debugging */
32641475Smckusick 		return (0);
32747211Skarels 	}
32847211Skarels 	if (kgdb_active == 0) {
32947211Skarels 		if (type != T_TRAP15) {
33047211Skarels 			/* No debugger active -- let trap handle this. */
33147211Skarels 			return (0);
33247211Skarels 		}
33347471Skarels 		kgdb_getc = 0;
33447471Skarels 		for (inlen = 0; constab[inlen].cn_probe; inlen++)
33547471Skarels 		    if (major(constab[inlen].cn_dev) == major(kgdb_dev)) {
33647471Skarels 			kgdb_getc = constab[inlen].cn_getc;
33747471Skarels 			kgdb_putc = constab[inlen].cn_putc;
33847471Skarels 			break;
33947471Skarels 		}
34047262Skarels 		if (kgdb_getc == 0 || kgdb_putc == 0)
34147211Skarels 			return (0);
34247262Skarels 		/*
34348473Skarels 		 * If the packet that woke us up isn't an exec packet,
34447262Skarels 		 * ignore it since there is no active debugger.  Also,
34547262Skarels 		 * we check that it's not an ack to be sure that the
34647262Skarels 		 * remote side doesn't send back a response after the
34747262Skarels 		 * local gdb has exited.  Otherwise, the local host
34847262Skarels 		 * could trap into gdb if it's running a gdb kernel too.
34947262Skarels 		 */
35047262Skarels 		in = GETC;
35148473Skarels 		/*
35248473Skarels 		 * If we came in asynchronously through the serial line,
35348473Skarels 		 * the framing character is eaten by the receive interrupt,
35448473Skarels 		 * but if we come in through a synchronous trap (i.e., via
35548473Skarels 		 * kgdb_connect()), we will see the extra character.
35648473Skarels 		 */
35755673Smckusick 		if (in == FRAME_START)
35848473Skarels 			in = GETC;
35948473Skarels 
36055673Smckusick 		/*
36155673Smckusick 		 * Check that this is a debugger exec message.  If so,
36255673Smckusick 		 * slurp up the entire message then ack it, and fall
36355673Smckusick 		 * through to the recv loop.
36455673Smckusick 		 */
36548473Skarels 		if (KGDB_CMD(in) != KGDB_EXEC || (in & KGDB_ACK) != 0)
36647262Skarels 			return (0);
36747262Skarels 		while (GETC != FRAME_END)
36847262Skarels 			;
36948473Skarels 		/*
37048473Skarels 		 * Do the printf *before* we ack the message.  This way
37148473Skarels 		 * we won't drop any inbound characters while we're
37248473Skarels 		 * doing the polling printf.
37348473Skarels 		 */
37448473Skarels 		printf("kgdb started from device %x\n", kgdb_dev);
37548473Skarels 		kgdb_send(in | KGDB_ACK, (u_char *)0, 0);
37647211Skarels 		kgdb_active = 1;
37747211Skarels 	}
37847211Skarels 	/*
37947211Skarels 	 * Stick frame regs into our reg cache then tell remote host
38047211Skarels 	 * that an exception has occured.
38147211Skarels 	 */
38247211Skarels 	regs_to_gdb(frame, gdb_regs);
38348473Skarels 	if (type != T_TRAP15) {
38448473Skarels 		/*
38548473Skarels 		 * Only send an asynchronous SIGNAL message when we hit
38648473Skarels 		 * a breakpoint.  Otherwise, we will drop the incoming
38748473Skarels 		 * packet while we output this one (and on entry the other
38848473Skarels 		 * side isn't interested in the SIGNAL type -- if it is,
38948473Skarels 		 * it will have used a signal packet.)
39048473Skarels 		 */
39148473Skarels 		outbuffer[0] = computeSignal(type);
39248473Skarels 		kgdb_send(KGDB_SIGNAL, outbuffer, 1);
39348473Skarels 	}
39441475Smckusick 
39547211Skarels 	while (1) {
39647211Skarels 		in = kgdb_recv(inbuffer, &inlen);
39747211Skarels 		if (in == 0 || (in & KGDB_ACK))
39847211Skarels 			/* Ignore inbound acks and error conditions. */
39947211Skarels 			continue;
40041475Smckusick 
40147211Skarels 		out = in | KGDB_ACK;
40247262Skarels 		switch (KGDB_CMD(in)) {
40347211Skarels 
40447211Skarels 		case KGDB_SIGNAL:
40547262Skarels 			/*
40647262Skarels 			 * if this command came from a running gdb,
40747262Skarels 			 * answer it -- the other guy has no way of
40847262Skarels 			 * knowing if we're in or out of this loop
40947262Skarels 			 * when he issues a "remote-signal".  (Note
41047262Skarels 			 * that without the length check, we could
41147262Skarels 			 * loop here forever if the ourput line is
41247262Skarels 			 * looped back or the remote host is echoing.)
41347262Skarels 			 */
41447262Skarels 			if (inlen == 0) {
41547262Skarels 				outbuffer[0] = computeSignal(type);
41647262Skarels 				kgdb_send(KGDB_SIGNAL, outbuffer, 1);
41747262Skarels 			}
41847262Skarels 			continue;
41947211Skarels 
42047211Skarels 		case KGDB_REG_R:
42147211Skarels 		case KGDB_REG_R | KGDB_DELTA:
42247211Skarels 			cp = outbuffer;
42347211Skarels 			outlen = 0;
42447262Skarels 			for (len = inbuffer[0]; len < NUM_REGS; ++len) {
42547262Skarels 				if (reg_cache[len] != gdb_regs[len] ||
42647211Skarels 				    (in & KGDB_DELTA) == 0) {
42755673Smckusick 					if (outlen + 5 > SL_MAXDATA) {
42847211Skarels 						out |= KGDB_MORE;
42947211Skarels 						break;
43047211Skarels 					}
43147262Skarels 					cp[outlen] = len;
43247262Skarels 					kgdb_copy((u_char *)&gdb_regs[len],
43347262Skarels 						  &cp[outlen + 1], 4);
43447262Skarels 					reg_cache[len] = gdb_regs[len];
43547211Skarels 					outlen += 5;
43647211Skarels 				}
43741475Smckusick 			}
43841475Smckusick 			break;
43947211Skarels 
44047211Skarels 		case KGDB_REG_W:
44147211Skarels 		case KGDB_REG_W | KGDB_DELTA:
44247211Skarels 			cp = inbuffer;
44347262Skarels 			for (len = 0; len < inlen; len += 5) {
44447262Skarels 				register int j = cp[len];
44541475Smckusick 
44647262Skarels 				kgdb_copy(&cp[len + 1],
44747262Skarels 					  (u_char *)&gdb_regs[j], 4);
44847211Skarels 				reg_cache[j] = gdb_regs[j];
44941475Smckusick 			}
45047211Skarels 			gdb_to_regs(frame, gdb_regs);
45147211Skarels 			outlen = 0;
45247211Skarels 			break;
45347211Skarels 
45447211Skarels 		case KGDB_MEM_R:
45547262Skarels 			len = inbuffer[0];
45647262Skarels 			kgdb_copy(&inbuffer[1], (u_char *)&addr, 4);
45755673Smckusick 			if (len > SL_MAXDATA) {
45847211Skarels 				outlen = 1;
45947211Skarels 				outbuffer[0] = E2BIG;
46047262Skarels 			} else if (!kgdb_acc(addr, len, B_READ)) {
46147211Skarels 				outlen = 1;
46247211Skarels 				outbuffer[0] = EFAULT;
46347211Skarels 			} else {
46447262Skarels 				outlen = len + 1;
46547211Skarels 				outbuffer[0] = 0;
46647262Skarels 				kgdb_copy(addr, &outbuffer[1], len);
46741475Smckusick 			}
46841475Smckusick 			break;
46941475Smckusick 
47047211Skarels 		case KGDB_MEM_W:
47147262Skarels 			len = inlen - 4;
47247262Skarels 			kgdb_copy(inbuffer, (u_char *)&addr, 4);
47347211Skarels 			outlen = 1;
47447262Skarels 			if (!kgdb_acc(addr, len, B_READ))
47547211Skarels 				outbuffer[0] = EFAULT;
47647211Skarels 			else {
47747211Skarels 				outbuffer[0] = 0;
47847262Skarels 				if (!kgdb_acc(addr, len, B_WRITE))
47947262Skarels 					chgkprot(addr, len, B_WRITE);
48047262Skarels 				kgdb_copy(&inbuffer[4], addr, len);
48154245Smckusick 				ICIA();
48241475Smckusick 			}
48341475Smckusick 			break;
48441475Smckusick 
48547211Skarels 		case KGDB_KILL:
48647211Skarels 			kgdb_active = 0;
48748473Skarels 			printf("kgdb detached\n");
48847211Skarels 			/* fall through */
48947211Skarels 		case KGDB_CONT:
49047211Skarels 			kgdb_send(out, 0, 0);
49147211Skarels 			frame->f_sr &=~ PSL_T;
49247211Skarels 			return (1);
49341475Smckusick 
49447211Skarels 		case KGDB_STEP:
49547211Skarels 			kgdb_send(out, 0, 0);
49647211Skarels 			frame->f_sr |= PSL_T;
49741475Smckusick 			return (1);
49841475Smckusick 
49948473Skarels 		case KGDB_EXEC:
50047211Skarels 		default:
50147211Skarels 			/* Unknown command.  Ack with a null message. */
50247211Skarels 			outlen = 0;
50347211Skarels 			break;
50441475Smckusick 		}
50547211Skarels 		/* Send the reply */
50647211Skarels 		kgdb_send(out, outbuffer, outlen);
50741475Smckusick 	}
50841475Smckusick }
50947262Skarels 
51047262Skarels /*
51147262Skarels  * XXX do kernacc call if safe, otherwise attempt
51247262Skarels  * to simulate by simple bounds-checking.
51347262Skarels  */
kgdb_acc(addr,len,rw)51447262Skarels kgdb_acc(addr, len, rw)
51547262Skarels 	caddr_t addr;
51665628Sbostic 	int len, rw;
51747262Skarels {
51849119Skarels 	extern char proc0paddr[], kstack[];	/* XXX */
51947262Skarels 	extern char *kernel_map;		/* XXX! */
52047262Skarels 
52147262Skarels 	if (kernel_map != NULL)
52247262Skarels 		return (kernacc(addr, len, rw));
52347262Skarels 	if (addr < proc0paddr + UPAGES * NBPG  ||
52449119Skarels 	    kstack <= addr && addr < kstack + UPAGES * NBPG)
52547262Skarels 		return (1);
52647262Skarels 	return (0);
52747262Skarels }
52865628Sbostic #endif /* KGDB */
529