trap.c revision 179648
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 179648 2008-06-08 08:56:46Z wkoszek $");
43
44#include "opt_ddb.h"
45#include "opt_global.h"
46
47#define	NO_REG_DEFS	1	/* Prevent asm.h from including regdef.h */
48#include <sys/param.h>
49#include <sys/systm.h>
50#include <sys/sysent.h>
51#include <sys/proc.h>
52#include <sys/kernel.h>
53#include <sys/signalvar.h>
54#include <sys/syscall.h>
55#include <sys/lock.h>
56#include <vm/vm.h>
57#include <vm/vm_extern.h>
58#include <vm/vm_kern.h>
59#include <vm/vm_page.h>
60#include <vm/vm_map.h>
61#include <vm/vm_param.h>
62#include <sys/vmmeter.h>
63#include <sys/ptrace.h>
64#include <sys/user.h>
65#include <sys/buf.h>
66#include <sys/vnode.h>
67#include <sys/pioctl.h>
68#include <sys/sysctl.h>
69#include <sys/syslog.h>
70#include <sys/bus.h>
71#ifdef KTRACE
72#include <sys/ktrace.h>
73#endif
74#include <net/netisr.h>
75
76#include <machine/trap.h>
77#include <machine/psl.h>
78#include <machine/cpu.h>
79#include <machine/intr.h>
80#include <machine/pte.h>
81#include <machine/pmap.h>
82#include <machine/mips_opcode.h>
83#include <machine/frame.h>
84#include <machine/regnum.h>
85#include <machine/rm7000.h>
86#include <machine/archtype.h>
87#include <machine/asm.h>
88
89#ifdef DDB
90#include <machine/db_machdep.h>
91#include <ddb/db_sym.h>
92#include <ddb/ddb.h>
93#include <sys/kdb.h>
94#endif
95
96#include <sys/cdefs.h>
97#include <sys/syslog.h>
98
99
100#ifdef TRAP_DEBUG
101int trap_debug = 1;
102
103#endif
104
105extern unsigned onfault_table[];
106
107extern void MipsKernGenException(void);
108extern void MipsUserGenException(void);
109extern void MipsKernIntr(void);
110extern void MipsUserIntr(void);
111extern void MipsTLBInvalidException(void);
112extern void MipsKernTLBInvalidException(void);
113extern void MipsUserTLBInvalidException(void);
114extern void MipsTLBMissException(void);
115static void log_bad_page_fault(char *, struct trapframe *, int);
116static void log_frame_dump(struct trapframe *frame);
117static void get_mapping_info(vm_offset_t, pd_entry_t **, pt_entry_t **);
118
119#ifdef TRAP_DEBUG
120static void trap_frame_dump(struct trapframe *frame);
121
122#endif
123extern char edata[];
124
125void (*machExceptionTable[]) (void)= {
126/*
127 * The kernel exception handlers.
128 */
129	MipsKernIntr,		/* external interrupt */
130	MipsKernGenException,	/* TLB modification */
131	MipsKernTLBInvalidException,	/* TLB miss (load or instr. fetch) */
132	MipsKernTLBInvalidException,	/* TLB miss (store) */
133	MipsKernGenException,	/* address error (load or I-fetch) */
134	MipsKernGenException,	/* address error (store) */
135	MipsKernGenException,	/* bus error (I-fetch) */
136	MipsKernGenException,	/* bus error (load or store) */
137	MipsKernGenException,	/* system call */
138	MipsKernGenException,	/* breakpoint */
139	MipsKernGenException,	/* reserved instruction */
140	MipsKernGenException,	/* coprocessor unusable */
141	MipsKernGenException,	/* arithmetic overflow */
142	MipsKernGenException,	/* trap exception */
143	MipsKernGenException,	/* virtual coherence exception inst */
144	MipsKernGenException,	/* floating point exception */
145	MipsKernGenException,	/* reserved */
146	MipsKernGenException,	/* reserved */
147	MipsKernGenException,	/* reserved */
148	MipsKernGenException,	/* reserved */
149	MipsKernGenException,	/* reserved */
150	MipsKernGenException,	/* reserved */
151	MipsKernGenException,	/* reserved */
152	MipsKernGenException,	/* watch exception */
153	MipsKernGenException,	/* reserved */
154	MipsKernGenException,	/* reserved */
155	MipsKernGenException,	/* reserved */
156	MipsKernGenException,	/* reserved */
157	MipsKernGenException,	/* reserved */
158	MipsKernGenException,	/* reserved */
159	MipsKernGenException,	/* reserved */
160	MipsKernGenException,	/* virtual coherence exception data */
161/*
162 * The user exception handlers.
163 */
164	MipsUserIntr,		/* 0 */
165	MipsUserGenException,	/* 1 */
166	MipsUserTLBInvalidException,	/* 2 */
167	MipsUserTLBInvalidException,	/* 3 */
168	MipsUserGenException,	/* 4 */
169	MipsUserGenException,	/* 5 */
170	MipsUserGenException,	/* 6 */
171	MipsUserGenException,	/* 7 */
172	MipsUserGenException,	/* 8 */
173	MipsUserGenException,	/* 9 */
174	MipsUserGenException,	/* 10 */
175	MipsUserGenException,	/* 11 */
176	MipsUserGenException,	/* 12 */
177	MipsUserGenException,	/* 13 */
178	MipsUserGenException,	/* 14 */
179	MipsUserGenException,	/* 15 */
180	MipsUserGenException,	/* 16 */
181	MipsUserGenException,	/* 17 */
182	MipsUserGenException,	/* 18 */
183	MipsUserGenException,	/* 19 */
184	MipsUserGenException,	/* 20 */
185	MipsUserGenException,	/* 21 */
186	MipsUserGenException,	/* 22 */
187	MipsUserGenException,	/* 23 */
188	MipsUserGenException,	/* 24 */
189	MipsUserGenException,	/* 25 */
190	MipsUserGenException,	/* 26 */
191	MipsUserGenException,	/* 27 */
192	MipsUserGenException,	/* 28 */
193	MipsUserGenException,	/* 29 */
194	MipsUserGenException,	/* 20 */
195	MipsUserGenException,	/* 31 */
196};
197
198char *trap_type[] = {
199	"external interrupt",
200	"TLB modification",
201	"TLB miss (load or instr. fetch)",
202	"TLB miss (store)",
203	"address error (load or I-fetch)",
204	"address error (store)",
205	"bus error (I-fetch)",
206	"bus error (load or store)",
207	"system call",
208	"breakpoint",
209	"reserved instruction",
210	"coprocessor unusable",
211	"arithmetic overflow",
212	"trap",
213	"virtual coherency instruction",
214	"floating point",
215	"reserved 16",
216	"reserved 17",
217	"reserved 18",
218	"reserved 19",
219	"reserved 20",
220	"reserved 21",
221	"reserved 22",
222	"watch",
223	"reserved 24",
224	"reserved 25",
225	"reserved 26",
226	"reserved 27",
227	"reserved 28",
228	"reserved 29",
229	"reserved 30",
230	"virtual coherency data",
231};
232
233#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
234struct trapdebug trapdebug[TRAPSIZE], *trp = trapdebug;
235
236#endif
237
238#if defined(DDB) || defined(DEBUG)
239void stacktrace(struct trapframe *);
240void logstacktrace(struct trapframe *);
241int kdbpeek(int *);
242
243/* extern functions printed by name in stack backtraces */
244extern void MipsTLBMiss(void);
245extern void MipsUserSyscallException(void);
246extern char _locore[];
247extern char _locoreEnd[];
248
249#endif				/* DDB || DEBUG */
250
251extern void MipsSwitchFPState(struct thread *, struct trapframe *);
252extern void MipsFPTrap(u_int, u_int, u_int);
253
254u_int trap(struct trapframe *);
255u_int MipsEmulateBranch(struct trapframe *, int, int, u_int);
256
257#define	KERNLAND(x) ((int)(x) < 0)
258#define	DELAYBRANCH(x) ((int)(x) < 0)
259
260/*
261 * kdbpeekD(addr) - skip one word starting at 'addr', then read the second word
262 */
263#define	kdbpeekD(addr)	kdbpeek(((int *)(addr)) + 1)
264int rrs_debug = 0;
265
266/*
267 * MIPS load/store access type
268 */
269enum {
270	MIPS_LHU_ACCESS = 1,
271	MIPS_LH_ACCESS,
272	MIPS_LWU_ACCESS,
273	MIPS_LW_ACCESS,
274	MIPS_LD_ACCESS,
275	MIPS_SH_ACCESS,
276	MIPS_SW_ACCESS,
277	MIPS_SD_ACCESS
278};
279
280char *access_name[] = {
281	"Load Halfword Unsigned",
282	"Load Halfword",
283	"Load Word Unsigned",
284	"Load Word",
285	"Load Doubleword",
286	"Store Halfword",
287	"Store Word",
288	"Store Doubleword"
289};
290
291
292static int allow_unaligned_acc = 1;
293
294SYSCTL_INT(_vm, OID_AUTO, allow_unaligned_acc, CTLFLAG_RW,
295    &allow_unaligned_acc, 0, "Allow unaligned accesses");
296
297static int emulate_unaligned_access(struct trapframe *frame);
298
299extern char *syscallnames[];
300
301/*
302 * Handle an exception.
303 * Called from MipsKernGenException() or MipsUserGenException()
304 * when a processor trap occurs.
305 * In the case of a kernel trap, we return the pc where to resume if
306 * p->p_addr->u_pcb.pcb_onfault is set, otherwise, return old pc.
307 */
308u_int
309trap(trapframe)
310	struct trapframe *trapframe;
311{
312	int type, usermode;
313	int i = 0;
314	unsigned ucode = 0;
315	struct thread *td = curthread;
316	struct proc *p = curproc;
317	vm_prot_t ftype;
318	pt_entry_t *pte;
319	unsigned int entry;
320	pmap_t pmap;
321	int quad_syscall = 0;
322	int access_type;
323	ksiginfo_t ksi;
324	char *msg = NULL;
325	register_t addr = 0;
326
327	trapdebug_enter(trapframe, 0);
328
329	type = (trapframe->cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT;
330	if (USERMODE(trapframe->sr)) {
331		type |= T_USER;
332		usermode = 1;
333	} else {
334		usermode = 0;
335	}
336
337	/*
338	 * Enable hardware interrupts if they were on before the trap. If it
339	 * was off disable all (splhigh) so we don't accidently enable it
340	 * when doing a spllower().
341	 */
342/*XXX do in locore? */
343	if (trapframe->sr & SR_INT_ENAB) {
344		set_intr_mask(~(trapframe->sr & ALL_INT_MASK));
345		enableintr();
346	} else {
347		disableintr();
348	}
349
350#ifdef TRAP_DEBUG
351	if (trap_debug) {
352		static vm_offset_t last_badvaddr = 0;
353		static vm_offset_t this_badvaddr = 0;
354		static int count = 0;
355		u_int32_t pid;
356
357		printf("trap type %x (%s - ", type,
358		    trap_type[type & (~T_USER)]);
359
360		if (type & T_USER)
361			printf("user mode)\n");
362		else
363			printf("kernel mode)\n");
364
365#ifdef SMP
366		printf("cpuid = %d\n", PCPU_GET(cpuid));
367#endif
368		MachTLBGetPID(pid);
369		printf("badaddr = %p, pc = %p, ra = %p, sp = %p, sr = 0x%x, pid = %d, ASID = 0x%x\n",
370		    trapframe->badvaddr, trapframe->pc, trapframe->ra,
371		    trapframe->sp, trapframe->sr,
372		    (curproc ? curproc->p_pid : -1), pid);
373
374		switch (type & ~T_USER) {
375		case T_TLB_MOD:
376		case T_TLB_LD_MISS:
377		case T_TLB_ST_MISS:
378		case T_ADDR_ERR_LD:
379		case T_ADDR_ERR_ST:
380			this_badvaddr = trapframe->badvaddr;
381			break;
382		case T_SYSCALL:
383			this_badvaddr = trapframe->ra;
384			break;
385		default:
386			this_badvaddr = trapframe->pc;
387			break;
388		}
389		if ((last_badvaddr == this_badvaddr) &&
390		    ((type & ~T_USER) != T_SYSCALL)) {
391			if (++count == 3) {
392				trap_frame_dump(trapframe);
393				panic("too many faults at %p\n", last_badvaddr);
394			}
395		} else {
396			last_badvaddr = this_badvaddr;
397			count = 0;
398		}
399	}
400#endif
401	switch (type) {
402	case T_MCHECK:
403#ifdef DDB
404		kdb_trap(type, 0, trapframe);
405#endif
406		panic("MCHECK\n");
407		break;
408	case T_TLB_MOD:
409		/* check for kernel address */
410		if (KERNLAND(trapframe->badvaddr)) {
411			vm_offset_t pa;
412
413			PMAP_LOCK(kernel_pmap);
414			if (!(pte = pmap_segmap(kernel_pmap,
415			    trapframe->badvaddr)))
416				panic("trap: ktlbmod: invalid segmap");
417			pte += (trapframe->badvaddr >> PGSHIFT) & (NPTEPG - 1);
418			entry = *pte;
419#ifdef SMP
420			/* It is possible that some other CPU changed m-bit */
421			if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) {
422				trapframe->badvaddr &= ~PGOFSET;
423				pmap_update_page(kernel_pmap,
424				    trapframe->badvaddr, entry);
425				PMAP_UNLOCK(kernel_pmap);
426				return (trapframe->pc);
427			}
428#else
429			if (!mips_pg_v(entry) || (entry & mips_pg_m_bit()))
430				panic("trap: ktlbmod: invalid pte");
431#endif
432			if (entry & mips_pg_ro_bit()) {
433				/* write to read only page in the kernel */
434				ftype = VM_PROT_WRITE;
435				PMAP_UNLOCK(kernel_pmap);
436				goto kernel_fault;
437			}
438			entry |= mips_pg_m_bit();
439			*pte = entry;
440			trapframe->badvaddr &= ~PGOFSET;
441			pmap_update_page(kernel_pmap, trapframe->badvaddr, entry);
442			pa = mips_tlbpfn_to_paddr(entry);
443			if (!page_is_managed(pa))
444				panic("trap: ktlbmod: unmanaged page");
445			pmap_set_modified(pa);
446			PMAP_UNLOCK(kernel_pmap);
447			return (trapframe->pc);
448		}
449		/* FALLTHROUGH */
450
451	case T_TLB_MOD + T_USER:
452		{
453			vm_offset_t pa;
454
455			pmap = &p->p_vmspace->vm_pmap;
456
457			PMAP_LOCK(pmap);
458			if (!(pte = pmap_segmap(pmap, trapframe->badvaddr)))
459				panic("trap: utlbmod: invalid segmap");
460			pte += (trapframe->badvaddr >> PGSHIFT) & (NPTEPG - 1);
461			entry = *pte;
462#ifdef SMP
463			/* It is possible that some other CPU changed m-bit */
464			if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) {
465				trapframe->badvaddr = (trapframe->badvaddr & ~PGOFSET);
466				pmap_update_page(pmap, trapframe->badvaddr, entry);
467				PMAP_UNLOCK(pmap);
468				goto out;
469			}
470#else
471			if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) {
472				panic("trap: utlbmod: invalid pte");
473			}
474#endif
475
476			if (entry & mips_pg_ro_bit()) {
477				/* write to read only page */
478				ftype = VM_PROT_WRITE;
479				PMAP_UNLOCK(pmap);
480				goto dofault;
481			}
482			entry |= mips_pg_m_bit();
483			*pte = entry;
484			trapframe->badvaddr = (trapframe->badvaddr & ~PGOFSET);
485			pmap_update_page(pmap, trapframe->badvaddr, entry);
486			trapframe->badvaddr |= (pmap->pm_asid[PCPU_GET(cpuid)].asid << VMTLB_PID_SHIFT);
487			pa = mips_tlbpfn_to_paddr(entry);
488			if (!page_is_managed(pa))
489				panic("trap: utlbmod: unmanaged page");
490			pmap_set_modified(pa);
491
492			PMAP_UNLOCK(pmap);
493			if (!usermode) {
494				return (trapframe->pc);
495			}
496			goto out;
497		}
498
499	case T_TLB_LD_MISS:
500	case T_TLB_ST_MISS:
501		ftype = (type == T_TLB_ST_MISS) ? VM_PROT_WRITE : VM_PROT_READ;
502		/* check for kernel address */
503		if (KERNLAND(trapframe->badvaddr)) {
504			vm_offset_t va;
505			int rv;
506
507	kernel_fault:
508			va = trunc_page((vm_offset_t)trapframe->badvaddr);
509			rv = vm_fault(kernel_map, va, ftype, VM_FAULT_NORMAL);
510			if (rv == KERN_SUCCESS)
511				return (trapframe->pc);
512			if ((i = td->td_pcb->pcb_onfault) != 0) {
513				td->td_pcb->pcb_onfault = 0;
514				return (onfault_table[i]);
515			}
516			goto err;
517		}
518		/*
519		 * It is an error for the kernel to access user space except
520		 * through the copyin/copyout routines.
521		 */
522		if ((i = td->td_pcb->pcb_onfault) == 0)
523			goto err;
524		/* check for fuswintr() or suswintr() getting a page fault */
525		if (i == 4) {
526			return (onfault_table[i]);
527		}
528		goto dofault;
529
530	case T_TLB_LD_MISS + T_USER:
531		ftype = VM_PROT_READ;
532		goto dofault;
533
534	case T_TLB_ST_MISS + T_USER:
535		ftype = VM_PROT_WRITE;
536dofault:
537		{
538			vm_offset_t va;
539			struct vmspace *vm;
540			vm_map_t map;
541			int rv = 0;
542			int flag;
543
544			vm = p->p_vmspace;
545			map = &vm->vm_map;
546			va = trunc_page((vm_offset_t)trapframe->badvaddr);
547			if ((vm_offset_t)trapframe->badvaddr < VM_MIN_KERNEL_ADDRESS) {
548				if (ftype & VM_PROT_WRITE)
549					flag = VM_FAULT_DIRTY;
550				else
551					flag = VM_FAULT_NORMAL;
552			} else {
553				/*
554				 * Don't allow user-mode faults in kernel
555				 * address space.
556				 */
557				goto nogo;
558			}
559
560			/*
561			 * Keep swapout from messing with us during this
562			 * critical time.
563			 */
564			PROC_LOCK(p);
565			++p->p_lock;
566			PROC_UNLOCK(p);
567
568			rv = vm_fault(map, va, ftype, flag);
569
570			PROC_LOCK(p);
571			--p->p_lock;
572			PROC_UNLOCK(p);
573#ifdef VMFAULT_TRACE
574			printf("vm_fault(%x (pmap %x), %x (%x), %x, %d) -> %x at pc %x\n",
575			    map, &vm->vm_pmap, va, trapframe->badvaddr, ftype, flag,
576			    rv, trapframe->pc);
577#endif
578
579			if (rv == KERN_SUCCESS) {
580				if (!usermode) {
581					return (trapframe->pc);
582				}
583				goto out;
584			}
585	nogo:
586			if (!usermode) {
587				if ((i = td->td_pcb->pcb_onfault) != 0) {
588					td->td_pcb->pcb_onfault = 0;
589					return (onfault_table[i]);
590				}
591				goto err;
592			}
593			ucode = ftype;
594			i = ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
595			addr = trapframe->pc;
596
597			msg = "BAD_PAGE_FAULT";
598			log_bad_page_fault(msg, trapframe, type);
599
600			break;
601		}
602
603	case T_ADDR_ERR_LD + T_USER:	/* misaligned or kseg access */
604	case T_ADDR_ERR_ST + T_USER:	/* misaligned or kseg access */
605		if (allow_unaligned_acc) {
606			int mode;
607
608			if (type == (T_ADDR_ERR_LD + T_USER))
609				mode = VM_PROT_READ;
610			else
611				mode = VM_PROT_WRITE;
612
613			/*
614			 * ADDR_ERR faults have higher priority than TLB
615			 * Miss faults.  Therefore, it is necessary to
616			 * verify that the faulting address is a valid
617			 * virtual address within the process' address space
618			 * before trying to emulate the unaligned access.
619			 */
620			if (useracc((caddr_t)
621			    (((vm_offset_t)trapframe->badvaddr) &
622			    ~(sizeof(int) - 1)), sizeof(int) * 2, mode)) {
623				access_type = emulate_unaligned_access(
624				    trapframe);
625				if (access_type != 0)
626					goto out;
627			}
628		}
629		msg = "ADDRESS_ERR";
630
631		/* FALL THROUGH */
632
633	case T_BUS_ERR_IFETCH + T_USER:	/* BERR asserted to cpu */
634	case T_BUS_ERR_LD_ST + T_USER:	/* BERR asserted to cpu */
635		ucode = 0;	/* XXX should be VM_PROT_something */
636		i = SIGBUS;
637		addr = trapframe->pc;
638		if (!msg)
639			msg = "BUS_ERR";
640		log_bad_page_fault(msg, trapframe, type);
641		break;
642
643	case T_SYSCALL + T_USER:
644		{
645			struct trapframe *locr0 = td->td_frame;
646			struct sysent *callp;
647			unsigned int code;
648			unsigned int tpc;
649			int nargs, nsaved;
650			register_t args[8];
651
652			/*
653			 * note: PCPU_LAZY_INC() can only be used if we can
654			 * afford occassional inaccuracy in the count.
655			 */
656			PCPU_LAZY_INC(cnt.v_syscall);
657			if (td->td_ucred != p->p_ucred)
658				cred_update_thread(td);
659#ifdef KSE
660			if (p->p_flag & P_SA)
661				thread_user_enter(td);
662#endif
663			/* compute next PC after syscall instruction */
664			tpc = trapframe->pc;	/* Remember if restart */
665			if (DELAYBRANCH(trapframe->cause)) {	/* Check BD bit */
666				locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0,
667				    0);
668			} else {
669				locr0->pc += sizeof(int);
670			}
671			code = locr0->v0;
672
673			switch (code) {
674			case SYS_syscall:
675				/*
676				 * Code is first argument, followed by
677				 * actual args.
678				 */
679				code = locr0->a0;
680				args[0] = locr0->a1;
681				args[1] = locr0->a2;
682				args[2] = locr0->a3;
683				nsaved = 3;
684				break;
685
686			case SYS___syscall:
687				/*
688				 * Like syscall, but code is a quad, so as
689				 * to maintain quad alignment for the rest
690				 * of the arguments.
691				 */
692				if (_QUAD_LOWWORD == 0) {
693					code = locr0->a0;
694				} else {
695					code = locr0->a1;
696				}
697				args[0] = locr0->a2;
698				args[1] = locr0->a3;
699				nsaved = 2;
700				quad_syscall = 1;
701				break;
702
703			default:
704				args[0] = locr0->a0;
705				args[1] = locr0->a1;
706				args[2] = locr0->a2;
707				args[3] = locr0->a3;
708				nsaved = 4;
709			}
710#ifdef TRAP_DEBUG
711			printf("SYSCALL #%d pid:%u\n", code, p->p_pid);
712#endif
713
714			if (p->p_sysent->sv_mask)
715				code &= p->p_sysent->sv_mask;
716
717			if (code >= p->p_sysent->sv_size)
718				callp = &p->p_sysent->sv_table[0];
719			else
720				callp = &p->p_sysent->sv_table[code];
721
722			nargs = callp->sy_narg;
723
724			if (nargs > nsaved) {
725				i = copyin((caddr_t)(locr0->sp +
726				    4 * sizeof(register_t)), (caddr_t)&args[nsaved],
727				    (u_int)(nargs - nsaved) * sizeof(register_t));
728				if (i) {
729					locr0->v0 = i;
730					locr0->a3 = 1;
731#ifdef KTRACE
732					if (KTRPOINT(td, KTR_SYSCALL))
733						ktrsyscall(code, nargs, args);
734#endif
735					goto done;
736				}
737			}
738#ifdef KTRACE
739			if (KTRPOINT(td, KTR_SYSCALL))
740				ktrsyscall(code, nargs, args);
741#endif
742			td->td_retval[0] = 0;
743			td->td_retval[1] = locr0->v1;
744
745#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
746			if (trp == trapdebug)
747				trapdebug[TRAPSIZE - 1].code = code;
748			else
749				trp[-1].code = code;
750#endif
751			STOPEVENT(p, S_SCE, nargs);
752
753			PTRACESTOP_SC(p, td, S_PT_SCE);
754			i = (*callp->sy_call) (td, args);
755#if 0
756			/*
757			 * Reinitialize proc pointer `p' as it may be
758			 * different if this is a child returning from fork
759			 * syscall.
760			 */
761			td = curthread;
762			locr0 = td->td_frame;
763#endif
764			trapdebug_enter(locr0, -code);
765			switch (i) {
766			case 0:
767				if (quad_syscall && code != SYS_lseek) {
768					/*
769					 * System call invoked through the
770					 * SYS___syscall interface but the
771					 * return value is really just 32
772					 * bits.
773					 */
774					locr0->v0 = td->td_retval[0];
775					if (_QUAD_LOWWORD)
776						locr0->v1 = td->td_retval[0];
777					locr0->a3 = 0;
778				} else {
779					locr0->v0 = td->td_retval[0];
780					locr0->v1 = td->td_retval[1];
781					locr0->a3 = 0;
782				}
783				break;
784
785			case ERESTART:
786				locr0->pc = tpc;
787				break;
788
789			case EJUSTRETURN:
790				break;	/* nothing to do */
791
792			default:
793				if (quad_syscall && code != SYS_lseek) {
794					locr0->v0 = i;
795					if (_QUAD_LOWWORD)
796						locr0->v1 = i;
797					locr0->a3 = 1;
798				} else {
799					locr0->v0 = i;
800					locr0->a3 = 1;
801				}
802			}
803
804			/*
805			 * The sync'ing of I & D caches for SYS_ptrace() is
806			 * done by procfs_domem() through procfs_rwmem()
807			 * instead of being done here under a special check
808			 * for SYS_ptrace().
809			 */
810	done:
811			/*
812			 * Check for misbehavior.
813			 */
814			WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
815			    (code >= 0 && code < SYS_MAXSYSCALL) ?
816			    syscallnames[code] : "???");
817			KASSERT(td->td_critnest == 0,
818			    ("System call %s returning in a critical section",
819			    (code >= 0 && code < SYS_MAXSYSCALL) ?
820			    syscallnames[code] : "???"));
821			KASSERT(td->td_locks == 0,
822			    ("System call %s returning with %d locks held",
823			    (code >= 0 && code < SYS_MAXSYSCALL) ?
824			    syscallnames[code] : "???",
825			    td->td_locks));
826			userret(td, trapframe);
827#ifdef KTRACE
828			if (KTRPOINT(p, KTR_SYSRET))
829				ktrsysret(code, i, td->td_retval[0]);
830#endif
831			/*
832			 * This works because errno is findable through the
833			 * register set.  If we ever support an emulation
834			 * where this is not the case, this code will need
835			 * to be revisited.
836			 */
837			STOPEVENT(p, S_SCX, code);
838
839			PTRACESTOP_SC(p, td, S_PT_SCX);
840
841			mtx_assert(&Giant, MA_NOTOWNED);
842			return (trapframe->pc);
843		}
844
845#ifdef DDB
846	case T_BREAK:
847		kdb_trap(type, 0, trapframe);
848		return (trapframe->pc);
849#endif
850
851	case T_BREAK + T_USER:
852		{
853			unsigned int va, instr;
854
855			/* compute address of break instruction */
856			va = trapframe->pc;
857			if (DELAYBRANCH(trapframe->cause))
858				va += sizeof(int);
859
860			/* read break instruction */
861			instr = fuword((caddr_t)va);
862#if 0
863			printf("trap: %s (%d) breakpoint %x at %x: (adr %x ins %x)\n",
864			    p->p_comm, p->p_pid, instr, trapframe->pc,
865			    p->p_md.md_ss_addr, p->p_md.md_ss_instr);	/* XXX */
866#endif
867			if (td->td_md.md_ss_addr != va || instr != BREAK_SSTEP) {
868				i = SIGTRAP;
869				addr = trapframe->pc;
870				break;
871			}
872			/*
873			 * The restoration of the original instruction and
874			 * the clearing of the berakpoint will be done later
875			 * by the call to ptrace_clear_single_step() in
876			 * issignal() when SIGTRAP is processed.
877			 */
878			addr = trapframe->pc;
879			i = SIGTRAP;
880			break;
881		}
882
883	case T_IWATCH + T_USER:
884	case T_DWATCH + T_USER:
885		{
886			unsigned int va;
887
888			/* compute address of trapped instruction */
889			va = trapframe->pc;
890			if (DELAYBRANCH(trapframe->cause))
891				va += sizeof(int);
892			printf("watch exception @ 0x%x\n", va);
893			i = SIGTRAP;
894			addr = va;
895			break;
896		}
897
898	case T_TRAP + T_USER:
899		{
900			unsigned int va, instr;
901			struct trapframe *locr0 = td->td_frame;
902
903			/* compute address of trap instruction */
904			va = trapframe->pc;
905			if (DELAYBRANCH(trapframe->cause))
906				va += sizeof(int);
907			/* read break instruction */
908			instr = fuword((caddr_t)va);
909
910			if (DELAYBRANCH(trapframe->cause)) {	/* Check BD bit */
911				locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0,
912				    0);
913			} else {
914				locr0->pc += sizeof(int);
915			}
916			addr = va;
917			i = SIGEMT;	/* Stuff it with something for now */
918			break;
919		}
920
921	case T_RES_INST + T_USER:
922		i = SIGILL;
923		addr = trapframe->pc;
924		break;
925	case T_C2E:
926	case T_C2E + T_USER:
927		goto err;
928		break;
929	case T_COP_UNUSABLE:
930		goto err;
931		break;
932	case T_COP_UNUSABLE + T_USER:
933#if defined(SOFTFLOAT)
934		/* FP (COP1) instruction */
935		if ((trapframe->cause & CR_COP_ERR) == 0x10000000) {
936			i = SIGILL;
937			break;
938		}
939#endif
940		if ((trapframe->cause & CR_COP_ERR) != 0x10000000) {
941			i = SIGILL;	/* only FPU instructions allowed */
942			break;
943		}
944		addr = trapframe->pc;
945		MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame);
946		PCPU_SET(fpcurthread, td);
947		td->td_frame->sr |= SR_COP_1_BIT;
948		td->td_md.md_flags |= MDTD_FPUSED;
949		goto out;
950
951	case T_FPE:
952#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
953		trapDump("fpintr");
954#else
955		printf("FPU Trap: PC %x CR %x SR %x\n",
956		    trapframe->pc, trapframe->cause, trapframe->sr);
957		goto err;
958#endif
959
960	case T_FPE + T_USER:
961		MachFPTrap(trapframe->sr, trapframe->cause, trapframe->pc);
962		goto out;
963
964	case T_OVFLOW + T_USER:
965		i = SIGFPE;
966		addr = trapframe->pc;
967		break;
968
969	case T_ADDR_ERR_LD:	/* misaligned access */
970	case T_ADDR_ERR_ST:	/* misaligned access */
971#ifdef TRAP_DEBUG
972		printf("+++ ADDR_ERR: type = %d, badvaddr = %x\n", type,
973		    trapframe->badvaddr);
974#endif
975		/* Only allow emulation on a user address */
976		if (allow_unaligned_acc &&
977		    ((vm_offset_t)trapframe->badvaddr < VM_MAXUSER_ADDRESS)) {
978			int mode;
979
980			if (type == T_ADDR_ERR_LD)
981				mode = VM_PROT_READ;
982			else
983				mode = VM_PROT_WRITE;
984
985			/*
986			 * ADDR_ERR faults have higher priority than TLB
987			 * Miss faults.  Therefore, it is necessary to
988			 * verify that the faulting address is a valid
989			 * virtual address within the process' address space
990			 * before trying to emulate the unaligned access.
991			 */
992			if (useracc((caddr_t)
993			    (((vm_offset_t)trapframe->badvaddr) &
994			    ~(sizeof(int) - 1)), sizeof(int) * 2, mode)) {
995				access_type = emulate_unaligned_access(
996				    trapframe);
997				if (access_type != 0) {
998					return (trapframe->pc);
999				}
1000			}
1001		}
1002		/* FALLTHROUGH */
1003
1004	case T_BUS_ERR_LD_ST:	/* BERR asserted to cpu */
1005		if ((i = td->td_pcb->pcb_onfault) != 0) {
1006			td->td_pcb->pcb_onfault = 0;
1007			return (onfault_table[i]);
1008		}
1009		/* FALLTHROUGH */
1010
1011	default:
1012err:
1013
1014#if !defined(SMP) && defined(DEBUG)
1015		stacktrace(!usermode ? trapframe : td->td_frame);
1016		trapDump("trap");
1017#endif
1018#ifdef SMP
1019		printf("cpu:%d-", PCPU_GET(cpuid));
1020#endif
1021		printf("Trap cause = %d (%s - ", type,
1022		    trap_type[type & (~T_USER)]);
1023
1024		if (type & T_USER)
1025			printf("user mode)\n");
1026		else
1027			printf("kernel mode)\n");
1028
1029#ifdef TRAP_DEBUG
1030		printf("badvaddr = %x, pc = %x, ra = %x, sr = 0x%x\n",
1031		       trapframe->badvaddr, trapframe->pc, trapframe->ra,
1032		       trapframe->sr);
1033#endif
1034
1035#ifdef KDB
1036		if (debugger_on_panic || kdb_active) {
1037			kdb_trap(type, 0, trapframe);
1038		}
1039#endif
1040		panic("trap");
1041	}
1042	td->td_frame->pc = trapframe->pc;
1043	td->td_frame->cause = trapframe->cause;
1044	td->td_frame->badvaddr = trapframe->badvaddr;
1045	ksiginfo_init_trap(&ksi);
1046	ksi.ksi_signo = i;
1047	ksi.ksi_code = ucode;
1048	ksi.ksi_addr = (void *)addr;
1049	ksi.ksi_trapno = type;
1050	trapsignal(td, &ksi);
1051out:
1052
1053	/*
1054	 * Note: we should only get here if returning to user mode.
1055	 */
1056	userret(td, trapframe);
1057	mtx_assert(&Giant, MA_NOTOWNED);
1058	return (trapframe->pc);
1059}
1060
1061#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
1062void
1063trapDump(char *msg)
1064{
1065	int i, s;
1066
1067	s = disableintr();
1068	printf("trapDump(%s)\n", msg);
1069	for (i = 0; i < TRAPSIZE; i++) {
1070		if (trp == trapdebug) {
1071			trp = &trapdebug[TRAPSIZE - 1];
1072		} else {
1073			trp--;
1074		}
1075
1076		if (trp->cause == 0)
1077			break;
1078
1079		printf("%s: ADR %x PC %x CR %x SR %x\n",
1080		    trap_type[(trp->cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT],
1081		    trp->vadr, trp->pc, trp->cause, trp->status);
1082
1083		printf("   RA %x SP %x code %d\n", trp->ra, trp->sp, trp->code);
1084	}
1085	restoreintr(s);
1086}
1087
1088#endif
1089
1090
1091/*
1092 * Return the resulting PC as if the branch was executed.
1093 */
1094u_int
1095MipsEmulateBranch(struct trapframe *framePtr, int instPC, int fpcCSR,
1096    u_int instptr)
1097{
1098	InstFmt inst;
1099	register_t *regsPtr = (register_t *) framePtr;
1100	unsigned retAddr = 0;
1101	int condition;
1102
1103#define	GetBranchDest(InstPtr, inst) \
1104	((unsigned)InstPtr + 4 + ((short)inst.IType.imm << 2))
1105
1106
1107	if (instptr) {
1108		if (instptr < MIPS_KSEG0_START)
1109			inst.word = fuword((void *)instptr);
1110		else
1111			inst = *(InstFmt *) instptr;
1112	} else {
1113		if ((vm_offset_t)instPC < MIPS_KSEG0_START)
1114			inst.word = fuword((void *)instPC);
1115		else
1116			inst = *(InstFmt *) instPC;
1117	}
1118
1119	switch ((int)inst.JType.op) {
1120	case OP_SPECIAL:
1121		switch ((int)inst.RType.func) {
1122		case OP_JR:
1123		case OP_JALR:
1124			retAddr = regsPtr[inst.RType.rs];
1125			break;
1126
1127		default:
1128			retAddr = instPC + 4;
1129			break;
1130		}
1131		break;
1132
1133	case OP_BCOND:
1134		switch ((int)inst.IType.rt) {
1135		case OP_BLTZ:
1136		case OP_BLTZL:
1137		case OP_BLTZAL:
1138		case OP_BLTZALL:
1139			if ((int)(regsPtr[inst.RType.rs]) < 0)
1140				retAddr = GetBranchDest(instPC, inst);
1141			else
1142				retAddr = instPC + 8;
1143			break;
1144
1145		case OP_BGEZ:
1146		case OP_BGEZL:
1147		case OP_BGEZAL:
1148		case OP_BGEZALL:
1149			if ((int)(regsPtr[inst.RType.rs]) >= 0)
1150				retAddr = GetBranchDest(instPC, inst);
1151			else
1152				retAddr = instPC + 8;
1153			break;
1154
1155		case OP_TGEI:
1156		case OP_TGEIU:
1157		case OP_TLTI:
1158		case OP_TLTIU:
1159		case OP_TEQI:
1160		case OP_TNEI:
1161			retAddr = instPC + 4;	/* Like syscall... */
1162			break;
1163
1164		default:
1165			panic("MipsEmulateBranch: Bad branch cond");
1166		}
1167		break;
1168
1169	case OP_J:
1170	case OP_JAL:
1171		retAddr = (inst.JType.target << 2) |
1172		    ((unsigned)instPC & 0xF0000000);
1173		break;
1174
1175	case OP_BEQ:
1176	case OP_BEQL:
1177		if (regsPtr[inst.RType.rs] == regsPtr[inst.RType.rt])
1178			retAddr = GetBranchDest(instPC, inst);
1179		else
1180			retAddr = instPC + 8;
1181		break;
1182
1183	case OP_BNE:
1184	case OP_BNEL:
1185		if (regsPtr[inst.RType.rs] != regsPtr[inst.RType.rt])
1186			retAddr = GetBranchDest(instPC, inst);
1187		else
1188			retAddr = instPC + 8;
1189		break;
1190
1191	case OP_BLEZ:
1192	case OP_BLEZL:
1193		if ((int)(regsPtr[inst.RType.rs]) <= 0)
1194			retAddr = GetBranchDest(instPC, inst);
1195		else
1196			retAddr = instPC + 8;
1197		break;
1198
1199	case OP_BGTZ:
1200	case OP_BGTZL:
1201		if ((int)(regsPtr[inst.RType.rs]) > 0)
1202			retAddr = GetBranchDest(instPC, inst);
1203		else
1204			retAddr = instPC + 8;
1205		break;
1206
1207	case OP_COP1:
1208		switch (inst.RType.rs) {
1209		case OP_BCx:
1210		case OP_BCy:
1211			if ((inst.RType.rt & COPz_BC_TF_MASK) == COPz_BC_TRUE)
1212				condition = fpcCSR & FPC_COND_BIT;
1213			else
1214				condition = !(fpcCSR & FPC_COND_BIT);
1215			if (condition)
1216				retAddr = GetBranchDest(instPC, inst);
1217			else
1218				retAddr = instPC + 8;
1219			break;
1220
1221		default:
1222			retAddr = instPC + 4;
1223		}
1224		break;
1225
1226	default:
1227		retAddr = instPC + 4;
1228	}
1229	return (retAddr);
1230}
1231
1232
1233#if defined(DDB) || defined(DEBUG)
1234#define	MIPS_JR_RA	0x03e00008	/* instruction code for jr ra */
1235
1236/* forward */
1237char *fn_name(unsigned addr);
1238
1239/*
1240 * Print a stack backtrace.
1241 */
1242void
1243stacktrace(struct trapframe *regs)
1244{
1245	stacktrace_subr(regs, printf);
1246}
1247
1248void
1249stacktrace_subr(struct trapframe *regs, int (*printfn) (const char *,...))
1250{
1251	InstFmt i;
1252	unsigned a0, a1, a2, a3, pc, sp, fp, ra, va, subr;
1253	unsigned instr, mask;
1254	unsigned int frames = 0;
1255	int more, stksize;
1256
1257	/* get initial values from the exception frame */
1258	sp = regs->sp;
1259	pc = regs->pc;
1260	fp = regs->s8;
1261	ra = regs->ra;		/* May be a 'leaf' function */
1262	a0 = regs->a0;
1263	a1 = regs->a1;
1264	a2 = regs->a2;
1265	a3 = regs->a3;
1266
1267/* Jump here when done with a frame, to start a new one */
1268loop:
1269
1270/* Jump here after a nonstandard (interrupt handler) frame */
1271	stksize = 0;
1272	subr = 0;
1273	if (frames++ > 100) {
1274		(*printfn) ("\nstackframe count exceeded\n");
1275		/* return breaks stackframe-size heuristics with gcc -O2 */
1276		goto finish;	/* XXX */
1277	}
1278	/* check for bad SP: could foul up next frame */
1279	if (sp & 3 || sp < 0x80000000) {
1280		(*printfn) ("SP 0x%x: not in kernel\n", sp);
1281		ra = 0;
1282		subr = 0;
1283		goto done;
1284	}
1285#define Between(x, y, z) \
1286		( ((x) <= (y)) && ((y) < (z)) )
1287#define pcBetween(a,b) \
1288		Between((unsigned)a, pc, (unsigned)b)
1289
1290	/*
1291	 * Check for current PC in  exception handler code that don't have a
1292	 * preceding "j ra" at the tail of the preceding function. Depends
1293	 * on relative ordering of functions in exception.S, swtch.S.
1294	 */
1295	if (pcBetween(MipsKernGenException, MipsUserGenException))
1296		subr = (unsigned)MipsKernGenException;
1297	else if (pcBetween(MipsUserGenException, MipsKernIntr))
1298		subr = (unsigned)MipsUserGenException;
1299	else if (pcBetween(MipsKernIntr, MipsUserIntr))
1300		subr = (unsigned)MipsKernIntr;
1301	else if (pcBetween(MipsUserIntr, MipsTLBInvalidException))
1302		subr = (unsigned)MipsUserIntr;
1303	else if (pcBetween(MipsTLBInvalidException,
1304	    MipsKernTLBInvalidException))
1305		subr = (unsigned)MipsTLBInvalidException;
1306	else if (pcBetween(MipsKernTLBInvalidException,
1307	    MipsUserTLBInvalidException))
1308		subr = (unsigned)MipsKernTLBInvalidException;
1309	else if (pcBetween(MipsUserTLBInvalidException, MipsTLBMissException))
1310		subr = (unsigned)MipsUserTLBInvalidException;
1311	else if (pcBetween(cpu_switch, MipsSwitchFPState))
1312		subr = (unsigned)cpu_switch;
1313	else if (pcBetween(_locore, _locoreEnd)) {
1314		subr = (unsigned)_locore;
1315		ra = 0;
1316		goto done;
1317	}
1318	/* check for bad PC */
1319	if (pc & 3 || pc < (unsigned)0x80000000 || pc >= (unsigned)edata) {
1320		(*printfn) ("PC 0x%x: not in kernel\n", pc);
1321		ra = 0;
1322		goto done;
1323	}
1324	/*
1325	 * Find the beginning of the current subroutine by scanning
1326	 * backwards from the current PC for the end of the previous
1327	 * subroutine.
1328	 */
1329	if (!subr) {
1330		va = pc - sizeof(int);
1331		while ((instr = kdbpeek((int *)va)) != MIPS_JR_RA)
1332			va -= sizeof(int);
1333		va += 2 * sizeof(int);	/* skip back over branch & delay slot */
1334		/* skip over nulls which might separate .o files */
1335		while ((instr = kdbpeek((int *)va)) == 0)
1336			va += sizeof(int);
1337		subr = va;
1338	}
1339	/* scan forwards to find stack size and any saved registers */
1340	stksize = 0;
1341	more = 3;
1342	mask = 0;
1343	for (va = subr; more; va += sizeof(int),
1344	    more = (more == 3) ? 3 : more - 1) {
1345		/* stop if hit our current position */
1346		if (va >= pc)
1347			break;
1348		instr = kdbpeek((int *)va);
1349		i.word = instr;
1350		switch (i.JType.op) {
1351		case OP_SPECIAL:
1352			switch (i.RType.func) {
1353			case OP_JR:
1354			case OP_JALR:
1355				more = 2;	/* stop after next instruction */
1356				break;
1357
1358			case OP_SYSCALL:
1359			case OP_BREAK:
1360				more = 1;	/* stop now */
1361			};
1362			break;
1363
1364		case OP_BCOND:
1365		case OP_J:
1366		case OP_JAL:
1367		case OP_BEQ:
1368		case OP_BNE:
1369		case OP_BLEZ:
1370		case OP_BGTZ:
1371			more = 2;	/* stop after next instruction */
1372			break;
1373
1374		case OP_COP0:
1375		case OP_COP1:
1376		case OP_COP2:
1377		case OP_COP3:
1378			switch (i.RType.rs) {
1379			case OP_BCx:
1380			case OP_BCy:
1381				more = 2;	/* stop after next instruction */
1382			};
1383			break;
1384
1385		case OP_SW:
1386			/* look for saved registers on the stack */
1387			if (i.IType.rs != 29)
1388				break;
1389			/* only restore the first one */
1390			if (mask & (1 << i.IType.rt))
1391				break;
1392			mask |= (1 << i.IType.rt);
1393			switch (i.IType.rt) {
1394			case 4:/* a0 */
1395				a0 = kdbpeek((int *)(sp + (short)i.IType.imm));
1396				break;
1397
1398			case 5:/* a1 */
1399				a1 = kdbpeek((int *)(sp + (short)i.IType.imm));
1400				break;
1401
1402			case 6:/* a2 */
1403				a2 = kdbpeek((int *)(sp + (short)i.IType.imm));
1404				break;
1405
1406			case 7:/* a3 */
1407				a3 = kdbpeek((int *)(sp + (short)i.IType.imm));
1408				break;
1409
1410			case 30:	/* fp */
1411				fp = kdbpeek((int *)(sp + (short)i.IType.imm));
1412				break;
1413
1414			case 31:	/* ra */
1415				ra = kdbpeek((int *)(sp + (short)i.IType.imm));
1416			}
1417			break;
1418
1419		case OP_SD:
1420			/* look for saved registers on the stack */
1421			if (i.IType.rs != 29)
1422				break;
1423			/* only restore the first one */
1424			if (mask & (1 << i.IType.rt))
1425				break;
1426			mask |= (1 << i.IType.rt);
1427			switch (i.IType.rt) {
1428			case 4:/* a0 */
1429				a0 = kdbpeekD((int *)(sp + (short)i.IType.imm));
1430				break;
1431
1432			case 5:/* a1 */
1433				a1 = kdbpeekD((int *)(sp + (short)i.IType.imm));
1434				break;
1435
1436			case 6:/* a2 */
1437				a2 = kdbpeekD((int *)(sp + (short)i.IType.imm));
1438				break;
1439
1440			case 7:/* a3 */
1441				a3 = kdbpeekD((int *)(sp + (short)i.IType.imm));
1442				break;
1443
1444			case 30:	/* fp */
1445				fp = kdbpeekD((int *)(sp + (short)i.IType.imm));
1446				break;
1447
1448			case 31:	/* ra */
1449				ra = kdbpeekD((int *)(sp + (short)i.IType.imm));
1450			}
1451			break;
1452
1453		case OP_ADDI:
1454		case OP_ADDIU:
1455			/* look for stack pointer adjustment */
1456			if (i.IType.rs != 29 || i.IType.rt != 29)
1457				break;
1458			stksize = -((short)i.IType.imm);
1459		}
1460	}
1461
1462done:
1463	(*printfn) ("%s+%x (%x,%x,%x,%x) ra %x sz %d\n",
1464	    fn_name(subr), pc - subr, a0, a1, a2, a3, ra, stksize);
1465
1466	if (ra) {
1467		if (pc == ra && stksize == 0)
1468			(*printfn) ("stacktrace: loop!\n");
1469		else {
1470			pc = ra;
1471			sp += stksize;
1472			ra = 0;
1473			goto loop;
1474		}
1475	} else {
1476finish:
1477		if (curproc)
1478			(*printfn) ("pid %d\n", curproc->p_pid);
1479		else
1480			(*printfn) ("curproc NULL\n");
1481	}
1482}
1483
1484/*
1485 * Functions ``special'' enough to print by name
1486 */
1487#ifdef __STDC__
1488#define	Name(_fn)  { (void*)_fn, # _fn }
1489#else
1490#define	Name(_fn) { _fn, "_fn"}
1491#endif
1492static struct {
1493	void *addr;
1494	char *name;
1495}      names[] = {
1496
1497	Name(trap),
1498	Name(MipsKernGenException),
1499	Name(MipsUserGenException),
1500	Name(MipsKernIntr),
1501	Name(MipsUserIntr),
1502	Name(cpu_switch),
1503	{
1504		0, 0
1505	}
1506};
1507
1508/*
1509 * Map a function address to a string name, if known; or a hex string.
1510 */
1511char *
1512fn_name(unsigned addr)
1513{
1514	static char buf[17];
1515	int i = 0;
1516
1517#ifdef DDB
1518	db_expr_t diff;
1519	c_db_sym_t sym;
1520	char *symname;
1521
1522	diff = 0;
1523	symname = NULL;
1524	sym = db_search_symbol((db_addr_t)addr, DB_STGY_ANY, &diff);
1525	db_symbol_values(sym, (const char **)&symname, (db_expr_t *)0);
1526	if (symname && diff == 0)
1527		return (symname);
1528#endif
1529
1530	for (i = 0; names[i].name; i++)
1531		if (names[i].addr == (void *)addr)
1532			return (names[i].name);
1533	sprintf(buf, "%x", addr);
1534	return (buf);
1535}
1536
1537#endif				/* DDB */
1538
1539static void
1540log_frame_dump(struct trapframe *frame)
1541{
1542	log(LOG_ERR, "Trapframe Register Dump:\n");
1543	log(LOG_ERR, "\tzero: %08x\tat: %08x\tv0: %08x\tv1: %08x\n",
1544	    0, frame->ast, frame->v0, frame->v1);
1545
1546	log(LOG_ERR, "\ta0: %08x\ta1: %08x\ta2: %08x\ta3: %08x\n",
1547	    frame->a0, frame->a1, frame->a2, frame->a3);
1548
1549	log(LOG_ERR, "\tt0: %08x\tt1: %08x\tt2: %08x\tt3: %08x\n",
1550	    frame->t0, frame->t1, frame->t2, frame->t3);
1551
1552	log(LOG_ERR, "\tt4: %08x\tt5: %08x\tt6: %08x\tt7: %08x\n",
1553	    frame->t4, frame->t5, frame->t6, frame->t7);
1554
1555	log(LOG_ERR, "\tt8: %08x\tt9: %08x\ts0: %08x\ts1: %08x\n",
1556	    frame->t8, frame->t9, frame->s0, frame->s1);
1557
1558	log(LOG_ERR, "\ts2: %08x\ts3: %08x\ts4: %08x\ts5: %08x\n",
1559	    frame->s2, frame->s3, frame->s4, frame->s5);
1560
1561	log(LOG_ERR, "\ts6: %08x\ts7: %08x\tk0: %08x\tk1: %08x\n",
1562	    frame->s6, frame->s7, frame->k0, frame->k1);
1563
1564	log(LOG_ERR, "\tgp: %08x\tsp: %08x\ts8: %08x\tra: %08x\n",
1565	    frame->gp, frame->sp, frame->s8, frame->ra);
1566
1567	log(LOG_ERR, "\tsr: %08x\tmullo: %08x\tmulhi: %08x\tbadvaddr: %08x\n",
1568	    frame->sr, frame->mullo, frame->mulhi, frame->badvaddr);
1569
1570#ifdef IC_REG
1571	log(LOG_ERR, "\tcause: %08x\tpc: %08x\tic: %08x\n",
1572	    frame->cause, frame->pc, frame->ic);
1573#else
1574	log(LOG_ERR, "\tcause: %08x\tpc: %08x\n",
1575	    frame->cause, frame->pc);
1576#endif
1577}
1578
1579#ifdef TRAP_DEBUG
1580static void
1581trap_frame_dump(struct trapframe *frame)
1582{
1583	printf("Trapframe Register Dump:\n");
1584	printf("\tzero: %08x\tat: %08x\tv0: %08x\tv1: %08x\n",
1585	    0, frame->ast, frame->v0, frame->v1);
1586
1587	printf("\ta0: %08x\ta1: %08x\ta2: %08x\ta3: %08x\n",
1588	    frame->a0, frame->a1, frame->a2, frame->a3);
1589
1590	printf("\tt0: %08x\tt1: %08x\tt2: %08x\tt3: %08x\n",
1591	    frame->t0, frame->t1, frame->t2, frame->t3);
1592
1593	printf("\tt4: %08x\tt5: %08x\tt6: %08x\tt7: %08x\n",
1594	    frame->t4, frame->t5, frame->t6, frame->t7);
1595
1596	printf("\tt8: %08x\tt9: %08x\ts0: %08x\ts1: %08x\n",
1597	    frame->t8, frame->t9, frame->s0, frame->s1);
1598
1599	printf("\ts2: %08x\ts3: %08x\ts4: %08x\ts5: %08x\n",
1600	    frame->s2, frame->s3, frame->s4, frame->s5);
1601
1602	printf("\ts6: %08x\ts7: %08x\tk0: %08x\tk1: %08x\n",
1603	    frame->s6, frame->s7, frame->k0, frame->k1);
1604
1605	printf("\tgp: %08x\tsp: %08x\ts8: %08x\tra: %08x\n",
1606	    frame->gp, frame->sp, frame->s8, frame->ra);
1607
1608	printf("\tsr: %08x\tmullo: %08x\tmulhi: %08x\tbadvaddr: %08x\n",
1609	    frame->sr, frame->mullo, frame->mulhi, frame->badvaddr);
1610
1611#ifdef IC_REG
1612	printf("\tcause: %08x\tpc: %08x\tic: %08x\n",
1613	    frame->cause, frame->pc, frame->ic);
1614#else
1615	printf("\tcause: %08x\tpc: %08x\n",
1616	    frame->cause, frame->pc);
1617#endif
1618}
1619
1620#endif
1621
1622
1623static void
1624get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp)
1625{
1626	pt_entry_t *ptep;
1627	pd_entry_t *pdep;
1628	struct proc *p = curproc;
1629
1630	pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[va >> SEGSHIFT]));
1631	if (*pdep)
1632		ptep = pmap_pte(&p->p_vmspace->vm_pmap, va);
1633	else
1634		ptep = (pt_entry_t *)0;
1635
1636	*pdepp = pdep;
1637	*ptepp = ptep;
1638}
1639
1640
1641static void
1642log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
1643{
1644	pt_entry_t *ptep;
1645	pd_entry_t *pdep;
1646	unsigned int *addr;
1647	struct proc *p = curproc;
1648	char *read_or_write;
1649	register_t pc;
1650
1651	trap_type &= ~T_USER;
1652
1653#ifdef SMP
1654	printf("cpuid = %d\n", PCPU_GET(cpuid));
1655#endif
1656	switch (trap_type) {
1657	case T_TLB_ST_MISS:
1658	case T_ADDR_ERR_ST:
1659		read_or_write = "write";
1660		break;
1661	case T_TLB_LD_MISS:
1662	case T_ADDR_ERR_LD:
1663	case T_BUS_ERR_IFETCH:
1664		read_or_write = "read";
1665		break;
1666	default:
1667		read_or_write = "";
1668	}
1669
1670	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1671	log(LOG_ERR, "%s: pid %d (%s), uid %d: pc 0x%x got a %s fault at 0x%x\n",
1672	    msg, p->p_pid, p->p_comm,
1673	    p->p_ucred ? p->p_ucred->cr_uid : -1,
1674	    pc,
1675	    read_or_write,
1676	    frame->badvaddr);
1677
1678	/* log registers in trap frame */
1679	log_frame_dump(frame);
1680
1681	get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1682
1683	/*
1684	 * Dump a few words around faulting instruction, if the addres is
1685	 * valid.
1686	 */
1687	if (!(pc & 3) && (pc != frame->badvaddr) &&
1688	    (trap_type != T_BUS_ERR_IFETCH) &&
1689	    useracc((caddr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1690		/* dump page table entry for faulting instruction */
1691		log(LOG_ERR, "Page table info for pc address 0x%x: pde = %p, pte = 0x%lx\n",
1692		    pc, *pdep, ptep ? *ptep : 0);
1693
1694		addr = (unsigned int *)pc;
1695		log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1696		    addr);
1697		log(LOG_ERR, "%08x %08x %08x %08x\n",
1698		    addr[0], addr[1], addr[2], addr[3]);
1699	} else {
1700		log(LOG_ERR, "pc address 0x%x is inaccessible, pde = 0x%p, pte = 0x%lx\n",
1701		    pc, *pdep, ptep ? *ptep : 0);
1702	}
1703	/*	panic("Bad trap");*/
1704}
1705
1706
1707/*
1708 * Unaligned load/store emulation
1709 */
1710static int
1711mips_unaligned_load_store(struct trapframe *frame, register_t addr, register_t pc)
1712{
1713	register_t *reg = (register_t *) frame;
1714	u_int32_t inst = *((u_int32_t *) pc);
1715	u_int32_t value_msb, value;
1716	int access_type = 0;
1717
1718	switch (MIPS_INST_OPCODE(inst)) {
1719	case OP_LHU:
1720		lbu_macro(value_msb, addr);
1721		addr += 1;
1722		lbu_macro(value, addr);
1723		value |= value_msb << 8;
1724		reg[MIPS_INST_RT(inst)] = value;
1725		access_type = MIPS_LHU_ACCESS;
1726		break;
1727
1728	case OP_LH:
1729		lb_macro(value_msb, addr);
1730		addr += 1;
1731		lbu_macro(value, addr);
1732		value |= value_msb << 8;
1733		reg[MIPS_INST_RT(inst)] = value;
1734		access_type = MIPS_LH_ACCESS;
1735		break;
1736
1737	case OP_LWU:
1738		lwl_macro(value, addr);
1739		addr += 3;
1740		lwr_macro(value, addr);
1741		value &= 0xffffffff;
1742		reg[MIPS_INST_RT(inst)] = value;
1743		access_type = MIPS_LWU_ACCESS;
1744		break;
1745
1746	case OP_LW:
1747		lwl_macro(value, addr);
1748		addr += 3;
1749		lwr_macro(value, addr);
1750		reg[MIPS_INST_RT(inst)] = value;
1751		access_type = MIPS_LW_ACCESS;
1752		break;
1753
1754	case OP_SH:
1755		value = reg[MIPS_INST_RT(inst)];
1756		value_msb = value >> 8;
1757		sb_macro(value_msb, addr);
1758		addr += 1;
1759		sb_macro(value, addr);
1760		access_type = MIPS_SH_ACCESS;
1761		break;
1762
1763	case OP_SW:
1764		value = reg[MIPS_INST_RT(inst)];
1765		swl_macro(value, addr);
1766		addr += 3;
1767		swr_macro(value, addr);
1768		access_type = MIPS_SW_ACCESS;
1769		break;
1770
1771	default:
1772		break;
1773	}
1774
1775	return access_type;
1776}
1777
1778
1779static int
1780emulate_unaligned_access(struct trapframe *frame)
1781{
1782	register_t pc;
1783	int access_type = 0;
1784
1785	pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1786
1787	/*
1788	 * Fall through if it's instruction fetch exception
1789	 */
1790	if (!((pc & 3) || (pc == frame->badvaddr))) {
1791
1792		/*
1793		 * Handle unaligned load and store
1794		 */
1795
1796		/*
1797		 * Return access type if the instruction was emulated.
1798		 * Otherwise restore pc and fall through.
1799		 */
1800		access_type = mips_unaligned_load_store(frame,
1801		    frame->badvaddr, pc);
1802
1803		if (access_type) {
1804			if (DELAYBRANCH(frame->cause))
1805				frame->pc = MipsEmulateBranch(frame, frame->pc,
1806				    0, 0);
1807			else
1808				frame->pc += 4;
1809
1810			log(LOG_INFO, "Unaligned %s: pc=0x%x, badvaddr=0x%x\n",
1811			    access_name[access_type - 1], pc, frame->badvaddr);
1812		}
1813	}
1814	return access_type;
1815}
1816