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