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