trap.c revision 335556
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 335556 2018-06-22 10:49:21Z avg $");
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				addr = trapframe->pc;
856				break;
857			}
858			/*
859			 * The restoration of the original instruction and
860			 * the clearing of the breakpoint will be done later
861			 * by the call to ptrace_clear_single_step() in
862			 * issignal() when SIGTRAP is processed.
863			 */
864			addr = trapframe->pc;
865			i = SIGTRAP;
866			break;
867		}
868
869	case T_IWATCH + T_USER:
870	case T_DWATCH + T_USER:
871		{
872			intptr_t va;
873
874			/* compute address of trapped instruction */
875			va = trapframe->pc;
876			if (DELAYBRANCH(trapframe->cause))
877				va += sizeof(int);
878			printf("watch exception @ %p\n", (void *)va);
879			i = SIGTRAP;
880			addr = va;
881			break;
882		}
883
884	case T_TRAP + T_USER:
885		{
886			intptr_t va;
887			uint32_t instr;
888			struct trapframe *locr0 = td->td_frame;
889
890			/* compute address of trap instruction */
891			va = trapframe->pc;
892			if (DELAYBRANCH(trapframe->cause))
893				va += sizeof(int);
894			/* read break instruction */
895			instr = fuword32((caddr_t)va);
896
897			if (DELAYBRANCH(trapframe->cause)) {	/* Check BD bit */
898				locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0,
899				    0);
900			} else {
901				locr0->pc += sizeof(int);
902			}
903			addr = va;
904			i = SIGEMT;	/* Stuff it with something for now */
905			break;
906		}
907
908	case T_RES_INST + T_USER:
909		{
910			InstFmt inst;
911			inst = *(InstFmt *)(intptr_t)trapframe->pc;
912			switch (inst.RType.op) {
913			case OP_SPECIAL3:
914				switch (inst.RType.func) {
915				case OP_RDHWR:
916					/* Register 29 used for TLS */
917					if (inst.RType.rd == 29) {
918						frame_regs = &(trapframe->zero);
919						frame_regs[inst.RType.rt] = (register_t)(intptr_t)td->td_md.md_tls;
920#if defined(__mips_n64) && defined(COMPAT_FREEBSD32)
921						if (SV_PROC_FLAG(td->td_proc, SV_ILP32))
922							frame_regs[inst.RType.rt] += TLS_TP_OFFSET + TLS_TCB_SIZE32;
923						else
924#endif
925						frame_regs[inst.RType.rt] += TLS_TP_OFFSET + TLS_TCB_SIZE;
926						trapframe->pc += sizeof(int);
927						goto out;
928					}
929				break;
930				}
931			break;
932			}
933
934			log_illegal_instruction("RES_INST", trapframe);
935			i = SIGILL;
936			addr = trapframe->pc;
937		}
938		break;
939	case T_C2E:
940	case T_C2E + T_USER:
941		goto err;
942		break;
943	case T_COP_UNUSABLE:
944#ifdef	CPU_CNMIPS
945		cop = (trapframe->cause & MIPS_CR_COP_ERR) >> MIPS_CR_COP_ERR_SHIFT;
946		/* Handle only COP2 exception */
947		if (cop != 2)
948			goto err;
949
950		addr = trapframe->pc;
951		/* save userland cop2 context if it has been touched */
952		if ((td->td_md.md_flags & MDTD_COP2USED) &&
953		    (td->td_md.md_cop2owner == COP2_OWNER_USERLAND)) {
954			if (td->td_md.md_ucop2)
955				octeon_cop2_save(td->td_md.md_ucop2);
956			else
957				panic("COP2 was used in user mode but md_ucop2 is NULL");
958		}
959
960		if (td->td_md.md_cop2 == NULL) {
961			td->td_md.md_cop2 = octeon_cop2_alloc_ctx();
962			if (td->td_md.md_cop2 == NULL)
963				panic("Failed to allocate COP2 context");
964			memset(td->td_md.md_cop2, 0, sizeof(*td->td_md.md_cop2));
965		}
966
967		octeon_cop2_restore(td->td_md.md_cop2);
968
969		/* Make userland re-request its context */
970		td->td_frame->sr &= ~MIPS_SR_COP_2_BIT;
971		td->td_md.md_flags |= MDTD_COP2USED;
972		td->td_md.md_cop2owner = COP2_OWNER_KERNEL;
973		/* Enable COP2, it will be disabled in cpu_switch */
974		mips_wr_status(mips_rd_status() | MIPS_SR_COP_2_BIT);
975		return (trapframe->pc);
976#else
977		goto err;
978		break;
979#endif
980
981	case T_COP_UNUSABLE + T_USER:
982		cop = (trapframe->cause & MIPS_CR_COP_ERR) >> MIPS_CR_COP_ERR_SHIFT;
983		if (cop == 1) {
984#if !defined(CPU_HAVEFPU)
985		/* FP (COP1) instruction */
986			log_illegal_instruction("COP1_UNUSABLE", trapframe);
987			i = SIGILL;
988			break;
989#else
990			addr = trapframe->pc;
991			MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame);
992			PCPU_SET(fpcurthread, td);
993			td->td_frame->sr |= MIPS_SR_COP_1_BIT;
994			td->td_md.md_flags |= MDTD_FPUSED;
995			goto out;
996#endif
997		}
998#ifdef	CPU_CNMIPS
999		else  if (cop == 2) {
1000			addr = trapframe->pc;
1001			if ((td->td_md.md_flags & MDTD_COP2USED) &&
1002			    (td->td_md.md_cop2owner == COP2_OWNER_KERNEL)) {
1003				if (td->td_md.md_cop2)
1004					octeon_cop2_save(td->td_md.md_cop2);
1005				else
1006					panic("COP2 was used in kernel mode but md_cop2 is NULL");
1007			}
1008
1009			if (td->td_md.md_ucop2 == NULL) {
1010				td->td_md.md_ucop2 = octeon_cop2_alloc_ctx();
1011				if (td->td_md.md_ucop2 == NULL)
1012					panic("Failed to allocate userland COP2 context");
1013				memset(td->td_md.md_ucop2, 0, sizeof(*td->td_md.md_ucop2));
1014			}
1015
1016			octeon_cop2_restore(td->td_md.md_ucop2);
1017
1018			td->td_frame->sr |= MIPS_SR_COP_2_BIT;
1019			td->td_md.md_flags |= MDTD_COP2USED;
1020			td->td_md.md_cop2owner = COP2_OWNER_USERLAND;
1021			goto out;
1022		}
1023#endif
1024		else {
1025			log_illegal_instruction("COPn_UNUSABLE", trapframe);
1026			i = SIGILL;	/* only FPU instructions allowed */
1027			break;
1028		}
1029
1030	case T_FPE:
1031#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
1032		trapDump("fpintr");
1033#else
1034		printf("FPU Trap: PC %#jx CR %x SR %x\n",
1035		    (intmax_t)trapframe->pc, (unsigned)trapframe->cause, (unsigned)trapframe->sr);
1036		goto err;
1037#endif
1038
1039	case T_FPE + T_USER:
1040		if (!emulate_fp) {
1041			i = SIGILL;
1042			addr = trapframe->pc;
1043			break;
1044		}
1045		MipsFPTrap(trapframe->sr, trapframe->cause, trapframe->pc);
1046		goto out;
1047
1048	case T_OVFLOW + T_USER:
1049		i = SIGFPE;
1050		addr = trapframe->pc;
1051		break;
1052
1053	case T_ADDR_ERR_LD:	/* misaligned access */
1054	case T_ADDR_ERR_ST:	/* misaligned access */
1055#ifdef TRAP_DEBUG
1056		if (trap_debug) {
1057			printf("+++ ADDR_ERR: type = %d, badvaddr = %#jx\n", type,
1058			    (intmax_t)trapframe->badvaddr);
1059		}
1060#endif
1061		/* Only allow emulation on a user address */
1062		if (allow_unaligned_acc &&
1063		    ((vm_offset_t)trapframe->badvaddr < VM_MAXUSER_ADDRESS)) {
1064			int mode;
1065
1066			if (type == T_ADDR_ERR_LD)
1067				mode = VM_PROT_READ;
1068			else
1069				mode = VM_PROT_WRITE;
1070
1071			access_type = emulate_unaligned_access(trapframe, mode);
1072			if (access_type != 0)
1073				return (trapframe->pc);
1074		}
1075		/* FALLTHROUGH */
1076
1077	case T_BUS_ERR_LD_ST:	/* BERR asserted to cpu */
1078		if (td->td_pcb->pcb_onfault != NULL) {
1079			pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
1080			td->td_pcb->pcb_onfault = NULL;
1081			return (pc);
1082		}
1083
1084		/* FALLTHROUGH */
1085
1086	default:
1087err:
1088
1089#if !defined(SMP) && defined(DEBUG)
1090		stacktrace(!usermode ? trapframe : td->td_frame);
1091		trapDump("trap");
1092#endif
1093#ifdef SMP
1094		printf("cpu:%d-", PCPU_GET(cpuid));
1095#endif
1096		printf("Trap cause = %d (%s - ", type,
1097		    trap_type[type & (~T_USER)]);
1098
1099		if (type & T_USER)
1100			printf("user mode)\n");
1101		else
1102			printf("kernel mode)\n");
1103
1104#ifdef TRAP_DEBUG
1105		if (trap_debug)
1106			printf("badvaddr = %#jx, pc = %#jx, ra = %#jx, sr = %#jxx\n",
1107			       (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
1108			       (intmax_t)trapframe->sr);
1109#endif
1110
1111#ifdef KDB
1112		if (debugger_on_panic) {
1113			kdb_why = KDB_WHY_TRAP;
1114			kdb_trap(type, 0, trapframe);
1115			kdb_why = KDB_WHY_UNSET;
1116		}
1117#endif
1118		panic("trap");
1119	}
1120	td->td_frame->pc = trapframe->pc;
1121	td->td_frame->cause = trapframe->cause;
1122	td->td_frame->badvaddr = trapframe->badvaddr;
1123	ksiginfo_init_trap(&ksi);
1124	ksi.ksi_signo = i;
1125	ksi.ksi_code = ucode;
1126	ksi.ksi_addr = (void *)addr;
1127	ksi.ksi_trapno = type;
1128	trapsignal(td, &ksi);
1129out:
1130
1131	/*
1132	 * Note: we should only get here if returning to user mode.
1133	 */
1134	userret(td, trapframe);
1135	return (trapframe->pc);
1136}
1137
1138#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
1139void
1140trapDump(char *msg)
1141{
1142	register_t s;
1143	int i;
1144
1145	s = intr_disable();
1146	printf("trapDump(%s)\n", msg);
1147	for (i = 0; i < TRAPSIZE; i++) {
1148		if (trp == trapdebug) {
1149			trp = &trapdebug[TRAPSIZE - 1];
1150		} else {
1151			trp--;
1152		}
1153
1154		if (trp->cause == 0)
1155			break;
1156
1157		printf("%s: ADR %jx PC %jx CR %jx SR %jx\n",
1158		    trap_type[(trp->cause & MIPS_CR_EXC_CODE) >>
1159			MIPS_CR_EXC_CODE_SHIFT],
1160		    (intmax_t)trp->vadr, (intmax_t)trp->pc,
1161		    (intmax_t)trp->cause, (intmax_t)trp->status);
1162
1163		printf("   RA %jx SP %jx code %d\n", (intmax_t)trp->ra,
1164		    (intmax_t)trp->sp, (int)trp->code);
1165	}
1166	intr_restore(s);
1167}
1168#endif
1169
1170
1171/*
1172 * Return the resulting PC as if the branch was executed.
1173 */
1174uintptr_t
1175MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR,
1176    uintptr_t instptr)
1177{
1178	InstFmt inst;
1179	register_t *regsPtr = (register_t *) framePtr;
1180	uintptr_t retAddr = 0;
1181	int condition;
1182
1183#define	GetBranchDest(InstPtr, inst) \
1184	(InstPtr + 4 + ((short)inst.IType.imm << 2))
1185
1186
1187	if (instptr) {
1188		if (instptr < MIPS_KSEG0_START)
1189			inst.word = fuword32((void *)instptr);
1190		else
1191			inst = *(InstFmt *) instptr;
1192	} else {
1193		if ((vm_offset_t)instPC < MIPS_KSEG0_START)
1194			inst.word = fuword32((void *)instPC);
1195		else
1196			inst = *(InstFmt *) instPC;
1197	}
1198
1199	switch ((int)inst.JType.op) {
1200	case OP_SPECIAL:
1201		switch ((int)inst.RType.func) {
1202		case OP_JR:
1203		case OP_JALR:
1204			retAddr = regsPtr[inst.RType.rs];
1205			break;
1206
1207		default:
1208			retAddr = instPC + 4;
1209			break;
1210		}
1211		break;
1212
1213	case OP_BCOND:
1214		switch ((int)inst.IType.rt) {
1215		case OP_BLTZ:
1216		case OP_BLTZL:
1217		case OP_BLTZAL:
1218		case OP_BLTZALL:
1219			if ((int)(regsPtr[inst.RType.rs]) < 0)
1220				retAddr = GetBranchDest(instPC, inst);
1221			else
1222				retAddr = instPC + 8;
1223			break;
1224
1225		case OP_BGEZ:
1226		case OP_BGEZL:
1227		case OP_BGEZAL:
1228		case OP_BGEZALL:
1229			if ((int)(regsPtr[inst.RType.rs]) >= 0)
1230				retAddr = GetBranchDest(instPC, inst);
1231			else
1232				retAddr = instPC + 8;
1233			break;
1234
1235		case OP_TGEI:
1236		case OP_TGEIU:
1237		case OP_TLTI:
1238		case OP_TLTIU:
1239		case OP_TEQI:
1240		case OP_TNEI:
1241			retAddr = instPC + 4;	/* Like syscall... */
1242			break;
1243
1244		default:
1245			panic("MipsEmulateBranch: Bad branch cond");
1246		}
1247		break;
1248
1249	case OP_J:
1250	case OP_JAL:
1251		retAddr = (inst.JType.target << 2) |
1252		    ((unsigned)(instPC + 4) & 0xF0000000);
1253		break;
1254
1255	case OP_BEQ:
1256	case OP_BEQL:
1257		if (regsPtr[inst.RType.rs] == regsPtr[inst.RType.rt])
1258			retAddr = GetBranchDest(instPC, inst);
1259		else
1260			retAddr = instPC + 8;
1261		break;
1262
1263	case OP_BNE:
1264	case OP_BNEL:
1265		if (regsPtr[inst.RType.rs] != regsPtr[inst.RType.rt])
1266			retAddr = GetBranchDest(instPC, inst);
1267		else
1268			retAddr = instPC + 8;
1269		break;
1270
1271	case OP_BLEZ:
1272	case OP_BLEZL:
1273		if ((int)(regsPtr[inst.RType.rs]) <= 0)
1274			retAddr = GetBranchDest(instPC, inst);
1275		else
1276			retAddr = instPC + 8;
1277		break;
1278
1279	case OP_BGTZ:
1280	case OP_BGTZL:
1281		if ((int)(regsPtr[inst.RType.rs]) > 0)
1282			retAddr = GetBranchDest(instPC, inst);
1283		else
1284			retAddr = instPC + 8;
1285		break;
1286
1287	case OP_COP1:
1288		switch (inst.RType.rs) {
1289		case OP_BCx:
1290		case OP_BCy:
1291			if ((inst.RType.rt & COPz_BC_TF_MASK) == COPz_BC_TRUE)
1292				condition = fpcCSR & MIPS_FPU_COND_BIT;
1293			else
1294				condition = !(fpcCSR & MIPS_FPU_COND_BIT);
1295			if (condition)
1296				retAddr = GetBranchDest(instPC, inst);
1297			else
1298				retAddr = instPC + 8;
1299			break;
1300
1301		default:
1302			retAddr = instPC + 4;
1303		}
1304		break;
1305
1306	default:
1307		retAddr = instPC + 4;
1308	}
1309	return (retAddr);
1310}
1311
1312
1313#if defined(DDB) || defined(DEBUG)
1314/*
1315 * Print a stack backtrace.
1316 */
1317void
1318stacktrace(struct trapframe *regs)
1319{
1320	stacktrace_subr(regs->pc, regs->sp, regs->ra, printf);
1321}
1322#endif
1323
1324static void
1325log_frame_dump(struct trapframe *frame)
1326{
1327	log(LOG_ERR, "Trapframe Register Dump:\n");
1328	log(LOG_ERR, "\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1329	    (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1330
1331	log(LOG_ERR, "\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1332	    (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1333
1334#if defined(__mips_n32) || defined(__mips_n64)
1335	log(LOG_ERR, "\ta4: %#jx\ta5: %#jx\ta6: %#jx\ta6: %#jx\n",
1336	    (intmax_t)frame->a4, (intmax_t)frame->a5, (intmax_t)frame->a6, (intmax_t)frame->a7);
1337
1338	log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1339	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1340#else
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
1344	log(LOG_ERR, "\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1345	    (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1346#endif
1347	log(LOG_ERR, "\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1348	    (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1349
1350	log(LOG_ERR, "\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1351	    (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1352
1353	log(LOG_ERR, "\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1354	    (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1355
1356	log(LOG_ERR, "\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1357	    (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1358
1359	log(LOG_ERR, "\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1360	    (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1361
1362#ifdef IC_REG
1363	log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
1364	    (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
1365#else
1366	log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\n",
1367	    (intmax_t)frame->cause, (intmax_t)frame->pc);
1368#endif
1369}
1370
1371#ifdef TRAP_DEBUG
1372static void
1373trap_frame_dump(struct trapframe *frame)
1374{
1375	printf("Trapframe Register Dump:\n");
1376	printf("\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1377	    (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1378
1379	printf("\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1380	    (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1381#if defined(__mips_n32) || defined(__mips_n64)
1382	printf("\ta4: %#jx\ta5: %#jx\ta6: %#jx\ta7: %#jx\n",
1383	    (intmax_t)frame->a4, (intmax_t)frame->a5, (intmax_t)frame->a6, (intmax_t)frame->a7);
1384
1385	printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1386	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1387#else
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
1391	printf("\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1392	    (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1393#endif
1394	printf("\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1395	    (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1396
1397	printf("\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1398	    (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1399
1400	printf("\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1401	    (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1402
1403	printf("\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1404	    (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1405
1406	printf("\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1407	    (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1408
1409#ifdef IC_REG
1410	printf("\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
1411	    (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
1412#else
1413	printf("\tcause: %#jx\tpc: %#jx\n",
1414	    (intmax_t)frame->cause, (intmax_t)frame->pc);
1415#endif
1416}
1417
1418#endif
1419
1420
1421static void
1422get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp)
1423{
1424	pt_entry_t *ptep;
1425	pd_entry_t *pdep;
1426	struct proc *p = curproc;
1427
1428	pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[(va >> SEGSHIFT) & (NPDEPG - 1)]));
1429	if (*pdep)
1430		ptep = pmap_pte(&p->p_vmspace->vm_pmap, va);
1431	else
1432		ptep = (pt_entry_t *)0;
1433
1434	*pdepp = pdep;
1435	*ptepp = ptep;
1436}
1437
1438static void
1439log_illegal_instruction(const char *msg, struct trapframe *frame)
1440{
1441	pt_entry_t *ptep;
1442	pd_entry_t *pdep;
1443	unsigned int *addr;
1444	struct thread *td;
1445	struct proc *p;
1446	register_t pc;
1447
1448	td = curthread;
1449	p = td->td_proc;
1450
1451#ifdef SMP
1452	printf("cpuid = %d\n", PCPU_GET(cpuid));
1453#endif
1454	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1455	log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx ra %#jx\n",
1456	    msg, p->p_pid, (long)td->td_tid, p->p_comm,
1457	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1458	    (intmax_t)pc,
1459	    (intmax_t)frame->ra);
1460
1461	/* log registers in trap frame */
1462	log_frame_dump(frame);
1463
1464	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1465
1466	/*
1467	 * Dump a few words around faulting instruction, if the addres is
1468	 * valid.
1469	 */
1470	if (!(pc & 3) &&
1471	    useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1472		/* dump page table entry for faulting instruction */
1473		log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n",
1474		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1475
1476		addr = (unsigned int *)(intptr_t)pc;
1477		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1478		    addr);
1479		log(LOG_ERR, "%08x %08x %08x %08x\n",
1480		    addr[0], addr[1], addr[2], addr[3]);
1481	} else {
1482		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1483		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1484	}
1485}
1486
1487static void
1488log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
1489{
1490	pt_entry_t *ptep;
1491	pd_entry_t *pdep;
1492	unsigned int *addr;
1493	struct thread *td;
1494	struct proc *p;
1495	char *read_or_write;
1496	register_t pc;
1497
1498	trap_type &= ~T_USER;
1499
1500	td = curthread;
1501	p = td->td_proc;
1502
1503#ifdef SMP
1504	printf("cpuid = %d\n", PCPU_GET(cpuid));
1505#endif
1506	switch (trap_type) {
1507	case T_TLB_MOD:
1508	case T_TLB_ST_MISS:
1509	case T_ADDR_ERR_ST:
1510		read_or_write = "write";
1511		break;
1512	case T_TLB_LD_MISS:
1513	case T_ADDR_ERR_LD:
1514	case T_BUS_ERR_IFETCH:
1515		read_or_write = "read";
1516		break;
1517	default:
1518		read_or_write = "unknown";
1519	}
1520
1521	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1522	log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx got a %s fault "
1523	    "(type %#x) at %#jx\n",
1524	    msg, p->p_pid, (long)td->td_tid, p->p_comm,
1525	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1526	    (intmax_t)pc,
1527	    read_or_write,
1528	    trap_type,
1529	    (intmax_t)frame->badvaddr);
1530
1531	/* log registers in trap frame */
1532	log_frame_dump(frame);
1533
1534	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1535
1536	/*
1537	 * Dump a few words around faulting instruction, if the addres is
1538	 * valid.
1539	 */
1540	if (!(pc & 3) && (pc != frame->badvaddr) &&
1541	    (trap_type != T_BUS_ERR_IFETCH) &&
1542	    useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1543		/* dump page table entry for faulting instruction */
1544		log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n",
1545		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1546
1547		addr = (unsigned int *)(intptr_t)pc;
1548		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1549		    addr);
1550		log(LOG_ERR, "%08x %08x %08x %08x\n",
1551		    addr[0], addr[1], addr[2], addr[3]);
1552	} else {
1553		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1554		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1555	}
1556
1557	get_mapping_info((vm_offset_t)frame->badvaddr, &pdep, &ptep);
1558	log(LOG_ERR, "Page table info for bad address %#jx: pde = %p, pte = %#jx\n",
1559	    (intmax_t)frame->badvaddr, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1560}
1561
1562
1563/*
1564 * Unaligned load/store emulation
1565 */
1566static int
1567mips_unaligned_load_store(struct trapframe *frame, int mode, register_t addr, register_t pc)
1568{
1569	register_t *reg = (register_t *) frame;
1570	u_int32_t inst = *((u_int32_t *)(intptr_t)pc);
1571	register_t value_msb, value;
1572	unsigned size;
1573
1574	/*
1575	 * ADDR_ERR faults have higher priority than TLB
1576	 * Miss faults.  Therefore, it is necessary to
1577	 * verify that the faulting address is a valid
1578	 * virtual address within the process' address space
1579	 * before trying to emulate the unaligned access.
1580	 */
1581	switch (MIPS_INST_OPCODE(inst)) {
1582	case OP_LHU: case OP_LH:
1583	case OP_SH:
1584		size = 2;
1585		break;
1586	case OP_LWU: case OP_LW:
1587	case OP_SW:
1588		size = 4;
1589		break;
1590	case OP_LD:
1591	case OP_SD:
1592		size = 8;
1593		break;
1594	default:
1595		printf("%s: unhandled opcode in address error: %#x\n", __func__, MIPS_INST_OPCODE(inst));
1596		return (0);
1597	}
1598
1599	if (!useracc((void *)rounddown2((vm_offset_t)addr, size), size * 2, mode))
1600		return (0);
1601
1602	/*
1603	 * XXX
1604	 * Handle LL/SC LLD/SCD.
1605	 */
1606	switch (MIPS_INST_OPCODE(inst)) {
1607	case OP_LHU:
1608		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1609		lbu_macro(value_msb, addr);
1610		addr += 1;
1611		lbu_macro(value, addr);
1612		value |= value_msb << 8;
1613		reg[MIPS_INST_RT(inst)] = value;
1614		return (MIPS_LHU_ACCESS);
1615
1616	case OP_LH:
1617		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1618		lb_macro(value_msb, addr);
1619		addr += 1;
1620		lbu_macro(value, addr);
1621		value |= value_msb << 8;
1622		reg[MIPS_INST_RT(inst)] = value;
1623		return (MIPS_LH_ACCESS);
1624
1625	case OP_LWU:
1626		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1627		lwl_macro(value, addr);
1628		addr += 3;
1629		lwr_macro(value, addr);
1630		value &= 0xffffffff;
1631		reg[MIPS_INST_RT(inst)] = value;
1632		return (MIPS_LWU_ACCESS);
1633
1634	case OP_LW:
1635		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1636		lwl_macro(value, addr);
1637		addr += 3;
1638		lwr_macro(value, addr);
1639		reg[MIPS_INST_RT(inst)] = value;
1640		return (MIPS_LW_ACCESS);
1641
1642#if defined(__mips_n32) || defined(__mips_n64)
1643	case OP_LD:
1644		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1645		ldl_macro(value, addr);
1646		addr += 7;
1647		ldr_macro(value, addr);
1648		reg[MIPS_INST_RT(inst)] = value;
1649		return (MIPS_LD_ACCESS);
1650#endif
1651
1652	case OP_SH:
1653		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1654		value = reg[MIPS_INST_RT(inst)];
1655		value_msb = value >> 8;
1656		sb_macro(value_msb, addr);
1657		addr += 1;
1658		sb_macro(value, addr);
1659		return (MIPS_SH_ACCESS);
1660
1661	case OP_SW:
1662		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1663		value = reg[MIPS_INST_RT(inst)];
1664		swl_macro(value, addr);
1665		addr += 3;
1666		swr_macro(value, addr);
1667		return (MIPS_SW_ACCESS);
1668
1669#if defined(__mips_n32) || defined(__mips_n64)
1670	case OP_SD:
1671		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1672		value = reg[MIPS_INST_RT(inst)];
1673		sdl_macro(value, addr);
1674		addr += 7;
1675		sdr_macro(value, addr);
1676		return (MIPS_SD_ACCESS);
1677#endif
1678	}
1679	panic("%s: should not be reached.", __func__);
1680}
1681
1682
1683/*
1684 * XXX TODO: SMP?
1685 */
1686static struct timeval unaligned_lasterr;
1687static int unaligned_curerr;
1688
1689static int unaligned_pps_log_limit = 4;
1690
1691SYSCTL_INT(_machdep, OID_AUTO, unaligned_log_pps_limit, CTLFLAG_RWTUN,
1692    &unaligned_pps_log_limit, 0,
1693    "limit number of userland unaligned log messages per second");
1694
1695static int
1696emulate_unaligned_access(struct trapframe *frame, int mode)
1697{
1698	register_t pc;
1699	int access_type = 0;
1700	struct thread *td = curthread;
1701	struct proc *p = curproc;
1702
1703	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1704
1705	/*
1706	 * Fall through if it's instruction fetch exception
1707	 */
1708	if (!((pc & 3) || (pc == frame->badvaddr))) {
1709
1710		/*
1711		 * Handle unaligned load and store
1712		 */
1713
1714		/*
1715		 * Return access type if the instruction was emulated.
1716		 * Otherwise restore pc and fall through.
1717		 */
1718		access_type = mips_unaligned_load_store(frame,
1719		    mode, frame->badvaddr, pc);
1720
1721		if (access_type) {
1722			if (DELAYBRANCH(frame->cause))
1723				frame->pc = MipsEmulateBranch(frame, frame->pc,
1724				    0, 0);
1725			else
1726				frame->pc += 4;
1727
1728			if (ppsratecheck(&unaligned_lasterr,
1729			    &unaligned_curerr, unaligned_pps_log_limit)) {
1730				/* XXX TODO: keep global/tid/pid counters? */
1731				log(LOG_INFO,
1732				    "Unaligned %s: pid=%ld (%s), tid=%ld, "
1733				    "pc=%#jx, badvaddr=%#jx\n",
1734				    access_name[access_type - 1],
1735				    (long) p->p_pid,
1736				    p->p_comm,
1737				    (long) td->td_tid,
1738				    (intmax_t)pc,
1739				    (intmax_t)frame->badvaddr);
1740			}
1741		}
1742	}
1743	return access_type;
1744}
1745