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