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