trap.c revision 239669
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 239669 2012-08-25 08:02:46Z rwatson $");
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	mtx_assert(&Giant, MA_NOTOWNED);
1099	return (trapframe->pc);
1100}
1101
1102#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
1103void
1104trapDump(char *msg)
1105{
1106	register_t s;
1107	int i;
1108
1109	s = intr_disable();
1110	printf("trapDump(%s)\n", msg);
1111	for (i = 0; i < TRAPSIZE; i++) {
1112		if (trp == trapdebug) {
1113			trp = &trapdebug[TRAPSIZE - 1];
1114		} else {
1115			trp--;
1116		}
1117
1118		if (trp->cause == 0)
1119			break;
1120
1121		printf("%s: ADR %jx PC %jx CR %jx SR %jx\n",
1122		    trap_type[(trp->cause & MIPS_CR_EXC_CODE) >>
1123			MIPS_CR_EXC_CODE_SHIFT],
1124		    (intmax_t)trp->vadr, (intmax_t)trp->pc,
1125		    (intmax_t)trp->cause, (intmax_t)trp->status);
1126
1127		printf("   RA %jx SP %jx code %d\n", (intmax_t)trp->ra,
1128		    (intmax_t)trp->sp, (int)trp->code);
1129	}
1130	intr_restore(s);
1131}
1132#endif
1133
1134
1135/*
1136 * Return the resulting PC as if the branch was executed.
1137 */
1138uintptr_t
1139MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR,
1140    uintptr_t instptr)
1141{
1142	InstFmt inst;
1143	register_t *regsPtr = (register_t *) framePtr;
1144	uintptr_t retAddr = 0;
1145	int condition;
1146
1147#define	GetBranchDest(InstPtr, inst) \
1148	(InstPtr + 4 + ((short)inst.IType.imm << 2))
1149
1150
1151	if (instptr) {
1152		if (instptr < MIPS_KSEG0_START)
1153			inst.word = fuword32((void *)instptr);
1154		else
1155			inst = *(InstFmt *) instptr;
1156	} else {
1157		if ((vm_offset_t)instPC < MIPS_KSEG0_START)
1158			inst.word = fuword32((void *)instPC);
1159		else
1160			inst = *(InstFmt *) instPC;
1161	}
1162
1163	switch ((int)inst.JType.op) {
1164	case OP_SPECIAL:
1165		switch ((int)inst.RType.func) {
1166		case OP_JR:
1167		case OP_JALR:
1168			retAddr = regsPtr[inst.RType.rs];
1169			break;
1170
1171		default:
1172			retAddr = instPC + 4;
1173			break;
1174		}
1175		break;
1176
1177	case OP_BCOND:
1178		switch ((int)inst.IType.rt) {
1179		case OP_BLTZ:
1180		case OP_BLTZL:
1181		case OP_BLTZAL:
1182		case OP_BLTZALL:
1183			if ((int)(regsPtr[inst.RType.rs]) < 0)
1184				retAddr = GetBranchDest(instPC, inst);
1185			else
1186				retAddr = instPC + 8;
1187			break;
1188
1189		case OP_BGEZ:
1190		case OP_BGEZL:
1191		case OP_BGEZAL:
1192		case OP_BGEZALL:
1193			if ((int)(regsPtr[inst.RType.rs]) >= 0)
1194				retAddr = GetBranchDest(instPC, inst);
1195			else
1196				retAddr = instPC + 8;
1197			break;
1198
1199		case OP_TGEI:
1200		case OP_TGEIU:
1201		case OP_TLTI:
1202		case OP_TLTIU:
1203		case OP_TEQI:
1204		case OP_TNEI:
1205			retAddr = instPC + 4;	/* Like syscall... */
1206			break;
1207
1208		default:
1209			panic("MipsEmulateBranch: Bad branch cond");
1210		}
1211		break;
1212
1213	case OP_J:
1214	case OP_JAL:
1215		retAddr = (inst.JType.target << 2) |
1216		    ((unsigned)(instPC + 4) & 0xF0000000);
1217		break;
1218
1219	case OP_BEQ:
1220	case OP_BEQL:
1221		if (regsPtr[inst.RType.rs] == regsPtr[inst.RType.rt])
1222			retAddr = GetBranchDest(instPC, inst);
1223		else
1224			retAddr = instPC + 8;
1225		break;
1226
1227	case OP_BNE:
1228	case OP_BNEL:
1229		if (regsPtr[inst.RType.rs] != regsPtr[inst.RType.rt])
1230			retAddr = GetBranchDest(instPC, inst);
1231		else
1232			retAddr = instPC + 8;
1233		break;
1234
1235	case OP_BLEZ:
1236	case OP_BLEZL:
1237		if ((int)(regsPtr[inst.RType.rs]) <= 0)
1238			retAddr = GetBranchDest(instPC, inst);
1239		else
1240			retAddr = instPC + 8;
1241		break;
1242
1243	case OP_BGTZ:
1244	case OP_BGTZL:
1245		if ((int)(regsPtr[inst.RType.rs]) > 0)
1246			retAddr = GetBranchDest(instPC, inst);
1247		else
1248			retAddr = instPC + 8;
1249		break;
1250
1251	case OP_COP1:
1252		switch (inst.RType.rs) {
1253		case OP_BCx:
1254		case OP_BCy:
1255			if ((inst.RType.rt & COPz_BC_TF_MASK) == COPz_BC_TRUE)
1256				condition = fpcCSR & MIPS_FPU_COND_BIT;
1257			else
1258				condition = !(fpcCSR & MIPS_FPU_COND_BIT);
1259			if (condition)
1260				retAddr = GetBranchDest(instPC, inst);
1261			else
1262				retAddr = instPC + 8;
1263			break;
1264
1265		default:
1266			retAddr = instPC + 4;
1267		}
1268		break;
1269
1270	default:
1271		retAddr = instPC + 4;
1272	}
1273	return (retAddr);
1274}
1275
1276
1277#if defined(DDB) || defined(DEBUG)
1278/*
1279 * Print a stack backtrace.
1280 */
1281void
1282stacktrace(struct trapframe *regs)
1283{
1284	stacktrace_subr(regs->pc, regs->sp, regs->ra, printf);
1285}
1286#endif
1287
1288static void
1289log_frame_dump(struct trapframe *frame)
1290{
1291	log(LOG_ERR, "Trapframe Register Dump:\n");
1292	log(LOG_ERR, "\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1293	    (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1294
1295	log(LOG_ERR, "\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1296	    (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1297
1298	log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1299	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1300
1301	log(LOG_ERR, "\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1302	    (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1303
1304	log(LOG_ERR, "\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1305	    (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1306
1307	log(LOG_ERR, "\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1308	    (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1309
1310	log(LOG_ERR, "\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1311	    (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1312
1313	log(LOG_ERR, "\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1314	    (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1315
1316	log(LOG_ERR, "\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1317	    (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1318
1319#ifdef IC_REG
1320	log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
1321	    (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
1322#else
1323	log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\n",
1324	    (intmax_t)frame->cause, (intmax_t)frame->pc);
1325#endif
1326}
1327
1328#ifdef TRAP_DEBUG
1329static void
1330trap_frame_dump(struct trapframe *frame)
1331{
1332	printf("Trapframe Register Dump:\n");
1333	printf("\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1334	    (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1335
1336	printf("\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1337	    (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1338
1339	printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1340	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1341
1342	printf("\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1343	    (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1344
1345	printf("\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1346	    (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1347
1348	printf("\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1349	    (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1350
1351	printf("\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1352	    (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1353
1354	printf("\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1355	    (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1356
1357	printf("\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1358	    (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1359
1360#ifdef IC_REG
1361	printf("\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
1362	    (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
1363#else
1364	printf("\tcause: %#jx\tpc: %#jx\n",
1365	    (intmax_t)frame->cause, (intmax_t)frame->pc);
1366#endif
1367}
1368
1369#endif
1370
1371
1372static void
1373get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp)
1374{
1375	pt_entry_t *ptep;
1376	pd_entry_t *pdep;
1377	struct proc *p = curproc;
1378
1379	pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[(va >> SEGSHIFT) & (NPDEPG - 1)]));
1380	if (*pdep)
1381		ptep = pmap_pte(&p->p_vmspace->vm_pmap, va);
1382	else
1383		ptep = (pt_entry_t *)0;
1384
1385	*pdepp = pdep;
1386	*ptepp = ptep;
1387}
1388
1389static void
1390log_illegal_instruction(const char *msg, struct trapframe *frame)
1391{
1392	pt_entry_t *ptep;
1393	pd_entry_t *pdep;
1394	unsigned int *addr;
1395	struct thread *td;
1396	struct proc *p;
1397	register_t pc;
1398
1399	td = curthread;
1400	p = td->td_proc;
1401
1402#ifdef SMP
1403	printf("cpuid = %d\n", PCPU_GET(cpuid));
1404#endif
1405	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1406	log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx ra %#jx\n",
1407	    msg, p->p_pid, (long)td->td_tid, p->p_comm,
1408	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1409	    (intmax_t)pc,
1410	    (intmax_t)frame->ra);
1411
1412	/* log registers in trap frame */
1413	log_frame_dump(frame);
1414
1415	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1416
1417	/*
1418	 * Dump a few words around faulting instruction, if the addres is
1419	 * valid.
1420	 */
1421	if (!(pc & 3) &&
1422	    useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1423		/* dump page table entry for faulting instruction */
1424		log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n",
1425		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1426
1427		addr = (unsigned int *)(intptr_t)pc;
1428		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1429		    addr);
1430		log(LOG_ERR, "%08x %08x %08x %08x\n",
1431		    addr[0], addr[1], addr[2], addr[3]);
1432	} else {
1433		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1434		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1435	}
1436}
1437
1438static void
1439log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
1440{
1441	pt_entry_t *ptep;
1442	pd_entry_t *pdep;
1443	unsigned int *addr;
1444	struct thread *td;
1445	struct proc *p;
1446	char *read_or_write;
1447	register_t pc;
1448
1449	trap_type &= ~T_USER;
1450
1451	td = curthread;
1452	p = td->td_proc;
1453
1454#ifdef SMP
1455	printf("cpuid = %d\n", PCPU_GET(cpuid));
1456#endif
1457	switch (trap_type) {
1458	case T_TLB_ST_MISS:
1459	case T_ADDR_ERR_ST:
1460		read_or_write = "write";
1461		break;
1462	case T_TLB_LD_MISS:
1463	case T_ADDR_ERR_LD:
1464	case T_BUS_ERR_IFETCH:
1465		read_or_write = "read";
1466		break;
1467	default:
1468		read_or_write = "unknown";
1469	}
1470
1471	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1472	log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx got a %s fault "
1473	    "(type %#x) at %#jx\n",
1474	    msg, p->p_pid, (long)td->td_tid, p->p_comm,
1475	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1476	    (intmax_t)pc,
1477	    read_or_write,
1478	    trap_type,
1479	    (intmax_t)frame->badvaddr);
1480
1481	/* log registers in trap frame */
1482	log_frame_dump(frame);
1483
1484	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1485
1486	/*
1487	 * Dump a few words around faulting instruction, if the addres is
1488	 * valid.
1489	 */
1490	if (!(pc & 3) && (pc != frame->badvaddr) &&
1491	    (trap_type != T_BUS_ERR_IFETCH) &&
1492	    useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1493		/* dump page table entry for faulting instruction */
1494		log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n",
1495		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1496
1497		addr = (unsigned int *)(intptr_t)pc;
1498		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1499		    addr);
1500		log(LOG_ERR, "%08x %08x %08x %08x\n",
1501		    addr[0], addr[1], addr[2], addr[3]);
1502	} else {
1503		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1504		    (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1505	}
1506
1507	get_mapping_info((vm_offset_t)frame->badvaddr, &pdep, &ptep);
1508	log(LOG_ERR, "Page table info for bad address %#jx: pde = %p, pte = %#jx\n",
1509	    (intmax_t)frame->badvaddr, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1510}
1511
1512
1513/*
1514 * Unaligned load/store emulation
1515 */
1516static int
1517mips_unaligned_load_store(struct trapframe *frame, int mode, register_t addr, register_t pc)
1518{
1519	register_t *reg = (register_t *) frame;
1520	u_int32_t inst = *((u_int32_t *)(intptr_t)pc);
1521	register_t value_msb, value;
1522	unsigned size;
1523
1524	/*
1525	 * ADDR_ERR faults have higher priority than TLB
1526	 * Miss faults.  Therefore, it is necessary to
1527	 * verify that the faulting address is a valid
1528	 * virtual address within the process' address space
1529	 * before trying to emulate the unaligned access.
1530	 */
1531	switch (MIPS_INST_OPCODE(inst)) {
1532	case OP_LHU: case OP_LH:
1533	case OP_SH:
1534		size = 2;
1535		break;
1536	case OP_LWU: case OP_LW:
1537	case OP_SW:
1538		size = 4;
1539		break;
1540	case OP_LD:
1541	case OP_SD:
1542		size = 8;
1543		break;
1544	default:
1545		printf("%s: unhandled opcode in address error: %#x\n", __func__, MIPS_INST_OPCODE(inst));
1546		return (0);
1547	}
1548
1549	if (!useracc((void *)((vm_offset_t)addr & ~(size - 1)), size * 2, mode))
1550		return (0);
1551
1552	/*
1553	 * XXX
1554	 * Handle LL/SC LLD/SCD.
1555	 */
1556	switch (MIPS_INST_OPCODE(inst)) {
1557	case OP_LHU:
1558		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1559		lbu_macro(value_msb, addr);
1560		addr += 1;
1561		lbu_macro(value, addr);
1562		value |= value_msb << 8;
1563		reg[MIPS_INST_RT(inst)] = value;
1564		return (MIPS_LHU_ACCESS);
1565
1566	case OP_LH:
1567		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1568		lb_macro(value_msb, addr);
1569		addr += 1;
1570		lbu_macro(value, addr);
1571		value |= value_msb << 8;
1572		reg[MIPS_INST_RT(inst)] = value;
1573		return (MIPS_LH_ACCESS);
1574
1575	case OP_LWU:
1576		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1577		lwl_macro(value, addr);
1578		addr += 3;
1579		lwr_macro(value, addr);
1580		value &= 0xffffffff;
1581		reg[MIPS_INST_RT(inst)] = value;
1582		return (MIPS_LWU_ACCESS);
1583
1584	case OP_LW:
1585		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1586		lwl_macro(value, addr);
1587		addr += 3;
1588		lwr_macro(value, addr);
1589		reg[MIPS_INST_RT(inst)] = value;
1590		return (MIPS_LW_ACCESS);
1591
1592#if defined(__mips_n32) || defined(__mips_n64)
1593	case OP_LD:
1594		KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1595		ldl_macro(value, addr);
1596		addr += 7;
1597		ldr_macro(value, addr);
1598		reg[MIPS_INST_RT(inst)] = value;
1599		return (MIPS_LD_ACCESS);
1600#endif
1601
1602	case OP_SH:
1603		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1604		value = reg[MIPS_INST_RT(inst)];
1605		value_msb = value >> 8;
1606		sb_macro(value_msb, addr);
1607		addr += 1;
1608		sb_macro(value, addr);
1609		return (MIPS_SH_ACCESS);
1610
1611	case OP_SW:
1612		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1613		value = reg[MIPS_INST_RT(inst)];
1614		swl_macro(value, addr);
1615		addr += 3;
1616		swr_macro(value, addr);
1617		return (MIPS_SW_ACCESS);
1618
1619#if defined(__mips_n32) || defined(__mips_n64)
1620	case OP_SD:
1621		KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1622		value = reg[MIPS_INST_RT(inst)];
1623		sdl_macro(value, addr);
1624		addr += 7;
1625		sdr_macro(value, addr);
1626		return (MIPS_SD_ACCESS);
1627#endif
1628	}
1629	panic("%s: should not be reached.", __func__);
1630}
1631
1632
1633static int
1634emulate_unaligned_access(struct trapframe *frame, int mode)
1635{
1636	register_t pc;
1637	int access_type = 0;
1638
1639	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1640
1641	/*
1642	 * Fall through if it's instruction fetch exception
1643	 */
1644	if (!((pc & 3) || (pc == frame->badvaddr))) {
1645
1646		/*
1647		 * Handle unaligned load and store
1648		 */
1649
1650		/*
1651		 * Return access type if the instruction was emulated.
1652		 * Otherwise restore pc and fall through.
1653		 */
1654		access_type = mips_unaligned_load_store(frame,
1655		    mode, frame->badvaddr, pc);
1656
1657		if (access_type) {
1658			if (DELAYBRANCH(frame->cause))
1659				frame->pc = MipsEmulateBranch(frame, frame->pc,
1660				    0, 0);
1661			else
1662				frame->pc += 4;
1663
1664			log(LOG_INFO, "Unaligned %s: pc=%#jx, badvaddr=%#jx\n",
1665			    access_name[access_type - 1], (intmax_t)pc,
1666			    (intmax_t)frame->badvaddr);
1667		}
1668	}
1669	return access_type;
1670}
1671