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