xref: /netbsd/sys/arch/next68k/next68k/trap.c (revision c4a72b64)
1 /*	$NetBSD: trap.c,v 1.38 2002/09/11 01:46:35 mycroft 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 	static int panicing = 0;
296 
297 	uvmexp.traps++;
298 	p = curproc;
299 	ucode = 0;
300 
301 	/* I have verified that this DOES happen! -gwr */
302 	if (p == NULL)
303 		p = &proc0;
304 #ifdef DIAGNOSTIC
305 	if (p->p_addr == NULL)
306 		panic("trap: no pcb");
307 #endif
308 
309 	if (USERMODE(frame.f_sr)) {
310 		type |= T_USER;
311 		sticks = p->p_sticks;
312 		p->p_md.md_regs = frame.f_regs;
313 	}
314 	switch (type) {
315 
316 	default:
317 	dopanic:
318 		/*
319 		 * Let the kernel debugger see the trap frame that
320 		 * caused us to panic.  This is a convenience so
321 		 * one can see registers at the point of failure.
322 		 */
323 		s = splhigh();
324 		panicing = 1;
325 		printf("trap type %d, code = 0x%x, v = 0x%x\n", type, code, v);
326 		printf("%s program counter = 0x%x\n",
327 		    (type & T_USER) ? "user" : "kernel", frame.f_pc);
328 #ifdef KGDB
329 		/* If connected, step or cont returns 1 */
330 		if (kgdb_trap(type, (db_regs_t *)&frame))
331 			goto kgdb_cont;
332 #endif
333 #ifdef DDB
334 		(void)kdb_trap(type, (db_regs_t *)&frame);
335 #endif
336 #ifdef KGDB
337 	kgdb_cont:
338 #endif
339 		splx(s);
340 		if (panicstr) {
341 			printf("trap during panic!\n");
342 #ifdef DEBUG
343 			/* XXX should be a machine-dependent hook */
344 			printf("(press a key)\n"); (void)cngetc();
345 #endif
346 		}
347 		regdump((struct trapframe *)&frame, 128);
348 		type &= ~T_USER;
349 		if ((u_int)type < trap_types)
350 			panic(trap_type[type]);
351 		panic("trap");
352 
353 	case T_BUSERR:		/* kernel bus error */
354 		if (p->p_addr->u_pcb.pcb_onfault == 0)
355 			goto dopanic;
356 		/* FALLTHROUGH */
357 
358 	copyfault:
359 		/*
360 		 * If we have arranged to catch this fault in any of the
361 		 * copy to/from user space routines, set PC to return to
362 		 * indicated location and set flag informing buserror code
363 		 * that it may need to clean up stack frame.
364 		 */
365 		frame.f_stackadj = exframesize[frame.f_format];
366 		frame.f_format = frame.f_vector = 0;
367 		frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault;
368 		return;
369 
370 	case T_BUSERR|T_USER:	/* bus error */
371 	case T_ADDRERR|T_USER:	/* address error */
372 		ucode = v;
373 		i = SIGBUS;
374 		break;
375 
376 	case T_COPERR:		/* kernel coprocessor violation */
377 	case T_FMTERR|T_USER:	/* do all RTE errors come in as T_USER? */
378 	case T_FMTERR:		/* ...just in case... */
379 	/*
380 	 * The user has most likely trashed the RTE or FP state info
381 	 * in the stack frame of a signal handler.
382 	 */
383 		printf("pid %d: kernel %s exception\n", p->p_pid,
384 		       type==T_COPERR ? "coprocessor" : "format");
385 		type |= T_USER;
386 		SIGACTION(p, SIGILL).sa_handler = SIG_DFL;
387 		sigdelset(&p->p_sigctx.ps_sigignore, SIGILL);
388 		sigdelset(&p->p_sigctx.ps_sigcatch, SIGILL);
389 		sigdelset(&p->p_sigctx.ps_sigmask, SIGILL);
390 		i = SIGILL;
391 		ucode = frame.f_format;	/* XXX was ILL_RESAD_FAULT */
392 		break;
393 
394 	case T_COPERR|T_USER:	/* user coprocessor violation */
395 	/* What is a proper response here? */
396 		ucode = 0;
397 		i = SIGFPE;
398 		break;
399 
400 	case T_FPERR|T_USER:	/* 68881 exceptions */
401 	/*
402 	 * We pass along the 68881 status register which locore stashed
403 	 * in code for us.  Note that there is a possibility that the
404 	 * bit pattern of this register will conflict with one of the
405 	 * FPE_* codes defined in signal.h.  Fortunately for us, the
406 	 * only such codes we use are all in the range 1-7 and the low
407 	 * 3 bits of the status register are defined as 0 so there is
408 	 * no clash.
409 	 */
410 		ucode = code;
411 		i = SIGFPE;
412 		break;
413 
414 #ifdef M68040
415 	case T_FPEMULI|T_USER:	/* unimplemented FP instuction */
416 	case T_FPEMULD|T_USER:	/* unimplemented FP data type */
417 		/* XXX need to FSAVE */
418 		printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n",
419 		       p->p_pid, p->p_comm,
420 		       frame.f_format == 2 ? "instruction" : "data type",
421 		       frame.f_pc, frame.f_fmt2.f_iaddr);
422 		/* XXX need to FRESTORE */
423 		i = SIGFPE;
424 		break;
425 #endif
426 
427 	case T_ILLINST|T_USER:	/* illegal instruction fault */
428 #ifdef COMPAT_HPUX
429 		if (p->p_emul == &emul_hpux) {
430 			ucode = HPUX_ILL_ILLINST_TRAP;
431 			i = SIGILL;
432 			break;
433 		}
434 		/* fall through */
435 #endif
436 	case T_PRIVINST|T_USER:	/* privileged instruction fault */
437 #ifdef COMPAT_HPUX
438 		if (p->p_emul == &emul_hpux)
439 			ucode = HPUX_ILL_PRIV_TRAP;
440 		else
441 #endif
442 		ucode = frame.f_format;	/* XXX was ILL_PRIVIN_FAULT */
443 		i = SIGILL;
444 		break;
445 
446 	case T_ZERODIV|T_USER:	/* Divide by zero */
447 #ifdef COMPAT_HPUX
448 		if (p->p_emul == &emul_hpux)
449 			ucode = HPUX_FPE_INTDIV_TRAP;
450 		else
451 #endif
452 		ucode = frame.f_format;	/* XXX was FPE_INTDIV_TRAP */
453 		i = SIGFPE;
454 		break;
455 
456 	case T_CHKINST|T_USER:	/* CHK instruction trap */
457 #ifdef COMPAT_HPUX
458 		if (p->p_emul == &emul_hpux) {
459 			/* handled differently under hp-ux */
460 			i = SIGILL;
461 			ucode = HPUX_ILL_CHK_TRAP;
462 			break;
463 		}
464 #endif
465 		ucode = frame.f_format;	/* XXX was FPE_SUBRNG_TRAP */
466 		i = SIGFPE;
467 		break;
468 
469 	case T_TRAPVINST|T_USER:	/* TRAPV instruction trap */
470 #ifdef COMPAT_HPUX
471 		if (p->p_emul == &emul_hpux) {
472 			/* handled differently under hp-ux */
473 			i = SIGILL;
474 			ucode = HPUX_ILL_TRAPV_TRAP;
475 			break;
476 		}
477 #endif
478 		ucode = frame.f_format;	/* XXX was FPE_INTOVF_TRAP */
479 		i = SIGFPE;
480 		break;
481 
482 	/*
483 	 * XXX: Trace traps are a nightmare.
484 	 *
485 	 *	HP-UX uses trap #1 for breakpoints,
486 	 *	NetBSD/m68k uses trap #2,
487 	 *	SUN 3.x uses trap #15,
488 	 *	DDB and KGDB uses trap #15 (for kernel breakpoints;
489 	 *	handled elsewhere).
490 	 *
491 	 * NetBSD and HP-UX traps both get mapped by locore.s into T_TRACE.
492 	 * SUN 3.x traps get passed through as T_TRAP15 and are not really
493 	 * supported yet.
494 	 *
495 	 * XXX: We should never get kernel-mode T_TRAP15
496 	 * XXX: because locore.s now gives them special treatment.
497 	 */
498 	case T_TRAP15:		/* kernel breakpoint */
499 #ifdef DEBUG
500 		printf("unexpected kernel trace trap, type = %d\n", type);
501 		printf("program counter = 0x%x\n", frame.f_pc);
502 #endif
503 		frame.f_sr &= ~PSL_T;
504 		return;
505 
506 	case T_TRACE|T_USER:	/* user trace trap */
507 #ifdef COMPAT_SUNOS
508 		/*
509 		 * SunOS uses Trap #2 for a "CPU cache flush".
510 		 * Just flush the on-chip caches and return.
511 		 */
512 		if (p->p_emul == &emul_sunos) {
513 			ICIA();
514 			DCIU();
515 			return;
516 		}
517 #endif
518 		/* FALLTHROUGH */
519 	case T_TRACE:		/* tracing a trap instruction */
520 	case T_TRAP15|T_USER:	/* SUN user trace trap */
521 		frame.f_sr &= ~PSL_T;
522 		i = SIGTRAP;
523 		break;
524 
525 	case T_ASTFLT:		/* system async trap, cannot happen */
526 		goto dopanic;
527 
528 	case T_ASTFLT|T_USER:	/* user async trap */
529 		astpending = 0;
530 		/*
531 		 * We check for software interrupts first.  This is because
532 		 * they are at a higher level than ASTs, and on a VAX would
533 		 * interrupt the AST.  We assume that if we are processing
534 		 * an AST that we must be at IPL0 so we don't bother to
535 		 * check.  Note that we ensure that we are at least at SIR
536 		 * IPL while processing the SIR.
537 		 */
538 		spl1();
539 		/* fall into... */
540 
541 	case T_SSIR:		/* software interrupt */
542 	case T_SSIR|T_USER:
543 		while ((bit = ffs(ssir))) {
544 			--bit;
545 			ssir &= ~(1 << bit);
546 			uvmexp.softs++;
547 			if (sir_routines[bit])
548 				sir_routines[bit](sir_args[bit]);
549 		}
550 		/*
551 		 * If this was not an AST trap, we are all done.
552 		 */
553 		if (type != (T_ASTFLT|T_USER)) {
554 			uvmexp.traps--;
555 			return;
556 		}
557 		spl0();
558 		if (p->p_flag & P_OWEUPC) {
559 			p->p_flag &= ~P_OWEUPC;
560 			ADDUPROF(p);
561 		}
562 		goto out;
563 
564 	case T_MMUFLT:		/* kernel mode page fault */
565 		/*
566 		 * If we were doing profiling ticks or other user mode
567 		 * stuff from interrupt code, Just Say No.
568 		 */
569 		if (p->p_addr->u_pcb.pcb_onfault == fubail ||
570 		    p->p_addr->u_pcb.pcb_onfault == subail)
571 			goto copyfault;
572 		/* fall into ... */
573 
574 	case T_MMUFLT|T_USER:	/* page fault */
575 	    {
576 		vaddr_t va;
577 		struct vmspace *vm = p->p_vmspace;
578 		struct vm_map *map;
579 		int rv;
580 		vm_prot_t ftype;
581 		extern struct vm_map *kernel_map;
582 
583 #ifdef DEBUG
584 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
585 		printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n",
586 		       p->p_pid, code, v, frame.f_pc, frame.f_sr);
587 #endif
588 		/*
589 		 * It is only a kernel address space fault iff:
590 		 * 	1. (type & T_USER) == 0  and
591 		 * 	2. pcb_onfault not set or
592 		 *	3. pcb_onfault set but supervisor space data fault
593 		 * The last can occur during an exec() copyin where the
594 		 * argument space is lazy-allocated.
595 		 */
596 		if ((type & T_USER) == 0 &&
597 		    ((p->p_addr->u_pcb.pcb_onfault == 0) || KDFAULT(code)))
598 			map = kernel_map;
599 		else
600 			map = vm ? &vm->vm_map : kernel_map;
601 
602 		if (WRFAULT(code))
603 			ftype = VM_PROT_WRITE;
604 		else
605 			ftype = VM_PROT_READ;
606 
607 		va = trunc_page((vaddr_t)v);
608 
609 		if (map == kernel_map && va == 0) {
610 			printf("trap: bad kernel %s access at 0x%x\n",
611 			    (ftype & VM_PROT_WRITE) ? "read/write" :
612 			    "read", v);
613 			goto dopanic;
614 		}
615 
616 #ifdef DIAGNOSTIC
617 		if (interrupt_depth && !panicing) {
618 			printf("trap: calling uvm_fault() from interrupt!\n");
619 			goto dopanic;
620 		}
621 #endif
622 
623 #ifdef COMPAT_HPUX
624 		if (ISHPMMADDR(va)) {
625 			int pmap_mapmulti __P((pmap_t, vaddr_t));
626 			vaddr_t bva;
627 
628 			rv = pmap_mapmulti(map->pmap, va);
629 			if (rv != 0) {
630 				bva = HPMMBASEADDR(va);
631 				rv = uvm_fault(map, bva, 0, ftype);
632 				if (rv == 0)
633 					(void) pmap_mapmulti(map->pmap, va);
634 			}
635 		} else
636 #endif
637 		rv = uvm_fault(map, va, 0, ftype);
638 #ifdef DEBUG
639 		if (rv && MDB_ISPID(p->p_pid))
640 			printf("uvm_fault(%p, 0x%lx, 0, 0x%x) -> 0x%x\n",
641 			    map, va, ftype, rv);
642 #endif
643 		/*
644 		 * If this was a stack access we keep track of the maximum
645 		 * accessed stack size.  Also, if vm_fault gets a protection
646 		 * failure it is due to accessing the stack region outside
647 		 * the current limit and we need to reflect that as an access
648 		 * error.
649 		 */
650 		if ((vm != NULL && (caddr_t)va >= vm->vm_maxsaddr)
651 		    && map != kernel_map) {
652 			if (rv == 0) {
653 				unsigned nss;
654 
655 				nss = btoc(USRSTACK-(unsigned)va);
656 				if (nss > vm->vm_ssize)
657 					vm->vm_ssize = nss;
658 			} else if (rv == EACCES)
659 				rv = EFAULT;
660 		}
661 		if (rv == 0) {
662 			if (type == T_MMUFLT) {
663 #ifdef M68040
664 				if (cputype == CPU_68040)
665 					(void) writeback(&frame, 1);
666 #endif
667 				return;
668 			}
669 			goto out;
670 		}
671 		if (type == T_MMUFLT) {
672 			if (p->p_addr->u_pcb.pcb_onfault)
673 				goto copyfault;
674 			printf("uvm_fault(%p, 0x%lx, 0, 0x%x) -> 0x%x\n",
675 			    map, va, ftype, rv);
676 			printf("  type %x, code [mmu,,ssw]: %x\n",
677 			       type, code);
678 			goto dopanic;
679 		}
680 		ucode = v;
681 		if (rv == ENOMEM) {
682 			printf("UVM: pid %d (%s), uid %d killed: out of swap\n",
683 			       p->p_pid, p->p_comm,
684 			       p->p_cred && p->p_ucred ?
685 			       p->p_ucred->cr_uid : -1);
686 			i = SIGKILL;
687 		} else {
688 			i = SIGSEGV;
689 		}
690 		break;
691 	    }
692 	}
693 	trapsignal(p, i, ucode);
694 	if ((type & T_USER) == 0)
695 		return;
696 out:
697 	userret(p, &frame, sticks, v, 1);
698 }
699 
700 #ifdef M68040
701 #ifdef DEBUG
702 struct writebackstats {
703 	int calls;
704 	int cpushes;
705 	int move16s;
706 	int wb1s, wb2s, wb3s;
707 	int wbsize[4];
708 } wbstats;
709 
710 char *f7sz[] = { "longword", "byte", "word", "line" };
711 char *f7tt[] = { "normal", "MOVE16", "AFC", "ACK" };
712 char *f7tm[] = { "d-push", "u-data", "u-code", "M-data",
713 		 "M-code", "k-data", "k-code", "RES" };
714 char wberrstr[] =
715     "WARNING: pid %d(%s) writeback [%s] failed, pc=%x fa=%x wba=%x wbd=%x\n";
716 #endif
717 
718 int
719 writeback(fp, docachepush)
720 	struct frame *fp;
721 	int docachepush;
722 {
723 	struct fmt7 *f = &fp->f_fmt7;
724 	struct proc *p = curproc;
725 	int err = 0;
726 	u_int fa;
727 	caddr_t oonfault = p->p_addr->u_pcb.pcb_onfault;
728 	paddr_t pa;
729 
730 #ifdef DEBUG
731 	if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) {
732 		printf(" pid=%d, fa=%x,", p->p_pid, f->f_fa);
733 		dumpssw(f->f_ssw);
734 	}
735 	wbstats.calls++;
736 #endif
737 	/*
738 	 * Deal with special cases first.
739 	 */
740 	if ((f->f_ssw & SSW4_TMMASK) == SSW4_TMDCP) {
741 		/*
742 		 * Dcache push fault.
743 		 * Line-align the address and write out the push data to
744 		 * the indicated physical address.
745 		 */
746 #ifdef DEBUG
747 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) {
748 			printf(" pushing %s to PA %x, data %x",
749 			       f7sz[(f->f_ssw & SSW4_SZMASK) >> 5],
750 			       f->f_fa, f->f_pd0);
751 			if ((f->f_ssw & SSW4_SZMASK) == SSW4_SZLN)
752 				printf("/%x/%x/%x",
753 				       f->f_pd1, f->f_pd2, f->f_pd3);
754 			printf("\n");
755 		}
756 		if (f->f_wb1s & SSW4_WBSV)
757 			panic("writeback: cache push with WB1S valid");
758 		wbstats.cpushes++;
759 #endif
760 		/*
761 		 * XXX there are security problems if we attempt to do a
762 		 * cache push after a signal handler has been called.
763 		 */
764 		if (docachepush) {
765 			pmap_enter(pmap_kernel(), (vaddr_t)vmmap,
766 			    trunc_page(f->f_fa), VM_PROT_WRITE,
767 			    VM_PROT_WRITE|PMAP_WIRED);
768 			pmap_update(pmap_kernel());
769 			fa = (u_int)&vmmap[(f->f_fa & PGOFSET) & ~0xF];
770 			bcopy((caddr_t)&f->f_pd0, (caddr_t)fa, 16);
771 			(void) pmap_extract(pmap_kernel(), (vaddr_t)fa, &pa);
772 			DCFL(pa);
773 			pmap_remove(pmap_kernel(), (vaddr_t)vmmap,
774 				    (vaddr_t)&vmmap[NBPG]);
775 			pmap_update(pmap_kernel());
776 		} else
777 			printf("WARNING: pid %d(%s) uid %d: CPUSH not done\n",
778 			       p->p_pid, p->p_comm, p->p_ucred->cr_uid);
779 	} else if ((f->f_ssw & (SSW4_RW|SSW4_TTMASK)) == SSW4_TTM16) {
780 		/*
781 		 * MOVE16 fault.
782 		 * Line-align the address and write out the push data to
783 		 * the indicated virtual address.
784 		 */
785 #ifdef DEBUG
786 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
787 			printf(" MOVE16 to VA %x(%x), data %x/%x/%x/%x\n",
788 			       f->f_fa, f->f_fa & ~0xF, f->f_pd0, f->f_pd1,
789 			       f->f_pd2, f->f_pd3);
790 		if (f->f_wb1s & SSW4_WBSV)
791 			panic("writeback: MOVE16 with WB1S valid");
792 		wbstats.move16s++;
793 #endif
794 		if (KDFAULT(f->f_wb1s))
795 			bcopy((caddr_t)&f->f_pd0, (caddr_t)(f->f_fa & ~0xF), 16);
796 		else
797 			err = suline((caddr_t)(f->f_fa & ~0xF), (caddr_t)&f->f_pd0);
798 		if (err) {
799 			fa = f->f_fa & ~0xF;
800 #ifdef DEBUG
801 			if (mmudebug & MDB_WBFAILED)
802 				printf(wberrstr, p->p_pid, p->p_comm,
803 				       "MOVE16", fp->f_pc, f->f_fa,
804 				       f->f_fa & ~0xF, f->f_pd0);
805 #endif
806 		}
807 	} else if (f->f_wb1s & SSW4_WBSV) {
808 		/*
809 		 * Writeback #1.
810 		 * Position the "memory-aligned" data and write it out.
811 		 */
812 		u_int wb1d = f->f_wb1d;
813 		int off;
814 
815 #ifdef DEBUG
816 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
817 			dumpwb(1, f->f_wb1s, f->f_wb1a, f->f_wb1d);
818 		wbstats.wb1s++;
819 		wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++;
820 #endif
821 		off = (f->f_wb1a & 3) * 8;
822 		switch (f->f_wb1s & SSW4_SZMASK) {
823 		case SSW4_SZLW:
824 			if (off)
825 				wb1d = (wb1d >> (32 - off)) | (wb1d << off);
826 			if (KDFAULT(f->f_wb1s))
827 				*(long *)f->f_wb1a = wb1d;
828 			else
829 				err = suword((caddr_t)f->f_wb1a, wb1d);
830 			break;
831 		case SSW4_SZB:
832 			off = 24 - off;
833 			if (off)
834 				wb1d >>= off;
835 			if (KDFAULT(f->f_wb1s))
836 				*(char *)f->f_wb1a = wb1d;
837 			else
838 				err = subyte((caddr_t)f->f_wb1a, wb1d);
839 			break;
840 		case SSW4_SZW:
841 			off = (off + 16) % 32;
842 			if (off)
843 				wb1d = (wb1d >> (32 - off)) | (wb1d << off);
844 			if (KDFAULT(f->f_wb1s))
845 				*(short *)f->f_wb1a = wb1d;
846 			else
847 				err = susword((caddr_t)f->f_wb1a, wb1d);
848 			break;
849 		}
850 		if (err) {
851 			fa = f->f_wb1a;
852 #ifdef DEBUG
853 			if (mmudebug & MDB_WBFAILED)
854 				printf(wberrstr, p->p_pid, p->p_comm,
855 				       "#1", fp->f_pc, f->f_fa,
856 				       f->f_wb1a, f->f_wb1d);
857 #endif
858 		}
859 	}
860 	/*
861 	 * Deal with the "normal" writebacks.
862 	 *
863 	 * XXX writeback2 is known to reflect a LINE size writeback after
864 	 * a MOVE16 was already dealt with above.  Ignore it.
865 	 */
866 	if (err == 0 && (f->f_wb2s & SSW4_WBSV) &&
867 	    (f->f_wb2s & SSW4_SZMASK) != SSW4_SZLN) {
868 #ifdef DEBUG
869 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
870 			dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d);
871 		wbstats.wb2s++;
872 		wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++;
873 #endif
874 		switch (f->f_wb2s & SSW4_SZMASK) {
875 		case SSW4_SZLW:
876 			if (KDFAULT(f->f_wb2s))
877 				*(long *)f->f_wb2a = f->f_wb2d;
878 			else
879 				err = suword((caddr_t)f->f_wb2a, f->f_wb2d);
880 			break;
881 		case SSW4_SZB:
882 			if (KDFAULT(f->f_wb2s))
883 				*(char *)f->f_wb2a = f->f_wb2d;
884 			else
885 				err = subyte((caddr_t)f->f_wb2a, f->f_wb2d);
886 			break;
887 		case SSW4_SZW:
888 			if (KDFAULT(f->f_wb2s))
889 				*(short *)f->f_wb2a = f->f_wb2d;
890 			else
891 				err = susword((caddr_t)f->f_wb2a, f->f_wb2d);
892 			break;
893 		}
894 		if (err) {
895 			fa = f->f_wb2a;
896 #ifdef DEBUG
897 			if (mmudebug & MDB_WBFAILED) {
898 				printf(wberrstr, p->p_pid, p->p_comm,
899 				       "#2", fp->f_pc, f->f_fa,
900 				       f->f_wb2a, f->f_wb2d);
901 				dumpssw(f->f_ssw);
902 				dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d);
903 			}
904 #endif
905 		}
906 	}
907 	if (err == 0 && (f->f_wb3s & SSW4_WBSV)) {
908 #ifdef DEBUG
909 		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))
910 			dumpwb(3, f->f_wb3s, f->f_wb3a, f->f_wb3d);
911 		wbstats.wb3s++;
912 		wbstats.wbsize[(f->f_wb3s&SSW4_SZMASK)>>5]++;
913 #endif
914 		switch (f->f_wb3s & SSW4_SZMASK) {
915 		case SSW4_SZLW:
916 			if (KDFAULT(f->f_wb3s))
917 				*(long *)f->f_wb3a = f->f_wb3d;
918 			else
919 				err = suword((caddr_t)f->f_wb3a, f->f_wb3d);
920 			break;
921 		case SSW4_SZB:
922 			if (KDFAULT(f->f_wb3s))
923 				*(char *)f->f_wb3a = f->f_wb3d;
924 			else
925 				err = subyte((caddr_t)f->f_wb3a, f->f_wb3d);
926 			break;
927 		case SSW4_SZW:
928 			if (KDFAULT(f->f_wb3s))
929 				*(short *)f->f_wb3a = f->f_wb3d;
930 			else
931 				err = susword((caddr_t)f->f_wb3a, f->f_wb3d);
932 			break;
933 #ifdef DEBUG
934 		case SSW4_SZLN:
935 			panic("writeback: wb3s indicates LINE write");
936 #endif
937 		}
938 		if (err) {
939 			fa = f->f_wb3a;
940 #ifdef DEBUG
941 			if (mmudebug & MDB_WBFAILED)
942 				printf(wberrstr, p->p_pid, p->p_comm,
943 				       "#3", fp->f_pc, f->f_fa,
944 				       f->f_wb3a, f->f_wb3d);
945 #endif
946 		}
947 	}
948 	p->p_addr->u_pcb.pcb_onfault = oonfault;
949 	if (err)
950 		err = SIGSEGV;
951 	return (err);
952 }
953 
954 #ifdef DEBUG
955 void
956 dumpssw(ssw)
957 	u_short ssw;
958 {
959 	printf(" SSW: %x: ", ssw);
960 	if (ssw & SSW4_CP)
961 		printf("CP,");
962 	if (ssw & SSW4_CU)
963 		printf("CU,");
964 	if (ssw & SSW4_CT)
965 		printf("CT,");
966 	if (ssw & SSW4_CM)
967 		printf("CM,");
968 	if (ssw & SSW4_MA)
969 		printf("MA,");
970 	if (ssw & SSW4_ATC)
971 		printf("ATC,");
972 	if (ssw & SSW4_LK)
973 		printf("LK,");
974 	if (ssw & SSW4_RW)
975 		printf("RW,");
976 	printf(" SZ=%s, TT=%s, TM=%s\n",
977 	       f7sz[(ssw & SSW4_SZMASK) >> 5],
978 	       f7tt[(ssw & SSW4_TTMASK) >> 3],
979 	       f7tm[ssw & SSW4_TMMASK]);
980 }
981 
982 void
983 dumpwb(num, s, a, d)
984 	int num;
985 	u_short s;
986 	u_int a, d;
987 {
988 	struct proc *p = curproc;
989 	paddr_t pa;
990 
991 	printf(" writeback #%d: VA %x, data %x, SZ=%s, TT=%s, TM=%s\n",
992 	       num, a, d, f7sz[(s & SSW4_SZMASK) >> 5],
993 	       f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]);
994 	printf("               PA ");
995 	if (pmap_extract(p->p_vmspace->vm_map.pmap, (vaddr_t)a, &pa) == FALSE)
996 		printf("<invalid address>");
997 	else
998 		printf("%lx, current value %lx", pa, fuword((caddr_t)a));
999 	printf("\n");
1000 }
1001 #endif
1002 #endif
1003 
1004 /*
1005  * Allocation routines for software interrupts.
1006  */
1007 u_long
1008 allocate_sir(proc, arg)
1009 	void (*proc)(void *);
1010 	void *arg;
1011 {
1012 	int bit;
1013 
1014 	if( next_sir >= NSIR )
1015 		panic("allocate_sir: none left");
1016 	bit = next_sir++;
1017 	sir_routines[bit] = proc;
1018 	sir_args[bit] = arg;
1019 	return (1 << bit);
1020 }
1021 
1022 void
1023 init_sir()
1024 {
1025 	extern void netintr(void);
1026 
1027 	sir_routines[0] = (void (*)(void *))netintr;
1028 	sir_routines[1] = softclock;
1029 	next_sir = 2;
1030 }
1031