xref: /netbsd-src/sys/arch/sun3/sun3/trap.c (revision c13a5359d541fd49b4c406f5b12209b1640235a5)
1 /*	$NetBSD: trap.c,v 1.150 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.150 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 <m68k/cacheops.h>
115 
116 #include <sun3/sun3/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 /*
133  * The sun3 wants faults to go through the pmap code, but
134  * the sun3x just goes directly to the common VM code.
135  */
136 #ifdef	_SUN3X_
137 # define _pmap_fault(map, va, ftype) \
138 	uvm_fault(map, va, ftype)
139 #endif	/* SUN3X */
140 
141 /* These are called from locore.s */
142 void trap(struct trapframe *, int type, u_int code, u_int v);
143 void trap_kdebug(int type, struct trapframe tf);
144 int _nodb_trap(int type, struct trapframe *);
145 void straytrap(struct trapframe);
146 
147 static void userret(struct lwp *, struct trapframe *, u_quad_t);
148 
149 volatile int astpending;
150 
151 const char *trap_type[] = {
152 	"Bus error",
153 	"Address error",
154 	"Illegal instruction",
155 	"Zero divide",
156 	"CHK instruction",
157 	"TRAPV instruction",
158 	"Privilege violation",
159 	"Trace trap",
160 	"MMU fault",
161 	"SSIR trap",
162 	"Format error",
163 	"68881 exception",
164 	"Coprocessor violation",
165 	"Async system trap",
166 	"Unused? (14)",
167 	"Breakpoint",
168 	"FPU instruction",
169 	"FPU data format",
170 };
171 u_int trap_types = sizeof(trap_type) / sizeof(trap_type[0]);
172 
173 /*
174  * Size of various exception stack frames (minus the standard 8 bytes)
175  */
176 short	exframesize[] = {
177 	FMT0SIZE,	/* type 0 - normal (68020/030/040/060) */
178 	FMT1SIZE,	/* type 1 - throwaway (68020/030/040) */
179 	FMT2SIZE,	/* type 2 - normal 6-word (68020/030/040/060) */
180 	FMT3SIZE,	/* type 3 - FP post-instruction (68040/060) */
181 	FMT4SIZE,	/* type 4 - access error/fp disabled (68060) */
182 	-1, -1,		/* type 5-6 - undefined */
183 	FMT7SIZE,	/* type 7 - access error (68040) */
184 	58,		/* type 8 - bus fault (68010) */
185 	FMT9SIZE,	/* type 9 - coprocessor mid-instruction (68020/030) */
186 	FMTASIZE,	/* type A - short bus fault (68020/030) */
187 	FMTBSIZE,	/* type B - long bus fault (68020/030) */
188 	-1, -1, -1, -1	/* type C-F - undefined */
189 };
190 
191 #define KDFAULT(c)	(((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
192 #define WRFAULT(c)	(((c) & SSW_DF) != 0 && \
193 			  ((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0)))
194 
195 /* #define	DEBUG XXX */
196 
197 #ifdef DEBUG
198 int mmudebug = 0;
199 int mmupid = -1;
200 #define MDB_ISPID(p)	((p) == mmupid)
201 #define MDB_FOLLOW	1
202 #define MDB_WBFOLLOW	2
203 #define MDB_WBFAILED	4
204 #define MDB_CPFAULT	8
205 #endif
206 
207 /*
208  * trap and syscall both need the following work done before
209  * returning to user mode.
210  */
211 static void
userret(struct lwp * l,struct trapframe * tf,u_quad_t oticks)212 userret(struct lwp *l, struct trapframe *tf, u_quad_t oticks)
213 {
214 	struct proc *p = l->l_proc;
215 
216 	/* Invoke MI userret code */
217 	mi_userret(l);
218 
219 	/*
220 	 * If profiling, charge system time to the trapped pc.
221 	 */
222 	if (p->p_stflag & PST_PROFIL) {
223 		extern int psratio;
224 		addupc_task(l, tf->tf_pc,
225 		            (int)(p->p_sticks - oticks) * psratio);
226 	}
227 }
228 
229 /*
230  * Used by the common m68k syscall() and child_return() functions.
231  * XXX: Temporary until all m68k ports share common trap()/userret() code.
232  */
233 void machine_userret(struct lwp *, struct frame *, u_quad_t);
234 
235 void
machine_userret(struct lwp * l,struct frame * f,u_quad_t t)236 machine_userret(struct lwp *l, struct frame *f, u_quad_t t)
237 {
238 
239 	userret(l, &f->F_t, t);
240 }
241 
242 /*
243  * Trap is called from locore to handle most types of processor traps,
244  * including events such as simulated software interrupts/AST's.
245  * System calls are broken out for efficiency.
246  */
247 /*ARGSUSED*/
248 void
trap(struct trapframe * tf,int type,u_int code,u_int v)249 trap(struct trapframe *tf, int type, u_int code, u_int v)
250 {
251 	struct lwp *l;
252 	struct proc *p;
253 	struct pcb *pcb;
254 	ksiginfo_t ksi;
255 	int tmp;
256 	int rv;
257 	u_quad_t sticks;
258 	void *onfault;
259 
260 	curcpu()->ci_data.cpu_ntrap++;
261 	l = curlwp;
262 	p = l->l_proc;
263 	pcb = lwp_getpcb(l);
264 	onfault = pcb->pcb_onfault;
265 
266 	KSI_INIT_TRAP(&ksi);
267 	ksi.ksi_trap = type & ~T_USER;
268 
269 	if (USERMODE(tf->tf_sr)) {
270 		type |= T_USER;
271 		sticks = p->p_sticks;
272 		l->l_md.md_regs = tf->tf_regs;
273 	} else {
274 		sticks = 0;
275 		/* XXX: Detect trap recursion? */
276 	}
277 
278 	switch (type) {
279 	default:
280 	dopanic:
281 		printf("trap type=0x%x, code=0x%x, v=0x%x\n", type, code, v);
282 		/*
283 		 * Let the kernel debugger see the trap frame that
284 		 * caused us to panic.  This is a convenience so
285 		 * one can see registers at the point of failure.
286 		 */
287 		tmp = splhigh();
288 #ifdef KGDB
289 		/* If connected, step or cont returns 1 */
290 		if (kgdb_trap(type, tf))
291 			goto kgdb_cont;
292 #endif
293 #ifdef	DDB
294 		(void) kdb_trap(type, (db_regs_t *) tf);
295 #endif
296 #ifdef KGDB
297 	kgdb_cont:
298 #endif
299 		splx(tmp);
300 		if (panicstr) {
301 			/*
302 			 * Note: panic is smart enough to do:
303 			 *   boot(RB_AUTOBOOT | RB_NOSYNC, NULL)
304 			 * if we call it again.
305 			 */
306 			panic("trap during panic!");
307 		}
308 		regdump(tf, 128);
309 		type &= ~T_USER;
310 		if ((u_int)type < trap_types)
311 			panic(trap_type[type]);
312 		panic("trap type 0x%x", type);
313 
314 	case T_BUSERR:		/* kernel bus error */
315 		if (onfault == NULL)
316 			goto dopanic;
317 		rv = EFAULT;
318 		/*FALLTHROUGH*/
319 
320 	copyfault:
321 		/*
322 		 * If we have arranged to catch this fault in any of the
323 		 * copy to/from user space routines, set PC to return to
324 		 * indicated location and set flag informing buserror code
325 		 * that it may need to clean up stack frame.
326 		 */
327 		tf->tf_stackadj = exframesize[tf->tf_format];
328 		tf->tf_format = tf->tf_vector = 0;
329 		tf->tf_pc = (int)onfault;
330 		tf->tf_regs[D0] = rv;
331 		goto done;
332 
333 	case T_BUSERR|T_USER:	/* bus error */
334 	case T_ADDRERR|T_USER:	/* address error */
335 		ksi.ksi_addr = (void *)v;
336 		ksi.ksi_signo = SIGBUS;
337 		ksi.ksi_code = (type == (T_BUSERR|T_USER)) ?
338 			BUS_OBJERR : BUS_ADRERR;
339 		break;
340 
341 	case T_COPERR:		/* kernel coprocessor violation */
342 	case T_FMTERR|T_USER:	/* do all RTE errors come in as T_USER? */
343 	case T_FMTERR:		/* ...just in case... */
344 		/*
345 		 * The user has most likely trashed the RTE or FP state info
346 		 * in the stack frame of a signal handler.
347 		 */
348 		printf("pid %d: kernel %s exception\n", p->p_pid,
349 		       type==T_COPERR ? "coprocessor" : "format");
350 		type |= T_USER;
351 
352 		mutex_enter(p->p_lock);
353 		SIGACTION(p, SIGILL).sa_handler = SIG_DFL;
354 		sigdelset(&p->p_sigctx.ps_sigignore, SIGILL);
355 		sigdelset(&p->p_sigctx.ps_sigcatch, SIGILL);
356 		sigdelset(&l->l_sigmask, SIGILL);
357 		mutex_exit(p->p_lock);
358 
359 		ksi.ksi_signo = SIGILL;
360 		ksi.ksi_addr = (void *)(int)tf->tf_format;
361 		ksi.ksi_code = (type == T_COPERR) ?
362 			ILL_COPROC : ILL_ILLOPC;
363 		break;
364 
365 	case T_COPERR|T_USER:	/* user coprocessor violation */
366 	/* What is a proper response here? */
367 		ksi.ksi_signo = SIGFPE;
368 		ksi.ksi_code = FPE_FLTINV;
369 		break;
370 
371 	case T_FPERR|T_USER:	/* 68881 exceptions */
372 		/*
373 		 * We pass along the 68881 status register which locore stashed
374 		 * in code for us.
375 		 */
376 		ksi.ksi_signo = SIGFPE;
377 		ksi.ksi_code = fpsr2siginfocode(code);
378 		break;
379 
380 	case T_FPEMULI:		/* FPU faults in supervisor mode */
381 	case T_FPEMULD:
382 		if (nofault)	/* Doing FPU probe? */
383 			longjmp(nofault);
384 		goto dopanic;
385 
386 	case T_FPEMULI|T_USER:	/* unimplemented FP instruction */
387 	case T_FPEMULD|T_USER:	/* unimplemented FP data type */
388 #ifdef	FPU_EMULATE
389 		if (fpu_emulate(tf, &pcb->pcb_fpregs, &ksi) == 0)
390 			; /* XXX - Deal with tracing? (tf->tf_sr & PSL_T) */
391 #else
392 		uprintf("pid %d killed: no floating point support\n", p->p_pid);
393 		ksi.ksi_signo = SIGILL;
394 		ksi.ksi_code = ILL_ILLOPC;
395 #endif
396 		break;
397 
398 	case T_ILLINST|T_USER:	/* illegal instruction fault */
399 	case T_PRIVINST|T_USER:	/* privileged instruction fault */
400 		ksi.ksi_addr = (void *)(int)tf->tf_format;
401 		ksi.ksi_signo = SIGILL;
402 		ksi.ksi_code = (type == (T_PRIVINST|T_USER)) ?
403 			ILL_PRVOPC : ILL_ILLOPC;
404 		break;
405 
406 	case T_ZERODIV|T_USER:	/* Integer divide by zero */
407 		ksi.ksi_code = FPE_INTDIV;
408 	case T_CHKINST|T_USER:	/* CHK instruction trap */
409 	case T_TRAPVINST|T_USER:	/* TRAPV instruction trap */
410 		ksi.ksi_addr = (void *)(int)tf->tf_format;
411 		ksi.ksi_signo = SIGFPE;
412 		break;
413 
414 	/*
415 	 * XXX: Trace traps are a nightmare.
416 	 *
417 	 *	HP-UX uses trap #1 for breakpoints,
418 	 *	NetBSD/m68k uses trap #2,
419 	 *	SUN 3.x uses trap #15,
420 	 *	DDB and KGDB uses trap #15 (for kernel breakpoints;
421 	 *	handled elsewhere).
422 	 *
423 	 * NetBSD and HP-UX traps both get mapped by locore.s into T_TRACE.
424 	 * SUN 3.x traps get passed through as T_TRAP15 and are not really
425 	 * supported yet.
426 	 *
427 	 * XXX: We should never get kernel-mode T_TRAP15
428 	 * XXX: because locore.s now gives them special treatment.
429 	 */
430 	case T_TRAP15:		/* kernel breakpoint */
431 		tf->tf_sr &= ~PSL_T;
432 		goto done;
433 
434 	case T_TRACE|T_USER:	/* user trace trap */
435 #ifdef COMPAT_SUNOS
436 		/*
437 		 * SunOS uses Trap #2 for a "CPU cache flush"
438 		 * Just flush the on-chip caches and return.
439 		 * XXX - Too bad NetBSD uses trap 2...
440 		 */
441 		if (p->p_emul == &emul_sunos) {
442 			ICIA();
443 			DCIU();
444 			/* get out fast */
445 			goto done;
446 		}
447 #endif
448 		/* FALLTHROUGH */
449 	case T_TRACE:		/* tracing a trap instruction */
450 	case T_TRAP15|T_USER:	/* SUN user trace trap */
451 		tf->tf_sr &= ~PSL_T;
452 		ksi.ksi_addr = (void *)tf->tf_pc;
453 		ksi.ksi_signo = SIGTRAP;
454 		if (type == (T_TRAP15|T_USER))
455 			ksi.ksi_code = TRAP_BRKPT;
456 		else
457 			ksi.ksi_code = TRAP_TRACE;
458 		break;
459 
460 	case T_ASTFLT:		/* system async trap, cannot happen */
461 		goto dopanic;
462 
463 	case T_ASTFLT|T_USER:	/* user async trap */
464 		astpending = 0;
465 		/* T_SSIR is not used on a Sun3. */
466 		if (l->l_pflag & LP_OWEUPC) {
467 			l->l_pflag &= ~LP_OWEUPC;
468 			ADDUPROF(l);
469 		}
470 		goto douret;
471 
472 	case T_MMUFLT:		/* kernel mode page fault */
473 		/* Hacks to avoid calling VM code from debugger. */
474 #ifdef	DDB
475 		if (db_recover != 0)
476 			goto dopanic;
477 #endif
478 #ifdef	KGDB
479 		if (kgdb_recover != 0)
480 			goto dopanic;
481 #endif
482 		/*FALLTHROUGH*/
483 
484 	case T_MMUFLT|T_USER: {		/* page fault */
485 		vaddr_t va;
486 		struct vmspace *vm = p->p_vmspace;
487 		struct vm_map *map;
488 		vm_prot_t ftype;
489 		extern struct vm_map *kernel_map;
490 
491 #ifdef DEBUG
492 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
493 		printf("trap: T_MMUFLT pid=%d, code=0x%x, v=0x%x, pc=0x%x, sr=0x%x\n",
494 		       p->p_pid, code, v, tf->tf_pc, tf->tf_sr);
495 #endif
496 
497 		/*
498 		 * It is only a kernel address space fault iff:
499 		 *	1. (type & T_USER) == 0  and: (2 or 3)
500 		 *	2. pcb_onfault not set or
501 		 *	3. pcb_onfault set but supervisor space data fault
502 		 * The last can occur during an exec() copyin where the
503 		 * argument space is lazy-allocated.
504 		 */
505 		map = &vm->vm_map;
506 		if ((type & T_USER) == 0) {
507 			/* supervisor mode fault */
508 			if (onfault == NULL || KDFAULT(code))
509 				map = kernel_map;
510 		}
511 
512 		if (WRFAULT(code))
513 			ftype = VM_PROT_WRITE;
514 		else
515 			ftype = VM_PROT_READ;
516 		va = m68k_trunc_page((vaddr_t)v);
517 
518 		/*
519 		 * Need to resolve the fault.
520 		 *
521 		 * We give the pmap code a chance to resolve faults by
522 		 * reloading translations that it was forced to unload.
523 		 * This function does that, and calls vm_fault if it
524 		 * could not resolve the fault by reloading the MMU.
525 		 * This function may also, for example, disallow any
526 		 * faults in the kernel text segment, etc.
527 		 */
528 
529 		pcb->pcb_onfault = NULL;
530 		rv = _pmap_fault(map, va, ftype);
531 		pcb->pcb_onfault = onfault;
532 
533 #ifdef	DEBUG
534 		if (rv && MDB_ISPID(p->p_pid)) {
535 			printf("vm_fault(%p, 0x%lx, 0x%x) -> 0x%x\n",
536 			       map, va, ftype, rv);
537 			if (mmudebug & MDB_WBFAILED)
538 				Debugger();
539 		}
540 #endif	/* DEBUG */
541 
542 		/*
543 		 * If this was a stack access we keep track of the maximum
544 		 * accessed stack size.  Also, if vm_fault gets a protection
545 		 * failure it is due to accessing the stack region outside
546 		 * the current limit and we need to reflect that as an access
547 		 * error.
548 		 */
549 		if (rv == 0) {
550 			if (map != kernel_map && (void *)va >= vm->vm_maxsaddr)
551 				uvm_grow(p, va);
552 
553 			goto finish;
554 		}
555 		if (rv == EACCES) {
556 			ksi.ksi_code = SEGV_ACCERR;
557 			rv = EFAULT;
558 		} else
559 			ksi.ksi_code = SEGV_MAPERR;
560 		if ((type & T_USER) == 0) {
561 			/* supervisor mode fault */
562 			if (onfault) {
563 #ifdef	DEBUG
564 				if (mmudebug & MDB_CPFAULT) {
565 					printf("trap: copyfault pcb_onfault\n");
566 					Debugger();
567 				}
568 #endif
569 				goto copyfault;
570 			}
571 			printf("vm_fault(%p, 0x%lx, 0x%x) -> 0x%x\n",
572 			       map, va, ftype, rv);
573 			goto dopanic;
574 		}
575 		ksi.ksi_addr = (void *)v;
576 		switch (rv) {
577 		case ENOMEM:
578 			printf("UVM: pid %d (%s), uid %d killed: out of swap\n",
579 			       p->p_pid, p->p_comm,
580 			       l->l_cred ?
581 			       kauth_cred_geteuid(l->l_cred) : -1);
582 			ksi.ksi_signo = SIGKILL;
583 			break;
584 		case EINVAL:
585 			ksi.ksi_signo = SIGBUS;
586 			ksi.ksi_code = BUS_ADRERR;
587 			break;
588 		case EACCES:
589 			ksi.ksi_signo = SIGSEGV;
590 			ksi.ksi_code = SEGV_ACCERR;
591 			break;
592 		default:
593 			ksi.ksi_signo = SIGSEGV;
594 			ksi.ksi_code = SEGV_MAPERR;
595 			break;
596 		}
597 		break;
598 		} /* T_MMUFLT */
599 	} /* switch */
600 
601 finish:
602 	/* If trap was from supervisor mode, just return. */
603 	if ((type & T_USER) == 0)
604 		goto done;
605 	/* Post a signal if necessary. */
606 	if (ksi.ksi_signo)
607 		trapsignal(l, &ksi);
608 douret:
609 	userret(l, tf, sticks);
610 
611 done:;
612 	/* XXX: Detect trap recursion? */
613 }
614 
615 /*
616  * This is used if we hit a kernel breakpoint or trace trap
617  * when there is no debugger installed (or not attached).
618  * Drop into the PROM temporarily...
619  */
620 int
_nodb_trap(int type,struct trapframe * tf)621 _nodb_trap(int type, struct trapframe *tf)
622 {
623 
624 	printf("\r\nKernel ");
625 	if ((0 <= type) && (type < trap_types))
626 		printf("%s", trap_type[type]);
627 	else
628 		printf("trap 0x%x", type);
629 	printf(", frame=%p\r\n", tf);
630 	printf("No debugger; doing PROM abort.\r\n");
631 	printf("To continue, type: c <RETURN>\r\n");
632 	sunmon_abort();
633 	/* OK then, just resume... */
634 	tf->tf_sr &= ~PSL_T;
635 	return(1);
636 }
637 
638 /*
639  * This is called by locore for supervisor-mode trace and
640  * breakpoint traps.  This is separate from trap() above
641  * so that breakpoints in trap() will work.
642  *
643  * If we have both DDB and KGDB, let KGDB see it first,
644  * because KGDB will just return 0 if not connected.
645  */
646 void
trap_kdebug(int type,struct trapframe tf)647 trap_kdebug(int type, struct trapframe tf)
648 {
649 
650 #ifdef	KGDB
651 	/* Let KGDB handle it (if connected) */
652 	if (kgdb_trap(type, &tf))
653 		return;
654 #endif
655 #ifdef	DDB
656 	/* Let DDB handle it. */
657 	if (kdb_trap(type, &tf))
658 		return;
659 #endif
660 
661 	/* Drop into the PROM temporarily... */
662 	(void)_nodb_trap(type, &tf);
663 }
664 
665 /*
666  * Called by locore.s for an unexpected interrupt.
667  * XXX - Almost identical to trap_kdebug...
668  */
669 void
straytrap(struct trapframe tf)670 straytrap(struct trapframe tf)
671 {
672 	int type = -1;
673 
674 	printf("unexpected trap; vector=0x%x at pc=0x%x\n",
675 		tf.tf_vector, tf.tf_pc);
676 
677 #ifdef	KGDB
678 	/* Let KGDB handle it (if connected) */
679 	if (kgdb_trap(type, &tf))
680 		return;
681 #endif
682 #ifdef	DDB
683 	/* Let DDB handle it. */
684 	if (kdb_trap(type, &tf))
685 		return;
686 #endif
687 
688 	/* Drop into the PROM temporarily... */
689 	(void)_nodb_trap(type, &tf);
690 }
691