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