trap.c revision 269752
1/*	$OpenBSD: trap.c,v 1.19 1998/09/30 12:40:41 pefo Exp $	*/
2/* tracked to 1.23 */
3/*-
4 * Copyright (c) 1988 University of Utah.
5 * Copyright (c) 1992, 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 and Ralph Campbell.
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 * 4. Neither the name of the University nor the names of its contributors
21 *    may be used to endorse or promote products derived from this software
22 *    without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * from: Utah Hdr: trap.c 1.32 91/04/06
37 *
38 *	from: @(#)trap.c	8.5 (Berkeley) 1/11/94
39 *	JNPR: trap.c,v 1.13.2.2 2007/08/29 10:03:49 girish
40 */
41#include <sys/cdefs.h>
42__FBSDID("$FreeBSD: stable/10/sys/mips/mips/trap.c 269752 2014-08-09 14:05:01Z markj $");
43
44#include "opt_compat.h"
45#include "opt_ddb.h"
46#include "opt_global.h"
47#include "opt_ktrace.h"
48#include "opt_kdtrace.h"
49
50#include <sys/param.h>
51#include <sys/systm.h>
52#include <sys/sysent.h>
53#include <sys/proc.h>
54#include <sys/kernel.h>
55#include <sys/signalvar.h>
56#include <sys/syscall.h>
57#include <sys/lock.h>
58#include <vm/vm.h>
59#include <vm/vm_extern.h>
60#include <vm/vm_kern.h>
61#include <vm/vm_page.h>
62#include <vm/vm_map.h>
63#include <vm/vm_param.h>
64#include <sys/vmmeter.h>
65#include <sys/ptrace.h>
66#include <sys/user.h>
67#include <sys/buf.h>
68#include <sys/vnode.h>
69#include <sys/pioctl.h>
70#include <sys/sysctl.h>
71#include <sys/syslog.h>
72#include <sys/bus.h>
73#ifdef KTRACE
74#include <sys/ktrace.h>
75#endif
76#include <net/netisr.h>
77
78#include <machine/trap.h>
79#include <machine/cpu.h>
80#include <machine/pte.h>
81#include <machine/pmap.h>
82#include <machine/md_var.h>
83#include <machine/mips_opcode.h>
84#include <machine/frame.h>
85#include <machine/regnum.h>
86#include <machine/tls.h>
87
88#ifdef DDB
89#include <machine/db_machdep.h>
90#include <ddb/db_sym.h>
91#include <ddb/ddb.h>
92#include <sys/kdb.h>
93#endif
94
95#ifdef KDTRACE_HOOKS
96#include <sys/dtrace_bsd.h>
97#endif
98
99#ifdef TRAP_DEBUG
100int trap_debug = 0;
101SYSCTL_INT(_machdep, OID_AUTO, trap_debug, CTLFLAG_RW,
102    &trap_debug, 0, "Debug information on all traps");
103#endif
104
105#define	lbu_macro(data, addr)						\
106	__asm __volatile ("lbu %0, 0x0(%1)"				\
107			: "=r" (data)	/* outputs */			\
108			: "r" (addr));	/* inputs */
109
110#define	lb_macro(data, addr)						\
111	__asm __volatile ("lb %0, 0x0(%1)"				\
112			: "=r" (data)	/* outputs */			\
113			: "r" (addr));	/* inputs */
114
115#define	lwl_macro(data, addr)						\
116	__asm __volatile ("lwl %0, 0x0(%1)"				\
117			: "=r" (data)	/* outputs */			\
118			: "r" (addr));	/* inputs */
119
120#define	lwr_macro(data, addr)						\
121	__asm __volatile ("lwr %0, 0x0(%1)"				\
122			: "=r" (data)	/* outputs */			\
123			: "r" (addr));	/* inputs */
124
125#define	ldl_macro(data, addr)						\
126	__asm __volatile ("ldl %0, 0x0(%1)"				\
127			: "=r" (data)	/* outputs */			\
128			: "r" (addr));	/* inputs */
129
130#define	ldr_macro(data, addr)						\
131	__asm __volatile ("ldr %0, 0x0(%1)"				\
132			: "=r" (data)	/* outputs */			\
133			: "r" (addr));	/* inputs */
134
135#define	sb_macro(data, addr)						\
136	__asm __volatile ("sb %0, 0x0(%1)"				\
137			:				/* outputs */	\
138			: "r" (data), "r" (addr));	/* inputs */
139
140#define	swl_macro(data, addr)						\
141	__asm __volatile ("swl %0, 0x0(%1)"				\
142			: 				/* outputs */	\
143			: "r" (data), "r" (addr));	/* inputs */
144
145#define	swr_macro(data, addr)						\
146	__asm __volatile ("swr %0, 0x0(%1)"				\
147			: 				/* outputs */	\
148			: "r" (data), "r" (addr));	/* inputs */
149
150#define	sdl_macro(data, addr)						\
151	__asm __volatile ("sdl %0, 0x0(%1)"				\
152			: 				/* outputs */	\
153			: "r" (data), "r" (addr));	/* inputs */
154
155#define	sdr_macro(data, addr)						\
156	__asm __volatile ("sdr %0, 0x0(%1)"				\
157			:				/* outputs */	\
158			: "r" (data), "r" (addr));	/* inputs */
159
160static void log_illegal_instruction(const char *, struct trapframe *);
161static void log_bad_page_fault(char *, struct trapframe *, int);
162static void log_frame_dump(struct trapframe *frame);
163static void get_mapping_info(vm_offset_t, pd_entry_t **, pt_entry_t **);
164
165#ifdef TRAP_DEBUG
166static void trap_frame_dump(struct trapframe *frame);
167#endif
168
169void (*machExceptionTable[]) (void)= {
170/*
171 * The kernel exception handlers.
172 */
173	MipsKernIntr,		/* external interrupt */
174	MipsKernGenException,	/* TLB modification */
175	MipsTLBInvalidException,/* TLB miss (load or instr. fetch) */
176	MipsTLBInvalidException,/* TLB miss (store) */
177	MipsKernGenException,	/* address error (load or I-fetch) */
178	MipsKernGenException,	/* address error (store) */
179	MipsKernGenException,	/* bus error (I-fetch) */
180	MipsKernGenException,	/* bus error (load or store) */
181	MipsKernGenException,	/* system call */
182	MipsKernGenException,	/* breakpoint */
183	MipsKernGenException,	/* reserved instruction */
184	MipsKernGenException,	/* coprocessor unusable */
185	MipsKernGenException,	/* arithmetic overflow */
186	MipsKernGenException,	/* trap exception */
187	MipsKernGenException,	/* virtual coherence exception inst */
188	MipsKernGenException,	/* floating point exception */
189	MipsKernGenException,	/* reserved */
190	MipsKernGenException,	/* reserved */
191	MipsKernGenException,	/* reserved */
192	MipsKernGenException,	/* reserved */
193	MipsKernGenException,	/* reserved */
194	MipsKernGenException,	/* reserved */
195	MipsKernGenException,	/* reserved */
196	MipsKernGenException,	/* watch exception */
197	MipsKernGenException,	/* reserved */
198	MipsKernGenException,	/* reserved */
199	MipsKernGenException,	/* reserved */
200	MipsKernGenException,	/* reserved */
201	MipsKernGenException,	/* reserved */
202	MipsKernGenException,	/* reserved */
203	MipsKernGenException,	/* reserved */
204	MipsKernGenException,	/* virtual coherence exception data */
205/*
206 * The user exception handlers.
207 */
208	MipsUserIntr,		/* 0 */
209	MipsUserGenException,	/* 1 */
210	MipsTLBInvalidException,/* 2 */
211	MipsTLBInvalidException,/* 3 */
212	MipsUserGenException,	/* 4 */
213	MipsUserGenException,	/* 5 */
214	MipsUserGenException,	/* 6 */
215	MipsUserGenException,	/* 7 */
216	MipsUserGenException,	/* 8 */
217	MipsUserGenException,	/* 9 */
218	MipsUserGenException,	/* 10 */
219	MipsUserGenException,	/* 11 */
220	MipsUserGenException,	/* 12 */
221	MipsUserGenException,	/* 13 */
222	MipsUserGenException,	/* 14 */
223	MipsUserGenException,	/* 15 */
224	MipsUserGenException,	/* 16 */
225	MipsUserGenException,	/* 17 */
226	MipsUserGenException,	/* 18 */
227	MipsUserGenException,	/* 19 */
228	MipsUserGenException,	/* 20 */
229	MipsUserGenException,	/* 21 */
230	MipsUserGenException,	/* 22 */
231	MipsUserGenException,	/* 23 */
232	MipsUserGenException,	/* 24 */
233	MipsUserGenException,	/* 25 */
234	MipsUserGenException,	/* 26 */
235	MipsUserGenException,	/* 27 */
236	MipsUserGenException,	/* 28 */
237	MipsUserGenException,	/* 29 */
238	MipsUserGenException,	/* 20 */
239	MipsUserGenException,	/* 31 */
240};
241
242char *trap_type[] = {
243	"external interrupt",
244	"TLB modification",
245	"TLB miss (load or instr. fetch)",
246	"TLB miss (store)",
247	"address error (load or I-fetch)",
248	"address error (store)",
249	"bus error (I-fetch)",
250	"bus error (load or store)",
251	"system call",
252	"breakpoint",
253	"reserved instruction",
254	"coprocessor unusable",
255	"arithmetic overflow",
256	"trap",
257	"virtual coherency instruction",
258	"floating point",
259	"reserved 16",
260	"reserved 17",
261	"reserved 18",
262	"reserved 19",
263	"reserved 20",
264	"reserved 21",
265	"reserved 22",
266	"watch",
267	"reserved 24",
268	"reserved 25",
269	"reserved 26",
270	"reserved 27",
271	"reserved 28",
272	"reserved 29",
273	"reserved 30",
274	"virtual coherency data",
275};
276
277#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
278struct trapdebug trapdebug[TRAPSIZE], *trp = trapdebug;
279#endif
280
281#if defined(DDB) || defined(DEBUG)
282void stacktrace(struct trapframe *);
283void logstacktrace(struct trapframe *);
284#endif
285
286#define	KERNLAND(x)	((vm_offset_t)(x) >= VM_MIN_KERNEL_ADDRESS && (vm_offset_t)(x) < VM_MAX_KERNEL_ADDRESS)
287#define	DELAYBRANCH(x)	((int)(x) < 0)
288
289/*
290 * MIPS load/store access type
291 */
292enum {
293	MIPS_LHU_ACCESS = 1,
294	MIPS_LH_ACCESS,
295	MIPS_LWU_ACCESS,
296	MIPS_LW_ACCESS,
297	MIPS_LD_ACCESS,
298	MIPS_SH_ACCESS,
299	MIPS_SW_ACCESS,
300	MIPS_SD_ACCESS
301};
302
303char *access_name[] = {
304	"Load Halfword Unsigned",
305	"Load Halfword",
306	"Load Word Unsigned",
307	"Load Word",
308	"Load Doubleword",
309	"Store Halfword",
310	"Store Word",
311	"Store Doubleword"
312};
313
314#ifdef	CPU_CNMIPS
315#include <machine/octeon_cop2.h>
316#endif
317
318static int allow_unaligned_acc = 1;
319
320SYSCTL_INT(_vm, OID_AUTO, allow_unaligned_acc, CTLFLAG_RW,
321    &allow_unaligned_acc, 0, "Allow unaligned accesses");
322
323/*
324 * FP emulation is assumed to work on O32, but the code is outdated and crufty
325 * enough that it's a more sensible default to have it disabled when using
326 * other ABIs.  At the very least, it needs a lot of help in using
327 * type-semantic ABI-oblivious macros for everything it does.
328 */
329#if defined(__mips_o32)
330static int emulate_fp = 1;
331#else
332static int emulate_fp = 0;
333#endif
334SYSCTL_INT(_machdep, OID_AUTO, emulate_fp, CTLFLAG_RW,
335    &emulate_fp, 0, "Emulate unimplemented FPU instructions");
336
337static int emulate_unaligned_access(struct trapframe *frame, int mode);
338
339extern void fswintrberr(void); /* XXX */
340
341int
342cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
343{
344	struct trapframe *locr0 = td->td_frame;
345	struct sysentvec *se;
346	int error, nsaved;
347
348	bzero(sa->args, sizeof(sa->args));
349
350	/* compute next PC after syscall instruction */
351	td->td_pcb->pcb_tpc = sa->trapframe->pc; /* Remember if restart */
352	if (DELAYBRANCH(sa->trapframe->cause))	 /* Check BD bit */
353		locr0->pc = MipsEmulateBranch(locr0, sa->trapframe->pc, 0, 0);
354	else
355		locr0->pc += sizeof(int);
356	sa->code = locr0->v0;
357
358	switch (sa->code) {
359	case SYS___syscall:
360	case SYS_syscall:
361		/*
362		 * This is an indirect syscall, in which the code is the first argument.
363		 */
364#if (!defined(__mips_n32) && !defined(__mips_n64)) || defined(COMPAT_FREEBSD32)
365		if (sa->code == SYS___syscall && SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
366			/*
367			 * Like syscall, but code is a quad, so as to maintain alignment
368			 * for the rest of the arguments.
369			 */
370			if (_QUAD_LOWWORD == 0)
371				sa->code = locr0->a0;
372			else
373				sa->code = locr0->a1;
374			sa->args[0] = locr0->a2;
375			sa->args[1] = locr0->a3;
376			nsaved = 2;
377			break;
378		}
379#endif
380		/*
381		 * This is either not a quad syscall, or is a quad syscall with a
382		 * new ABI in which quads fit in a single register.
383		 */
384		sa->code = locr0->a0;
385		sa->args[0] = locr0->a1;
386		sa->args[1] = locr0->a2;
387		sa->args[2] = locr0->a3;
388		nsaved = 3;
389#if defined(__mips_n32) || defined(__mips_n64)
390#ifdef COMPAT_FREEBSD32
391		if (!SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
392#endif
393			/*
394			 * Non-o32 ABIs support more arguments in registers.
395			 */
396			sa->args[3] = locr0->a4;
397			sa->args[4] = locr0->a5;
398			sa->args[5] = locr0->a6;
399			sa->args[6] = locr0->a7;
400			nsaved += 4;
401#ifdef COMPAT_FREEBSD32
402		}
403#endif
404#endif
405		break;
406	default:
407		/*
408		 * A direct syscall, arguments are just parameters to the syscall.
409		 */
410		sa->args[0] = locr0->a0;
411		sa->args[1] = locr0->a1;
412		sa->args[2] = locr0->a2;
413		sa->args[3] = locr0->a3;
414		nsaved = 4;
415#if defined (__mips_n32) || defined(__mips_n64)
416#ifdef COMPAT_FREEBSD32
417		if (!SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
418#endif
419			/*
420			 * Non-o32 ABIs support more arguments in registers.
421			 */
422			sa->args[4] = locr0->a4;
423			sa->args[5] = locr0->a5;
424			sa->args[6] = locr0->a6;
425			sa->args[7] = locr0->a7;
426			nsaved += 4;
427#ifdef COMPAT_FREEBSD32
428		}
429#endif
430#endif
431		break;
432	}
433
434#ifdef TRAP_DEBUG
435	if (trap_debug)
436		printf("SYSCALL #%d pid:%u\n", sa->code, td->td_proc->p_pid);
437#endif
438
439	se = td->td_proc->p_sysent;
440	/*
441	 * XXX
442	 * Shouldn't this go before switching on the code?
443	 */
444	if (se->sv_mask)
445		sa->code &= se->sv_mask;
446
447	if (sa->code >= se->sv_size)
448		sa->callp = &se->sv_table[0];
449	else
450		sa->callp = &se->sv_table[sa->code];
451
452	sa->narg = sa->callp->sy_narg;
453
454	if (sa->narg > nsaved) {
455#if defined(__mips_n32) || defined(__mips_n64)
456		/*
457		 * XXX
458		 * Is this right for new ABIs?  I think the 4 there
459		 * should be 8, size there are 8 registers to skip,
460		 * not 4, but I'm not certain.
461		 */
462#ifdef COMPAT_FREEBSD32
463		if (!SV_PROC_FLAG(td->td_proc, SV_ILP32))
464#endif
465			printf("SYSCALL #%u pid:%u, narg (%u) > nsaved (%u).\n",
466			    sa->code, td->td_proc->p_pid, sa->narg, nsaved);
467#endif
468#if (defined(__mips_n32) || defined(__mips_n64)) && defined(COMPAT_FREEBSD32)
469		if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
470			unsigned i;
471			int32_t arg;
472
473			error = 0; /* XXX GCC is awful.  */
474			for (i = nsaved; i < sa->narg; i++) {
475				error = copyin((caddr_t)(intptr_t)(locr0->sp +
476				    (4 + (i - nsaved)) * sizeof(int32_t)),
477				    (caddr_t)&arg, sizeof arg);
478				if (error != 0)
479					break;
480				sa->args[i] = arg;
481			}
482		} else
483#endif
484		error = copyin((caddr_t)(intptr_t)(locr0->sp +
485		    4 * sizeof(register_t)), (caddr_t)&sa->args[nsaved],
486		   (u_int)(sa->narg - nsaved) * sizeof(register_t));
487		if (error != 0) {
488			locr0->v0 = error;
489			locr0->a3 = 1;
490		}
491	} else
492		error = 0;
493
494	if (error == 0) {
495		td->td_retval[0] = 0;
496		td->td_retval[1] = locr0->v1;
497	}
498
499	return (error);
500}
501
502#undef __FBSDID
503#define __FBSDID(x)
504#include "../../kern/subr_syscall.c"
505
506/*
507 * Handle an exception.
508 * Called from MipsKernGenException() or MipsUserGenException()
509 * when a processor trap occurs.
510 * In the case of a kernel trap, we return the pc where to resume if
511 * p->p_addr->u_pcb.pcb_onfault is set, otherwise, return old pc.
512 */
513register_t
514trap(struct trapframe *trapframe)
515{
516	int type, usermode;
517	int i = 0;
518	unsigned ucode = 0;
519	struct thread *td = curthread;
520	struct proc *p = curproc;
521	vm_prot_t ftype;
522	pmap_t pmap;
523	int access_type;
524	ksiginfo_t ksi;
525	char *msg = NULL;
526	intptr_t addr = 0;
527	register_t pc;
528	int cop;
529	register_t *frame_regs;
530
531	trapdebug_enter(trapframe, 0);
532
533	type = (trapframe->cause & MIPS_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT;
534	if (TRAPF_USERMODE(trapframe)) {
535		type |= T_USER;
536		usermode = 1;
537	} else {
538		usermode = 0;
539	}
540
541	/*
542	 * Enable hardware interrupts if they were on before the trap. If it
543	 * was off disable all so we don't accidently enable it when doing a
544	 * return to userland.
545	 */
546	if (trapframe->sr & MIPS_SR_INT_IE) {
547		set_intr_mask(trapframe->sr & MIPS_SR_INT_MASK);
548		intr_enable();
549	} else {
550		intr_disable();
551	}
552
553#ifdef TRAP_DEBUG
554	if (trap_debug) {
555		static vm_offset_t last_badvaddr = 0;
556		static vm_offset_t this_badvaddr = 0;
557		static int count = 0;
558		u_int32_t pid;
559
560		printf("trap type %x (%s - ", type,
561		    trap_type[type & (~T_USER)]);
562
563		if (type & T_USER)
564			printf("user mode)\n");
565		else
566			printf("kernel mode)\n");
567
568#ifdef SMP
569		printf("cpuid = %d\n", PCPU_GET(cpuid));
570#endif
571		pid = mips_rd_entryhi() & TLBHI_ASID_MASK;
572		printf("badaddr = %#jx, pc = %#jx, ra = %#jx, sp = %#jx, sr = %jx, pid = %d, ASID = %u\n",
573		    (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
574		    (intmax_t)trapframe->sp, (intmax_t)trapframe->sr,
575		    (curproc ? curproc->p_pid : -1), pid);
576
577		switch (type & ~T_USER) {
578		case T_TLB_MOD:
579		case T_TLB_LD_MISS:
580		case T_TLB_ST_MISS:
581		case T_ADDR_ERR_LD:
582		case T_ADDR_ERR_ST:
583			this_badvaddr = trapframe->badvaddr;
584			break;
585		case T_SYSCALL:
586			this_badvaddr = trapframe->ra;
587			break;
588		default:
589			this_badvaddr = trapframe->pc;
590			break;
591		}
592		if ((last_badvaddr == this_badvaddr) &&
593		    ((type & ~T_USER) != T_SYSCALL)) {
594			if (++count == 3) {
595				trap_frame_dump(trapframe);
596				panic("too many faults at %p\n", (void *)last_badvaddr);
597			}
598		} else {
599			last_badvaddr = this_badvaddr;
600			count = 0;
601		}
602	}
603#endif
604
605#ifdef KDTRACE_HOOKS
606	/*
607	 * A trap can occur while DTrace executes a probe. Before
608	 * executing the probe, DTrace blocks re-scheduling and sets
609	 * a flag in it's per-cpu flags to indicate that it doesn't
610	 * want to fault. On returning from the probe, the no-fault
611	 * flag is cleared and finally re-scheduling is enabled.
612	 *
613	 * If the DTrace kernel module has registered a trap handler,
614	 * call it and if it returns non-zero, assume that it has
615	 * handled the trap and modified the trap frame so that this
616	 * function can return normally.
617	 */
618	/*
619	 * XXXDTRACE: add pid probe handler here (if ever)
620	 */
621	if (!usermode) {
622		if (dtrace_trap_func != NULL && (*dtrace_trap_func)(trapframe, type))
623			return (trapframe->pc);
624	}
625#endif
626
627	switch (type) {
628	case T_MCHECK:
629#ifdef DDB
630		kdb_trap(type, 0, trapframe);
631#endif
632		panic("MCHECK\n");
633		break;
634	case T_TLB_MOD:
635		/* check for kernel address */
636		if (KERNLAND(trapframe->badvaddr)) {
637			if (pmap_emulate_modified(kernel_pmap,
638			    trapframe->badvaddr) != 0) {
639				ftype = VM_PROT_WRITE;
640				goto kernel_fault;
641			}
642			return (trapframe->pc);
643		}
644		/* FALLTHROUGH */
645
646	case T_TLB_MOD + T_USER:
647		pmap = &p->p_vmspace->vm_pmap;
648		if (pmap_emulate_modified(pmap, trapframe->badvaddr) != 0) {
649			ftype = VM_PROT_WRITE;
650			goto dofault;
651		}
652		if (!usermode)
653			return (trapframe->pc);
654		goto out;
655
656	case T_TLB_LD_MISS:
657	case T_TLB_ST_MISS:
658		ftype = (type == T_TLB_ST_MISS) ? VM_PROT_WRITE : VM_PROT_READ;
659		/* check for kernel address */
660		if (KERNLAND(trapframe->badvaddr)) {
661			vm_offset_t va;
662			int rv;
663
664	kernel_fault:
665			va = trunc_page((vm_offset_t)trapframe->badvaddr);
666			rv = vm_fault(kernel_map, va, ftype, VM_FAULT_NORMAL);
667			if (rv == KERN_SUCCESS)
668				return (trapframe->pc);
669			if (td->td_pcb->pcb_onfault != NULL) {
670				pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
671				td->td_pcb->pcb_onfault = NULL;
672				return (pc);
673			}
674			goto err;
675		}
676
677		/*
678		 * It is an error for the kernel to access user space except
679		 * through the copyin/copyout routines.
680		 */
681		if (td->td_pcb->pcb_onfault == NULL)
682			goto err;
683
684		/* check for fuswintr() or suswintr() getting a page fault */
685		/* XXX There must be a nicer way to do this.  */
686		if (td->td_pcb->pcb_onfault == fswintrberr) {
687			pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
688			td->td_pcb->pcb_onfault = NULL;
689			return (pc);
690		}
691
692		goto dofault;
693
694	case T_TLB_LD_MISS + T_USER:
695		ftype = VM_PROT_READ;
696		goto dofault;
697
698	case T_TLB_ST_MISS + T_USER:
699		ftype = VM_PROT_WRITE;
700dofault:
701		{
702			vm_offset_t va;
703			struct vmspace *vm;
704			vm_map_t map;
705			int rv = 0;
706
707			vm = p->p_vmspace;
708			map = &vm->vm_map;
709			va = trunc_page((vm_offset_t)trapframe->badvaddr);
710			if (KERNLAND(trapframe->badvaddr)) {
711				/*
712				 * Don't allow user-mode faults in kernel
713				 * address space.
714				 */
715				goto nogo;
716			}
717
718			/*
719			 * Keep swapout from messing with us during this
720			 * critical time.
721			 */
722			PROC_LOCK(p);
723			++p->p_lock;
724			PROC_UNLOCK(p);
725
726			rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
727
728			PROC_LOCK(p);
729			--p->p_lock;
730			PROC_UNLOCK(p);
731			/*
732			 * XXXDTRACE: add dtrace_doubletrap_func here?
733			 */
734#ifdef VMFAULT_TRACE
735			printf("vm_fault(%p (pmap %p), %p (%p), %x, %d) -> %x at pc %p\n",
736			    map, &vm->vm_pmap, (void *)va, (void *)(intptr_t)trapframe->badvaddr,
737			    ftype, VM_FAULT_NORMAL, rv, (void *)(intptr_t)trapframe->pc);
738#endif
739
740			if (rv == KERN_SUCCESS) {
741				if (!usermode) {
742					return (trapframe->pc);
743				}
744				goto out;
745			}
746	nogo:
747			if (!usermode) {
748				if (td->td_pcb->pcb_onfault != NULL) {
749					pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
750					td->td_pcb->pcb_onfault = NULL;
751					return (pc);
752				}
753				goto err;
754			}
755			ucode = ftype;
756			i = ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
757			addr = trapframe->pc;
758
759			msg = "BAD_PAGE_FAULT";
760			log_bad_page_fault(msg, trapframe, type);
761
762			break;
763		}
764
765	case T_ADDR_ERR_LD + T_USER:	/* misaligned or kseg access */
766	case T_ADDR_ERR_ST + T_USER:	/* misaligned or kseg access */
767		if (trapframe->badvaddr < 0 ||
768		    trapframe->badvaddr >= VM_MAXUSER_ADDRESS) {
769			msg = "ADDRESS_SPACE_ERR";
770		} else if (allow_unaligned_acc) {
771			int mode;
772
773			if (type == (T_ADDR_ERR_LD + T_USER))
774				mode = VM_PROT_READ;
775			else
776				mode = VM_PROT_WRITE;
777
778			access_type = emulate_unaligned_access(trapframe, mode);
779			if (access_type != 0)
780				goto out;
781			msg = "ALIGNMENT_FIX_ERR";
782		} else {
783			msg = "ADDRESS_ERR";
784		}
785
786		/* FALL THROUGH */
787
788	case T_BUS_ERR_IFETCH + T_USER:	/* BERR asserted to cpu */
789	case T_BUS_ERR_LD_ST + T_USER:	/* BERR asserted to cpu */
790		ucode = 0;	/* XXX should be VM_PROT_something */
791		i = SIGBUS;
792		addr = trapframe->pc;
793		if (!msg)
794			msg = "BUS_ERR";
795		log_bad_page_fault(msg, trapframe, type);
796		break;
797
798	case T_SYSCALL + T_USER:
799		{
800			struct syscall_args sa;
801			int error;
802
803			sa.trapframe = trapframe;
804			error = syscallenter(td, &sa);
805
806#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
807			if (trp == trapdebug)
808				trapdebug[TRAPSIZE - 1].code = sa.code;
809			else
810				trp[-1].code = sa.code;
811#endif
812			trapdebug_enter(td->td_frame, -sa.code);
813
814			/*
815			 * The sync'ing of I & D caches for SYS_ptrace() is
816			 * done by procfs_domem() through procfs_rwmem()
817			 * instead of being done here under a special check
818			 * for SYS_ptrace().
819			 */
820			syscallret(td, error, &sa);
821			return (trapframe->pc);
822		}
823
824#ifdef DDB
825	case T_BREAK:
826		kdb_trap(type, 0, trapframe);
827		return (trapframe->pc);
828#endif
829
830	case T_BREAK + T_USER:
831		{
832			intptr_t va;
833			uint32_t instr;
834
835			/* compute address of break instruction */
836			va = trapframe->pc;
837			if (DELAYBRANCH(trapframe->cause))
838				va += sizeof(int);
839
840			/* read break instruction */
841			instr = fuword32((caddr_t)va);
842#if 0
843			printf("trap: %s (%d) breakpoint %x at %x: (adr %x ins %x)\n",
844			    p->p_comm, p->p_pid, instr, trapframe->pc,
845			    p->p_md.md_ss_addr, p->p_md.md_ss_instr);	/* XXX */
846#endif
847			if (td->td_md.md_ss_addr != va ||
848			    instr != MIPS_BREAK_SSTEP) {
849				i = SIGTRAP;
850				addr = trapframe->pc;
851				break;
852			}
853			/*
854			 * The restoration of the original instruction and
855			 * the clearing of the berakpoint will be done later
856			 * by the call to ptrace_clear_single_step() in
857			 * issignal() when SIGTRAP is processed.
858			 */
859			addr = trapframe->pc;
860			i = SIGTRAP;
861			break;
862		}
863
864	case T_IWATCH + T_USER:
865	case T_DWATCH + T_USER:
866		{
867			intptr_t va;
868
869			/* compute address of trapped instruction */
870			va = trapframe->pc;
871			if (DELAYBRANCH(trapframe->cause))
872				va += sizeof(int);
873			printf("watch exception @ %p\n", (void *)va);
874			i = SIGTRAP;
875			addr = va;
876			break;
877		}
878
879	case T_TRAP + T_USER:
880		{
881			intptr_t va;
882			uint32_t instr;
883			struct trapframe *locr0 = td->td_frame;
884
885			/* compute address of trap instruction */
886			va = trapframe->pc;
887			if (DELAYBRANCH(trapframe->cause))
888				va += sizeof(int);
889			/* read break instruction */
890			instr = fuword32((caddr_t)va);
891
892			if (DELAYBRANCH(trapframe->cause)) {	/* Check BD bit */
893				locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0,
894				    0);
895			} else {
896				locr0->pc += sizeof(int);
897			}
898			addr = va;
899			i = SIGEMT;	/* Stuff it with something for now */
900			break;
901		}
902
903	case T_RES_INST + T_USER:
904		{
905			InstFmt inst;
906			inst = *(InstFmt *)(intptr_t)trapframe->pc;
907			switch (inst.RType.op) {
908			case OP_SPECIAL3:
909				switch (inst.RType.func) {
910				case OP_RDHWR:
911					/* Register 29 used for TLS */
912					if (inst.RType.rd == 29) {
913						frame_regs = &(trapframe->zero);
914						frame_regs[inst.RType.rt] = (register_t)(intptr_t)td->td_md.md_tls;
915#if defined(__mips_n64) && defined(COMPAT_FREEBSD32)
916						if (SV_PROC_FLAG(td->td_proc, SV_ILP32))
917							frame_regs[inst.RType.rt] += TLS_TP_OFFSET + TLS_TCB_SIZE32;
918						else
919#endif
920						frame_regs[inst.RType.rt] += TLS_TP_OFFSET + TLS_TCB_SIZE;
921						trapframe->pc += sizeof(int);
922						goto out;
923					}
924				break;
925				}
926			break;
927			}
928
929			log_illegal_instruction("RES_INST", trapframe);
930			i = SIGILL;
931			addr = trapframe->pc;
932		}
933		break;
934	case T_C2E:
935	case T_C2E + T_USER:
936		goto err;
937		break;
938	case T_COP_UNUSABLE:
939#ifdef	CPU_CNMIPS
940		cop = (trapframe->cause & MIPS_CR_COP_ERR) >> MIPS_CR_COP_ERR_SHIFT;
941		/* Handle only COP2 exception */
942		if (cop != 2)
943			goto err;
944
945		addr = trapframe->pc;
946		/* save userland cop2 context if it has been touched */
947		if ((td->td_md.md_flags & MDTD_COP2USED) &&
948		    (td->td_md.md_cop2owner == COP2_OWNER_USERLAND)) {
949			if (td->td_md.md_ucop2)
950				octeon_cop2_save(td->td_md.md_ucop2);
951			else
952				panic("COP2 was used in user mode but md_ucop2 is NULL");
953		}
954
955		if (td->td_md.md_cop2 == NULL) {
956			td->td_md.md_cop2 = octeon_cop2_alloc_ctx();
957			if (td->td_md.md_cop2 == NULL)
958				panic("Failed to allocate COP2 context");
959			memset(td->td_md.md_cop2, 0, sizeof(*td->td_md.md_cop2));
960		}
961
962		octeon_cop2_restore(td->td_md.md_cop2);
963
964		/* Make userland re-request its context */
965		td->td_frame->sr &= ~MIPS_SR_COP_2_BIT;
966		td->td_md.md_flags |= MDTD_COP2USED;
967		td->td_md.md_cop2owner = COP2_OWNER_KERNEL;
968		/* Enable COP2, it will be disabled in cpu_switch */
969		mips_wr_status(mips_rd_status() | MIPS_SR_COP_2_BIT);
970		return (trapframe->pc);
971#else
972		goto err;
973		break;
974#endif
975
976	case T_COP_UNUSABLE + T_USER:
977		cop = (trapframe->cause & MIPS_CR_COP_ERR) >> MIPS_CR_COP_ERR_SHIFT;
978		if (cop == 1) {
979#if !defined(CPU_HAVEFPU)
980		/* FP (COP1) instruction */
981			log_illegal_instruction("COP1_UNUSABLE", trapframe);
982			i = SIGILL;
983			break;
984#else
985			addr = trapframe->pc;
986			MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame);
987			PCPU_SET(fpcurthread, td);
988			td->td_frame->sr |= MIPS_SR_COP_1_BIT;
989			td->td_md.md_flags |= MDTD_FPUSED;
990			goto out;
991#endif
992		}
993#ifdef	CPU_CNMIPS
994		else  if (cop == 2) {
995			addr = trapframe->pc;
996			if ((td->td_md.md_flags & MDTD_COP2USED) &&
997			    (td->td_md.md_cop2owner == COP2_OWNER_KERNEL)) {
998				if (td->td_md.md_cop2)
999					octeon_cop2_save(td->td_md.md_cop2);
1000				else
1001					panic("COP2 was used in kernel mode but md_cop2 is NULL");
1002			}
1003
1004			if (td->td_md.md_ucop2 == NULL) {
1005				td->td_md.md_ucop2 = octeon_cop2_alloc_ctx();
1006				if (td->td_md.md_ucop2 == NULL)
1007					panic("Failed to allocate userland COP2 context");
1008				memset(td->td_md.md_ucop2, 0, sizeof(*td->td_md.md_ucop2));
1009			}
1010
1011			octeon_cop2_restore(td->td_md.md_ucop2);
1012
1013			td->td_frame->sr |= MIPS_SR_COP_2_BIT;
1014			td->td_md.md_flags |= MDTD_COP2USED;
1015			td->td_md.md_cop2owner = COP2_OWNER_USERLAND;
1016			goto out;
1017		}
1018#endif
1019		else {
1020			log_illegal_instruction("COPn_UNUSABLE", trapframe);
1021			i = SIGILL;	/* only FPU instructions allowed */
1022			break;
1023		}
1024
1025	case T_FPE:
1026#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
1027		trapDump("fpintr");
1028#else
1029		printf("FPU Trap: PC %#jx CR %x SR %x\n",
1030		    (intmax_t)trapframe->pc, (unsigned)trapframe->cause, (unsigned)trapframe->sr);
1031		goto err;
1032#endif
1033
1034	case T_FPE + T_USER:
1035		if (!emulate_fp) {
1036			i = SIGILL;
1037			addr = trapframe->pc;
1038			break;
1039		}
1040		MipsFPTrap(trapframe->sr, trapframe->cause, trapframe->pc);
1041		goto out;
1042
1043	case T_OVFLOW + T_USER:
1044		i = SIGFPE;
1045		addr = trapframe->pc;
1046		break;
1047
1048	case T_ADDR_ERR_LD:	/* misaligned access */
1049	case T_ADDR_ERR_ST:	/* misaligned access */
1050#ifdef TRAP_DEBUG
1051		if (trap_debug) {
1052			printf("+++ ADDR_ERR: type = %d, badvaddr = %#jx\n", type,
1053			    (intmax_t)trapframe->badvaddr);
1054		}
1055#endif
1056		/* Only allow emulation on a user address */
1057		if (allow_unaligned_acc &&
1058		    ((vm_offset_t)trapframe->badvaddr < VM_MAXUSER_ADDRESS)) {
1059			int mode;
1060
1061			if (type == T_ADDR_ERR_LD)
1062				mode = VM_PROT_READ;
1063			else
1064				mode = VM_PROT_WRITE;
1065
1066			access_type = emulate_unaligned_access(trapframe, mode);
1067			if (access_type != 0)
1068				return (trapframe->pc);
1069		}
1070		/* FALLTHROUGH */
1071
1072	case T_BUS_ERR_LD_ST:	/* BERR asserted to cpu */
1073		if (td->td_pcb->pcb_onfault != NULL) {
1074			pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
1075			td->td_pcb->pcb_onfault = NULL;
1076			return (pc);
1077		}
1078
1079		/* FALLTHROUGH */
1080
1081	default:
1082err:
1083
1084#if !defined(SMP) && defined(DEBUG)
1085		stacktrace(!usermode ? trapframe : td->td_frame);
1086		trapDump("trap");
1087#endif
1088#ifdef SMP
1089		printf("cpu:%d-", PCPU_GET(cpuid));
1090#endif
1091		printf("Trap cause = %d (%s - ", type,
1092		    trap_type[type & (~T_USER)]);
1093
1094		if (type & T_USER)
1095			printf("user mode)\n");
1096		else
1097			printf("kernel mode)\n");
1098
1099#ifdef TRAP_DEBUG
1100		if (trap_debug)
1101			printf("badvaddr = %#jx, pc = %#jx, ra = %#jx, sr = %#jxx\n",
1102			       (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
1103			       (intmax_t)trapframe->sr);
1104#endif
1105
1106#ifdef KDB
1107		if (debugger_on_panic || kdb_active) {
1108			kdb_trap(type, 0, trapframe);
1109		}
1110#endif
1111		panic("trap");
1112	}
1113	td->td_frame->pc = trapframe->pc;
1114	td->td_frame->cause = trapframe->cause;
1115	td->td_frame->badvaddr = trapframe->badvaddr;
1116	ksiginfo_init_trap(&ksi);
1117	ksi.ksi_signo = i;
1118	ksi.ksi_code = ucode;
1119	ksi.ksi_addr = (void *)addr;
1120	ksi.ksi_trapno = type;
1121	trapsignal(td, &ksi);
1122out:
1123
1124	/*
1125	 * Note: we should only get here if returning to user mode.
1126	 */
1127	userret(td, trapframe);
1128	return (trapframe->pc);
1129}
1130
1131#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
1132void
1133trapDump(char *msg)
1134{
1135	register_t s;
1136	int i;
1137
1138	s = intr_disable();
1139	printf("trapDump(%s)\n", msg);
1140	for (i = 0; i < TRAPSIZE; i++) {
1141		if (trp == trapdebug) {
1142			trp = &trapdebug[TRAPSIZE - 1];
1143		} else {
1144			trp--;
1145		}
1146
1147		if (trp->cause == 0)
1148			break;
1149
1150		printf("%s: ADR %jx PC %jx CR %jx SR %jx\n",
1151		    trap_type[(trp->cause & MIPS_CR_EXC_CODE) >>
1152			MIPS_CR_EXC_CODE_SHIFT],
1153		    (intmax_t)trp->vadr, (intmax_t)trp->pc,
1154		    (intmax_t)trp->cause, (intmax_t)trp->status);
1155
1156		printf("   RA %jx SP %jx code %d\n", (intmax_t)trp->ra,
1157		    (intmax_t)trp->sp, (int)trp->code);
1158	}
1159	intr_restore(s);
1160}
1161#endif
1162
1163
1164/*
1165 * Return the resulting PC as if the branch was executed.
1166 */
1167uintptr_t
1168MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR,
1169    uintptr_t instptr)
1170{
1171	InstFmt inst;
1172	register_t *regsPtr = (register_t *) framePtr;
1173	uintptr_t retAddr = 0;
1174	int condition;
1175
1176#define	GetBranchDest(InstPtr, inst) \
1177	(InstPtr + 4 + ((short)inst.IType.imm << 2))
1178
1179
1180	if (instptr) {
1181		if (instptr < MIPS_KSEG0_START)
1182			inst.word = fuword32((void *)instptr);
1183		else
1184			inst = *(InstFmt *) instptr;
1185	} else {
1186		if ((vm_offset_t)instPC < MIPS_KSEG0_START)
1187			inst.word = fuword32((void *)instPC);
1188		else
1189			inst = *(InstFmt *) instPC;
1190	}
1191
1192	switch ((int)inst.JType.op) {
1193	case OP_SPECIAL:
1194		switch ((int)inst.RType.func) {
1195		case OP_JR:
1196		case OP_JALR:
1197			retAddr = regsPtr[inst.RType.rs];
1198			break;
1199
1200		default:
1201			retAddr = instPC + 4;
1202			break;
1203		}
1204		break;
1205
1206	case OP_BCOND:
1207		switch ((int)inst.IType.rt) {
1208		case OP_BLTZ:
1209		case OP_BLTZL:
1210		case OP_BLTZAL:
1211		case OP_BLTZALL:
1212			if ((int)(regsPtr[inst.RType.rs]) < 0)
1213				retAddr = GetBranchDest(instPC, inst);
1214			else
1215				retAddr = instPC + 8;
1216			break;
1217
1218		case OP_BGEZ:
1219		case OP_BGEZL:
1220		case OP_BGEZAL:
1221		case OP_BGEZALL:
1222			if ((int)(regsPtr[inst.RType.rs]) >= 0)
1223				retAddr = GetBranchDest(instPC, inst);
1224			else
1225				retAddr = instPC + 8;
1226			break;
1227
1228		case OP_TGEI:
1229		case OP_TGEIU:
1230		case OP_TLTI:
1231		case OP_TLTIU:
1232		case OP_TEQI:
1233		case OP_TNEI:
1234			retAddr = instPC + 4;	/* Like syscall... */
1235			break;
1236
1237		default:
1238			panic("MipsEmulateBranch: Bad branch cond");
1239		}
1240		break;
1241
1242	case OP_J:
1243	case OP_JAL:
1244		retAddr = (inst.JType.target << 2) |
1245		    ((unsigned)(instPC + 4) & 0xF0000000);
1246		break;
1247
1248	case OP_BEQ:
1249	case OP_BEQL:
1250		if (regsPtr[inst.RType.rs] == regsPtr[inst.RType.rt])
1251			retAddr = GetBranchDest(instPC, inst);
1252		else
1253			retAddr = instPC + 8;
1254		break;
1255
1256	case OP_BNE:
1257	case OP_BNEL:
1258		if (regsPtr[inst.RType.rs] != regsPtr[inst.RType.rt])
1259			retAddr = GetBranchDest(instPC, inst);
1260		else
1261			retAddr = instPC + 8;
1262		break;
1263
1264	case OP_BLEZ:
1265	case OP_BLEZL:
1266		if ((int)(regsPtr[inst.RType.rs]) <= 0)
1267			retAddr = GetBranchDest(instPC, inst);
1268		else
1269			retAddr = instPC + 8;
1270		break;
1271
1272	case OP_BGTZ:
1273	case OP_BGTZL:
1274		if ((int)(regsPtr[inst.RType.rs]) > 0)
1275			retAddr = GetBranchDest(instPC, inst);
1276		else
1277			retAddr = instPC + 8;
1278		break;
1279
1280	case OP_COP1:
1281		switch (inst.RType.rs) {
1282		case OP_BCx:
1283		case OP_BCy:
1284			if ((inst.RType.rt & COPz_BC_TF_MASK) == COPz_BC_TRUE)
1285				condition = fpcCSR & MIPS_FPU_COND_BIT;
1286			else
1287				condition = !(fpcCSR & MIPS_FPU_COND_BIT);
1288			if (condition)
1289				retAddr = GetBranchDest(instPC, inst);
1290			else
1291				retAddr = instPC + 8;
1292			break;
1293
1294		default:
1295			retAddr = instPC + 4;
1296		}
1297		break;
1298
1299	default:
1300		retAddr = instPC + 4;
1301	}
1302	return (retAddr);
1303}
1304
1305
1306#if defined(DDB) || defined(DEBUG)
1307/*
1308 * Print a stack backtrace.
1309 */
1310void
1311stacktrace(struct trapframe *regs)
1312{
1313	stacktrace_subr(regs->pc, regs->sp, regs->ra, printf);
1314}
1315#endif
1316
1317static void
1318log_frame_dump(struct trapframe *frame)
1319{
1320	log(LOG_ERR, "Trapframe Register Dump:\n");
1321	log(LOG_ERR, "\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1322	    (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1323
1324	log(LOG_ERR, "\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1325	    (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1326
1327#if defined(__mips_n32) || defined(__mips_n64)
1328	log(LOG_ERR, "\ta4: %#jx\ta5: %#jx\ta6: %#jx\ta6: %#jx\n",
1329	    (intmax_t)frame->a4, (intmax_t)frame->a5, (intmax_t)frame->a6, (intmax_t)frame->a7);
1330
1331	log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1332	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1333#else
1334	log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1335	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1336
1337	log(LOG_ERR, "\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1338	    (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1339#endif
1340	log(LOG_ERR, "\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1341	    (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1342
1343	log(LOG_ERR, "\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1344	    (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1345
1346	log(LOG_ERR, "\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1347	    (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1348
1349	log(LOG_ERR, "\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1350	    (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1351
1352	log(LOG_ERR, "\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1353	    (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1354
1355#ifdef IC_REG
1356	log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
1357	    (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
1358#else
1359	log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\n",
1360	    (intmax_t)frame->cause, (intmax_t)frame->pc);
1361#endif
1362}
1363
1364#ifdef TRAP_DEBUG
1365static void
1366trap_frame_dump(struct trapframe *frame)
1367{
1368	printf("Trapframe Register Dump:\n");
1369	printf("\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1370	    (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1371
1372	printf("\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1373	    (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1374#if defined(__mips_n32) || defined(__mips_n64)
1375	printf("\ta4: %#jx\ta5: %#jx\ta6: %#jx\ta7: %#jx\n",
1376	    (intmax_t)frame->a4, (intmax_t)frame->a5, (intmax_t)frame->a6, (intmax_t)frame->a7);
1377
1378	printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1379	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1380#else
1381	printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1382	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1383
1384	printf("\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1385	    (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1386#endif
1387	printf("\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1388	    (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1389
1390	printf("\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1391	    (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1392
1393	printf("\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1394	    (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1395
1396	printf("\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1397	    (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1398
1399	printf("\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1400	    (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1401
1402#ifdef IC_REG
1403	printf("\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
1404	    (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
1405#else
1406	printf("\tcause: %#jx\tpc: %#jx\n",
1407	    (intmax_t)frame->cause, (intmax_t)frame->pc);
1408#endif
1409}
1410
1411#endif
1412
1413
1414static void
1415get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp)
1416{
1417	pt_entry_t *ptep;
1418	pd_entry_t *pdep;
1419	struct proc *p = curproc;
1420
1421	pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[(va >> SEGSHIFT) & (NPDEPG - 1)]));
1422	if (*pdep)
1423		ptep = pmap_pte(&p->p_vmspace->vm_pmap, va);
1424	else
1425		ptep = (pt_entry_t *)0;
1426
1427	*pdepp = pdep;
1428	*ptepp = ptep;
1429}
1430
1431static void
1432log_illegal_instruction(const char *msg, struct trapframe *frame)
1433{
1434	pt_entry_t *ptep;
1435	pd_entry_t *pdep;
1436	unsigned int *addr;
1437	struct thread *td;
1438	struct proc *p;
1439	register_t pc;
1440
1441	td = curthread;
1442	p = td->td_proc;
1443
1444#ifdef SMP
1445	printf("cpuid = %d\n", PCPU_GET(cpuid));
1446#endif
1447	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1448	log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx ra %#jx\n",
1449	    msg, p->p_pid, (long)td->td_tid, p->p_comm,
1450	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1451	    (intmax_t)pc,
1452	    (intmax_t)frame->ra);
1453
1454	/* log registers in trap frame */
1455	log_frame_dump(frame);
1456
1457	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1458
1459	/*
1460	 * Dump a few words around faulting instruction, if the addres is
1461	 * valid.
1462	 */
1463	if (!(pc & 3) &&
1464	    useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1465		/* dump page table entry for faulting instruction */
1466		log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n",
1467		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1468
1469		addr = (unsigned int *)(intptr_t)pc;
1470		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1471		    addr);
1472		log(LOG_ERR, "%08x %08x %08x %08x\n",
1473		    addr[0], addr[1], addr[2], addr[3]);
1474	} else {
1475		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1476		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1477	}
1478}
1479
1480static void
1481log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
1482{
1483	pt_entry_t *ptep;
1484	pd_entry_t *pdep;
1485	unsigned int *addr;
1486	struct thread *td;
1487	struct proc *p;
1488	char *read_or_write;
1489	register_t pc;
1490
1491	trap_type &= ~T_USER;
1492
1493	td = curthread;
1494	p = td->td_proc;
1495
1496#ifdef SMP
1497	printf("cpuid = %d\n", PCPU_GET(cpuid));
1498#endif
1499	switch (trap_type) {
1500	case T_TLB_MOD:
1501	case T_TLB_ST_MISS:
1502	case T_ADDR_ERR_ST:
1503		read_or_write = "write";
1504		break;
1505	case T_TLB_LD_MISS:
1506	case T_ADDR_ERR_LD:
1507	case T_BUS_ERR_IFETCH:
1508		read_or_write = "read";
1509		break;
1510	default:
1511		read_or_write = "unknown";
1512	}
1513
1514	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1515	log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx got a %s fault "
1516	    "(type %#x) at %#jx\n",
1517	    msg, p->p_pid, (long)td->td_tid, p->p_comm,
1518	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1519	    (intmax_t)pc,
1520	    read_or_write,
1521	    trap_type,
1522	    (intmax_t)frame->badvaddr);
1523
1524	/* log registers in trap frame */
1525	log_frame_dump(frame);
1526
1527	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1528
1529	/*
1530	 * Dump a few words around faulting instruction, if the addres is
1531	 * valid.
1532	 */
1533	if (!(pc & 3) && (pc != frame->badvaddr) &&
1534	    (trap_type != T_BUS_ERR_IFETCH) &&
1535	    useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1536		/* dump page table entry for faulting instruction */
1537		log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n",
1538		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1539
1540		addr = (unsigned int *)(intptr_t)pc;
1541		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1542		    addr);
1543		log(LOG_ERR, "%08x %08x %08x %08x\n",
1544		    addr[0], addr[1], addr[2], addr[3]);
1545	} else {
1546		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1547		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1548	}
1549
1550	get_mapping_info((vm_offset_t)frame->badvaddr, &pdep, &ptep);
1551	log(LOG_ERR, "Page table info for bad address %#jx: pde = %p, pte = %#jx\n",
1552	    (intmax_t)frame->badvaddr, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1553}
1554
1555
1556/*
1557 * Unaligned load/store emulation
1558 */
1559static int
1560mips_unaligned_load_store(struct trapframe *frame, int mode, register_t addr, register_t pc)
1561{
1562	register_t *reg = (register_t *) frame;
1563	u_int32_t inst = *((u_int32_t *)(intptr_t)pc);
1564	register_t value_msb, value;
1565	unsigned size;
1566
1567	/*
1568	 * ADDR_ERR faults have higher priority than TLB
1569	 * Miss faults.  Therefore, it is necessary to
1570	 * verify that the faulting address is a valid
1571	 * virtual address within the process' address space
1572	 * before trying to emulate the unaligned access.
1573	 */
1574	switch (MIPS_INST_OPCODE(inst)) {
1575	case OP_LHU: case OP_LH:
1576	case OP_SH:
1577		size = 2;
1578		break;
1579	case OP_LWU: case OP_LW:
1580	case OP_SW:
1581		size = 4;
1582		break;
1583	case OP_LD:
1584	case OP_SD:
1585		size = 8;
1586		break;
1587	default:
1588		printf("%s: unhandled opcode in address error: %#x\n", __func__, MIPS_INST_OPCODE(inst));
1589		return (0);
1590	}
1591
1592	if (!useracc((void *)((vm_offset_t)addr & ~(size - 1)), size * 2, mode))
1593		return (0);
1594
1595	/*
1596	 * XXX
1597	 * Handle LL/SC LLD/SCD.
1598	 */
1599	switch (MIPS_INST_OPCODE(inst)) {
1600	case OP_LHU:
1601		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1602		lbu_macro(value_msb, addr);
1603		addr += 1;
1604		lbu_macro(value, addr);
1605		value |= value_msb << 8;
1606		reg[MIPS_INST_RT(inst)] = value;
1607		return (MIPS_LHU_ACCESS);
1608
1609	case OP_LH:
1610		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1611		lb_macro(value_msb, addr);
1612		addr += 1;
1613		lbu_macro(value, addr);
1614		value |= value_msb << 8;
1615		reg[MIPS_INST_RT(inst)] = value;
1616		return (MIPS_LH_ACCESS);
1617
1618	case OP_LWU:
1619		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1620		lwl_macro(value, addr);
1621		addr += 3;
1622		lwr_macro(value, addr);
1623		value &= 0xffffffff;
1624		reg[MIPS_INST_RT(inst)] = value;
1625		return (MIPS_LWU_ACCESS);
1626
1627	case OP_LW:
1628		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1629		lwl_macro(value, addr);
1630		addr += 3;
1631		lwr_macro(value, addr);
1632		reg[MIPS_INST_RT(inst)] = value;
1633		return (MIPS_LW_ACCESS);
1634
1635#if defined(__mips_n32) || defined(__mips_n64)
1636	case OP_LD:
1637		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1638		ldl_macro(value, addr);
1639		addr += 7;
1640		ldr_macro(value, addr);
1641		reg[MIPS_INST_RT(inst)] = value;
1642		return (MIPS_LD_ACCESS);
1643#endif
1644
1645	case OP_SH:
1646		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1647		value = reg[MIPS_INST_RT(inst)];
1648		value_msb = value >> 8;
1649		sb_macro(value_msb, addr);
1650		addr += 1;
1651		sb_macro(value, addr);
1652		return (MIPS_SH_ACCESS);
1653
1654	case OP_SW:
1655		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1656		value = reg[MIPS_INST_RT(inst)];
1657		swl_macro(value, addr);
1658		addr += 3;
1659		swr_macro(value, addr);
1660		return (MIPS_SW_ACCESS);
1661
1662#if defined(__mips_n32) || defined(__mips_n64)
1663	case OP_SD:
1664		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1665		value = reg[MIPS_INST_RT(inst)];
1666		sdl_macro(value, addr);
1667		addr += 7;
1668		sdr_macro(value, addr);
1669		return (MIPS_SD_ACCESS);
1670#endif
1671	}
1672	panic("%s: should not be reached.", __func__);
1673}
1674
1675
1676static int
1677emulate_unaligned_access(struct trapframe *frame, int mode)
1678{
1679	register_t pc;
1680	int access_type = 0;
1681
1682	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1683
1684	/*
1685	 * Fall through if it's instruction fetch exception
1686	 */
1687	if (!((pc & 3) || (pc == frame->badvaddr))) {
1688
1689		/*
1690		 * Handle unaligned load and store
1691		 */
1692
1693		/*
1694		 * Return access type if the instruction was emulated.
1695		 * Otherwise restore pc and fall through.
1696		 */
1697		access_type = mips_unaligned_load_store(frame,
1698		    mode, frame->badvaddr, pc);
1699
1700		if (access_type) {
1701			if (DELAYBRANCH(frame->cause))
1702				frame->pc = MipsEmulateBranch(frame, frame->pc,
1703				    0, 0);
1704			else
1705				frame->pc += 4;
1706
1707			log(LOG_INFO, "Unaligned %s: pc=%#jx, badvaddr=%#jx\n",
1708			    access_name[access_type - 1], (intmax_t)pc,
1709			    (intmax_t)frame->badvaddr);
1710		}
1711	}
1712	return access_type;
1713}
1714