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