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