xref: /netbsd/sys/arch/cesfic/cesfic/trap.c (revision 6550d01e)
1 /*	$NetBSD: trap.c,v 1.54 2011/01/17 14:53:42 tsutsui 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  *
37  *	@(#)trap.c	8.5 (Berkeley) 1/4/94
38  */
39 /*
40  * Copyright (c) 1988 University of Utah.
41  *
42  * This code is derived from software contributed to Berkeley by
43  * the Systems Programming Group of the University of Utah Computer
44  * Science Department.
45  *
46  * Redistribution and use in source and binary forms, with or without
47  * modification, are permitted provided that the following conditions
48  * are met:
49  * 1. Redistributions of source code must retain the above copyright
50  *    notice, this list of conditions and the following disclaimer.
51  * 2. Redistributions in binary form must reproduce the above copyright
52  *    notice, this list of conditions and the following disclaimer in the
53  *    documentation and/or other materials provided with the distribution.
54  * 3. All advertising materials mentioning features or use of this software
55  *    must display the following acknowledgement:
56  *	This product includes software developed by the University of
57  *	California, Berkeley and its contributors.
58  * 4. Neither the name of the University nor the names of its contributors
59  *    may be used to endorse or promote products derived from this software
60  *    without specific prior written permission.
61  *
62  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
63  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
64  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
65  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
66  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
67  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
68  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
71  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
72  * SUCH DAMAGE.
73  *
74  * from: Utah $Hdr: trap.c 1.37 92/12/20$
75  *
76  *	@(#)trap.c	8.5 (Berkeley) 1/4/94
77  */
78 
79 #include <sys/cdefs.h>
80 __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.54 2011/01/17 14:53:42 tsutsui Exp $");
81 
82 #include "opt_ddb.h"
83 #include "opt_execfmt.h"
84 #include "opt_kgdb.h"
85 #include "opt_compat_netbsd.h"
86 #include "opt_compat_sunos.h"
87 #include "opt_compat_linux.h"
88 #include "opt_m68k_arch.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/sa.h>
98 #include <sys/savar.h>
99 #include <sys/syscall.h>
100 #include <sys/syslog.h>
101 #include <sys/userret.h>
102 #include <sys/kauth.h>
103 #ifdef	KGDB
104 #include <sys/kgdb.h>
105 #endif
106 
107 #include <m68k/frame.h>
108 #include <m68k/cacheops.h>
109 
110 #include <machine/db_machdep.h>
111 #include <machine/pcb.h>
112 #include <machine/psl.h>
113 #include <machine/trap.h>
114 #include <machine/cpu.h>
115 #include <machine/reg.h>
116 
117 #include <uvm/uvm_extern.h>
118 
119 #include <dev/cons.h>
120 
121 #ifdef COMPAT_SUNOS
122 #include <compat/sunos/sunos_syscall.h>
123 extern struct emul emul_sunos;
124 #endif
125 
126 int	writeback(struct frame *fp, int docachepush);
127 void	trap(struct frame *fp, int type, u_int code, u_int v);
128 void	syscall(register_t code, struct frame frame);
129 void	trap_kdebug(int, struct trapframe);
130 
131 #ifdef DEBUG
132 void	dumpssw(u_short);
133 void	dumpwb(int, u_short, u_int, u_int);
134 #endif
135 
136 static inline void userret(struct lwp *l, struct frame *fp,
137 	    u_quad_t oticks, u_int faultaddr, int fromtrap);
138 
139 int astpending;
140 
141 const char *trap_type[] = {
142 	"Bus error",
143 	"Address error",
144 	"Illegal instruction",
145 	"Zero divide",
146 	"CHK instruction",
147 	"TRAPV instruction",
148 	"Privilege violation",
149 	"Trace trap",
150 	"MMU fault",
151 	"SSIR trap",
152 	"Format error",
153 	"68881 exception",
154 	"Coprocessor violation",
155 	"Async system trap"
156 };
157 int	trap_types = sizeof trap_type / sizeof trap_type[0];
158 
159 /*
160  * Size of various exception stack frames (minus the standard 8 bytes)
161  */
162 short	exframesize[] = {
163 	FMT0SIZE,	/* type 0 - normal (68020/030/040/060) */
164 	FMT1SIZE,	/* type 1 - throwaway (68020/030/040) */
165 	FMT2SIZE,	/* type 2 - normal 6-word (68020/030/040/060) */
166 	FMT3SIZE,	/* type 3 - FP post-instruction (68040/060) */
167 	FMT4SIZE,	/* type 4 - access error/fp disabled (68060) */
168 	-1, -1,		/* type 5-6 - undefined */
169 	FMT7SIZE,	/* type 7 - access error (68040) */
170 	58,		/* type 8 - bus fault (68010) */
171 	FMT9SIZE,	/* type 9 - coprocessor mid-instruction (68020/030) */
172 	FMTASIZE,	/* type A - short bus fault (68020/030) */
173 	FMTBSIZE,	/* type B - long bus fault (68020/030) */
174 	-1, -1, -1, -1	/* type C-F - undefined */
175 };
176 
177 #ifdef M68060
178 #define	KDFAULT_060(c)	(cputype == CPU_68060 && ((c) & FSLW_TM_SV))
179 #define	WRFAULT_060(c)	(cputype == CPU_68060 && ((c) & FSLW_RW_W))
180 #else
181 #define	KDFAULT_060(c)	0
182 #define	WRFAULT_060(c)	0
183 #endif
184 
185 #ifdef M68040
186 #define	KDFAULT_040(c)	(cputype == CPU_68040 && \
187 			 ((c) & SSW4_TMMASK) == SSW4_TMKD)
188 #define	WRFAULT_040(c)	(cputype == CPU_68040 && \
189 			 ((c) & (SSW4_LK|SSW4_RW)) != SSW4_RW)
190 #else
191 #define	KDFAULT_040(c)	0
192 #define	WRFAULT_040(c)	0
193 #endif
194 
195 #if defined(M68030) || defined(M68020)
196 #define	KDFAULT_OTH(c)	(cputype <= CPU_68030 && \
197 			 ((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
198 #define	WRFAULT_OTH(c)	(cputype <= CPU_68030 && \
199 			 (((c) & SSW_DF) != 0 && \
200 			 ((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0))))
201 #else
202 #define	KDFAULT_OTH(c)	0
203 #define	WRFAULT_OTH(c)	0
204 #endif
205 
206 #define	KDFAULT(c)	(KDFAULT_060(c) || KDFAULT_040(c) || KDFAULT_OTH(c))
207 #define	WRFAULT(c)	(WRFAULT_060(c) || WRFAULT_040(c) || WRFAULT_OTH(c))
208 
209 #ifdef DEBUG
210 int mmudebug = 0;
211 int mmupid = -1;
212 #define MDB_FOLLOW	1
213 #define MDB_WBFOLLOW	2
214 #define MDB_WBFAILED	4
215 #define MDB_ISPID(p)	((p) == mmupid)
216 #endif
217 
218 /*
219  * trap and syscall both need the following work done before returning
220  * to user mode.
221  */
222 static inline void
223 userret(struct lwp *l, struct frame *fp, u_quad_t oticks, u_int faultaddr, int fromtrap)
224 {
225 	struct proc *p = l->l_proc;
226 #ifdef M68040
227 	int sig;
228 	int beenhere = 0;
229 
230 again:
231 #endif
232 	/* Invoke MI userret code */
233 	mi_userret(l);
234 
235 	/*
236 	 * If profiling, charge system time to the trapped pc.
237 	 */
238 	if (p->p_stflag & PST_PROFIL) {
239 		extern int psratio;
240 
241 		addupc_task(l, fp->f_pc,
242 			    (int)(p->p_sticks - oticks) * psratio);
243 	}
244 #ifdef M68040
245 	/*
246 	 * Deal with user mode writebacks (from trap, or from sigreturn).
247 	 * If any writeback fails, go back and attempt signal delivery.
248 	 * unless we have already been here and attempted the writeback
249 	 * (e.g. bad address with user ignoring SIGSEGV).  In that case
250 	 * we just return to the user without successfully completing
251 	 * the writebacks.  Maybe we should just drop the sucker?
252 	 */
253 	if (cputype == CPU_68040 && fp->f_format == FMT7) {
254 		if (beenhere) {
255 #ifdef DEBUG
256 			if (mmudebug & MDB_WBFAILED)
257 				printf(fromtrap ?
258 		"pid %d(%s): writeback aborted, pc=%x, fa=%x\n" :
259 		"pid %d(%s): writeback aborted in sigreturn, pc=%x\n",
260 				    p->p_pid, p->p_comm, fp->f_pc, faultaddr);
261 #endif
262 		} else if ((sig = writeback(fp, fromtrap))) {
263 			ksiginfo_t ksi;
264 			beenhere = 1;
265 			oticks = p->p_sticks;
266 			(void)memset(&ksi, 0, sizeof(ksi));
267 			ksi.ksi_signo = sig;
268 			ksi.ksi_addr = (void *)faultaddr;
269 			ksi.ksi_code = BUS_OBJERR;
270 			trapsignal(l, &ksi);
271 			goto again;
272 		}
273 	}
274 #endif
275 }
276 
277 /*
278  * Used by the common m68k syscall() and child_return() functions.
279  * XXX: Temporary until all m68k ports share common trap()/userret() code.
280  */
281 void machine_userret(struct lwp *, struct frame *, u_quad_t);
282 
283 void
284 machine_userret(struct lwp *l, struct frame *f, u_quad_t t)
285 {
286 
287 	userret(l, f, t, 0, 0);
288 }
289 
290 /*
291  * Trap is called from locore to handle most types of processor traps,
292  * including events such as simulated software interrupts/AST's.
293  * System calls are broken out for efficiency.
294  */
295 /*ARGSUSED*/
296 void
297 trap(struct frame *fp, int type, unsigned code, unsigned v)
298 {
299 	extern char fubail[], subail[];
300 	struct lwp *l;
301 	struct proc *p;
302 	struct pcb *pcb;
303 	void *onfault;
304 	ksiginfo_t ksi;
305 	int s;
306 	int rv;
307 	u_quad_t sticks = 0 /* XXX initializer works around compiler bug */;
308 
309 	curcpu()->ci_data.cpu_ntrap++;
310 	l = curlwp;
311 	p = l->l_proc;
312 	pcb = lwp_getpcb(l);
313 
314 	KSI_INIT_TRAP(&ksi);
315 	ksi.ksi_trap = type & ~T_USER;
316 
317 	if (USERMODE(fp->f_sr)) {
318 		type |= T_USER;
319 		sticks = p->p_sticks;
320 		l->l_md.md_regs = fp->f_regs;
321 		LWP_CACHE_CREDS(l, p);
322 	}
323 	switch (type) {
324 
325 	default:
326 	dopanic:
327 		printf("trap type %d, code = 0x%x, v = 0x%x\n", type, code, v);
328 		printf("%s program counter = 0x%x\n",
329 		    (type & T_USER) ? "user" : "kernel", fp->f_pc);
330 		/*
331 		 * Let the kernel debugger see the trap frame that
332 		 * caused us to panic.  This is a convenience so
333 		 * one can see registers at the point of failure.
334 		 */
335 		s = splhigh();
336 #ifdef KGDB
337 		/* If connected, step or cont returns 1 */
338 		if (kgdb_trap(type, fp))
339 			goto kgdb_cont;
340 #endif
341 #ifdef DDB
342 		(void)kdb_trap(type, (db_regs_t *)fp);
343 #endif
344 #ifdef KGDB
345 	kgdb_cont:
346 #endif
347 		splx(s);
348 		if (panicstr) {
349 			printf("trap during panic!\n");
350 #ifdef DEBUG
351 			/* XXX should be a machine-dependent hook */
352 			printf("(press a key)\n"); (void)cngetc();
353 #endif
354 		}
355 		regdump((struct trapframe *)fp, 128);
356 		type &= ~T_USER;
357 		if ((u_int)type < trap_types)
358 			panic(trap_type[type]);
359 		panic("trap");
360 
361 	case T_BUSERR:		/* kernel bus error */
362 		onfault = pcb->pcb_onfault;
363 		if (onfault == NULL)
364 			goto dopanic;
365 		rv = EFAULT;
366 		/* FALLTHROUGH */
367 
368 	copyfault:
369 		/*
370 		 * If we have arranged to catch this fault in any of the
371 		 * copy to/from user space routines, set PC to return to
372 		 * indicated location and set flag informing buserror code
373 		 * that it may need to clean up stack frame.
374 		 */
375 		fp->f_stackadj = exframesize[fp->f_format];
376 		fp->f_format = fp->f_vector = 0;
377 		fp->f_pc = (int)onfault;
378 		fp->f_regs[D0] = rv;
379 		return;
380 
381 	case T_BUSERR|T_USER:	/* bus error */
382 	case T_ADDRERR|T_USER:	/* address error */
383 		ksi.ksi_addr = (void *)v;
384 		ksi.ksi_signo = SIGBUS;
385 		ksi.ksi_code = (type == (T_BUSERR|T_USER)) ?
386 			BUS_OBJERR : BUS_ADRERR;
387 		break;
388 
389 	case T_COPERR:		/* kernel coprocessor violation */
390 	case T_FMTERR|T_USER:	/* do all RTE errors come in as T_USER? */
391 	case T_FMTERR:		/* ...just in case... */
392 	/*
393 	 * The user has most likely trashed the RTE or FP state info
394 	 * in the stack frame of a signal handler.
395 	 */
396 		printf("pid %d: kernel %s exception\n", p->p_pid,
397 		       type==T_COPERR ? "coprocessor" : "format");
398 		type |= T_USER;
399 
400 		mutex_enter(p->p_lock);
401 		SIGACTION(p, SIGILL).sa_handler = SIG_DFL;
402 		sigdelset(&p->p_sigctx.ps_sigignore, SIGILL);
403 		sigdelset(&p->p_sigctx.ps_sigcatch, SIGILL);
404 		sigdelset(&l->l_sigmask, SIGILL);
405 		mutex_exit(p->p_lock);
406 
407 		ksi.ksi_signo = SIGILL;
408 		ksi.ksi_addr = (void *)(int)fp->f_format;
409 				/* XXX was ILL_RESAD_FAULT */
410 		ksi.ksi_code = (type == T_COPERR) ?
411 			ILL_COPROC : ILL_ILLOPC;
412 		break;
413 
414 	case T_COPERR|T_USER:	/* user coprocessor violation */
415 	/* What is a proper response here? */
416 		ksi.ksi_signo = SIGFPE;
417 		ksi.ksi_code = FPE_FLTINV;
418 		break;
419 
420 	case T_FPERR|T_USER:	/* 68881 exceptions */
421 	/*
422 	 * We pass along the 68881 status which locore stashed
423 	 * in code for us.
424 	 */
425 		ksi.ksi_signo = SIGFPE;
426 		ksi.ksi_code = fpsr2siginfocode(code);
427 		break;
428 
429 #ifdef M68040
430 	case T_FPEMULI|T_USER:	/* unimplemented FP instruction */
431 	case T_FPEMULD|T_USER:	/* unimplemented FP data type */
432 		/* XXX need to FSAVE */
433 		printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n",
434 		       p->p_pid, p->p_comm,
435 		       fp->f_format == 2 ? "instruction" : "data type",
436 		       fp->f_pc, fp->f_fmt2.f_iaddr);
437 		/* XXX need to FRESTORE */
438 		ksi.ksi_signo = SIGFPE;
439 		ksi.ksi_code = FPE_FLTINV;
440 		break;
441 #endif
442 
443 	case T_ILLINST|T_USER:	/* illegal instruction fault */
444 	case T_PRIVINST|T_USER:	/* privileged instruction fault */
445 		ksi.ksi_addr = (void *)(int)fp->f_format;
446 				/* XXX was ILL_PRIVIN_FAULT */
447 		ksi.ksi_signo = SIGILL;
448 		ksi.ksi_code = (type == (T_PRIVINST|T_USER)) ?
449 			ILL_PRVOPC : ILL_ILLOPC;
450 		break;
451 
452 	case T_ZERODIV|T_USER:	/* Divide by zero */
453 		ksi.ksi_addr = (void *)(int)fp->f_format;
454 				/* XXX was FPE_INTDIV_TRAP */
455 		ksi.ksi_signo = SIGFPE;
456 		ksi.ksi_code = FPE_FLTDIV;
457 		break;
458 
459 	case T_CHKINST|T_USER:	/* CHK instruction trap */
460 		ksi.ksi_addr = (void *)(int)fp->f_format;
461 				/* XXX was FPE_SUBRNG_TRAP */
462 		ksi.ksi_signo = SIGFPE;
463 		break;
464 
465 	case T_TRAPVINST|T_USER:	/* TRAPV instruction trap */
466 		ksi.ksi_addr = (void *)(int)fp->f_format;
467 				/* XXX was FPE_INTOVF_TRAP */
468 		ksi.ksi_signo = SIGFPE;
469 		break;
470 
471 	/*
472 	 * XXX: Trace traps are a nightmare.
473 	 *
474 	 *	HP-UX uses trap #1 for breakpoints,
475 	 *	NetBSD/m68k uses trap #2,
476 	 *	SUN 3.x uses trap #15,
477 	 *	DDB and KGDB uses trap #15 (for kernel breakpoints;
478 	 *	handled elsewhere).
479 	 *
480 	 * NetBSD and HP-UX traps both get mapped by locore.s into T_TRACE.
481 	 * SUN 3.x traps get passed through as T_TRAP15 and are not really
482 	 * supported yet.
483 	 *
484 	 * XXX: We should never get kernel-mode T_TRACE or T_TRAP15
485 	 * XXX: because locore.s now gives them special treatment.
486 	 */
487 	case T_TRACE:		/* kernel trace trap */
488 	case T_TRAP15:		/* kernel breakpoint */
489 #ifdef DEBUG
490 		printf("unexpected kernel trace trap, type = %d\n", type);
491 		printf("program counter = 0x%x\n", fp->f_pc);
492 #endif
493 		fp->f_sr &= ~PSL_T;
494 		return;
495 
496 	case T_TRACE|T_USER:	/* user trace trap */
497 	case T_TRAP15|T_USER:	/* SUN user trace trap */
498 #ifdef COMPAT_SUNOS
499 		/*
500 		 * SunOS uses Trap #2 for a "CPU cache flush".
501 		 * Just flush the on-chip caches and return.
502 		 */
503 		if (p->p_emul == &emul_sunos) {
504 			ICIA();
505 			DCIU();
506 			return;
507 		}
508 #endif
509 		fp->f_sr &= ~PSL_T;
510 		ksi.ksi_signo = SIGTRAP;
511 		break;
512 
513 	case T_ASTFLT:		/* system async trap, cannot happen */
514 		goto dopanic;
515 
516 	case T_ASTFLT|T_USER:	/* user async trap */
517 		astpending = 0;
518 		/*
519 		 * We check for software interrupts first.  This is because
520 		 * they are at a higher level than ASTs, and on a VAX would
521 		 * interrupt the AST.  We assume that if we are processing
522 		 * an AST that we must be at IPL0 so we don't bother to
523 		 * check.  Note that we ensure that we are at least at SIR
524 		 * IPL while processing the SIR.
525 		 */
526 		spl1();
527 		/* fall into... */
528 
529 	case T_SSIR:		/* software interrupt */
530 	case T_SSIR|T_USER:
531 
532 #ifdef __HAVE_FAST_SOFTINTS
533 		softintr_dispatch();
534 #endif
535 
536 		/*
537 		 * If this was not an AST trap, we are all done.
538 		 */
539 		if (type != (T_ASTFLT|T_USER)) {
540 			curcpu()->ci_data.cpu_ntrap--;
541 			return;
542 		}
543 		spl0();
544 		if (l->l_pflag & LP_OWEUPC) {
545 			l->l_pflag &= ~LP_OWEUPC;
546 			ADDUPROF(l);
547 		}
548 		if (curcpu()->ci_want_resched)
549 			preempt();
550 		goto out;
551 
552 	case T_MMUFLT:		/* kernel mode page fault */
553 		/*
554 		 * If we were doing profiling ticks or other user mode
555 		 * stuff from interrupt code, Just Say No.
556 		 */
557 		onfault = pcb->pcb_onfault;
558 		if (onfault == fubail || onfault == subail) {
559 			rv = EFAULT;
560 			goto copyfault;
561 		}
562 		/* fall into ... */
563 
564 	case T_MMUFLT|T_USER:	/* page fault */
565 	    {
566 		vaddr_t va;
567 		struct vmspace *vm = p->p_vmspace;
568 		struct vm_map *map;
569 		vm_prot_t ftype;
570 		extern struct vm_map *kernel_map;
571 
572 		onfault = pcb->pcb_onfault;
573 
574 #ifdef DEBUG
575 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
576 		printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n",
577 		       p->p_pid, code, v, fp->f_pc, fp->f_sr);
578 #endif
579 		/*
580 		 * It is only a kernel address space fault iff:
581 		 * 	1. (type & T_USER) == 0  and
582 		 * 	2. pcb_onfault not set or
583 		 *	3. pcb_onfault set but supervisor space data fault
584 		 * The last can occur during an exec() copyin where the
585 		 * argument space is lazy-allocated.
586 		 */
587 		if ((type & T_USER) == 0 && (onfault == NULL || KDFAULT(code)))
588 			map = kernel_map;
589 		else {
590 			map = vm ? &vm->vm_map : kernel_map;
591 			if ((l->l_flag & LW_SA)
592 			    && (~l->l_pflag & LP_SA_NOBLOCK)) {
593 				l->l_savp->savp_faultaddr = (vaddr_t)v;
594 				l->l_pflag |= LP_SA_PAGEFAULT;
595 			}
596 		}
597 
598 		if (WRFAULT(code))
599 			ftype = VM_PROT_WRITE;
600 		else
601 			ftype = VM_PROT_READ;
602 
603 		va = trunc_page((vaddr_t)v);
604 
605 		if (map == kernel_map && va == 0) {
606 			printf("trap: bad kernel %s access at 0x%x\n",
607 			    (ftype & VM_PROT_WRITE) ? "read/write" :
608 			    "read", v);
609 			goto dopanic;
610 		}
611 
612 		pcb->pcb_onfault = NULL;
613 		rv = uvm_fault(map, va, ftype);
614 		pcb->pcb_onfault = onfault;
615 #ifdef DEBUG
616 		if (rv && MDB_ISPID(p->p_pid))
617 			printf("uvm_fault(%p, 0x%lx, 0x%x) -> 0x%x\n",
618 			    map, va, ftype, rv);
619 #endif
620 		/*
621 		 * If this was a stack access we keep track of the maximum
622 		 * accessed stack size.  Also, if vm_fault gets a protection
623 		 * failure it is due to accessing the stack region outside
624 		 * the current limit and we need to reflect that as an access
625 		 * error.
626 		 */
627 		if (rv == 0) {
628 			if (map != kernel_map && (void *)va >= vm->vm_maxsaddr)
629 				uvm_grow(p, va);
630 
631 			if (type == T_MMUFLT) {
632 				if (ucas_ras_check(&fp->F_t)) {
633 					return;
634 				}
635 #ifdef M68040
636 				if (cputype == CPU_68040)
637 					(void) writeback(fp, 1);
638 #endif
639 				return;
640 			}
641 			l->l_pflag &= ~LP_SA_PAGEFAULT;
642 			goto out;
643 		}
644 		if (rv == EACCES) {
645 			ksi.ksi_code = SEGV_ACCERR;
646 			rv = EFAULT;
647 		} else
648 			ksi.ksi_code = SEGV_MAPERR;
649 		if (type == T_MMUFLT) {
650 			if (onfault)
651 				goto copyfault;
652 			printf("uvm_fault(%p, 0x%lx, 0x%x) -> 0x%x\n",
653 			    map, va, ftype, rv);
654 			printf("  type %x, code [mmu,,ssw]: %x\n",
655 			       type, code);
656 			goto dopanic;
657 		}
658 		l->l_pflag &= ~LP_SA_PAGEFAULT;
659 		ksi.ksi_addr = (void *)v;
660 		if (rv == ENOMEM) {
661 			printf("UVM: pid %d (%s), uid %d killed: out of swap\n",
662 			       p->p_pid, p->p_comm,
663 			       l->l_cred ?
664 			       kauth_cred_geteuid(l->l_cred) : -1);
665 			ksi.ksi_signo = SIGKILL;
666 		} else {
667 			ksi.ksi_signo = SIGSEGV;
668 		}
669 		break;
670 	    }
671 	}
672 	trapsignal(l, &ksi);
673 	if ((type & T_USER) == 0)
674 		return;
675 out:
676 	userret(l, fp, sticks, v, 1);
677 }
678 
679 #ifdef M68040
680 #ifdef DEBUG
681 struct writebackstats {
682 	int calls;
683 	int cpushes;
684 	int move16s;
685 	int wb1s, wb2s, wb3s;
686 	int wbsize[4];
687 } wbstats;
688 
689 const char *f7sz[] = { "longword", "byte", "word", "line" };
690 const char *f7tt[] = { "normal", "MOVE16", "AFC", "ACK" };
691 const char *f7tm[] = { "d-push", "u-data", "u-code", "M-data",
692 		 "M-code", "k-data", "k-code", "RES" };
693 const char wberrstr[] =
694     "WARNING: pid %d(%s) writeback [%s] failed, pc=%x fa=%x wba=%x wbd=%x\n";
695 #endif
696 
697 int
698 writeback(struct frame *fp, int docachepush)
699 {
700 	struct fmt7 *f = &fp->f_fmt7;
701 	struct lwp *l = curlwp;
702 	struct proc *p = l->l_proc;
703 	struct pcb *pcb = lwp_getpcb(l);
704 	int err = 0;
705 	u_int fa;
706 	void *oonfault = pcb->pcb_onfault;
707 	paddr_t pa;
708 
709 #ifdef DEBUG
710 	if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) {
711 		printf(" pid=%d, fa=%x,", p->p_pid, f->f_fa);
712 		dumpssw(f->f_ssw);
713 	}
714 	wbstats.calls++;
715 #endif
716 	/*
717 	 * Deal with special cases first.
718 	 */
719 	if ((f->f_ssw & SSW4_TMMASK) == SSW4_TMDCP) {
720 		/*
721 		 * Dcache push fault.
722 		 * Line-align the address and write out the push data to
723 		 * the indicated physical address.
724 		 */
725 #ifdef DEBUG
726 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) {
727 			printf(" pushing %s to PA %x, data %x",
728 			       f7sz[(f->f_ssw & SSW4_SZMASK) >> 5],
729 			       f->f_fa, f->f_pd0);
730 			if ((f->f_ssw & SSW4_SZMASK) == SSW4_SZLN)
731 				printf("/%x/%x/%x",
732 				       f->f_pd1, f->f_pd2, f->f_pd3);
733 			printf("\n");
734 		}
735 		if (f->f_wb1s & SSW4_WBSV)
736 			panic("writeback: cache push with WB1S valid");
737 		wbstats.cpushes++;
738 #endif
739 		/*
740 		 * XXX there are security problems if we attempt to do a
741 		 * cache push after a signal handler has been called.
742 		 */
743 		if (docachepush) {
744 			pmap_enter(pmap_kernel(), (vaddr_t)vmmap,
745 			    trunc_page(f->f_fa), VM_PROT_WRITE,
746 			    VM_PROT_WRITE|PMAP_WIRED);
747 			pmap_update(pmap_kernel());
748 			fa = (u_int)&vmmap[(f->f_fa & PGOFSET) & ~0xF];
749 			memcpy((void *)fa, (void *)&f->f_pd0, 16);
750 			pmap_extract(pmap_kernel(), (vaddr_t)fa, &pa);
751 			DCFL(pa);
752 			pmap_remove(pmap_kernel(), (vaddr_t)vmmap,
753 				    (vaddr_t)&vmmap[PAGE_SIZE]);
754 			pmap_update(pmap_kernel());
755 		} else
756 			printf("WARNING: pid %d(%s) uid %d: CPUSH not done\n",
757 			    p->p_pid, p->p_comm, kauth_cred_geteuid(l->l_cred));
758 	} else if ((f->f_ssw & (SSW4_RW|SSW4_TTMASK)) == SSW4_TTM16) {
759 		/*
760 		 * MOVE16 fault.
761 		 * Line-align the address and write out the push data to
762 		 * the indicated virtual address.
763 		 */
764 #ifdef DEBUG
765 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
766 			printf(" MOVE16 to VA %x(%x), data %x/%x/%x/%x\n",
767 			       f->f_fa, f->f_fa & ~0xF, f->f_pd0, f->f_pd1,
768 			       f->f_pd2, f->f_pd3);
769 		if (f->f_wb1s & SSW4_WBSV)
770 			panic("writeback: MOVE16 with WB1S valid");
771 		wbstats.move16s++;
772 #endif
773 		if (KDFAULT(f->f_wb1s))
774 			memcpy((void *)(f->f_fa & ~0xF), (void *)&f->f_pd0, 16);
775 		else
776 			err = suline((void *)(f->f_fa & ~0xF), (void *)&f->f_pd0);
777 		if (err) {
778 			fa = f->f_fa & ~0xF;
779 #ifdef DEBUG
780 			if (mmudebug & MDB_WBFAILED)
781 				printf(wberrstr, p->p_pid, p->p_comm,
782 				       "MOVE16", fp->f_pc, f->f_fa,
783 				       f->f_fa & ~0xF, f->f_pd0);
784 #endif
785 		}
786 	} else if (f->f_wb1s & SSW4_WBSV) {
787 		/*
788 		 * Writeback #1.
789 		 * Position the "memory-aligned" data and write it out.
790 		 */
791 		u_int wb1d = f->f_wb1d;
792 		int off;
793 
794 #ifdef DEBUG
795 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
796 			dumpwb(1, f->f_wb1s, f->f_wb1a, f->f_wb1d);
797 		wbstats.wb1s++;
798 		wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++;
799 #endif
800 		off = (f->f_wb1a & 3) * 8;
801 		switch (f->f_wb1s & SSW4_SZMASK) {
802 		case SSW4_SZLW:
803 			if (off)
804 				wb1d = (wb1d >> (32 - off)) | (wb1d << off);
805 			if (KDFAULT(f->f_wb1s))
806 				*(long *)f->f_wb1a = wb1d;
807 			else
808 				err = suword((void *)f->f_wb1a, wb1d);
809 			break;
810 		case SSW4_SZB:
811 			off = 24 - off;
812 			if (off)
813 				wb1d >>= off;
814 			if (KDFAULT(f->f_wb1s))
815 				*(char *)f->f_wb1a = wb1d;
816 			else
817 				err = subyte((void *)f->f_wb1a, wb1d);
818 			break;
819 		case SSW4_SZW:
820 			off = (off + 16) % 32;
821 			if (off)
822 				wb1d = (wb1d >> (32 - off)) | (wb1d << off);
823 			if (KDFAULT(f->f_wb1s))
824 				*(short *)f->f_wb1a = wb1d;
825 			else
826 				err = susword((void *)f->f_wb1a, wb1d);
827 			break;
828 		}
829 		if (err) {
830 			fa = f->f_wb1a;
831 #ifdef DEBUG
832 			if (mmudebug & MDB_WBFAILED)
833 				printf(wberrstr, p->p_pid, p->p_comm,
834 				       "#1", fp->f_pc, f->f_fa,
835 				       f->f_wb1a, f->f_wb1d);
836 #endif
837 		}
838 	}
839 	/*
840 	 * Deal with the "normal" writebacks.
841 	 *
842 	 * XXX writeback2 is known to reflect a LINE size writeback after
843 	 * a MOVE16 was already dealt with above.  Ignore it.
844 	 */
845 	if (err == 0 && (f->f_wb2s & SSW4_WBSV) &&
846 	    (f->f_wb2s & SSW4_SZMASK) != SSW4_SZLN) {
847 #ifdef DEBUG
848 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
849 			dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d);
850 		wbstats.wb2s++;
851 		wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++;
852 #endif
853 		switch (f->f_wb2s & SSW4_SZMASK) {
854 		case SSW4_SZLW:
855 			if (KDFAULT(f->f_wb2s))
856 				*(long *)f->f_wb2a = f->f_wb2d;
857 			else
858 				err = suword((void *)f->f_wb2a, f->f_wb2d);
859 			break;
860 		case SSW4_SZB:
861 			if (KDFAULT(f->f_wb2s))
862 				*(char *)f->f_wb2a = f->f_wb2d;
863 			else
864 				err = subyte((void *)f->f_wb2a, f->f_wb2d);
865 			break;
866 		case SSW4_SZW:
867 			if (KDFAULT(f->f_wb2s))
868 				*(short *)f->f_wb2a = f->f_wb2d;
869 			else
870 				err = susword((void *)f->f_wb2a, f->f_wb2d);
871 			break;
872 		}
873 		if (err) {
874 			fa = f->f_wb2a;
875 #ifdef DEBUG
876 			if (mmudebug & MDB_WBFAILED) {
877 				printf(wberrstr, p->p_pid, p->p_comm,
878 				       "#2", fp->f_pc, f->f_fa,
879 				       f->f_wb2a, f->f_wb2d);
880 				dumpssw(f->f_ssw);
881 				dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d);
882 			}
883 #endif
884 		}
885 	}
886 	if (err == 0 && (f->f_wb3s & SSW4_WBSV)) {
887 #ifdef DEBUG
888 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
889 			dumpwb(3, f->f_wb3s, f->f_wb3a, f->f_wb3d);
890 		wbstats.wb3s++;
891 		wbstats.wbsize[(f->f_wb3s&SSW4_SZMASK)>>5]++;
892 #endif
893 		switch (f->f_wb3s & SSW4_SZMASK) {
894 		case SSW4_SZLW:
895 			if (KDFAULT(f->f_wb3s))
896 				*(long *)f->f_wb3a = f->f_wb3d;
897 			else
898 				err = suword((void *)f->f_wb3a, f->f_wb3d);
899 			break;
900 		case SSW4_SZB:
901 			if (KDFAULT(f->f_wb3s))
902 				*(char *)f->f_wb3a = f->f_wb3d;
903 			else
904 				err = subyte((void *)f->f_wb3a, f->f_wb3d);
905 			break;
906 		case SSW4_SZW:
907 			if (KDFAULT(f->f_wb3s))
908 				*(short *)f->f_wb3a = f->f_wb3d;
909 			else
910 				err = susword((void *)f->f_wb3a, f->f_wb3d);
911 			break;
912 #ifdef DEBUG
913 		case SSW4_SZLN:
914 			panic("writeback: wb3s indicates LINE write");
915 #endif
916 		}
917 		if (err) {
918 			fa = f->f_wb3a;
919 #ifdef DEBUG
920 			if (mmudebug & MDB_WBFAILED)
921 				printf(wberrstr, p->p_pid, p->p_comm,
922 				       "#3", fp->f_pc, f->f_fa,
923 				       f->f_wb3a, f->f_wb3d);
924 #endif
925 		}
926 	}
927 	pcb->pcb_onfault = oonfault;
928 	if (err)
929 		err = SIGSEGV;
930 	return (err);
931 }
932 
933 #ifdef DEBUG
934 void
935 dumpssw(u_short ssw)
936 {
937 	printf(" SSW: %x: ", ssw);
938 	if (ssw & SSW4_CP)
939 		printf("CP,");
940 	if (ssw & SSW4_CU)
941 		printf("CU,");
942 	if (ssw & SSW4_CT)
943 		printf("CT,");
944 	if (ssw & SSW4_CM)
945 		printf("CM,");
946 	if (ssw & SSW4_MA)
947 		printf("MA,");
948 	if (ssw & SSW4_ATC)
949 		printf("ATC,");
950 	if (ssw & SSW4_LK)
951 		printf("LK,");
952 	if (ssw & SSW4_RW)
953 		printf("RW,");
954 	printf(" SZ=%s, TT=%s, TM=%s\n",
955 	       f7sz[(ssw & SSW4_SZMASK) >> 5],
956 	       f7tt[(ssw & SSW4_TTMASK) >> 3],
957 	       f7tm[ssw & SSW4_TMMASK]);
958 }
959 
960 void
961 dumpwb(int num, u_short s, u_int a, u_int d)
962 {
963 	struct lwp *l = curlwp;
964 	struct proc *p = l->l_proc;
965 	paddr_t pa;
966 
967 	printf(" writeback #%d: VA %x, data %x, SZ=%s, TT=%s, TM=%s\n",
968 	       num, a, d, f7sz[(s & SSW4_SZMASK) >> 5],
969 	       f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]);
970 	printf("               PA ");
971 	if (pmap_extract(p->p_vmspace->vm_map.pmap, (vaddr_t)a, &pa) == false)
972 		printf("<invalid address>");
973 	else
974 		printf("%lx, current value %lx", pa, fuword((void *)a));
975 	printf("\n");
976 }
977 #endif
978 #endif
979 
980 /*
981  * This is called by locore for supervisor-mode trace and
982  * breakpoint traps.  This is separate from trap() above
983  * so that breakpoints in trap() will work.
984  *
985  * If we have both DDB and KGDB, let KGDB see it first,
986  * because KGDB will just return 0 if not connected.
987  */
988 void
989 trap_kdebug(int type, struct trapframe tf)
990 {
991 #ifdef	KGDB
992 	/* Let KGDB handle it (if connected) */
993 	if (kgdb_trap(type, &tf))
994 		return;
995 #endif
996 #ifdef	DDB
997 	/* Let DDB handle it. */
998 	if (kdb_trap(type, &tf))
999 		return;
1000 #endif
1001 
1002 	panic("unexpected BPT trap");
1003 }
1004