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