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