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