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