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