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