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