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/10/sys/mips/mips/trap.c 335557 2018-06-22 11:16:17Z avg $");
43
44#include "opt_compat.h"
45#include "opt_ddb.h"
46#include "opt_global.h"
47#include "opt_ktrace.h"
48#include "opt_kdtrace.h"
49
50#include <sys/param.h>
51#include <sys/systm.h>
52#include <sys/sysent.h>
53#include <sys/proc.h>
54#include <sys/kernel.h>
55#include <sys/signalvar.h>
56#include <sys/syscall.h>
57#include <sys/lock.h>
58#include <vm/vm.h>
59#include <vm/vm_extern.h>
60#include <vm/vm_kern.h>
61#include <vm/vm_page.h>
62#include <vm/vm_map.h>
63#include <vm/vm_param.h>
64#include <sys/vmmeter.h>
65#include <sys/ptrace.h>
66#include <sys/user.h>
67#include <sys/buf.h>
68#include <sys/vnode.h>
69#include <sys/pioctl.h>
70#include <sys/sysctl.h>
71#include <sys/syslog.h>
72#include <sys/bus.h>
73#ifdef KTRACE
74#include <sys/ktrace.h>
75#endif
76#include <net/netisr.h>
77
78#include <machine/trap.h>
79#include <machine/cpu.h>
80#include <machine/pte.h>
81#include <machine/pmap.h>
82#include <machine/md_var.h>
83#include <machine/mips_opcode.h>
84#include <machine/frame.h>
85#include <machine/regnum.h>
86#include <machine/tls.h>
87
88#ifdef DDB
89#include <machine/db_machdep.h>
90#include <ddb/db_sym.h>
91#include <ddb/ddb.h>
92#include <sys/kdb.h>
93#endif
94
95#ifdef KDTRACE_HOOKS
96#include <sys/dtrace_bsd.h>
97#endif
98
99#ifdef TRAP_DEBUG
100int trap_debug = 0;
101SYSCTL_INT(_machdep, OID_AUTO, trap_debug, CTLFLAG_RW,
102    &trap_debug, 0, "Debug information on all traps");
103#endif
104
105#define	lbu_macro(data, addr)						\
106	__asm __volatile ("lbu %0, 0x0(%1)"				\
107			: "=r" (data)	/* outputs */			\
108			: "r" (addr));	/* inputs */
109
110#define	lb_macro(data, addr)						\
111	__asm __volatile ("lb %0, 0x0(%1)"				\
112			: "=r" (data)	/* outputs */			\
113			: "r" (addr));	/* inputs */
114
115#define	lwl_macro(data, addr)						\
116	__asm __volatile ("lwl %0, 0x0(%1)"				\
117			: "=r" (data)	/* outputs */			\
118			: "r" (addr));	/* inputs */
119
120#define	lwr_macro(data, addr)						\
121	__asm __volatile ("lwr %0, 0x0(%1)"				\
122			: "=r" (data)	/* outputs */			\
123			: "r" (addr));	/* inputs */
124
125#define	ldl_macro(data, addr)						\
126	__asm __volatile ("ldl %0, 0x0(%1)"				\
127			: "=r" (data)	/* outputs */			\
128			: "r" (addr));	/* inputs */
129
130#define	ldr_macro(data, addr)						\
131	__asm __volatile ("ldr %0, 0x0(%1)"				\
132			: "=r" (data)	/* outputs */			\
133			: "r" (addr));	/* inputs */
134
135#define	sb_macro(data, addr)						\
136	__asm __volatile ("sb %0, 0x0(%1)"				\
137			:				/* outputs */	\
138			: "r" (data), "r" (addr));	/* inputs */
139
140#define	swl_macro(data, addr)						\
141	__asm __volatile ("swl %0, 0x0(%1)"				\
142			: 				/* outputs */	\
143			: "r" (data), "r" (addr));	/* inputs */
144
145#define	swr_macro(data, addr)						\
146	__asm __volatile ("swr %0, 0x0(%1)"				\
147			: 				/* outputs */	\
148			: "r" (data), "r" (addr));	/* inputs */
149
150#define	sdl_macro(data, addr)						\
151	__asm __volatile ("sdl %0, 0x0(%1)"				\
152			: 				/* outputs */	\
153			: "r" (data), "r" (addr));	/* inputs */
154
155#define	sdr_macro(data, addr)						\
156	__asm __volatile ("sdr %0, 0x0(%1)"				\
157			:				/* outputs */	\
158			: "r" (data), "r" (addr));	/* inputs */
159
160static void log_illegal_instruction(const char *, struct trapframe *);
161static void log_bad_page_fault(char *, struct trapframe *, int);
162static void log_frame_dump(struct trapframe *frame);
163static void get_mapping_info(vm_offset_t, pd_entry_t **, pt_entry_t **);
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, struct syscall_args *sa)
343{
344	struct trapframe *locr0 = td->td_frame;
345	struct sysentvec *se;
346	int error, nsaved;
347
348	bzero(sa->args, sizeof(sa->args));
349
350	/* compute next PC after syscall instruction */
351	td->td_pcb->pcb_tpc = sa->trapframe->pc; /* Remember if restart */
352	if (DELAYBRANCH(sa->trapframe->cause))	 /* Check BD bit */
353		locr0->pc = MipsEmulateBranch(locr0, sa->trapframe->pc, 0, 0);
354	else
355		locr0->pc += sizeof(int);
356	sa->code = locr0->v0;
357
358	switch (sa->code) {
359	case SYS___syscall:
360	case SYS_syscall:
361		/*
362		 * This is an indirect syscall, in which the code is the first argument.
363		 */
364#if (!defined(__mips_n32) && !defined(__mips_n64)) || defined(COMPAT_FREEBSD32)
365		if (sa->code == SYS___syscall && SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
366			/*
367			 * Like syscall, but code is a quad, so as to maintain alignment
368			 * for the rest of the arguments.
369			 */
370			if (_QUAD_LOWWORD == 0)
371				sa->code = locr0->a0;
372			else
373				sa->code = locr0->a1;
374			sa->args[0] = locr0->a2;
375			sa->args[1] = locr0->a3;
376			nsaved = 2;
377			break;
378		}
379#endif
380		/*
381		 * This is either not a quad syscall, or is a quad syscall with a
382		 * new ABI in which quads fit in a single register.
383		 */
384		sa->code = locr0->a0;
385		sa->args[0] = locr0->a1;
386		sa->args[1] = locr0->a2;
387		sa->args[2] = locr0->a3;
388		nsaved = 3;
389#if defined(__mips_n32) || defined(__mips_n64)
390#ifdef COMPAT_FREEBSD32
391		if (!SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
392#endif
393			/*
394			 * Non-o32 ABIs support more arguments in registers.
395			 */
396			sa->args[3] = locr0->a4;
397			sa->args[4] = locr0->a5;
398			sa->args[5] = locr0->a6;
399			sa->args[6] = locr0->a7;
400			nsaved += 4;
401#ifdef COMPAT_FREEBSD32
402		}
403#endif
404#endif
405		break;
406	default:
407		/*
408		 * A direct syscall, arguments are just parameters to the syscall.
409		 */
410		sa->args[0] = locr0->a0;
411		sa->args[1] = locr0->a1;
412		sa->args[2] = locr0->a2;
413		sa->args[3] = locr0->a3;
414		nsaved = 4;
415#if defined (__mips_n32) || defined(__mips_n64)
416#ifdef COMPAT_FREEBSD32
417		if (!SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
418#endif
419			/*
420			 * Non-o32 ABIs support more arguments in registers.
421			 */
422			sa->args[4] = locr0->a4;
423			sa->args[5] = locr0->a5;
424			sa->args[6] = locr0->a6;
425			sa->args[7] = locr0->a7;
426			nsaved += 4;
427#ifdef COMPAT_FREEBSD32
428		}
429#endif
430#endif
431		break;
432	}
433
434#ifdef TRAP_DEBUG
435	if (trap_debug)
436		printf("SYSCALL #%d pid:%u\n", sa->code, td->td_proc->p_pid);
437#endif
438
439	se = td->td_proc->p_sysent;
440	/*
441	 * XXX
442	 * Shouldn't this go before switching on the code?
443	 */
444	if (se->sv_mask)
445		sa->code &= se->sv_mask;
446
447	if (sa->code >= se->sv_size)
448		sa->callp = &se->sv_table[0];
449	else
450		sa->callp = &se->sv_table[sa->code];
451
452	sa->narg = sa->callp->sy_narg;
453
454	if (sa->narg > nsaved) {
455#if defined(__mips_n32) || defined(__mips_n64)
456		/*
457		 * XXX
458		 * Is this right for new ABIs?  I think the 4 there
459		 * should be 8, size there are 8 registers to skip,
460		 * not 4, but I'm not certain.
461		 */
462#ifdef COMPAT_FREEBSD32
463		if (!SV_PROC_FLAG(td->td_proc, SV_ILP32))
464#endif
465			printf("SYSCALL #%u pid:%u, narg (%u) > nsaved (%u).\n",
466			    sa->code, td->td_proc->p_pid, sa->narg, nsaved);
467#endif
468#if (defined(__mips_n32) || defined(__mips_n64)) && defined(COMPAT_FREEBSD32)
469		if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
470			unsigned i;
471			int32_t arg;
472
473			error = 0; /* XXX GCC is awful.  */
474			for (i = nsaved; i < sa->narg; i++) {
475				error = copyin((caddr_t)(intptr_t)(locr0->sp +
476				    (4 + (i - nsaved)) * sizeof(int32_t)),
477				    (caddr_t)&arg, sizeof arg);
478				if (error != 0)
479					break;
480				sa->args[i] = arg;
481			}
482		} else
483#endif
484		error = copyin((caddr_t)(intptr_t)(locr0->sp +
485		    4 * sizeof(register_t)), (caddr_t)&sa->args[nsaved],
486		   (u_int)(sa->narg - nsaved) * sizeof(register_t));
487		if (error != 0) {
488			locr0->v0 = error;
489			locr0->a3 = 1;
490		}
491	} else
492		error = 0;
493
494	if (error == 0) {
495		td->td_retval[0] = 0;
496		td->td_retval[1] = locr0->v1;
497	}
498
499	return (error);
500}
501
502#undef __FBSDID
503#define __FBSDID(x)
504#include "../../kern/subr_syscall.c"
505
506/*
507 * Handle an exception.
508 * Called from MipsKernGenException() or MipsUserGenException()
509 * when a processor trap occurs.
510 * In the case of a kernel trap, we return the pc where to resume if
511 * p->p_addr->u_pcb.pcb_onfault is set, otherwise, return old pc.
512 */
513register_t
514trap(struct trapframe *trapframe)
515{
516	int type, usermode;
517	int i = 0;
518	unsigned ucode = 0;
519	struct thread *td = curthread;
520	struct proc *p = curproc;
521	vm_prot_t ftype;
522	pmap_t pmap;
523	int access_type;
524	ksiginfo_t ksi;
525	char *msg = NULL;
526	intptr_t addr = 0;
527	register_t pc;
528	int cop;
529	register_t *frame_regs;
530
531	trapdebug_enter(trapframe, 0);
532#ifdef KDB
533	if (kdb_active) {
534		kdb_reenter();
535		return (0);
536	}
537#endif
538	type = (trapframe->cause & MIPS_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT;
539	if (TRAPF_USERMODE(trapframe)) {
540		type |= T_USER;
541		usermode = 1;
542	} else {
543		usermode = 0;
544	}
545
546	/*
547	 * Enable hardware interrupts if they were on before the trap. If it
548	 * was off disable all so we don't accidently enable it when doing a
549	 * return to userland.
550	 */
551	if (trapframe->sr & MIPS_SR_INT_IE) {
552		set_intr_mask(trapframe->sr & MIPS_SR_INT_MASK);
553		intr_enable();
554	} else {
555		intr_disable();
556	}
557
558#ifdef TRAP_DEBUG
559	if (trap_debug) {
560		static vm_offset_t last_badvaddr = 0;
561		static vm_offset_t this_badvaddr = 0;
562		static int count = 0;
563		u_int32_t pid;
564
565		printf("trap type %x (%s - ", type,
566		    trap_type[type & (~T_USER)]);
567
568		if (type & T_USER)
569			printf("user mode)\n");
570		else
571			printf("kernel mode)\n");
572
573#ifdef SMP
574		printf("cpuid = %d\n", PCPU_GET(cpuid));
575#endif
576		pid = mips_rd_entryhi() & TLBHI_ASID_MASK;
577		printf("badaddr = %#jx, pc = %#jx, ra = %#jx, sp = %#jx, sr = %jx, pid = %d, ASID = %u\n",
578		    (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
579		    (intmax_t)trapframe->sp, (intmax_t)trapframe->sr,
580		    (curproc ? curproc->p_pid : -1), pid);
581
582		switch (type & ~T_USER) {
583		case T_TLB_MOD:
584		case T_TLB_LD_MISS:
585		case T_TLB_ST_MISS:
586		case T_ADDR_ERR_LD:
587		case T_ADDR_ERR_ST:
588			this_badvaddr = trapframe->badvaddr;
589			break;
590		case T_SYSCALL:
591			this_badvaddr = trapframe->ra;
592			break;
593		default:
594			this_badvaddr = trapframe->pc;
595			break;
596		}
597		if ((last_badvaddr == this_badvaddr) &&
598		    ((type & ~T_USER) != T_SYSCALL)) {
599			if (++count == 3) {
600				trap_frame_dump(trapframe);
601				panic("too many faults at %p\n", (void *)last_badvaddr);
602			}
603		} else {
604			last_badvaddr = this_badvaddr;
605			count = 0;
606		}
607	}
608#endif
609
610#ifdef KDTRACE_HOOKS
611	/*
612	 * A trap can occur while DTrace executes a probe. Before
613	 * executing the probe, DTrace blocks re-scheduling and sets
614	 * a flag in it's per-cpu flags to indicate that it doesn't
615	 * want to fault. On returning from the probe, the no-fault
616	 * flag is cleared and finally re-scheduling is enabled.
617	 *
618	 * If the DTrace kernel module has registered a trap handler,
619	 * call it and if it returns non-zero, assume that it has
620	 * handled the trap and modified the trap frame so that this
621	 * function can return normally.
622	 */
623	/*
624	 * XXXDTRACE: add pid probe handler here (if ever)
625	 */
626	if (!usermode) {
627		if (dtrace_trap_func != NULL && (*dtrace_trap_func)(trapframe, type))
628			return (trapframe->pc);
629	}
630#endif
631
632	switch (type) {
633	case T_MCHECK:
634#ifdef DDB
635		kdb_trap(type, 0, trapframe);
636#endif
637		panic("MCHECK\n");
638		break;
639	case T_TLB_MOD:
640		/* check for kernel address */
641		if (KERNLAND(trapframe->badvaddr)) {
642			if (pmap_emulate_modified(kernel_pmap,
643			    trapframe->badvaddr) != 0) {
644				ftype = VM_PROT_WRITE;
645				goto kernel_fault;
646			}
647			return (trapframe->pc);
648		}
649		/* FALLTHROUGH */
650
651	case T_TLB_MOD + T_USER:
652		pmap = &p->p_vmspace->vm_pmap;
653		if (pmap_emulate_modified(pmap, trapframe->badvaddr) != 0) {
654			ftype = VM_PROT_WRITE;
655			goto dofault;
656		}
657		if (!usermode)
658			return (trapframe->pc);
659		goto out;
660
661	case T_TLB_LD_MISS:
662	case T_TLB_ST_MISS:
663		ftype = (type == T_TLB_ST_MISS) ? VM_PROT_WRITE : VM_PROT_READ;
664		/* check for kernel address */
665		if (KERNLAND(trapframe->badvaddr)) {
666			vm_offset_t va;
667			int rv;
668
669	kernel_fault:
670			va = trunc_page((vm_offset_t)trapframe->badvaddr);
671			rv = vm_fault(kernel_map, va, ftype, VM_FAULT_NORMAL);
672			if (rv == KERN_SUCCESS)
673				return (trapframe->pc);
674			if (td->td_pcb->pcb_onfault != NULL) {
675				pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
676				td->td_pcb->pcb_onfault = NULL;
677				return (pc);
678			}
679			goto err;
680		}
681
682		/*
683		 * It is an error for the kernel to access user space except
684		 * through the copyin/copyout routines.
685		 */
686		if (td->td_pcb->pcb_onfault == NULL)
687			goto err;
688
689		/* check for fuswintr() or suswintr() getting a page fault */
690		/* XXX There must be a nicer way to do this.  */
691		if (td->td_pcb->pcb_onfault == fswintrberr) {
692			pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
693			td->td_pcb->pcb_onfault = NULL;
694			return (pc);
695		}
696
697		goto dofault;
698
699	case T_TLB_LD_MISS + T_USER:
700		ftype = VM_PROT_READ;
701		goto dofault;
702
703	case T_TLB_ST_MISS + T_USER:
704		ftype = VM_PROT_WRITE;
705dofault:
706		{
707			vm_offset_t va;
708			struct vmspace *vm;
709			vm_map_t map;
710			int rv = 0;
711
712			vm = p->p_vmspace;
713			map = &vm->vm_map;
714			va = trunc_page((vm_offset_t)trapframe->badvaddr);
715			if (KERNLAND(trapframe->badvaddr)) {
716				/*
717				 * Don't allow user-mode faults in kernel
718				 * address space.
719				 */
720				goto nogo;
721			}
722
723			/*
724			 * Keep swapout from messing with us during this
725			 * critical time.
726			 */
727			PROC_LOCK(p);
728			++p->p_lock;
729			PROC_UNLOCK(p);
730
731			rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
732
733			PROC_LOCK(p);
734			--p->p_lock;
735			PROC_UNLOCK(p);
736			/*
737			 * XXXDTRACE: add dtrace_doubletrap_func here?
738			 */
739#ifdef VMFAULT_TRACE
740			printf("vm_fault(%p (pmap %p), %p (%p), %x, %d) -> %x at pc %p\n",
741			    map, &vm->vm_pmap, (void *)va, (void *)(intptr_t)trapframe->badvaddr,
742			    ftype, VM_FAULT_NORMAL, rv, (void *)(intptr_t)trapframe->pc);
743#endif
744
745			if (rv == KERN_SUCCESS) {
746				if (!usermode) {
747					return (trapframe->pc);
748				}
749				goto out;
750			}
751	nogo:
752			if (!usermode) {
753				if (td->td_pcb->pcb_onfault != NULL) {
754					pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
755					td->td_pcb->pcb_onfault = NULL;
756					return (pc);
757				}
758				goto err;
759			}
760			ucode = ftype;
761			i = ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
762			addr = trapframe->pc;
763
764			msg = "BAD_PAGE_FAULT";
765			log_bad_page_fault(msg, trapframe, type);
766
767			break;
768		}
769
770	case T_ADDR_ERR_LD + T_USER:	/* misaligned or kseg access */
771	case T_ADDR_ERR_ST + T_USER:	/* misaligned or kseg access */
772		if (trapframe->badvaddr < 0 ||
773		    trapframe->badvaddr >= VM_MAXUSER_ADDRESS) {
774			msg = "ADDRESS_SPACE_ERR";
775		} else if (allow_unaligned_acc) {
776			int mode;
777
778			if (type == (T_ADDR_ERR_LD + T_USER))
779				mode = VM_PROT_READ;
780			else
781				mode = VM_PROT_WRITE;
782
783			access_type = emulate_unaligned_access(trapframe, mode);
784			if (access_type != 0)
785				goto out;
786			msg = "ALIGNMENT_FIX_ERR";
787		} else {
788			msg = "ADDRESS_ERR";
789		}
790
791		/* FALL THROUGH */
792
793	case T_BUS_ERR_IFETCH + T_USER:	/* BERR asserted to cpu */
794	case T_BUS_ERR_LD_ST + T_USER:	/* BERR asserted to cpu */
795		ucode = 0;	/* XXX should be VM_PROT_something */
796		i = SIGBUS;
797		addr = trapframe->pc;
798		if (!msg)
799			msg = "BUS_ERR";
800		log_bad_page_fault(msg, trapframe, type);
801		break;
802
803	case T_SYSCALL + T_USER:
804		{
805			struct syscall_args sa;
806			int error;
807
808			sa.trapframe = trapframe;
809			error = syscallenter(td, &sa);
810
811#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
812			if (trp == trapdebug)
813				trapdebug[TRAPSIZE - 1].code = sa.code;
814			else
815				trp[-1].code = sa.code;
816#endif
817			trapdebug_enter(td->td_frame, -sa.code);
818
819			/*
820			 * The sync'ing of I & D caches for SYS_ptrace() is
821			 * done by procfs_domem() through procfs_rwmem()
822			 * instead of being done here under a special check
823			 * for SYS_ptrace().
824			 */
825			syscallret(td, error, &sa);
826			return (trapframe->pc);
827		}
828
829#ifdef DDB
830	case T_BREAK:
831		kdb_trap(type, 0, trapframe);
832		return (trapframe->pc);
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 berakpoint 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 *)((vm_offset_t)addr & ~(size - 1)), 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
1683static int
1684emulate_unaligned_access(struct trapframe *frame, int mode)
1685{
1686	register_t pc;
1687	int access_type = 0;
1688
1689	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1690
1691	/*
1692	 * Fall through if it's instruction fetch exception
1693	 */
1694	if (!((pc & 3) || (pc == frame->badvaddr))) {
1695
1696		/*
1697		 * Handle unaligned load and store
1698		 */
1699
1700		/*
1701		 * Return access type if the instruction was emulated.
1702		 * Otherwise restore pc and fall through.
1703		 */
1704		access_type = mips_unaligned_load_store(frame,
1705		    mode, frame->badvaddr, pc);
1706
1707		if (access_type) {
1708			if (DELAYBRANCH(frame->cause))
1709				frame->pc = MipsEmulateBranch(frame, frame->pc,
1710				    0, 0);
1711			else
1712				frame->pc += 4;
1713
1714			log(LOG_INFO, "Unaligned %s: pc=%#jx, badvaddr=%#jx\n",
1715			    access_name[access_type - 1], (intmax_t)pc,
1716			    (intmax_t)frame->badvaddr);
1717		}
1718	}
1719	return access_type;
1720}
1721