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