trap.c revision 208453
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 208453 2010-05-23 18:32:02Z kib $");
43
44#include "opt_ddb.h"
45#include "opt_global.h"
46#include "opt_ktrace.h"
47
48#define	NO_REG_DEFS	1	/* Prevent asm.h from including regdef.h */
49#include <sys/param.h>
50#include <sys/systm.h>
51#include <sys/sysent.h>
52#include <sys/proc.h>
53#include <sys/kernel.h>
54#include <sys/signalvar.h>
55#include <sys/syscall.h>
56#include <sys/lock.h>
57#include <vm/vm.h>
58#include <vm/vm_extern.h>
59#include <vm/vm_kern.h>
60#include <vm/vm_page.h>
61#include <vm/vm_map.h>
62#include <vm/vm_param.h>
63#include <sys/vmmeter.h>
64#include <sys/ptrace.h>
65#include <sys/user.h>
66#include <sys/buf.h>
67#include <sys/vnode.h>
68#include <sys/pioctl.h>
69#include <sys/sysctl.h>
70#include <sys/syslog.h>
71#include <sys/bus.h>
72#ifdef KTRACE
73#include <sys/ktrace.h>
74#endif
75#include <net/netisr.h>
76
77#include <machine/trap.h>
78#include <machine/cpu.h>
79#include <machine/pte.h>
80#include <machine/pmap.h>
81#include <machine/md_var.h>
82#include <machine/mips_opcode.h>
83#include <machine/frame.h>
84#include <machine/regnum.h>
85#include <machine/asm.h>
86
87#ifdef DDB
88#include <machine/db_machdep.h>
89#include <ddb/db_sym.h>
90#include <ddb/ddb.h>
91#include <sys/kdb.h>
92#endif
93
94#include <sys/cdefs.h>
95#include <sys/syslog.h>
96
97
98#ifdef TRAP_DEBUG
99int trap_debug = 1;
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
257static int allow_unaligned_acc = 1;
258
259SYSCTL_INT(_vm, OID_AUTO, allow_unaligned_acc, CTLFLAG_RW,
260    &allow_unaligned_acc, 0, "Allow unaligned accesses");
261
262static int emulate_unaligned_access(struct trapframe *frame);
263
264extern void fswintrberr(void); /* XXX */
265
266/*
267 * Handle an exception.
268 * Called from MipsKernGenException() or MipsUserGenException()
269 * when a processor trap occurs.
270 * In the case of a kernel trap, we return the pc where to resume if
271 * p->p_addr->u_pcb.pcb_onfault is set, otherwise, return old pc.
272 */
273register_t
274trap(struct trapframe *trapframe)
275{
276	int type, usermode;
277	int i = 0;
278	unsigned ucode = 0;
279	struct thread *td = curthread;
280	struct proc *p = curproc;
281	vm_prot_t ftype;
282	pt_entry_t *pte;
283	pmap_t pmap;
284	int access_type;
285	ksiginfo_t ksi;
286	char *msg = NULL;
287	intptr_t addr = 0;
288	register_t pc;
289
290	trapdebug_enter(trapframe, 0);
291
292	type = (trapframe->cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT;
293	if (TRAPF_USERMODE(trapframe)) {
294		type |= T_USER;
295		usermode = 1;
296	} else {
297		usermode = 0;
298	}
299
300	/*
301	 * Enable hardware interrupts if they were on before the trap. If it
302	 * was off disable all so we don't accidently enable it when doing a
303	 * return to userland.
304	 */
305	if (trapframe->sr & SR_INT_ENAB) {
306		set_intr_mask(~(trapframe->sr & ALL_INT_MASK));
307		intr_enable();
308	} else {
309		intr_disable();
310	}
311
312#ifdef TRAP_DEBUG
313	if (trap_debug) {
314		static vm_offset_t last_badvaddr = 0;
315		static vm_offset_t this_badvaddr = 0;
316		static int count = 0;
317		u_int32_t pid;
318
319		printf("trap type %x (%s - ", type,
320		    trap_type[type & (~T_USER)]);
321
322		if (type & T_USER)
323			printf("user mode)\n");
324		else
325			printf("kernel mode)\n");
326
327#ifdef SMP
328		printf("cpuid = %d\n", PCPU_GET(cpuid));
329#endif
330		MachTLBGetPID(pid);
331		printf("badaddr = %#jx, pc = %#jx, ra = %#jx, sp = %#jx, sr = %jx, pid = %d, ASID = %u\n",
332		    (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
333		    (intmax_t)trapframe->sp, (intmax_t)trapframe->sr,
334		    (curproc ? curproc->p_pid : -1), pid);
335
336		switch (type & ~T_USER) {
337		case T_TLB_MOD:
338		case T_TLB_LD_MISS:
339		case T_TLB_ST_MISS:
340		case T_ADDR_ERR_LD:
341		case T_ADDR_ERR_ST:
342			this_badvaddr = trapframe->badvaddr;
343			break;
344		case T_SYSCALL:
345			this_badvaddr = trapframe->ra;
346			break;
347		default:
348			this_badvaddr = trapframe->pc;
349			break;
350		}
351		if ((last_badvaddr == this_badvaddr) &&
352		    ((type & ~T_USER) != T_SYSCALL)) {
353			if (++count == 3) {
354				trap_frame_dump(trapframe);
355				panic("too many faults at %p\n", (void *)last_badvaddr);
356			}
357		} else {
358			last_badvaddr = this_badvaddr;
359			count = 0;
360		}
361	}
362#endif
363	switch (type) {
364	case T_MCHECK:
365#ifdef DDB
366		kdb_trap(type, 0, trapframe);
367#endif
368		panic("MCHECK\n");
369		break;
370	case T_TLB_MOD:
371		/* check for kernel address */
372		if (KERNLAND(trapframe->badvaddr)) {
373			vm_offset_t pa;
374
375			PMAP_LOCK(kernel_pmap);
376			pte = pmap_pte(kernel_pmap, trapframe->badvaddr);
377			if (pte == NULL)
378				panic("trap: ktlbmod: can't find PTE");
379#ifdef SMP
380			/* It is possible that some other CPU changed m-bit */
381			if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit())) {
382				pmap_update_page(kernel_pmap,
383				    trapframe->badvaddr, *pte);
384				PMAP_UNLOCK(kernel_pmap);
385				return (trapframe->pc);
386			}
387#else
388			if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit()))
389				panic("trap: ktlbmod: invalid pte");
390#endif
391			if (*pte & mips_pg_ro_bit()) {
392				/* write to read only page in the kernel */
393				ftype = VM_PROT_WRITE;
394				PMAP_UNLOCK(kernel_pmap);
395				goto kernel_fault;
396			}
397			*pte |= mips_pg_m_bit();
398			pmap_update_page(kernel_pmap, trapframe->badvaddr, *pte);
399			pa = mips_tlbpfn_to_paddr(*pte);
400			if (!page_is_managed(pa))
401				panic("trap: ktlbmod: unmanaged page");
402			pmap_set_modified(pa);
403			PMAP_UNLOCK(kernel_pmap);
404			return (trapframe->pc);
405		}
406		/* FALLTHROUGH */
407
408	case T_TLB_MOD + T_USER:
409		{
410			vm_offset_t pa;
411
412			pmap = &p->p_vmspace->vm_pmap;
413
414			PMAP_LOCK(pmap);
415			pte = pmap_pte(pmap, trapframe->badvaddr);
416			if (pte == NULL)
417				panic("trap: utlbmod: can't find PTE");
418#ifdef SMP
419			/* It is possible that some other CPU changed m-bit */
420			if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit())) {
421				pmap_update_page(pmap, trapframe->badvaddr, *pte);
422				PMAP_UNLOCK(pmap);
423				goto out;
424			}
425#else
426			if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit()))
427				panic("trap: utlbmod: invalid pte");
428#endif
429
430			if (*pte & mips_pg_ro_bit()) {
431				/* write to read only page */
432				ftype = VM_PROT_WRITE;
433				PMAP_UNLOCK(pmap);
434				goto dofault;
435			}
436			*pte |= mips_pg_m_bit();
437			pmap_update_page(pmap, trapframe->badvaddr, *pte);
438			pa = mips_tlbpfn_to_paddr(*pte);
439			if (!page_is_managed(pa))
440				panic("trap: utlbmod: unmanaged page");
441			pmap_set_modified(pa);
442
443			PMAP_UNLOCK(pmap);
444			if (!usermode) {
445				return (trapframe->pc);
446			}
447			goto out;
448		}
449
450	case T_TLB_LD_MISS:
451	case T_TLB_ST_MISS:
452		ftype = (type == T_TLB_ST_MISS) ? VM_PROT_WRITE : VM_PROT_READ;
453		/* check for kernel address */
454		if (KERNLAND(trapframe->badvaddr)) {
455			vm_offset_t va;
456			int rv;
457
458	kernel_fault:
459			va = trunc_page((vm_offset_t)trapframe->badvaddr);
460			rv = vm_fault(kernel_map, va, ftype, VM_FAULT_NORMAL);
461			if (rv == KERN_SUCCESS)
462				return (trapframe->pc);
463			if (td->td_pcb->pcb_onfault != NULL) {
464				pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
465				td->td_pcb->pcb_onfault = NULL;
466				return (pc);
467			}
468			goto err;
469		}
470
471                /*
472		 * It is an error for the kernel to access user space except
473		 * through the copyin/copyout routines.
474		 */
475		if (td->td_pcb->pcb_onfault == NULL)
476			goto err;
477
478		/* check for fuswintr() or suswintr() getting a page fault */
479		/* XXX There must be a nicer way to do this.  */
480		if (td->td_pcb->pcb_onfault == fswintrberr) {
481			pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
482			td->td_pcb->pcb_onfault = NULL;
483			return (pc);
484		}
485
486		goto dofault;
487
488	case T_TLB_LD_MISS + T_USER:
489		ftype = VM_PROT_READ;
490		goto dofault;
491
492	case T_TLB_ST_MISS + T_USER:
493		ftype = VM_PROT_WRITE;
494dofault:
495		{
496			vm_offset_t va;
497			struct vmspace *vm;
498			vm_map_t map;
499			int rv = 0;
500
501			vm = p->p_vmspace;
502			map = &vm->vm_map;
503			va = trunc_page((vm_offset_t)trapframe->badvaddr);
504			if (KERNLAND(trapframe->badvaddr)) {
505				/*
506				 * Don't allow user-mode faults in kernel
507				 * address space.
508				 */
509				goto nogo;
510			}
511
512			/*
513			 * Keep swapout from messing with us during this
514			 * critical time.
515			 */
516			PROC_LOCK(p);
517			++p->p_lock;
518			PROC_UNLOCK(p);
519
520			rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
521
522			PROC_LOCK(p);
523			--p->p_lock;
524			PROC_UNLOCK(p);
525#ifdef VMFAULT_TRACE
526			printf("vm_fault(%p (pmap %p), %p (%p), %x, %d) -> %x at pc %p\n",
527			    map, &vm->vm_pmap, (void *)va, (void *)(intptr_t)trapframe->badvaddr,
528			    ftype, VM_FAULT_NORMAL, rv, (void *)(intptr_t)trapframe->pc);
529#endif
530
531			if (rv == KERN_SUCCESS) {
532				if (!usermode) {
533					return (trapframe->pc);
534				}
535				goto out;
536			}
537	nogo:
538			if (!usermode) {
539				if (td->td_pcb->pcb_onfault != NULL) {
540					pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
541					td->td_pcb->pcb_onfault = NULL;
542					return (pc);
543				}
544				goto err;
545			}
546			ucode = ftype;
547			i = ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
548			addr = trapframe->pc;
549
550			msg = "BAD_PAGE_FAULT";
551			log_bad_page_fault(msg, trapframe, type);
552
553			break;
554		}
555
556	case T_ADDR_ERR_LD + T_USER:	/* misaligned or kseg access */
557	case T_ADDR_ERR_ST + T_USER:	/* misaligned or kseg access */
558		if (allow_unaligned_acc) {
559			int mode;
560
561			if (type == (T_ADDR_ERR_LD + T_USER))
562				mode = VM_PROT_READ;
563			else
564				mode = VM_PROT_WRITE;
565
566			/*
567			 * ADDR_ERR faults have higher priority than TLB
568			 * Miss faults.  Therefore, it is necessary to
569			 * verify that the faulting address is a valid
570			 * virtual address within the process' address space
571			 * before trying to emulate the unaligned access.
572			 */
573			if (useracc((caddr_t)
574			    (((vm_offset_t)trapframe->badvaddr) &
575			    ~(sizeof(int) - 1)), sizeof(int) * 2, mode)) {
576				access_type = emulate_unaligned_access(
577				    trapframe);
578				if (access_type != 0)
579					goto out;
580			}
581		}
582		msg = "ADDRESS_ERR";
583
584		/* FALL THROUGH */
585
586	case T_BUS_ERR_IFETCH + T_USER:	/* BERR asserted to cpu */
587	case T_BUS_ERR_LD_ST + T_USER:	/* BERR asserted to cpu */
588		ucode = 0;	/* XXX should be VM_PROT_something */
589		i = SIGBUS;
590		addr = trapframe->pc;
591		if (!msg)
592			msg = "BUS_ERR";
593		log_bad_page_fault(msg, trapframe, type);
594		break;
595
596	case T_SYSCALL + T_USER:
597		{
598			struct trapframe *locr0 = td->td_frame;
599			struct sysent *callp;
600			unsigned int code;
601			int nargs, nsaved;
602			register_t args[8];
603
604			bzero(args, sizeof args);
605
606			/*
607			 * note: PCPU_LAZY_INC() can only be used if we can
608			 * afford occassional inaccuracy in the count.
609			 */
610			PCPU_LAZY_INC(cnt.v_syscall);
611			if (td->td_ucred != p->p_ucred)
612				cred_update_thread(td);
613#ifdef KSE
614			if (p->p_flag & P_SA)
615				thread_user_enter(td);
616#endif
617			/* compute next PC after syscall instruction */
618			td->td_pcb->pcb_tpc = trapframe->pc;	/* Remember if restart */
619			if (DELAYBRANCH(trapframe->cause)) {	/* Check BD bit */
620				locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0,
621				    0);
622			} else {
623				locr0->pc += sizeof(int);
624			}
625			code = locr0->v0;
626
627			switch (code) {
628			case SYS_syscall:
629				/*
630				 * Code is first argument, followed by
631				 * actual args.
632				 */
633				code = locr0->a0;
634				args[0] = locr0->a1;
635				args[1] = locr0->a2;
636				args[2] = locr0->a3;
637				nsaved = 3;
638				break;
639
640			case SYS___syscall:
641				/*
642				 * Like syscall, but code is a quad, so as
643				 * to maintain quad alignment for the rest
644				 * of the arguments.
645				 */
646				if (_QUAD_LOWWORD == 0) {
647					code = locr0->a0;
648				} else {
649					code = locr0->a1;
650				}
651				args[0] = locr0->a2;
652				args[1] = locr0->a3;
653				nsaved = 2;
654				break;
655
656			default:
657				args[0] = locr0->a0;
658				args[1] = locr0->a1;
659				args[2] = locr0->a2;
660				args[3] = locr0->a3;
661				nsaved = 4;
662			}
663#ifdef TRAP_DEBUG
664			printf("SYSCALL #%d pid:%u\n", code, p->p_pid);
665#endif
666
667			if (p->p_sysent->sv_mask)
668				code &= p->p_sysent->sv_mask;
669
670			if (code >= p->p_sysent->sv_size)
671				callp = &p->p_sysent->sv_table[0];
672			else
673				callp = &p->p_sysent->sv_table[code];
674
675			nargs = callp->sy_narg;
676
677			if (nargs > nsaved) {
678				i = copyin((caddr_t)(intptr_t)(locr0->sp +
679				    4 * sizeof(register_t)), (caddr_t)&args[nsaved],
680				    (u_int)(nargs - nsaved) * sizeof(register_t));
681				if (i) {
682					locr0->v0 = i;
683					locr0->a3 = 1;
684#ifdef KTRACE
685					if (KTRPOINT(td, KTR_SYSCALL))
686						ktrsyscall(code, nargs, args);
687#endif
688					goto done;
689				}
690			}
691#ifdef KTRACE
692			if (KTRPOINT(td, KTR_SYSCALL))
693				ktrsyscall(code, nargs, args);
694#endif
695			td->td_retval[0] = 0;
696			td->td_retval[1] = locr0->v1;
697
698#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
699			if (trp == trapdebug)
700				trapdebug[TRAPSIZE - 1].code = code;
701			else
702				trp[-1].code = code;
703#endif
704			STOPEVENT(p, S_SCE, nargs);
705
706			PTRACESTOP_SC(p, td, S_PT_SCE);
707			i = (*callp->sy_call) (td, args);
708#if 0
709			/*
710			 * Reinitialize proc pointer `p' as it may be
711			 * different if this is a child returning from fork
712			 * syscall.
713			 */
714			td = curthread;
715			locr0 = td->td_frame;
716#endif
717			trapdebug_enter(locr0, -code);
718			cpu_set_syscall_retval(td, i);
719
720			/*
721			 * The sync'ing of I & D caches for SYS_ptrace() is
722			 * done by procfs_domem() through procfs_rwmem()
723			 * instead of being done here under a special check
724			 * for SYS_ptrace().
725			 */
726	done:
727			/*
728			 * Check for misbehavior.
729			 */
730			WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
731			    (code >= 0 && code < SYS_MAXSYSCALL) ?
732			    syscallnames[code] : "???");
733			KASSERT(td->td_critnest == 0,
734			    ("System call %s returning in a critical section",
735			    (code >= 0 && code < SYS_MAXSYSCALL) ?
736			    syscallnames[code] : "???"));
737			KASSERT(td->td_locks == 0,
738			    ("System call %s returning with %d locks held",
739			    (code >= 0 && code < SYS_MAXSYSCALL) ?
740			    syscallnames[code] : "???",
741			    td->td_locks));
742			userret(td, trapframe);
743#ifdef KTRACE
744			if (KTRPOINT(td, KTR_SYSRET))
745				ktrsysret(code, i, td->td_retval[0]);
746#endif
747			/*
748			 * This works because errno is findable through the
749			 * register set.  If we ever support an emulation
750			 * where this is not the case, this code will need
751			 * to be revisited.
752			 */
753			STOPEVENT(p, S_SCX, code);
754
755			PTRACESTOP_SC(p, td, S_PT_SCX);
756
757			mtx_assert(&Giant, MA_NOTOWNED);
758			return (trapframe->pc);
759		}
760
761#ifdef DDB
762	case T_BREAK:
763		kdb_trap(type, 0, trapframe);
764		return (trapframe->pc);
765#endif
766
767	case T_BREAK + T_USER:
768		{
769			intptr_t va;
770			uint32_t instr;
771
772			/* compute address of break instruction */
773			va = trapframe->pc;
774			if (DELAYBRANCH(trapframe->cause))
775				va += sizeof(int);
776
777			/* read break instruction */
778			instr = fuword((caddr_t)va);
779#if 0
780			printf("trap: %s (%d) breakpoint %x at %x: (adr %x ins %x)\n",
781			    p->p_comm, p->p_pid, instr, trapframe->pc,
782			    p->p_md.md_ss_addr, p->p_md.md_ss_instr);	/* XXX */
783#endif
784			if (td->td_md.md_ss_addr != va || instr != BREAK_SSTEP) {
785				i = SIGTRAP;
786				addr = trapframe->pc;
787				break;
788			}
789			/*
790			 * The restoration of the original instruction and
791			 * the clearing of the berakpoint will be done later
792			 * by the call to ptrace_clear_single_step() in
793			 * issignal() when SIGTRAP is processed.
794			 */
795			addr = trapframe->pc;
796			i = SIGTRAP;
797			break;
798		}
799
800	case T_IWATCH + T_USER:
801	case T_DWATCH + T_USER:
802		{
803			intptr_t va;
804
805			/* compute address of trapped instruction */
806			va = trapframe->pc;
807			if (DELAYBRANCH(trapframe->cause))
808				va += sizeof(int);
809			printf("watch exception @ %p\n", (void *)va);
810			i = SIGTRAP;
811			addr = va;
812			break;
813		}
814
815	case T_TRAP + T_USER:
816		{
817			intptr_t va;
818			uint32_t instr;
819			struct trapframe *locr0 = td->td_frame;
820
821			/* compute address of trap instruction */
822			va = trapframe->pc;
823			if (DELAYBRANCH(trapframe->cause))
824				va += sizeof(int);
825			/* read break instruction */
826			instr = fuword((caddr_t)va);
827
828			if (DELAYBRANCH(trapframe->cause)) {	/* Check BD bit */
829				locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0,
830				    0);
831			} else {
832				locr0->pc += sizeof(int);
833			}
834			addr = va;
835			i = SIGEMT;	/* Stuff it with something for now */
836			break;
837		}
838
839	case T_RES_INST + T_USER:
840		log_illegal_instruction("RES_INST", trapframe);
841		i = SIGILL;
842		addr = trapframe->pc;
843		break;
844	case T_C2E:
845	case T_C2E + T_USER:
846		goto err;
847		break;
848	case T_COP_UNUSABLE:
849		goto err;
850		break;
851	case T_COP_UNUSABLE + T_USER:
852#if !defined(CPU_HAVEFPU)
853		/* FP (COP1) instruction */
854		if ((trapframe->cause & CR_COP_ERR) == 0x10000000) {
855			log_illegal_instruction("COP1_UNUSABLE", trapframe);
856			i = SIGILL;
857			break;
858		}
859#endif
860		if ((trapframe->cause & CR_COP_ERR) != 0x10000000) {
861			log_illegal_instruction("COPn_UNUSABLE", trapframe);
862			i = SIGILL;	/* only FPU instructions allowed */
863			break;
864		}
865		addr = trapframe->pc;
866		MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame);
867		PCPU_SET(fpcurthread, td);
868		td->td_frame->sr |= SR_COP_1_BIT;
869		td->td_md.md_flags |= MDTD_FPUSED;
870		goto out;
871
872	case T_FPE:
873#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
874		trapDump("fpintr");
875#else
876		printf("FPU Trap: PC %#jx CR %x SR %x\n",
877		    (intmax_t)trapframe->pc, (unsigned)trapframe->cause, (unsigned)trapframe->sr);
878		goto err;
879#endif
880
881	case T_FPE + T_USER:
882		MipsFPTrap(trapframe->sr, trapframe->cause, trapframe->pc);
883		goto out;
884
885	case T_OVFLOW + T_USER:
886		i = SIGFPE;
887		addr = trapframe->pc;
888		break;
889
890	case T_ADDR_ERR_LD:	/* misaligned access */
891	case T_ADDR_ERR_ST:	/* misaligned access */
892#ifdef TRAP_DEBUG
893		printf("+++ ADDR_ERR: type = %d, badvaddr = %#jx\n", type,
894		    (intmax_t)trapframe->badvaddr);
895#endif
896		/* Only allow emulation on a user address */
897		if (allow_unaligned_acc &&
898		    ((vm_offset_t)trapframe->badvaddr < VM_MAXUSER_ADDRESS)) {
899			int mode;
900
901			if (type == T_ADDR_ERR_LD)
902				mode = VM_PROT_READ;
903			else
904				mode = VM_PROT_WRITE;
905
906			/*
907			 * ADDR_ERR faults have higher priority than TLB
908			 * Miss faults.  Therefore, it is necessary to
909			 * verify that the faulting address is a valid
910			 * virtual address within the process' address space
911			 * before trying to emulate the unaligned access.
912			 */
913			if (useracc((caddr_t)
914			    (((vm_offset_t)trapframe->badvaddr) &
915			    ~(sizeof(int) - 1)), sizeof(int) * 2, mode)) {
916				access_type = emulate_unaligned_access(
917				    trapframe);
918				if (access_type != 0) {
919					return (trapframe->pc);
920				}
921			}
922		}
923		/* FALLTHROUGH */
924
925	case T_BUS_ERR_LD_ST:	/* BERR asserted to cpu */
926		if (td->td_pcb->pcb_onfault != NULL) {
927			pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
928			td->td_pcb->pcb_onfault = NULL;
929			return (pc);
930		}
931
932		/* FALLTHROUGH */
933
934	default:
935err:
936
937#if !defined(SMP) && defined(DEBUG)
938		stacktrace(!usermode ? trapframe : td->td_frame);
939		trapDump("trap");
940#endif
941#ifdef SMP
942		printf("cpu:%d-", PCPU_GET(cpuid));
943#endif
944		printf("Trap cause = %d (%s - ", type,
945		    trap_type[type & (~T_USER)]);
946
947		if (type & T_USER)
948			printf("user mode)\n");
949		else
950			printf("kernel mode)\n");
951
952#ifdef TRAP_DEBUG
953		printf("badvaddr = %#jx, pc = %#jx, ra = %#jx, sr = %#jxx\n",
954		       (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
955		       (intmax_t)trapframe->sr);
956#endif
957
958#ifdef KDB
959		if (debugger_on_panic || kdb_active) {
960			kdb_trap(type, 0, trapframe);
961		}
962#endif
963		panic("trap");
964	}
965	td->td_frame->pc = trapframe->pc;
966	td->td_frame->cause = trapframe->cause;
967	td->td_frame->badvaddr = trapframe->badvaddr;
968	ksiginfo_init_trap(&ksi);
969	ksi.ksi_signo = i;
970	ksi.ksi_code = ucode;
971	ksi.ksi_addr = (void *)addr;
972	ksi.ksi_trapno = type;
973	trapsignal(td, &ksi);
974out:
975
976	/*
977	 * Note: we should only get here if returning to user mode.
978	 */
979	userret(td, trapframe);
980	mtx_assert(&Giant, MA_NOTOWNED);
981	return (trapframe->pc);
982}
983
984#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
985void
986trapDump(char *msg)
987{
988	register_t s;
989	int i;
990
991	s = intr_disable();
992	printf("trapDump(%s)\n", msg);
993	for (i = 0; i < TRAPSIZE; i++) {
994		if (trp == trapdebug) {
995			trp = &trapdebug[TRAPSIZE - 1];
996		} else {
997			trp--;
998		}
999
1000		if (trp->cause == 0)
1001			break;
1002
1003		printf("%s: ADR %jx PC %jx CR %jx SR %jx\n",
1004		    trap_type[(trp->cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT],
1005		    (intmax_t)trp->vadr, (intmax_t)trp->pc, (intmax_t)trp->cause, (intmax_t)trp->status);
1006
1007		printf("   RA %jx SP %jx code %d\n", (intmax_t)trp->ra, (intmax_t)trp->sp, (int)trp->code);
1008	}
1009	intr_restore(s);
1010}
1011#endif
1012
1013
1014/*
1015 * Return the resulting PC as if the branch was executed.
1016 */
1017uintptr_t
1018MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR,
1019    uintptr_t instptr)
1020{
1021	InstFmt inst;
1022	register_t *regsPtr = (register_t *) framePtr;
1023	uintptr_t retAddr = 0;
1024	int condition;
1025
1026#define	GetBranchDest(InstPtr, inst) \
1027	(InstPtr + 4 + ((short)inst.IType.imm << 2))
1028
1029
1030	if (instptr) {
1031		if (instptr < MIPS_KSEG0_START)
1032			inst.word = fuword32((void *)instptr);
1033		else
1034			inst = *(InstFmt *) instptr;
1035	} else {
1036		if ((vm_offset_t)instPC < MIPS_KSEG0_START)
1037			inst.word = fuword32((void *)instPC);
1038		else
1039			inst = *(InstFmt *) instPC;
1040	}
1041
1042	switch ((int)inst.JType.op) {
1043	case OP_SPECIAL:
1044		switch ((int)inst.RType.func) {
1045		case OP_JR:
1046		case OP_JALR:
1047			retAddr = regsPtr[inst.RType.rs];
1048			break;
1049
1050		default:
1051			retAddr = instPC + 4;
1052			break;
1053		}
1054		break;
1055
1056	case OP_BCOND:
1057		switch ((int)inst.IType.rt) {
1058		case OP_BLTZ:
1059		case OP_BLTZL:
1060		case OP_BLTZAL:
1061		case OP_BLTZALL:
1062			if ((int)(regsPtr[inst.RType.rs]) < 0)
1063				retAddr = GetBranchDest(instPC, inst);
1064			else
1065				retAddr = instPC + 8;
1066			break;
1067
1068		case OP_BGEZ:
1069		case OP_BGEZL:
1070		case OP_BGEZAL:
1071		case OP_BGEZALL:
1072			if ((int)(regsPtr[inst.RType.rs]) >= 0)
1073				retAddr = GetBranchDest(instPC, inst);
1074			else
1075				retAddr = instPC + 8;
1076			break;
1077
1078		case OP_TGEI:
1079		case OP_TGEIU:
1080		case OP_TLTI:
1081		case OP_TLTIU:
1082		case OP_TEQI:
1083		case OP_TNEI:
1084			retAddr = instPC + 4;	/* Like syscall... */
1085			break;
1086
1087		default:
1088			panic("MipsEmulateBranch: Bad branch cond");
1089		}
1090		break;
1091
1092	case OP_J:
1093	case OP_JAL:
1094		retAddr = (inst.JType.target << 2) |
1095		    ((unsigned)(instPC + 4) & 0xF0000000);
1096		break;
1097
1098	case OP_BEQ:
1099	case OP_BEQL:
1100		if (regsPtr[inst.RType.rs] == regsPtr[inst.RType.rt])
1101			retAddr = GetBranchDest(instPC, inst);
1102		else
1103			retAddr = instPC + 8;
1104		break;
1105
1106	case OP_BNE:
1107	case OP_BNEL:
1108		if (regsPtr[inst.RType.rs] != regsPtr[inst.RType.rt])
1109			retAddr = GetBranchDest(instPC, inst);
1110		else
1111			retAddr = instPC + 8;
1112		break;
1113
1114	case OP_BLEZ:
1115	case OP_BLEZL:
1116		if ((int)(regsPtr[inst.RType.rs]) <= 0)
1117			retAddr = GetBranchDest(instPC, inst);
1118		else
1119			retAddr = instPC + 8;
1120		break;
1121
1122	case OP_BGTZ:
1123	case OP_BGTZL:
1124		if ((int)(regsPtr[inst.RType.rs]) > 0)
1125			retAddr = GetBranchDest(instPC, inst);
1126		else
1127			retAddr = instPC + 8;
1128		break;
1129
1130	case OP_COP1:
1131		switch (inst.RType.rs) {
1132		case OP_BCx:
1133		case OP_BCy:
1134			if ((inst.RType.rt & COPz_BC_TF_MASK) == COPz_BC_TRUE)
1135				condition = fpcCSR & FPC_COND_BIT;
1136			else
1137				condition = !(fpcCSR & FPC_COND_BIT);
1138			if (condition)
1139				retAddr = GetBranchDest(instPC, inst);
1140			else
1141				retAddr = instPC + 8;
1142			break;
1143
1144		default:
1145			retAddr = instPC + 4;
1146		}
1147		break;
1148
1149	default:
1150		retAddr = instPC + 4;
1151	}
1152	return (retAddr);
1153}
1154
1155
1156#if defined(DDB) || defined(DEBUG)
1157/*
1158 * Print a stack backtrace.
1159 */
1160void
1161stacktrace(struct trapframe *regs)
1162{
1163	stacktrace_subr(regs->pc, regs->sp, regs->ra, printf);
1164}
1165#endif
1166
1167static void
1168log_frame_dump(struct trapframe *frame)
1169{
1170	log(LOG_ERR, "Trapframe Register Dump:\n");
1171	log(LOG_ERR, "\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1172	    (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1173
1174	log(LOG_ERR, "\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1175	    (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1176
1177	log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1178	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1179
1180	log(LOG_ERR, "\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1181	    (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1182
1183	log(LOG_ERR, "\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1184	    (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1185
1186	log(LOG_ERR, "\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1187	    (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1188
1189	log(LOG_ERR, "\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1190	    (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1191
1192	log(LOG_ERR, "\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1193	    (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1194
1195	log(LOG_ERR, "\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1196	    (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1197
1198#ifdef IC_REG
1199	log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
1200	    (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
1201#else
1202	log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\n",
1203	    (intmax_t)frame->cause, (intmax_t)frame->pc);
1204#endif
1205}
1206
1207#ifdef TRAP_DEBUG
1208static void
1209trap_frame_dump(struct trapframe *frame)
1210{
1211	printf("Trapframe Register Dump:\n");
1212	printf("\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	printf("\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	printf("\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	printf("\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	printf("\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	printf("\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	printf("\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	printf("\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	printf("\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	printf("\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
1241	    (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
1242#else
1243	printf("\tcause: %#jx\tpc: %#jx\n",
1244	    (intmax_t)frame->cause, (intmax_t)frame->pc);
1245#endif
1246}
1247
1248#endif
1249
1250
1251static void
1252get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp)
1253{
1254	pt_entry_t *ptep;
1255	pd_entry_t *pdep;
1256	struct proc *p = curproc;
1257
1258	pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[(va >> SEGSHIFT) & (NPDEPG - 1)]));
1259	if (*pdep)
1260		ptep = pmap_pte(&p->p_vmspace->vm_pmap, va);
1261	else
1262		ptep = (pt_entry_t *)0;
1263
1264	*pdepp = pdep;
1265	*ptepp = ptep;
1266}
1267
1268static void
1269log_illegal_instruction(const char *msg, struct trapframe *frame)
1270{
1271	pt_entry_t *ptep;
1272	pd_entry_t *pdep;
1273	unsigned int *addr;
1274	struct proc *p = curproc;
1275	register_t pc;
1276
1277#ifdef SMP
1278	printf("cpuid = %d\n", PCPU_GET(cpuid));
1279#endif
1280	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1281	log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %#jx ra %#jx\n",
1282	    msg, p->p_pid, p->p_comm,
1283	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1284	    (intmax_t)pc,
1285	    (intmax_t)frame->ra);
1286
1287	/* log registers in trap frame */
1288	log_frame_dump(frame);
1289
1290	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1291
1292	/*
1293	 * Dump a few words around faulting instruction, if the addres is
1294	 * valid.
1295	 */
1296	if (!(pc & 3) &&
1297	    useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1298		/* dump page table entry for faulting instruction */
1299		log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#x\n",
1300		    (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
1301
1302		addr = (unsigned int *)(intptr_t)pc;
1303		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1304		    addr);
1305		log(LOG_ERR, "%08x %08x %08x %08x\n",
1306		    addr[0], addr[1], addr[2], addr[3]);
1307	} else {
1308		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#x\n",
1309		    (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
1310	}
1311}
1312
1313static void
1314log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
1315{
1316	pt_entry_t *ptep;
1317	pd_entry_t *pdep;
1318	unsigned int *addr;
1319	struct proc *p = curproc;
1320	char *read_or_write;
1321	register_t pc;
1322
1323	trap_type &= ~T_USER;
1324
1325#ifdef SMP
1326	printf("cpuid = %d\n", PCPU_GET(cpuid));
1327#endif
1328	switch (trap_type) {
1329	case T_TLB_ST_MISS:
1330	case T_ADDR_ERR_ST:
1331		read_or_write = "write";
1332		break;
1333	case T_TLB_LD_MISS:
1334	case T_ADDR_ERR_LD:
1335	case T_BUS_ERR_IFETCH:
1336		read_or_write = "read";
1337		break;
1338	default:
1339		read_or_write = "";
1340	}
1341
1342	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1343	log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %#jx got a %s fault at %#jx\n",
1344	    msg, p->p_pid, p->p_comm,
1345	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1346	    (intmax_t)pc,
1347	    read_or_write,
1348	    (intmax_t)frame->badvaddr);
1349
1350	/* log registers in trap frame */
1351	log_frame_dump(frame);
1352
1353	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1354
1355	/*
1356	 * Dump a few words around faulting instruction, if the addres is
1357	 * valid.
1358	 */
1359	if (!(pc & 3) && (pc != frame->badvaddr) &&
1360	    (trap_type != T_BUS_ERR_IFETCH) &&
1361	    useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1362		/* dump page table entry for faulting instruction */
1363		log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#x\n",
1364		    (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
1365
1366		addr = (unsigned int *)(intptr_t)pc;
1367		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1368		    addr);
1369		log(LOG_ERR, "%08x %08x %08x %08x\n",
1370		    addr[0], addr[1], addr[2], addr[3]);
1371	} else {
1372		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#x\n",
1373		    (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
1374	}
1375
1376	get_mapping_info((vm_offset_t)frame->badvaddr, &pdep, &ptep);
1377	log(LOG_ERR, "Page table info for bad address %#jx: pde = %p, pte = %#x\n",
1378	    (intmax_t)frame->badvaddr, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
1379}
1380
1381
1382/*
1383 * Unaligned load/store emulation
1384 */
1385static int
1386mips_unaligned_load_store(struct trapframe *frame, register_t addr, register_t pc)
1387{
1388	register_t *reg = (register_t *) frame;
1389	u_int32_t inst = *((u_int32_t *)(intptr_t)pc);
1390	u_int32_t value_msb, value;
1391	int access_type = 0;
1392
1393	switch (MIPS_INST_OPCODE(inst)) {
1394	case OP_LHU:
1395		lbu_macro(value_msb, addr);
1396		addr += 1;
1397		lbu_macro(value, addr);
1398		value |= value_msb << 8;
1399		reg[MIPS_INST_RT(inst)] = value;
1400		access_type = MIPS_LHU_ACCESS;
1401		break;
1402
1403	case OP_LH:
1404		lb_macro(value_msb, addr);
1405		addr += 1;
1406		lbu_macro(value, addr);
1407		value |= value_msb << 8;
1408		reg[MIPS_INST_RT(inst)] = value;
1409		access_type = MIPS_LH_ACCESS;
1410		break;
1411
1412	case OP_LWU:
1413		lwl_macro(value, addr);
1414		addr += 3;
1415		lwr_macro(value, addr);
1416		value &= 0xffffffff;
1417		reg[MIPS_INST_RT(inst)] = value;
1418		access_type = MIPS_LWU_ACCESS;
1419		break;
1420
1421	case OP_LW:
1422		lwl_macro(value, addr);
1423		addr += 3;
1424		lwr_macro(value, addr);
1425		reg[MIPS_INST_RT(inst)] = value;
1426		access_type = MIPS_LW_ACCESS;
1427		break;
1428
1429	case OP_SH:
1430		value = reg[MIPS_INST_RT(inst)];
1431		value_msb = value >> 8;
1432		sb_macro(value_msb, addr);
1433		addr += 1;
1434		sb_macro(value, addr);
1435		access_type = MIPS_SH_ACCESS;
1436		break;
1437
1438	case OP_SW:
1439		value = reg[MIPS_INST_RT(inst)];
1440		swl_macro(value, addr);
1441		addr += 3;
1442		swr_macro(value, addr);
1443		access_type = MIPS_SW_ACCESS;
1444		break;
1445
1446	default:
1447		break;
1448	}
1449
1450	return access_type;
1451}
1452
1453
1454static int
1455emulate_unaligned_access(struct trapframe *frame)
1456{
1457	register_t pc;
1458	int access_type = 0;
1459
1460	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1461
1462	/*
1463	 * Fall through if it's instruction fetch exception
1464	 */
1465	if (!((pc & 3) || (pc == frame->badvaddr))) {
1466
1467		/*
1468		 * Handle unaligned load and store
1469		 */
1470
1471		/*
1472		 * Return access type if the instruction was emulated.
1473		 * Otherwise restore pc and fall through.
1474		 */
1475		access_type = mips_unaligned_load_store(frame,
1476		    frame->badvaddr, pc);
1477
1478		if (access_type) {
1479			if (DELAYBRANCH(frame->cause))
1480				frame->pc = MipsEmulateBranch(frame, frame->pc,
1481				    0, 0);
1482			else
1483				frame->pc += 4;
1484
1485			log(LOG_INFO, "Unaligned %s: pc=%#jx, badvaddr=%#jx\n",
1486			    access_name[access_type - 1], (intmax_t)pc,
1487			    (intmax_t)frame->badvaddr);
1488		}
1489	}
1490	return access_type;
1491}
1492