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