xref: /netbsd/sys/arch/sun3/sun3/trap.c (revision c4a72b64)
1 /*	$NetBSD: trap.c,v 1.106 2002/10/20 02:37:37 chs Exp $	*/
2 
3 /*
4  * Copyright (c) 1994 Gordon W. Ross
5  * Copyright (c) 1993 Adam Glass
6  * Copyright (c) 1988 University of Utah.
7  * Copyright (c) 1982, 1986, 1990, 1993
8  *	The Regents of the University of California.  All rights reserved.
9  *
10  * This code is derived from software contributed to Berkeley by
11  * the Systems Programming Group of the University of Utah Computer
12  * Science Department.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  * 3. All advertising materials mentioning features or use of this software
23  *    must display the following acknowledgement:
24  *	This product includes software developed by the University of
25  *	California, Berkeley and its contributors.
26  * 4. Neither the name of the University nor the names of its contributors
27  *    may be used to endorse or promote products derived from this software
28  *    without specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
31  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
34  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40  * SUCH DAMAGE.
41  *
42  *	from: Utah Hdr: trap.c 1.37 92/12/20
43  *	from: @(#)trap.c	8.5 (Berkeley) 1/4/94
44  */
45 
46 #include "opt_ddb.h"
47 #include "opt_execfmt.h"
48 #include "opt_kgdb.h"
49 #include "opt_compat_aout_m68k.h"
50 #include "opt_compat_sunos.h"
51 
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/proc.h>
55 #include <sys/acct.h>
56 #include <sys/kernel.h>
57 #include <sys/signalvar.h>
58 #include <sys/resourcevar.h>
59 #include <sys/syscall.h>
60 #include <sys/syslog.h>
61 #include <sys/user.h>
62 #ifdef	KGDB
63 #include <sys/kgdb.h>
64 #endif
65 
66 #include <uvm/uvm_extern.h>
67 
68 #include <machine/cpu.h>
69 #include <machine/endian.h>
70 #include <machine/psl.h>
71 #include <machine/trap.h>
72 #include <machine/reg.h>
73 #include <m68k/cacheops.h>
74 
75 #include <sun3/sun3/fc.h>
76 #include <sun3/sun3/machdep.h>
77 
78 #ifdef DDB
79 #include <machine/db_machdep.h>
80 #include <ddb/db_extern.h>
81 #endif
82 
83 #ifdef COMPAT_SUNOS
84 #include <compat/sunos/sunos_syscall.h>
85 extern struct emul emul_sunos;
86 #endif
87 
88 #ifdef COMPAT_AOUT_M68K
89 extern struct emul emul_netbsd_aoutm68k;
90 #endif
91 
92 /*
93  * The sun3 wants faults to go through the pmap code, but
94  * the sun3x just goes directly to the common VM code.
95  */
96 #ifdef	_SUN3X_
97 # define _pmap_fault(map, va, ftype) \
98 	uvm_fault(map, va, 0, ftype)
99 #endif	/* SUN3X */
100 
101 /* Special labels in m68k/copy.s */
102 extern char fubail[], subail[];
103 
104 /* These are called from locore.s */
105 void trap __P((int type, u_int code, u_int v, struct trapframe));
106 void trap_kdebug __P((int type, struct trapframe tf));
107 int _nodb_trap __P((int type, struct trapframe *));
108 void straytrap __P((struct trapframe));
109 
110 static void userret __P((struct proc *, struct trapframe *, u_quad_t));
111 
112 int astpending;
113 int want_resched;
114 
115 char	*trap_type[] = {
116 	"Bus error",
117 	"Address error",
118 	"Illegal instruction",
119 	"Zero divide",
120 	"CHK instruction",
121 	"TRAPV instruction",
122 	"Privilege violation",
123 	"Trace trap",
124 	"MMU fault",
125 	"SSIR trap",
126 	"Format error",
127 	"68881 exception",
128 	"Coprocessor violation",
129 	"Async system trap",
130 	"Unused? (14)",
131 	"Breakpoint",
132 	"FPU instruction",
133 	"FPU data format",
134 };
135 u_int trap_types = sizeof(trap_type) / sizeof(trap_type[0]);
136 
137 /*
138  * Size of various exception stack frames (minus the standard 8 bytes)
139  */
140 short	exframesize[] = {
141 	FMT0SIZE,	/* type 0 - normal (68020/030/040/060) */
142 	FMT1SIZE,	/* type 1 - throwaway (68020/030/040) */
143 	FMT2SIZE,	/* type 2 - normal 6-word (68020/030/040/060) */
144 	FMT3SIZE,	/* type 3 - FP post-instruction (68040/060) */
145 	FMT4SIZE,	/* type 4 - access error/fp disabled (68060) */
146 	-1, -1, 	/* type 5-6 - undefined */
147 	FMT7SIZE,	/* type 7 - access error (68040) */
148 	58,		/* type 8 - bus fault (68010) */
149 	FMT9SIZE,	/* type 9 - coprocessor mid-instruction (68020/030) */
150 	FMTASIZE,	/* type A - short bus fault (68020/030) */
151 	FMTBSIZE,	/* type B - long bus fault (68020/030) */
152 	-1, -1, -1, -1	/* type C-F - undefined */
153 };
154 
155 #define KDFAULT(c)	(((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
156 #define WRFAULT(c)	(((c) & (SSW_DF|SSW_RW)) == SSW_DF)
157 
158 /* #define	DEBUG XXX */
159 
160 #ifdef DEBUG
161 int mmudebug = 0;
162 int mmupid = -1;
163 #define MDB_ISPID(p)	((p) == mmupid)
164 #define MDB_FOLLOW	1
165 #define MDB_WBFOLLOW	2
166 #define MDB_WBFAILED	4
167 #define MDB_CPFAULT 	8
168 #endif
169 
170 /*
171  * trap and syscall both need the following work done before
172  * returning to user mode.
173  */
174 static void
175 userret(p, tf, oticks)
176 	struct proc *p;
177 	struct trapframe *tf;
178 	u_quad_t oticks;
179 {
180 	int sig;
181 
182 	/* take pending signals */
183 	while ((sig = CURSIG(p)) != 0)
184 		postsig(sig);
185 
186 	p->p_priority = p->p_usrpri;
187 
188 	if (want_resched) {
189 		/*
190 		 * We are being preempted.
191 		 */
192 		preempt(NULL);
193 		while ((sig = CURSIG(p)) != 0)
194 			postsig(sig);
195 	}
196 
197 	/*
198 	 * If profiling, charge system time to the trapped pc.
199 	 */
200 	if (p->p_flag & P_PROFIL) {
201 		extern int psratio;
202 		addupc_task(p, tf->tf_pc,
203 		            (int)(p->p_sticks - oticks) * psratio);
204 	}
205 
206 	curcpu()->ci_schedstate.spc_curpriority = p->p_priority;
207 }
208 
209 /*
210  * Used by the common m68k syscall() and child_return() functions.
211  * XXX: Temporary until all m68k ports share common trap()/userret() code.
212  */
213 void machine_userret(struct proc *, struct frame *, u_quad_t);
214 
215 void
216 machine_userret(p, f, t)
217 	struct proc *p;
218 	struct frame *f;
219 	u_quad_t t;
220 {
221 
222 	userret(p, &f->F_t, t);
223 }
224 
225 /*
226  * Trap is called from locore to handle most types of processor traps,
227  * including events such as simulated software interrupts/AST's.
228  * System calls are broken out for efficiency.
229  */
230 /*ARGSUSED*/
231 void
232 trap(type, code, v, tf)
233 	int type;
234 	u_int code, v;
235 	struct trapframe tf;
236 {
237 	struct proc *p;
238 	int sig, tmp;
239 	u_int ucode;
240 	u_quad_t sticks;
241 	caddr_t onfault;
242 
243 	uvmexp.traps++;
244 	p = curproc;
245 	ucode = 0;
246 	sig = 0;
247 
248 	/* I have verified that this DOES happen! -gwr */
249 	if (p == NULL)
250 		p = &proc0;
251 #ifdef	DIAGNOSTIC
252 	if (p->p_addr == NULL)
253 		panic("trap: no pcb");
254 #endif
255 
256 	if (USERMODE(tf.tf_sr)) {
257 		type |= T_USER;
258 		sticks = p->p_sticks;
259 		p->p_md.md_regs = tf.tf_regs;
260 	} else {
261 		sticks = 0;
262 		/* XXX: Detect trap recursion? */
263 	}
264 
265 	switch (type) {
266 	default:
267 	dopanic:
268 		printf("trap type=0x%x, code=0x%x, v=0x%x\n", type, code, v);
269 		/*
270 		 * Let the kernel debugger see the trap frame that
271 		 * caused us to panic.  This is a convenience so
272 		 * one can see registers at the point of failure.
273 		 */
274 		tmp = splhigh();
275 #ifdef KGDB
276 		/* If connected, step or cont returns 1 */
277 		if (kgdb_trap(type, &tf))
278 			goto kgdb_cont;
279 #endif
280 #ifdef	DDB
281 		(void) kdb_trap(type, (db_regs_t *) &tf);
282 #endif
283 #ifdef KGDB
284 	kgdb_cont:
285 #endif
286 		splx(tmp);
287 		if (panicstr) {
288 			/*
289 			 * Note: panic is smart enough to do:
290 			 *   boot(RB_AUTOBOOT | RB_NOSYNC, NULL)
291 			 * if we call it again.
292 			 */
293 			panic("trap during panic!");
294 		}
295 		regdump(&tf, 128);
296 		type &= ~T_USER;
297 		if ((u_int)type < trap_types)
298 			panic(trap_type[type]);
299 		panic("trap type 0x%x", type);
300 
301 	case T_BUSERR:		/* kernel bus error */
302 		if (p->p_addr->u_pcb.pcb_onfault == NULL)
303 			goto dopanic;
304 		/*FALLTHROUGH*/
305 
306 	copyfault:
307 		/*
308 		 * If we have arranged to catch this fault in any of the
309 		 * copy to/from user space routines, set PC to return to
310 		 * indicated location and set flag informing buserror code
311 		 * that it may need to clean up stack frame.
312 		 */
313 		tf.tf_stackadj = exframesize[tf.tf_format];
314 		tf.tf_format = tf.tf_vector = 0;
315 		tf.tf_pc = (int) p->p_addr->u_pcb.pcb_onfault;
316 		goto done;
317 
318 	case T_BUSERR|T_USER:	/* bus error */
319 	case T_ADDRERR|T_USER:	/* address error */
320 		ucode = v;
321 		sig = SIGBUS;
322 		break;
323 
324 	case T_COPERR:		/* kernel coprocessor violation */
325 	case T_FMTERR|T_USER:	/* do all RTE errors come in as T_USER? */
326 	case T_FMTERR:		/* ...just in case... */
327 		/*
328 		 * The user has most likely trashed the RTE or FP state info
329 		 * in the stack frame of a signal handler.
330 		 */
331 		printf("pid %d: kernel %s exception\n", p->p_pid,
332 		       type==T_COPERR ? "coprocessor" : "format");
333 		type |= T_USER;
334 		SIGACTION(p, SIGILL).sa_handler = SIG_DFL;
335 		sigdelset(&p->p_sigctx.ps_sigignore, SIGILL);
336 		sigdelset(&p->p_sigctx.ps_sigcatch, SIGILL);
337 		sigdelset(&p->p_sigctx.ps_sigmask, SIGILL);
338 		sig = SIGILL;
339 		ucode = tf.tf_format;
340 		break;
341 
342 	case T_COPERR|T_USER:	/* user coprocessor violation */
343 		/* What is a proper response here? */
344 		ucode = 0;
345 		sig = SIGFPE;
346 		break;
347 
348 	case T_FPERR|T_USER:	/* 68881 exceptions */
349 		/*
350 		 * We pass along the 68881 status register which locore stashed
351 		 * in code for us.  Note that there is a possibility that the
352 		 * bit pattern of this register will conflict with one of the
353 		 * FPE_* codes defined in signal.h.  Fortunately for us, the
354 		 * only such codes we use are all in the range 1-7 and the low
355 		 * 3 bits of the status register are defined as 0 so there is
356 		 * no clash.
357 		 */
358 		ucode = code;
359 		sig = SIGFPE;
360 		break;
361 
362 	case T_FPEMULI:		/* FPU faults in supervisor mode */
363 	case T_FPEMULD:
364 		if (nofault)	/* Doing FPU probe? */
365 			longjmp(nofault);
366 		goto dopanic;
367 
368 	case T_FPEMULI|T_USER:	/* unimplemented FP instuction */
369 	case T_FPEMULD|T_USER:	/* unimplemented FP data type */
370 #ifdef	FPU_EMULATE
371 		sig = fpu_emulate(&tf, &p->p_addr->u_pcb.pcb_fpregs);
372 		/* XXX - Deal with tracing? (tf.tf_sr & PSL_T) */
373 #else
374 		uprintf("pid %d killed: no floating point support\n", p->p_pid);
375 		sig = SIGILL;
376 #endif
377 		break;
378 
379 	case T_ILLINST|T_USER:	/* illegal instruction fault */
380 	case T_PRIVINST|T_USER:	/* privileged instruction fault */
381 		ucode = tf.tf_format;
382 		sig = SIGILL;
383 		break;
384 
385 	case T_ZERODIV|T_USER:	/* Divide by zero */
386 	case T_CHKINST|T_USER:	/* CHK instruction trap */
387 	case T_TRAPVINST|T_USER:	/* TRAPV instruction trap */
388 		ucode = tf.tf_format;
389 		sig = SIGFPE;
390 		break;
391 
392 	/*
393 	 * XXX: Trace traps are a nightmare.
394 	 *
395 	 *	HP-UX uses trap #1 for breakpoints,
396 	 *	NetBSD/m68k uses trap #2,
397 	 *	SUN 3.x uses trap #15,
398 	 *	DDB and KGDB uses trap #15 (for kernel breakpoints;
399 	 *	handled elsewhere).
400 	 *
401 	 * NetBSD and HP-UX traps both get mapped by locore.s into T_TRACE.
402 	 * SUN 3.x traps get passed through as T_TRAP15 and are not really
403 	 * supported yet.
404 	 *
405 	 * XXX: We should never get kernel-mode T_TRAP15
406 	 * XXX: because locore.s now gives them special treatment.
407 	 */
408 	case T_TRAP15:		/* kernel breakpoint */
409 		tf.tf_sr &= ~PSL_T;
410 		goto done;
411 
412 	case T_TRACE|T_USER:	/* user trace trap */
413 #ifdef COMPAT_SUNOS
414 		/*
415 		 * SunOS uses Trap #2 for a "CPU cache flush"
416 		 * Just flush the on-chip caches and return.
417 		 * XXX - Too bad NetBSD uses trap 2...
418 		 */
419 		if (p->p_emul == &emul_sunos) {
420 			ICIA();
421 			DCIU();
422 			/* get out fast */
423 			goto done;
424 		}
425 #endif
426 		/* FALLTHROUGH */
427 	case T_TRACE:		/* tracing a trap instruction */
428 	case T_TRAP15|T_USER:	/* SUN user trace trap */
429 		tf.tf_sr &= ~PSL_T;
430 		sig = SIGTRAP;
431 		break;
432 
433 	case T_ASTFLT:		/* system async trap, cannot happen */
434 		goto dopanic;
435 
436 	case T_ASTFLT|T_USER:	/* user async trap */
437 		astpending = 0;
438 		/* T_SSIR is not used on a Sun3. */
439 		if (p->p_flag & P_OWEUPC) {
440 			p->p_flag &= ~P_OWEUPC;
441 			ADDUPROF(p);
442 		}
443 		goto douret;
444 
445 	case T_MMUFLT:		/* kernel mode page fault */
446 		/* Hacks to avoid calling VM code from debugger. */
447 #ifdef	DDB
448 		if (db_recover != 0)
449 			goto dopanic;
450 #endif
451 #ifdef	KGDB
452 		if (kgdb_recover != 0)
453 			goto dopanic;
454 #endif
455 		/*
456 		 * If we were doing profiling ticks or other user mode
457 		 * stuff from interrupt code, Just Say No.
458 		 */
459 		if (p->p_addr->u_pcb.pcb_onfault == (caddr_t)fubail ||
460 		    p->p_addr->u_pcb.pcb_onfault == (caddr_t)subail)
461 		{
462 #ifdef	DEBUG
463 			if (mmudebug & MDB_CPFAULT) {
464 				printf("trap: copyfault fu/su bail\n");
465 				Debugger();
466 			}
467 #endif
468 			goto copyfault;
469 		}
470 		/*FALLTHROUGH*/
471 
472 	case T_MMUFLT|T_USER: { 	/* page fault */
473 		vaddr_t va;
474 		struct vmspace *vm = p->p_vmspace;
475 		struct vm_map *map;
476 		int rv;
477 		vm_prot_t ftype;
478 		extern struct vm_map *kernel_map;
479 
480 #ifdef DEBUG
481 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
482 		printf("trap: T_MMUFLT pid=%d, code=0x%x, v=0x%x, pc=0x%x, sr=0x%x\n",
483 		       p->p_pid, code, v, tf.tf_pc, tf.tf_sr);
484 #endif
485 
486 		/*
487 		 * It is only a kernel address space fault iff:
488 		 * 	1. (type & T_USER) == 0  and: (2 or 3)
489 		 * 	2. pcb_onfault not set or
490 		 *	3. pcb_onfault set but supervisor space data fault
491 		 * The last can occur during an exec() copyin where the
492 		 * argument space is lazy-allocated.
493 		 */
494 		map = &vm->vm_map;
495 		if ((type & T_USER) == 0) {
496 			/* supervisor mode fault */
497 			if ((p->p_addr->u_pcb.pcb_onfault == NULL) || KDFAULT(code))
498 				map = kernel_map;
499 		}
500 
501 		if (WRFAULT(code))
502 			ftype = VM_PROT_WRITE;
503 		else
504 			ftype = VM_PROT_READ;
505 		va = m68k_trunc_page((vaddr_t)v);
506 
507 		/*
508 		 * Need to resolve the fault.
509 		 *
510 		 * We give the pmap code a chance to resolve faults by
511 		 * reloading translations that it was forced to unload.
512 		 * This function does that, and calls vm_fault if it
513 		 * could not resolve the fault by reloading the MMU.
514 		 * This function may also, for example, disallow any
515 		 * faults in the kernel text segment, etc.
516 		 */
517 
518 		onfault = p->p_addr->u_pcb.pcb_onfault;
519 		p->p_addr->u_pcb.pcb_onfault = NULL;
520 		rv = _pmap_fault(map, va, ftype);
521 		p->p_addr->u_pcb.pcb_onfault = onfault;
522 
523 #ifdef	DEBUG
524 		if (rv && MDB_ISPID(p->p_pid)) {
525 			printf("vm_fault(%p, 0x%lx, 0x%x, 0) -> 0x%x\n",
526 			       map, va, ftype, rv);
527 			if (mmudebug & MDB_WBFAILED)
528 				Debugger();
529 		}
530 #endif	/* DEBUG */
531 
532 		/*
533 		 * If this was a stack access we keep track of the maximum
534 		 * accessed stack size.  Also, if vm_fault gets a protection
535 		 * failure it is due to accessing the stack region outside
536 		 * the current limit and we need to reflect that as an access
537 		 * error.
538 		 */
539 		if ((map != kernel_map) && ((caddr_t)va >= vm->vm_maxsaddr)) {
540 			if (rv == 0) {
541 				unsigned nss;
542 
543 				nss = btoc((u_int)(USRSTACK-va));
544 				if (nss > vm->vm_ssize)
545 					vm->vm_ssize = nss;
546 			} else if (rv == EACCES)
547 				rv = EFAULT;
548 		}
549 		if (rv == 0)
550 			goto finish;
551 
552 		if ((type & T_USER) == 0) {
553 			/* supervisor mode fault */
554 			if (p->p_addr->u_pcb.pcb_onfault) {
555 #ifdef	DEBUG
556 				if (mmudebug & MDB_CPFAULT) {
557 					printf("trap: copyfault pcb_onfault\n");
558 					Debugger();
559 				}
560 #endif
561 				goto copyfault;
562 			}
563 			printf("vm_fault(%p, 0x%lx, 0x%x, 0) -> 0x%x\n",
564 			       map, va, ftype, rv);
565 			goto dopanic;
566 		}
567 		ucode = v;
568 		if (rv == ENOMEM) {
569 			printf("UVM: pid %d (%s), uid %d killed: out of swap\n",
570 			       p->p_pid, p->p_comm,
571 			       p->p_cred && p->p_ucred ?
572 			       p->p_ucred->cr_uid : -1);
573 			sig = SIGKILL;
574 		} else {
575 			sig = SIGSEGV;
576 		}
577 		break;
578 		} /* T_MMUFLT */
579 	} /* switch */
580 
581 finish:
582 	/* If trap was from supervisor mode, just return. */
583 	if ((type & T_USER) == 0)
584 		goto done;
585 	/* Post a signal if necessary. */
586 	if (sig != 0)
587 		trapsignal(p, sig, ucode);
588 douret:
589 	userret(p, &tf, sticks);
590 
591 done:;
592 	/* XXX: Detect trap recursion? */
593 }
594 
595 /*
596  * This is used if we hit a kernel breakpoint or trace trap
597  * when there is no debugger installed (or not attached).
598  * Drop into the PROM temporarily...
599  */
600 int
601 _nodb_trap(type, tf)
602 	int type;
603 	struct trapframe *tf;
604 {
605 
606 	printf("\r\nKernel ");
607 	if ((0 <= type) && (type < trap_types))
608 		printf("%s", trap_type[type]);
609 	else
610 		printf("trap 0x%x", type);
611 	printf(", frame=%p\r\n", tf);
612 	printf("No debugger; doing PROM abort.\r\n");
613 	printf("To continue, type: c <RETURN>\r\n");
614 	sunmon_abort();
615 	/* OK then, just resume... */
616 	tf->tf_sr &= ~PSL_T;
617 	return(1);
618 }
619 
620 /*
621  * This is called by locore for supervisor-mode trace and
622  * breakpoint traps.  This is separate from trap() above
623  * so that breakpoints in trap() will work.
624  *
625  * If we have both DDB and KGDB, let KGDB see it first,
626  * because KGDB will just return 0 if not connected.
627  */
628 void
629 trap_kdebug(type, tf)
630 	int type;
631 	struct trapframe tf;
632 {
633 
634 #ifdef	KGDB
635 	/* Let KGDB handle it (if connected) */
636 	if (kgdb_trap(type, &tf))
637 		return;
638 #endif
639 #ifdef	DDB
640 	/* Let DDB handle it. */
641 	if (kdb_trap(type, &tf))
642 		return;
643 #endif
644 
645 	/* Drop into the PROM temporarily... */
646 	(void)_nodb_trap(type, &tf);
647 }
648 
649 /*
650  * Called by locore.s for an unexpected interrupt.
651  * XXX - Almost identical to trap_kdebug...
652  */
653 void
654 straytrap(tf)
655 	struct trapframe tf;
656 {
657 	int type = -1;
658 
659 	printf("unexpected trap; vector=0x%x at pc=0x%x\n",
660 		tf.tf_vector, tf.tf_pc);
661 
662 #ifdef	KGDB
663 	/* Let KGDB handle it (if connected) */
664 	if (kgdb_trap(type, &tf))
665 		return;
666 #endif
667 #ifdef	DDB
668 	/* Let DDB handle it. */
669 	if (kdb_trap(type, &tf))
670 		return;
671 #endif
672 
673 	/* Drop into the PROM temporarily... */
674 	(void)_nodb_trap(type, &tf);
675 }
676