trap.c revision 209500
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 209500 2010-06-24 08:08:43Z jchandra $");
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		pid = mips_rd_entryhi() & TLBHI_ASID_MASK;
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 (!pte_test(pte, PTE_V) || pte_test(pte, PTE_D)) {
382				pmap_update_page(kernel_pmap,
383				    trapframe->badvaddr, *pte);
384				PMAP_UNLOCK(kernel_pmap);
385				return (trapframe->pc);
386			}
387#else
388			if (!pte_test(pte, PTE_V) || pte_test(pte, PTE_D))
389				panic("trap: ktlbmod: invalid pte");
390#endif
391			if (pte_test(pte, PTE_RO)) {
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_set(pte, PTE_D);
398			pmap_update_page(kernel_pmap, trapframe->badvaddr, *pte);
399			pa = TLBLO_PTE_TO_PA(*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 (!pte_test(pte, PTE_V) || pte_test(pte, PTE_D)) {
421				pmap_update_page(pmap, trapframe->badvaddr, *pte);
422				PMAP_UNLOCK(pmap);
423				goto out;
424			}
425#else
426			if (!pte_test(pte, PTE_V) || pte_test(pte, PTE_D))
427				panic("trap: utlbmod: invalid pte");
428#endif
429
430			if (pte_test(pte, PTE_RO)) {
431				/* write to read only page */
432				ftype = VM_PROT_WRITE;
433				PMAP_UNLOCK(pmap);
434				goto dofault;
435			}
436			pte_set(pte, PTE_D);
437			pmap_update_page(pmap, trapframe->badvaddr, *pte);
438			pa = TLBLO_PTE_TO_PA(*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#if defined(__mips_n32) || defined(__mips_n64)
629			case SYS___syscall:
630				/*
631				 * Quads fit in a single register in
632				 * new ABIs.
633				 *
634				 * XXX o64?
635				 */
636#endif
637			case SYS_syscall:
638				/*
639				 * Code is first argument, followed by
640				 * actual args.
641				 */
642				code = locr0->a0;
643				args[0] = locr0->a1;
644				args[1] = locr0->a2;
645				args[2] = locr0->a3;
646				nsaved = 3;
647#if defined(__mips_n32) || defined(__mips_n64)
648				args[3] = locr0->t4;
649				args[4] = locr0->t5;
650				args[5] = locr0->t6;
651				args[6] = locr0->t7;
652				nsaved += 4;
653#endif
654				break;
655
656#if defined(__mips_o32)
657			case SYS___syscall:
658				/*
659				 * Like syscall, but code is a quad, so as
660				 * to maintain quad alignment for the rest
661				 * of the arguments.
662				 */
663				if (_QUAD_LOWWORD == 0) {
664					code = locr0->a0;
665				} else {
666					code = locr0->a1;
667				}
668				args[0] = locr0->a2;
669				args[1] = locr0->a3;
670				nsaved = 2;
671				break;
672#endif
673
674			default:
675				args[0] = locr0->a0;
676				args[1] = locr0->a1;
677				args[2] = locr0->a2;
678				args[3] = locr0->a3;
679				nsaved = 4;
680#if defined (__mips_n32) || defined(__mips_n64)
681				args[4] = locr0->t4;
682				args[5] = locr0->t5;
683				args[6] = locr0->t6;
684				args[7] = locr0->t7;
685				nsaved += 4;
686#endif
687			}
688#ifdef TRAP_DEBUG
689			printf("SYSCALL #%d pid:%u\n", code, p->p_pid);
690#endif
691
692			if (p->p_sysent->sv_mask)
693				code &= p->p_sysent->sv_mask;
694
695			if (code >= p->p_sysent->sv_size)
696				callp = &p->p_sysent->sv_table[0];
697			else
698				callp = &p->p_sysent->sv_table[code];
699
700			nargs = callp->sy_narg;
701
702			if (nargs > nsaved) {
703#if defined(__mips_n32) || defined(__mips_n64)
704				/*
705				 * XXX
706				 * Is this right for new ABIs?  I think the 4 there
707				 * should be 8, size there are 8 registers to skip,
708				 * not 4, but I'm not certain.
709				 */
710				printf("SYSCALL #%u pid:%u, nargs > nsaved.\n", code, p->p_pid);
711#endif
712				i = copyin((caddr_t)(intptr_t)(locr0->sp +
713				    4 * sizeof(register_t)), (caddr_t)&args[nsaved],
714				    (u_int)(nargs - nsaved) * sizeof(register_t));
715				if (i) {
716					locr0->v0 = i;
717					locr0->a3 = 1;
718#ifdef KTRACE
719					if (KTRPOINT(td, KTR_SYSCALL))
720						ktrsyscall(code, nargs, args);
721#endif
722					goto done;
723				}
724			}
725#ifdef TRAP_DEBUG
726			for (i = 0; i < nargs; i++) {
727				printf("args[%d] = %#jx\n", i, (intmax_t)args[i]);
728			}
729#endif
730#ifdef SYSCALL_TRACING
731			printf("%s(", syscallnames[code]);
732			for (i = 0; i < nargs; i++) {
733				printf("%s%#jx", i == 0 ? "" : ", ", (intmax_t)args[i]);
734			}
735			printf(")\n");
736#endif
737#ifdef KTRACE
738			if (KTRPOINT(td, KTR_SYSCALL))
739				ktrsyscall(code, nargs, args);
740#endif
741			td->td_retval[0] = 0;
742			td->td_retval[1] = locr0->v1;
743
744#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
745			if (trp == trapdebug)
746				trapdebug[TRAPSIZE - 1].code = code;
747			else
748				trp[-1].code = code;
749#endif
750			STOPEVENT(p, S_SCE, nargs);
751
752			PTRACESTOP_SC(p, td, S_PT_SCE);
753			i = (*callp->sy_call) (td, args);
754#if 0
755			/*
756			 * Reinitialize proc pointer `p' as it may be
757			 * different if this is a child returning from fork
758			 * syscall.
759			 */
760			td = curthread;
761			locr0 = td->td_frame;
762#endif
763			trapdebug_enter(locr0, -code);
764			cpu_set_syscall_retval(td, i);
765
766			/*
767			 * The sync'ing of I & D caches for SYS_ptrace() is
768			 * done by procfs_domem() through procfs_rwmem()
769			 * instead of being done here under a special check
770			 * for SYS_ptrace().
771			 */
772	done:
773			/*
774			 * Check for misbehavior.
775			 */
776			WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
777			    (code >= 0 && code < SYS_MAXSYSCALL) ?
778			    syscallnames[code] : "???");
779			KASSERT(td->td_critnest == 0,
780			    ("System call %s returning in a critical section",
781			    (code >= 0 && code < SYS_MAXSYSCALL) ?
782			    syscallnames[code] : "???"));
783			KASSERT(td->td_locks == 0,
784			    ("System call %s returning with %d locks held",
785			    (code >= 0 && code < SYS_MAXSYSCALL) ?
786			    syscallnames[code] : "???",
787			    td->td_locks));
788			userret(td, trapframe);
789#ifdef KTRACE
790			if (KTRPOINT(td, KTR_SYSRET))
791				ktrsysret(code, i, td->td_retval[0]);
792#endif
793			/*
794			 * This works because errno is findable through the
795			 * register set.  If we ever support an emulation
796			 * where this is not the case, this code will need
797			 * to be revisited.
798			 */
799			STOPEVENT(p, S_SCX, code);
800
801			PTRACESTOP_SC(p, td, S_PT_SCX);
802
803			mtx_assert(&Giant, MA_NOTOWNED);
804			return (trapframe->pc);
805		}
806
807#ifdef DDB
808	case T_BREAK:
809		kdb_trap(type, 0, trapframe);
810		return (trapframe->pc);
811#endif
812
813	case T_BREAK + T_USER:
814		{
815			intptr_t va;
816			uint32_t instr;
817
818			/* compute address of break instruction */
819			va = trapframe->pc;
820			if (DELAYBRANCH(trapframe->cause))
821				va += sizeof(int);
822
823			/* read break instruction */
824			instr = fuword((caddr_t)va);
825#if 0
826			printf("trap: %s (%d) breakpoint %x at %x: (adr %x ins %x)\n",
827			    p->p_comm, p->p_pid, instr, trapframe->pc,
828			    p->p_md.md_ss_addr, p->p_md.md_ss_instr);	/* XXX */
829#endif
830			if (td->td_md.md_ss_addr != va || instr != BREAK_SSTEP) {
831				i = SIGTRAP;
832				addr = trapframe->pc;
833				break;
834			}
835			/*
836			 * The restoration of the original instruction and
837			 * the clearing of the berakpoint will be done later
838			 * by the call to ptrace_clear_single_step() in
839			 * issignal() when SIGTRAP is processed.
840			 */
841			addr = trapframe->pc;
842			i = SIGTRAP;
843			break;
844		}
845
846	case T_IWATCH + T_USER:
847	case T_DWATCH + T_USER:
848		{
849			intptr_t va;
850
851			/* compute address of trapped instruction */
852			va = trapframe->pc;
853			if (DELAYBRANCH(trapframe->cause))
854				va += sizeof(int);
855			printf("watch exception @ %p\n", (void *)va);
856			i = SIGTRAP;
857			addr = va;
858			break;
859		}
860
861	case T_TRAP + T_USER:
862		{
863			intptr_t va;
864			uint32_t instr;
865			struct trapframe *locr0 = td->td_frame;
866
867			/* compute address of trap instruction */
868			va = trapframe->pc;
869			if (DELAYBRANCH(trapframe->cause))
870				va += sizeof(int);
871			/* read break instruction */
872			instr = fuword((caddr_t)va);
873
874			if (DELAYBRANCH(trapframe->cause)) {	/* Check BD bit */
875				locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0,
876				    0);
877			} else {
878				locr0->pc += sizeof(int);
879			}
880			addr = va;
881			i = SIGEMT;	/* Stuff it with something for now */
882			break;
883		}
884
885	case T_RES_INST + T_USER:
886		log_illegal_instruction("RES_INST", trapframe);
887		i = SIGILL;
888		addr = trapframe->pc;
889		break;
890	case T_C2E:
891	case T_C2E + T_USER:
892		goto err;
893		break;
894	case T_COP_UNUSABLE:
895		goto err;
896		break;
897	case T_COP_UNUSABLE + T_USER:
898#if !defined(CPU_HAVEFPU)
899		/* FP (COP1) instruction */
900		if ((trapframe->cause & CR_COP_ERR) == 0x10000000) {
901			log_illegal_instruction("COP1_UNUSABLE", trapframe);
902			i = SIGILL;
903			break;
904		}
905#endif
906		if ((trapframe->cause & CR_COP_ERR) != 0x10000000) {
907			log_illegal_instruction("COPn_UNUSABLE", trapframe);
908			i = SIGILL;	/* only FPU instructions allowed */
909			break;
910		}
911		addr = trapframe->pc;
912		MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame);
913		PCPU_SET(fpcurthread, td);
914		td->td_frame->sr |= SR_COP_1_BIT;
915		td->td_md.md_flags |= MDTD_FPUSED;
916		goto out;
917
918	case T_FPE:
919#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
920		trapDump("fpintr");
921#else
922		printf("FPU Trap: PC %#jx CR %x SR %x\n",
923		    (intmax_t)trapframe->pc, (unsigned)trapframe->cause, (unsigned)trapframe->sr);
924		goto err;
925#endif
926
927	case T_FPE + T_USER:
928		MipsFPTrap(trapframe->sr, trapframe->cause, trapframe->pc);
929		goto out;
930
931	case T_OVFLOW + T_USER:
932		i = SIGFPE;
933		addr = trapframe->pc;
934		break;
935
936	case T_ADDR_ERR_LD:	/* misaligned access */
937	case T_ADDR_ERR_ST:	/* misaligned access */
938#ifdef TRAP_DEBUG
939		printf("+++ ADDR_ERR: type = %d, badvaddr = %#jx\n", type,
940		    (intmax_t)trapframe->badvaddr);
941#endif
942		/* Only allow emulation on a user address */
943		if (allow_unaligned_acc &&
944		    ((vm_offset_t)trapframe->badvaddr < VM_MAXUSER_ADDRESS)) {
945			int mode;
946
947			if (type == T_ADDR_ERR_LD)
948				mode = VM_PROT_READ;
949			else
950				mode = VM_PROT_WRITE;
951
952			/*
953			 * ADDR_ERR faults have higher priority than TLB
954			 * Miss faults.  Therefore, it is necessary to
955			 * verify that the faulting address is a valid
956			 * virtual address within the process' address space
957			 * before trying to emulate the unaligned access.
958			 */
959			if (useracc((caddr_t)
960			    (((vm_offset_t)trapframe->badvaddr) &
961			    ~(sizeof(int) - 1)), sizeof(int) * 2, mode)) {
962				access_type = emulate_unaligned_access(
963				    trapframe);
964				if (access_type != 0) {
965					return (trapframe->pc);
966				}
967			}
968		}
969		/* FALLTHROUGH */
970
971	case T_BUS_ERR_LD_ST:	/* BERR asserted to cpu */
972		if (td->td_pcb->pcb_onfault != NULL) {
973			pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
974			td->td_pcb->pcb_onfault = NULL;
975			return (pc);
976		}
977
978		/* FALLTHROUGH */
979
980	default:
981err:
982
983#if !defined(SMP) && defined(DEBUG)
984		stacktrace(!usermode ? trapframe : td->td_frame);
985		trapDump("trap");
986#endif
987#ifdef SMP
988		printf("cpu:%d-", PCPU_GET(cpuid));
989#endif
990		printf("Trap cause = %d (%s - ", type,
991		    trap_type[type & (~T_USER)]);
992
993		if (type & T_USER)
994			printf("user mode)\n");
995		else
996			printf("kernel mode)\n");
997
998#ifdef TRAP_DEBUG
999		printf("badvaddr = %#jx, pc = %#jx, ra = %#jx, sr = %#jxx\n",
1000		       (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
1001		       (intmax_t)trapframe->sr);
1002#endif
1003
1004#ifdef KDB
1005		if (debugger_on_panic || kdb_active) {
1006			kdb_trap(type, 0, trapframe);
1007		}
1008#endif
1009		panic("trap");
1010	}
1011	td->td_frame->pc = trapframe->pc;
1012	td->td_frame->cause = trapframe->cause;
1013	td->td_frame->badvaddr = trapframe->badvaddr;
1014	ksiginfo_init_trap(&ksi);
1015	ksi.ksi_signo = i;
1016	ksi.ksi_code = ucode;
1017	ksi.ksi_addr = (void *)addr;
1018	ksi.ksi_trapno = type;
1019	trapsignal(td, &ksi);
1020out:
1021
1022	/*
1023	 * Note: we should only get here if returning to user mode.
1024	 */
1025	userret(td, trapframe);
1026	mtx_assert(&Giant, MA_NOTOWNED);
1027	return (trapframe->pc);
1028}
1029
1030#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
1031void
1032trapDump(char *msg)
1033{
1034	register_t s;
1035	int i;
1036
1037	s = intr_disable();
1038	printf("trapDump(%s)\n", msg);
1039	for (i = 0; i < TRAPSIZE; i++) {
1040		if (trp == trapdebug) {
1041			trp = &trapdebug[TRAPSIZE - 1];
1042		} else {
1043			trp--;
1044		}
1045
1046		if (trp->cause == 0)
1047			break;
1048
1049		printf("%s: ADR %jx PC %jx CR %jx SR %jx\n",
1050		    trap_type[(trp->cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT],
1051		    (intmax_t)trp->vadr, (intmax_t)trp->pc, (intmax_t)trp->cause, (intmax_t)trp->status);
1052
1053		printf("   RA %jx SP %jx code %d\n", (intmax_t)trp->ra, (intmax_t)trp->sp, (int)trp->code);
1054	}
1055	intr_restore(s);
1056}
1057#endif
1058
1059
1060/*
1061 * Return the resulting PC as if the branch was executed.
1062 */
1063uintptr_t
1064MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR,
1065    uintptr_t instptr)
1066{
1067	InstFmt inst;
1068	register_t *regsPtr = (register_t *) framePtr;
1069	uintptr_t retAddr = 0;
1070	int condition;
1071
1072#define	GetBranchDest(InstPtr, inst) \
1073	(InstPtr + 4 + ((short)inst.IType.imm << 2))
1074
1075
1076	if (instptr) {
1077		if (instptr < MIPS_KSEG0_START)
1078			inst.word = fuword32((void *)instptr);
1079		else
1080			inst = *(InstFmt *) instptr;
1081	} else {
1082		if ((vm_offset_t)instPC < MIPS_KSEG0_START)
1083			inst.word = fuword32((void *)instPC);
1084		else
1085			inst = *(InstFmt *) instPC;
1086	}
1087
1088	switch ((int)inst.JType.op) {
1089	case OP_SPECIAL:
1090		switch ((int)inst.RType.func) {
1091		case OP_JR:
1092		case OP_JALR:
1093			retAddr = regsPtr[inst.RType.rs];
1094			break;
1095
1096		default:
1097			retAddr = instPC + 4;
1098			break;
1099		}
1100		break;
1101
1102	case OP_BCOND:
1103		switch ((int)inst.IType.rt) {
1104		case OP_BLTZ:
1105		case OP_BLTZL:
1106		case OP_BLTZAL:
1107		case OP_BLTZALL:
1108			if ((int)(regsPtr[inst.RType.rs]) < 0)
1109				retAddr = GetBranchDest(instPC, inst);
1110			else
1111				retAddr = instPC + 8;
1112			break;
1113
1114		case OP_BGEZ:
1115		case OP_BGEZL:
1116		case OP_BGEZAL:
1117		case OP_BGEZALL:
1118			if ((int)(regsPtr[inst.RType.rs]) >= 0)
1119				retAddr = GetBranchDest(instPC, inst);
1120			else
1121				retAddr = instPC + 8;
1122			break;
1123
1124		case OP_TGEI:
1125		case OP_TGEIU:
1126		case OP_TLTI:
1127		case OP_TLTIU:
1128		case OP_TEQI:
1129		case OP_TNEI:
1130			retAddr = instPC + 4;	/* Like syscall... */
1131			break;
1132
1133		default:
1134			panic("MipsEmulateBranch: Bad branch cond");
1135		}
1136		break;
1137
1138	case OP_J:
1139	case OP_JAL:
1140		retAddr = (inst.JType.target << 2) |
1141		    ((unsigned)(instPC + 4) & 0xF0000000);
1142		break;
1143
1144	case OP_BEQ:
1145	case OP_BEQL:
1146		if (regsPtr[inst.RType.rs] == regsPtr[inst.RType.rt])
1147			retAddr = GetBranchDest(instPC, inst);
1148		else
1149			retAddr = instPC + 8;
1150		break;
1151
1152	case OP_BNE:
1153	case OP_BNEL:
1154		if (regsPtr[inst.RType.rs] != regsPtr[inst.RType.rt])
1155			retAddr = GetBranchDest(instPC, inst);
1156		else
1157			retAddr = instPC + 8;
1158		break;
1159
1160	case OP_BLEZ:
1161	case OP_BLEZL:
1162		if ((int)(regsPtr[inst.RType.rs]) <= 0)
1163			retAddr = GetBranchDest(instPC, inst);
1164		else
1165			retAddr = instPC + 8;
1166		break;
1167
1168	case OP_BGTZ:
1169	case OP_BGTZL:
1170		if ((int)(regsPtr[inst.RType.rs]) > 0)
1171			retAddr = GetBranchDest(instPC, inst);
1172		else
1173			retAddr = instPC + 8;
1174		break;
1175
1176	case OP_COP1:
1177		switch (inst.RType.rs) {
1178		case OP_BCx:
1179		case OP_BCy:
1180			if ((inst.RType.rt & COPz_BC_TF_MASK) == COPz_BC_TRUE)
1181				condition = fpcCSR & FPC_COND_BIT;
1182			else
1183				condition = !(fpcCSR & FPC_COND_BIT);
1184			if (condition)
1185				retAddr = GetBranchDest(instPC, inst);
1186			else
1187				retAddr = instPC + 8;
1188			break;
1189
1190		default:
1191			retAddr = instPC + 4;
1192		}
1193		break;
1194
1195	default:
1196		retAddr = instPC + 4;
1197	}
1198	return (retAddr);
1199}
1200
1201
1202#if defined(DDB) || defined(DEBUG)
1203/*
1204 * Print a stack backtrace.
1205 */
1206void
1207stacktrace(struct trapframe *regs)
1208{
1209	stacktrace_subr(regs->pc, regs->sp, regs->ra, printf);
1210}
1211#endif
1212
1213static void
1214log_frame_dump(struct trapframe *frame)
1215{
1216	log(LOG_ERR, "Trapframe Register Dump:\n");
1217	log(LOG_ERR, "\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1218	    (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1219
1220	log(LOG_ERR, "\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1221	    (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1222
1223	log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1224	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1225
1226	log(LOG_ERR, "\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1227	    (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1228
1229	log(LOG_ERR, "\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1230	    (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1231
1232	log(LOG_ERR, "\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1233	    (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1234
1235	log(LOG_ERR, "\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1236	    (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1237
1238	log(LOG_ERR, "\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1239	    (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1240
1241	log(LOG_ERR, "\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1242	    (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1243
1244#ifdef IC_REG
1245	log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
1246	    (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
1247#else
1248	log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\n",
1249	    (intmax_t)frame->cause, (intmax_t)frame->pc);
1250#endif
1251}
1252
1253#ifdef TRAP_DEBUG
1254static void
1255trap_frame_dump(struct trapframe *frame)
1256{
1257	printf("Trapframe Register Dump:\n");
1258	printf("\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1259	    (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1260
1261	printf("\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1262	    (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1263
1264	printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1265	    (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1266
1267	printf("\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1268	    (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1269
1270	printf("\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1271	    (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1272
1273	printf("\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1274	    (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1275
1276	printf("\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1277	    (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1278
1279	printf("\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1280	    (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1281
1282	printf("\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1283	    (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1284
1285#ifdef IC_REG
1286	printf("\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
1287	    (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
1288#else
1289	printf("\tcause: %#jx\tpc: %#jx\n",
1290	    (intmax_t)frame->cause, (intmax_t)frame->pc);
1291#endif
1292}
1293
1294#endif
1295
1296
1297static void
1298get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp)
1299{
1300	pt_entry_t *ptep;
1301	pd_entry_t *pdep;
1302	struct proc *p = curproc;
1303
1304	pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[(va >> SEGSHIFT) & (NPDEPG - 1)]));
1305	if (*pdep)
1306		ptep = pmap_pte(&p->p_vmspace->vm_pmap, va);
1307	else
1308		ptep = (pt_entry_t *)0;
1309
1310	*pdepp = pdep;
1311	*ptepp = ptep;
1312}
1313
1314static void
1315log_illegal_instruction(const char *msg, struct trapframe *frame)
1316{
1317	pt_entry_t *ptep;
1318	pd_entry_t *pdep;
1319	unsigned int *addr;
1320	struct proc *p = curproc;
1321	register_t pc;
1322
1323#ifdef SMP
1324	printf("cpuid = %d\n", PCPU_GET(cpuid));
1325#endif
1326	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1327	log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %#jx ra %#jx\n",
1328	    msg, p->p_pid, p->p_comm,
1329	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1330	    (intmax_t)pc,
1331	    (intmax_t)frame->ra);
1332
1333	/* log registers in trap frame */
1334	log_frame_dump(frame);
1335
1336	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1337
1338	/*
1339	 * Dump a few words around faulting instruction, if the addres is
1340	 * valid.
1341	 */
1342	if (!(pc & 3) &&
1343	    useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1344		/* dump page table entry for faulting instruction */
1345		log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#x\n",
1346		    (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
1347
1348		addr = (unsigned int *)(intptr_t)pc;
1349		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1350		    addr);
1351		log(LOG_ERR, "%08x %08x %08x %08x\n",
1352		    addr[0], addr[1], addr[2], addr[3]);
1353	} else {
1354		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#x\n",
1355		    (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
1356	}
1357}
1358
1359static void
1360log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
1361{
1362	pt_entry_t *ptep;
1363	pd_entry_t *pdep;
1364	unsigned int *addr;
1365	struct proc *p = curproc;
1366	char *read_or_write;
1367	register_t pc;
1368
1369	trap_type &= ~T_USER;
1370
1371#ifdef SMP
1372	printf("cpuid = %d\n", PCPU_GET(cpuid));
1373#endif
1374	switch (trap_type) {
1375	case T_TLB_ST_MISS:
1376	case T_ADDR_ERR_ST:
1377		read_or_write = "write";
1378		break;
1379	case T_TLB_LD_MISS:
1380	case T_ADDR_ERR_LD:
1381	case T_BUS_ERR_IFETCH:
1382		read_or_write = "read";
1383		break;
1384	default:
1385		read_or_write = "";
1386	}
1387
1388	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1389	log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %#jx got a %s fault at %#jx\n",
1390	    msg, p->p_pid, p->p_comm,
1391	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1392	    (intmax_t)pc,
1393	    read_or_write,
1394	    (intmax_t)frame->badvaddr);
1395
1396	/* log registers in trap frame */
1397	log_frame_dump(frame);
1398
1399	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1400
1401	/*
1402	 * Dump a few words around faulting instruction, if the addres is
1403	 * valid.
1404	 */
1405	if (!(pc & 3) && (pc != frame->badvaddr) &&
1406	    (trap_type != T_BUS_ERR_IFETCH) &&
1407	    useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1408		/* dump page table entry for faulting instruction */
1409		log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#x\n",
1410		    (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
1411
1412		addr = (unsigned int *)(intptr_t)pc;
1413		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1414		    addr);
1415		log(LOG_ERR, "%08x %08x %08x %08x\n",
1416		    addr[0], addr[1], addr[2], addr[3]);
1417	} else {
1418		log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#x\n",
1419		    (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
1420	}
1421
1422	get_mapping_info((vm_offset_t)frame->badvaddr, &pdep, &ptep);
1423	log(LOG_ERR, "Page table info for bad address %#jx: pde = %p, pte = %#x\n",
1424	    (intmax_t)frame->badvaddr, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
1425}
1426
1427
1428/*
1429 * Unaligned load/store emulation
1430 */
1431static int
1432mips_unaligned_load_store(struct trapframe *frame, register_t addr, register_t pc)
1433{
1434	register_t *reg = (register_t *) frame;
1435	u_int32_t inst = *((u_int32_t *)(intptr_t)pc);
1436	u_int32_t value_msb, value;
1437	int access_type = 0;
1438
1439	switch (MIPS_INST_OPCODE(inst)) {
1440	case OP_LHU:
1441		lbu_macro(value_msb, addr);
1442		addr += 1;
1443		lbu_macro(value, addr);
1444		value |= value_msb << 8;
1445		reg[MIPS_INST_RT(inst)] = value;
1446		access_type = MIPS_LHU_ACCESS;
1447		break;
1448
1449	case OP_LH:
1450		lb_macro(value_msb, addr);
1451		addr += 1;
1452		lbu_macro(value, addr);
1453		value |= value_msb << 8;
1454		reg[MIPS_INST_RT(inst)] = value;
1455		access_type = MIPS_LH_ACCESS;
1456		break;
1457
1458	case OP_LWU:
1459		lwl_macro(value, addr);
1460		addr += 3;
1461		lwr_macro(value, addr);
1462		value &= 0xffffffff;
1463		reg[MIPS_INST_RT(inst)] = value;
1464		access_type = MIPS_LWU_ACCESS;
1465		break;
1466
1467	case OP_LW:
1468		lwl_macro(value, addr);
1469		addr += 3;
1470		lwr_macro(value, addr);
1471		reg[MIPS_INST_RT(inst)] = value;
1472		access_type = MIPS_LW_ACCESS;
1473		break;
1474
1475	case OP_SH:
1476		value = reg[MIPS_INST_RT(inst)];
1477		value_msb = value >> 8;
1478		sb_macro(value_msb, addr);
1479		addr += 1;
1480		sb_macro(value, addr);
1481		access_type = MIPS_SH_ACCESS;
1482		break;
1483
1484	case OP_SW:
1485		value = reg[MIPS_INST_RT(inst)];
1486		swl_macro(value, addr);
1487		addr += 3;
1488		swr_macro(value, addr);
1489		access_type = MIPS_SW_ACCESS;
1490		break;
1491
1492	default:
1493		break;
1494	}
1495
1496	return access_type;
1497}
1498
1499
1500static int
1501emulate_unaligned_access(struct trapframe *frame)
1502{
1503	register_t pc;
1504	int access_type = 0;
1505
1506	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1507
1508	/*
1509	 * Fall through if it's instruction fetch exception
1510	 */
1511	if (!((pc & 3) || (pc == frame->badvaddr))) {
1512
1513		/*
1514		 * Handle unaligned load and store
1515		 */
1516
1517		/*
1518		 * Return access type if the instruction was emulated.
1519		 * Otherwise restore pc and fall through.
1520		 */
1521		access_type = mips_unaligned_load_store(frame,
1522		    frame->badvaddr, pc);
1523
1524		if (access_type) {
1525			if (DELAYBRANCH(frame->cause))
1526				frame->pc = MipsEmulateBranch(frame, frame->pc,
1527				    0, 0);
1528			else
1529				frame->pc += 4;
1530
1531			log(LOG_INFO, "Unaligned %s: pc=%#jx, badvaddr=%#jx\n",
1532			    access_name[access_type - 1], (intmax_t)pc,
1533			    (intmax_t)frame->badvaddr);
1534		}
1535	}
1536	return access_type;
1537}
1538