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