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