trap.c revision 344905
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 344905 2019-03-08 00:20:37Z jhb $");
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;
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	if (!(pc & 3) &&
1474	    useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
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		addr = (unsigned int *)(intptr_t)pc;
1480		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1481		    addr);
1482		log(LOG_ERR, "%08x %08x %08x %08x\n",
1483		    addr[0], addr[1], addr[2], addr[3]);
1484	} else {
1485		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1486		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1487	}
1488}
1489
1490static void
1491log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
1492{
1493	pt_entry_t *ptep;
1494	pd_entry_t *pdep;
1495	unsigned int *addr;
1496	struct thread *td;
1497	struct proc *p;
1498	char *read_or_write;
1499	register_t pc;
1500
1501	trap_type &= ~T_USER;
1502
1503	td = curthread;
1504	p = td->td_proc;
1505
1506#ifdef SMP
1507	printf("cpuid = %d\n", PCPU_GET(cpuid));
1508#endif
1509	switch (trap_type) {
1510	case T_TLB_MOD:
1511	case T_TLB_ST_MISS:
1512	case T_ADDR_ERR_ST:
1513		read_or_write = "write";
1514		break;
1515	case T_TLB_LD_MISS:
1516	case T_ADDR_ERR_LD:
1517	case T_BUS_ERR_IFETCH:
1518		read_or_write = "read";
1519		break;
1520	default:
1521		read_or_write = "unknown";
1522	}
1523
1524	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1525	log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx got a %s fault "
1526	    "(type %#x) at %#jx\n",
1527	    msg, p->p_pid, (long)td->td_tid, p->p_comm,
1528	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1529	    (intmax_t)pc,
1530	    read_or_write,
1531	    trap_type,
1532	    (intmax_t)frame->badvaddr);
1533
1534	/* log registers in trap frame */
1535	log_frame_dump(frame);
1536
1537	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1538
1539	/*
1540	 * Dump a few words around faulting instruction, if the addres is
1541	 * valid.
1542	 */
1543	if (!(pc & 3) && (pc != frame->badvaddr) &&
1544	    (trap_type != T_BUS_ERR_IFETCH) &&
1545	    useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
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		addr = (unsigned int *)(intptr_t)pc;
1551		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1552		    addr);
1553		log(LOG_ERR, "%08x %08x %08x %08x\n",
1554		    addr[0], addr[1], addr[2], addr[3]);
1555	} else {
1556		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1557		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1558	}
1559
1560	get_mapping_info((vm_offset_t)frame->badvaddr, &pdep, &ptep);
1561	log(LOG_ERR, "Page table info for bad address %#jx: pde = %p, pte = %#jx\n",
1562	    (intmax_t)frame->badvaddr, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1563}
1564
1565
1566/*
1567 * Unaligned load/store emulation
1568 */
1569static int
1570mips_unaligned_load_store(struct trapframe *frame, int mode, register_t addr, register_t pc)
1571{
1572	register_t *reg = (register_t *) frame;
1573	u_int32_t inst = *((u_int32_t *)(intptr_t)pc);
1574	register_t value_msb, value;
1575	unsigned size;
1576
1577	/*
1578	 * ADDR_ERR faults have higher priority than TLB
1579	 * Miss faults.  Therefore, it is necessary to
1580	 * verify that the faulting address is a valid
1581	 * virtual address within the process' address space
1582	 * before trying to emulate the unaligned access.
1583	 */
1584	switch (MIPS_INST_OPCODE(inst)) {
1585	case OP_LHU: case OP_LH:
1586	case OP_SH:
1587		size = 2;
1588		break;
1589	case OP_LWU: case OP_LW:
1590	case OP_SW:
1591		size = 4;
1592		break;
1593	case OP_LD:
1594	case OP_SD:
1595		size = 8;
1596		break;
1597	default:
1598		printf("%s: unhandled opcode in address error: %#x\n", __func__, MIPS_INST_OPCODE(inst));
1599		return (0);
1600	}
1601
1602	if (!useracc((void *)rounddown2((vm_offset_t)addr, size), size * 2, mode))
1603		return (0);
1604
1605	/*
1606	 * XXX
1607	 * Handle LL/SC LLD/SCD.
1608	 */
1609	switch (MIPS_INST_OPCODE(inst)) {
1610	case OP_LHU:
1611		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1612		lbu_macro(value_msb, addr);
1613		addr += 1;
1614		lbu_macro(value, addr);
1615		value |= value_msb << 8;
1616		reg[MIPS_INST_RT(inst)] = value;
1617		return (MIPS_LHU_ACCESS);
1618
1619	case OP_LH:
1620		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1621		lb_macro(value_msb, addr);
1622		addr += 1;
1623		lbu_macro(value, addr);
1624		value |= value_msb << 8;
1625		reg[MIPS_INST_RT(inst)] = value;
1626		return (MIPS_LH_ACCESS);
1627
1628	case OP_LWU:
1629		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1630		lwl_macro(value, addr);
1631		addr += 3;
1632		lwr_macro(value, addr);
1633		value &= 0xffffffff;
1634		reg[MIPS_INST_RT(inst)] = value;
1635		return (MIPS_LWU_ACCESS);
1636
1637	case OP_LW:
1638		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1639		lwl_macro(value, addr);
1640		addr += 3;
1641		lwr_macro(value, addr);
1642		reg[MIPS_INST_RT(inst)] = value;
1643		return (MIPS_LW_ACCESS);
1644
1645#if defined(__mips_n32) || defined(__mips_n64)
1646	case OP_LD:
1647		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1648		ldl_macro(value, addr);
1649		addr += 7;
1650		ldr_macro(value, addr);
1651		reg[MIPS_INST_RT(inst)] = value;
1652		return (MIPS_LD_ACCESS);
1653#endif
1654
1655	case OP_SH:
1656		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1657		value = reg[MIPS_INST_RT(inst)];
1658		value_msb = value >> 8;
1659		sb_macro(value_msb, addr);
1660		addr += 1;
1661		sb_macro(value, addr);
1662		return (MIPS_SH_ACCESS);
1663
1664	case OP_SW:
1665		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1666		value = reg[MIPS_INST_RT(inst)];
1667		swl_macro(value, addr);
1668		addr += 3;
1669		swr_macro(value, addr);
1670		return (MIPS_SW_ACCESS);
1671
1672#if defined(__mips_n32) || defined(__mips_n64)
1673	case OP_SD:
1674		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1675		value = reg[MIPS_INST_RT(inst)];
1676		sdl_macro(value, addr);
1677		addr += 7;
1678		sdr_macro(value, addr);
1679		return (MIPS_SD_ACCESS);
1680#endif
1681	}
1682	panic("%s: should not be reached.", __func__);
1683}
1684
1685
1686/*
1687 * XXX TODO: SMP?
1688 */
1689static struct timeval unaligned_lasterr;
1690static int unaligned_curerr;
1691
1692static int unaligned_pps_log_limit = 4;
1693
1694SYSCTL_INT(_machdep, OID_AUTO, unaligned_log_pps_limit, CTLFLAG_RWTUN,
1695    &unaligned_pps_log_limit, 0,
1696    "limit number of userland unaligned log messages per second");
1697
1698static int
1699emulate_unaligned_access(struct trapframe *frame, int mode)
1700{
1701	register_t pc;
1702	int access_type = 0;
1703	struct thread *td = curthread;
1704	struct proc *p = curproc;
1705
1706	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1707
1708	/*
1709	 * Fall through if it's instruction fetch exception
1710	 */
1711	if (!((pc & 3) || (pc == frame->badvaddr))) {
1712
1713		/*
1714		 * Handle unaligned load and store
1715		 */
1716
1717		/*
1718		 * Return access type if the instruction was emulated.
1719		 * Otherwise restore pc and fall through.
1720		 */
1721		access_type = mips_unaligned_load_store(frame,
1722		    mode, frame->badvaddr, pc);
1723
1724		if (access_type) {
1725			if (DELAYBRANCH(frame->cause))
1726				frame->pc = MipsEmulateBranch(frame, frame->pc,
1727				    0, 0);
1728			else
1729				frame->pc += 4;
1730
1731			if (ppsratecheck(&unaligned_lasterr,
1732			    &unaligned_curerr, unaligned_pps_log_limit)) {
1733				/* XXX TODO: keep global/tid/pid counters? */
1734				log(LOG_INFO,
1735				    "Unaligned %s: pid=%ld (%s), tid=%ld, "
1736				    "pc=%#jx, badvaddr=%#jx\n",
1737				    access_name[access_type - 1],
1738				    (long) p->p_pid,
1739				    p->p_comm,
1740				    (long) td->td_tid,
1741				    (intmax_t)pc,
1742				    (intmax_t)frame->badvaddr);
1743			}
1744		}
1745	}
1746	return access_type;
1747}
1748