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