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