]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/mips/mips/trap.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / mips / mips / trap.c
1 /*      $OpenBSD: trap.c,v 1.19 1998/09/30 12:40:41 pefo Exp $  */
2 /* tracked to 1.23 */
3 /*-
4  * Copyright (c) 1988 University of Utah.
5  * Copyright (c) 1992, 1993
6  *      The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * the Systems Programming Group of the University of Utah Computer
10  * Science Department and Ralph Campbell.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * from: Utah Hdr: trap.c 1.32 91/04/06
37  *
38  *      from: @(#)trap.c        8.5 (Berkeley) 1/11/94
39  *      JNPR: trap.c,v 1.13.2.2 2007/08/29 10:03:49 girish
40  */
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
43
44 #include "opt_ddb.h"
45 #include "opt_global.h"
46 #include "opt_ktrace.h"
47
48 #define NO_REG_DEFS     1       /* Prevent asm.h from including regdef.h */
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/asm.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 TRAP_DEBUG
95 int trap_debug = 0;
96 SYSCTL_INT(_machdep, OID_AUTO, trap_debug, CTLFLAG_RW,
97     &trap_debug, 0, "Debug information on all traps");
98 #endif
99
100 static void log_illegal_instruction(const char *, struct trapframe *);
101 static void log_bad_page_fault(char *, struct trapframe *, int);
102 static void log_frame_dump(struct trapframe *frame);
103 static void get_mapping_info(vm_offset_t, pd_entry_t **, pt_entry_t **);
104
105 #ifdef TRAP_DEBUG
106 static void trap_frame_dump(struct trapframe *frame);
107 #endif
108
109 void (*machExceptionTable[]) (void)= {
110 /*
111  * The kernel exception handlers.
112  */
113         MipsKernIntr,           /* external interrupt */
114         MipsKernGenException,   /* TLB modification */
115         MipsTLBInvalidException,/* TLB miss (load or instr. fetch) */
116         MipsTLBInvalidException,/* TLB miss (store) */
117         MipsKernGenException,   /* address error (load or I-fetch) */
118         MipsKernGenException,   /* address error (store) */
119         MipsKernGenException,   /* bus error (I-fetch) */
120         MipsKernGenException,   /* bus error (load or store) */
121         MipsKernGenException,   /* system call */
122         MipsKernGenException,   /* breakpoint */
123         MipsKernGenException,   /* reserved instruction */
124         MipsKernGenException,   /* coprocessor unusable */
125         MipsKernGenException,   /* arithmetic overflow */
126         MipsKernGenException,   /* trap exception */
127         MipsKernGenException,   /* virtual coherence exception inst */
128         MipsKernGenException,   /* floating point exception */
129         MipsKernGenException,   /* reserved */
130         MipsKernGenException,   /* reserved */
131         MipsKernGenException,   /* reserved */
132         MipsKernGenException,   /* reserved */
133         MipsKernGenException,   /* reserved */
134         MipsKernGenException,   /* reserved */
135         MipsKernGenException,   /* reserved */
136         MipsKernGenException,   /* watch exception */
137         MipsKernGenException,   /* reserved */
138         MipsKernGenException,   /* reserved */
139         MipsKernGenException,   /* reserved */
140         MipsKernGenException,   /* reserved */
141         MipsKernGenException,   /* reserved */
142         MipsKernGenException,   /* reserved */
143         MipsKernGenException,   /* reserved */
144         MipsKernGenException,   /* virtual coherence exception data */
145 /*
146  * The user exception handlers.
147  */
148         MipsUserIntr,           /* 0 */
149         MipsUserGenException,   /* 1 */
150         MipsTLBInvalidException,/* 2 */
151         MipsTLBInvalidException,/* 3 */
152         MipsUserGenException,   /* 4 */
153         MipsUserGenException,   /* 5 */
154         MipsUserGenException,   /* 6 */
155         MipsUserGenException,   /* 7 */
156         MipsUserGenException,   /* 8 */
157         MipsUserGenException,   /* 9 */
158         MipsUserGenException,   /* 10 */
159         MipsUserGenException,   /* 11 */
160         MipsUserGenException,   /* 12 */
161         MipsUserGenException,   /* 13 */
162         MipsUserGenException,   /* 14 */
163         MipsUserGenException,   /* 15 */
164         MipsUserGenException,   /* 16 */
165         MipsUserGenException,   /* 17 */
166         MipsUserGenException,   /* 18 */
167         MipsUserGenException,   /* 19 */
168         MipsUserGenException,   /* 20 */
169         MipsUserGenException,   /* 21 */
170         MipsUserGenException,   /* 22 */
171         MipsUserGenException,   /* 23 */
172         MipsUserGenException,   /* 24 */
173         MipsUserGenException,   /* 25 */
174         MipsUserGenException,   /* 26 */
175         MipsUserGenException,   /* 27 */
176         MipsUserGenException,   /* 28 */
177         MipsUserGenException,   /* 29 */
178         MipsUserGenException,   /* 20 */
179         MipsUserGenException,   /* 31 */
180 };
181
182 char *trap_type[] = {
183         "external interrupt",
184         "TLB modification",
185         "TLB miss (load or instr. fetch)",
186         "TLB miss (store)",
187         "address error (load or I-fetch)",
188         "address error (store)",
189         "bus error (I-fetch)",
190         "bus error (load or store)",
191         "system call",
192         "breakpoint",
193         "reserved instruction",
194         "coprocessor unusable",
195         "arithmetic overflow",
196         "trap",
197         "virtual coherency instruction",
198         "floating point",
199         "reserved 16",
200         "reserved 17",
201         "reserved 18",
202         "reserved 19",
203         "reserved 20",
204         "reserved 21",
205         "reserved 22",
206         "watch",
207         "reserved 24",
208         "reserved 25",
209         "reserved 26",
210         "reserved 27",
211         "reserved 28",
212         "reserved 29",
213         "reserved 30",
214         "virtual coherency data",
215 };
216
217 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
218 struct trapdebug trapdebug[TRAPSIZE], *trp = trapdebug;
219 #endif
220
221 #if defined(DDB) || defined(DEBUG)
222 void stacktrace(struct trapframe *);
223 void logstacktrace(struct trapframe *);
224 #endif
225
226 #define KERNLAND(x)     ((vm_offset_t)(x) >= VM_MIN_KERNEL_ADDRESS && (vm_offset_t)(x) < VM_MAX_KERNEL_ADDRESS)
227 #define DELAYBRANCH(x)  ((int)(x) < 0)
228
229 /*
230  * MIPS load/store access type
231  */
232 enum {
233         MIPS_LHU_ACCESS = 1,
234         MIPS_LH_ACCESS,
235         MIPS_LWU_ACCESS,
236         MIPS_LW_ACCESS,
237         MIPS_LD_ACCESS,
238         MIPS_SH_ACCESS,
239         MIPS_SW_ACCESS,
240         MIPS_SD_ACCESS
241 };
242
243 char *access_name[] = {
244         "Load Halfword Unsigned",
245         "Load Halfword",
246         "Load Word Unsigned",
247         "Load Word",
248         "Load Doubleword",
249         "Store Halfword",
250         "Store Word",
251         "Store Doubleword"
252 };
253
254
255 static int allow_unaligned_acc = 1;
256
257 SYSCTL_INT(_vm, OID_AUTO, allow_unaligned_acc, CTLFLAG_RW,
258     &allow_unaligned_acc, 0, "Allow unaligned accesses");
259
260 static int emulate_unaligned_access(struct trapframe *frame, int mode);
261
262 extern void fswintrberr(void); /* XXX */
263
264 int
265 cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
266 {
267         struct trapframe *locr0 = td->td_frame;
268         struct sysentvec *se;
269         int error, nsaved;
270
271         bzero(sa->args, sizeof(sa->args));
272
273         /* compute next PC after syscall instruction */
274         td->td_pcb->pcb_tpc = sa->trapframe->pc; /* Remember if restart */
275         if (DELAYBRANCH(sa->trapframe->cause))   /* Check BD bit */
276                 locr0->pc = MipsEmulateBranch(locr0, sa->trapframe->pc, 0, 0);
277         else
278                 locr0->pc += sizeof(int);
279         sa->code = locr0->v0;
280
281         switch (sa->code) {
282 #if defined(__mips_n32) || defined(__mips_n64)
283         case SYS___syscall:
284                 /*
285                  * Quads fit in a single register in
286                  * new ABIs.
287                  *
288                  * XXX o64?
289                  */
290 #endif
291         case SYS_syscall:
292                 /*
293                  * Code is first argument, followed by
294                  * actual args.
295                  */
296                 sa->code = locr0->a0;
297                 sa->args[0] = locr0->a1;
298                 sa->args[1] = locr0->a2;
299                 sa->args[2] = locr0->a3;
300                 nsaved = 3;
301 #if defined(__mips_n32) || defined(__mips_n64)
302                 sa->args[3] = locr0->t4;
303                 sa->args[4] = locr0->t5;
304                 sa->args[5] = locr0->t6;
305                 sa->args[6] = locr0->t7;
306                 nsaved += 4;
307 #endif
308                 break;
309
310 #if defined(__mips_o32)
311         case SYS___syscall:
312                 /*
313                  * Like syscall, but code is a quad, so as
314                  * to maintain quad alignment for the rest
315                  * of the arguments.
316                  */
317                 if (_QUAD_LOWWORD == 0)
318                         sa->code = locr0->a0;
319                 else
320                         sa->code = locr0->a1;
321                 sa->args[0] = locr0->a2;
322                 sa->args[1] = locr0->a3;
323                 nsaved = 2;
324                 break;
325 #endif
326
327         default:
328                 sa->args[0] = locr0->a0;
329                 sa->args[1] = locr0->a1;
330                 sa->args[2] = locr0->a2;
331                 sa->args[3] = locr0->a3;
332                 nsaved = 4;
333 #if defined (__mips_n32) || defined(__mips_n64)
334                 sa->args[4] = locr0->t4;
335                 sa->args[5] = locr0->t5;
336                 sa->args[6] = locr0->t6;
337                 sa->args[7] = locr0->t7;
338                 nsaved += 4;
339 #endif
340                 break;
341         }
342 #ifdef TRAP_DEBUG
343         if (trap_debug)
344                 printf("SYSCALL #%d pid:%u\n", code, p->p_pid);
345 #endif
346
347         se = td->td_proc->p_sysent;
348         if (se->sv_mask)
349                 sa->code &= se->sv_mask;
350
351         if (sa->code >= se->sv_size)
352                 sa->callp = &se->sv_table[0];
353         else
354                 sa->callp = &se->sv_table[sa->code];
355
356         sa->narg = sa->callp->sy_narg;
357
358         if (sa->narg > nsaved) {
359 #if defined(__mips_n32) || defined(__mips_n64)
360                 /*
361                  * XXX
362                  * Is this right for new ABIs?  I think the 4 there
363                  * should be 8, size there are 8 registers to skip,
364                  * not 4, but I'm not certain.
365                  */
366                 printf("SYSCALL #%u pid:%u, nargs > nsaved.\n", sa->code,
367                     td->td_proc->p_pid);
368 #endif
369                 error = copyin((caddr_t)(intptr_t)(locr0->sp +
370                     4 * sizeof(register_t)), (caddr_t)&sa->args[nsaved],
371                    (u_int)(sa->narg - nsaved) * sizeof(register_t));
372                 if (error != 0) {
373                         locr0->v0 = error;
374                         locr0->a3 = 1;
375                 }
376         } else
377                 error = 0;
378
379         if (error == 0) {
380                 td->td_retval[0] = 0;
381                 td->td_retval[1] = locr0->v1;
382         }
383
384         return (error);
385 }
386
387 #undef __FBSDID
388 #define __FBSDID(x)
389 #include "../../kern/subr_syscall.c"
390
391 /*
392  * Handle an exception.
393  * Called from MipsKernGenException() or MipsUserGenException()
394  * when a processor trap occurs.
395  * In the case of a kernel trap, we return the pc where to resume if
396  * p->p_addr->u_pcb.pcb_onfault is set, otherwise, return old pc.
397  */
398 register_t
399 trap(struct trapframe *trapframe)
400 {
401         int type, usermode;
402         int i = 0;
403         unsigned ucode = 0;
404         struct thread *td = curthread;
405         struct proc *p = curproc;
406         vm_prot_t ftype;
407         pmap_t pmap;
408         int access_type;
409         ksiginfo_t ksi;
410         char *msg = NULL;
411         intptr_t addr = 0;
412         register_t pc;
413
414         trapdebug_enter(trapframe, 0);
415         
416         type = (trapframe->cause & MIPS3_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT;
417         if (TRAPF_USERMODE(trapframe)) {
418                 type |= T_USER;
419                 usermode = 1;
420         } else {
421                 usermode = 0;
422         }
423
424         /*
425          * Enable hardware interrupts if they were on before the trap. If it
426          * was off disable all so we don't accidently enable it when doing a
427          * return to userland.
428          */
429         if (trapframe->sr & MIPS_SR_INT_IE) {
430                 set_intr_mask(trapframe->sr & MIPS_SR_INT_MASK);
431                 intr_enable();
432         } else {
433                 intr_disable();
434         }
435
436 #ifdef TRAP_DEBUG
437         if (trap_debug) {
438                 static vm_offset_t last_badvaddr = 0;
439                 static vm_offset_t this_badvaddr = 0;
440                 static int count = 0;
441                 u_int32_t pid;
442
443                 printf("trap type %x (%s - ", type,
444                     trap_type[type & (~T_USER)]);
445
446                 if (type & T_USER)
447                         printf("user mode)\n");
448                 else
449                         printf("kernel mode)\n");
450
451 #ifdef SMP
452                 printf("cpuid = %d\n", PCPU_GET(cpuid));
453 #endif
454                 pid = mips_rd_entryhi() & TLBHI_ASID_MASK;
455                 printf("badaddr = %#jx, pc = %#jx, ra = %#jx, sp = %#jx, sr = %jx, pid = %d, ASID = %u\n",
456                     (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
457                     (intmax_t)trapframe->sp, (intmax_t)trapframe->sr,
458                     (curproc ? curproc->p_pid : -1), pid);
459
460                 switch (type & ~T_USER) {
461                 case T_TLB_MOD:
462                 case T_TLB_LD_MISS:
463                 case T_TLB_ST_MISS:
464                 case T_ADDR_ERR_LD:
465                 case T_ADDR_ERR_ST:
466                         this_badvaddr = trapframe->badvaddr;
467                         break;
468                 case T_SYSCALL:
469                         this_badvaddr = trapframe->ra;
470                         break;
471                 default:
472                         this_badvaddr = trapframe->pc;
473                         break;
474                 }
475                 if ((last_badvaddr == this_badvaddr) &&
476                     ((type & ~T_USER) != T_SYSCALL)) {
477                         if (++count == 3) {
478                                 trap_frame_dump(trapframe);
479                                 panic("too many faults at %p\n", (void *)last_badvaddr);
480                         }
481                 } else {
482                         last_badvaddr = this_badvaddr;
483                         count = 0;
484                 }
485         }
486 #endif
487         switch (type) {
488         case T_MCHECK:
489 #ifdef DDB
490                 kdb_trap(type, 0, trapframe);
491 #endif
492                 panic("MCHECK\n");
493                 break;
494         case T_TLB_MOD:
495                 /* check for kernel address */
496                 if (KERNLAND(trapframe->badvaddr)) {
497                         if (pmap_emulate_modified(kernel_pmap, 
498                             trapframe->badvaddr) != 0) {
499                                 ftype = VM_PROT_WRITE;
500                                 goto kernel_fault;
501                         }
502                         return (trapframe->pc);
503                 }
504                 /* FALLTHROUGH */
505
506         case T_TLB_MOD + T_USER:
507                 pmap = &p->p_vmspace->vm_pmap;
508                 if (pmap_emulate_modified(pmap, trapframe->badvaddr) != 0) {
509                         ftype = VM_PROT_WRITE;
510                         goto dofault;
511                 }
512                 if (!usermode)
513                         return (trapframe->pc);
514                 goto out;
515
516         case T_TLB_LD_MISS:
517         case T_TLB_ST_MISS:
518                 ftype = (type == T_TLB_ST_MISS) ? VM_PROT_WRITE : VM_PROT_READ;
519                 /* check for kernel address */
520                 if (KERNLAND(trapframe->badvaddr)) {
521                         vm_offset_t va;
522                         int rv;
523
524         kernel_fault:
525                         va = trunc_page((vm_offset_t)trapframe->badvaddr);
526                         rv = vm_fault(kernel_map, va, ftype, VM_FAULT_NORMAL);
527                         if (rv == KERN_SUCCESS)
528                                 return (trapframe->pc);
529                         if (td->td_pcb->pcb_onfault != NULL) {
530                                 pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
531                                 td->td_pcb->pcb_onfault = NULL;
532                                 return (pc);
533                         }
534                         goto err;
535                 }
536
537                 /*
538                  * It is an error for the kernel to access user space except
539                  * through the copyin/copyout routines.
540                  */
541                 if (td->td_pcb->pcb_onfault == NULL)
542                         goto err;
543
544                 /* check for fuswintr() or suswintr() getting a page fault */
545                 /* XXX There must be a nicer way to do this.  */
546                 if (td->td_pcb->pcb_onfault == fswintrberr) {
547                         pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
548                         td->td_pcb->pcb_onfault = NULL;
549                         return (pc);
550                 }
551
552                 goto dofault;
553
554         case T_TLB_LD_MISS + T_USER:
555                 ftype = VM_PROT_READ;
556                 goto dofault;
557
558         case T_TLB_ST_MISS + T_USER:
559                 ftype = VM_PROT_WRITE;
560 dofault:
561                 {
562                         vm_offset_t va;
563                         struct vmspace *vm;
564                         vm_map_t map;
565                         int rv = 0;
566
567                         vm = p->p_vmspace;
568                         map = &vm->vm_map;
569                         va = trunc_page((vm_offset_t)trapframe->badvaddr);
570                         if (KERNLAND(trapframe->badvaddr)) {
571                                 /*
572                                  * Don't allow user-mode faults in kernel
573                                  * address space.
574                                  */
575                                 goto nogo;
576                         }
577
578                         /*
579                          * Keep swapout from messing with us during this
580                          * critical time.
581                          */
582                         PROC_LOCK(p);
583                         ++p->p_lock;
584                         PROC_UNLOCK(p);
585
586                         rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
587
588                         PROC_LOCK(p);
589                         --p->p_lock;
590                         PROC_UNLOCK(p);
591 #ifdef VMFAULT_TRACE
592                         printf("vm_fault(%p (pmap %p), %p (%p), %x, %d) -> %x at pc %p\n",
593                             map, &vm->vm_pmap, (void *)va, (void *)(intptr_t)trapframe->badvaddr,
594                             ftype, VM_FAULT_NORMAL, rv, (void *)(intptr_t)trapframe->pc);
595 #endif
596
597                         if (rv == KERN_SUCCESS) {
598                                 if (!usermode) {
599                                         return (trapframe->pc);
600                                 }
601                                 goto out;
602                         }
603         nogo:
604                         if (!usermode) {
605                                 if (td->td_pcb->pcb_onfault != NULL) {
606                                         pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
607                                         td->td_pcb->pcb_onfault = NULL;
608                                         return (pc);
609                                 }
610                                 goto err;
611                         }
612                         ucode = ftype;
613                         i = ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
614                         addr = trapframe->pc;
615
616                         msg = "BAD_PAGE_FAULT";
617                         log_bad_page_fault(msg, trapframe, type);
618
619                         break;
620                 }
621
622         case T_ADDR_ERR_LD + T_USER:    /* misaligned or kseg access */
623         case T_ADDR_ERR_ST + T_USER:    /* misaligned or kseg access */
624                 if (trapframe->badvaddr < 0 ||
625                     trapframe->badvaddr >= VM_MAXUSER_ADDRESS) {
626                         msg = "ADDRESS_SPACE_ERR";
627                 } else if (allow_unaligned_acc) {
628                         int mode;
629
630                         if (type == (T_ADDR_ERR_LD + T_USER))
631                                 mode = VM_PROT_READ;
632                         else
633                                 mode = VM_PROT_WRITE;
634
635                         access_type = emulate_unaligned_access(trapframe, mode);
636                         if (access_type != 0)
637                                 goto out;
638                         msg = "ALIGNMENT_FIX_ERR";
639                 } else {
640                         msg = "ADDRESS_ERR";
641                 }
642
643                 /* FALL THROUGH */
644
645         case T_BUS_ERR_IFETCH + T_USER: /* BERR asserted to cpu */
646         case T_BUS_ERR_LD_ST + T_USER:  /* BERR asserted to cpu */
647                 ucode = 0;      /* XXX should be VM_PROT_something */
648                 i = SIGBUS;
649                 addr = trapframe->pc;
650                 if (!msg)
651                         msg = "BUS_ERR";
652                 log_bad_page_fault(msg, trapframe, type);
653                 break;
654
655         case T_SYSCALL + T_USER:
656                 {
657                         struct syscall_args sa;
658                         int error;
659
660                         sa.trapframe = trapframe;
661                         error = syscallenter(td, &sa);
662
663 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
664                         if (trp == trapdebug)
665                                 trapdebug[TRAPSIZE - 1].code = sa.code;
666                         else
667                                 trp[-1].code = sa.code;
668 #endif
669                         trapdebug_enter(td->td_frame, -sa.code);
670
671                         /*
672                          * The sync'ing of I & D caches for SYS_ptrace() is
673                          * done by procfs_domem() through procfs_rwmem()
674                          * instead of being done here under a special check
675                          * for SYS_ptrace().
676                          */
677                         syscallret(td, error, &sa);
678                         return (trapframe->pc);
679                 }
680
681 #ifdef DDB
682         case T_BREAK:
683                 kdb_trap(type, 0, trapframe);
684                 return (trapframe->pc);
685 #endif
686
687         case T_BREAK + T_USER:
688                 {
689                         intptr_t va;
690                         uint32_t instr;
691
692                         /* compute address of break instruction */
693                         va = trapframe->pc;
694                         if (DELAYBRANCH(trapframe->cause))
695                                 va += sizeof(int);
696
697                         /* read break instruction */
698                         instr = fuword32((caddr_t)va);
699 #if 0
700                         printf("trap: %s (%d) breakpoint %x at %x: (adr %x ins %x)\n",
701                             p->p_comm, p->p_pid, instr, trapframe->pc,
702                             p->p_md.md_ss_addr, p->p_md.md_ss_instr);   /* XXX */
703 #endif
704                         if (td->td_md.md_ss_addr != va ||
705                             instr != MIPS_BREAK_SSTEP) {
706                                 i = SIGTRAP;
707                                 addr = trapframe->pc;
708                                 break;
709                         }
710                         /*
711                          * The restoration of the original instruction and
712                          * the clearing of the berakpoint will be done later
713                          * by the call to ptrace_clear_single_step() in
714                          * issignal() when SIGTRAP is processed.
715                          */
716                         addr = trapframe->pc;
717                         i = SIGTRAP;
718                         break;
719                 }
720
721         case T_IWATCH + T_USER:
722         case T_DWATCH + T_USER:
723                 {
724                         intptr_t va;
725
726                         /* compute address of trapped instruction */
727                         va = trapframe->pc;
728                         if (DELAYBRANCH(trapframe->cause))
729                                 va += sizeof(int);
730                         printf("watch exception @ %p\n", (void *)va);
731                         i = SIGTRAP;
732                         addr = va;
733                         break;
734                 }
735
736         case T_TRAP + T_USER:
737                 {
738                         intptr_t va;
739                         uint32_t instr;
740                         struct trapframe *locr0 = td->td_frame;
741
742                         /* compute address of trap instruction */
743                         va = trapframe->pc;
744                         if (DELAYBRANCH(trapframe->cause))
745                                 va += sizeof(int);
746                         /* read break instruction */
747                         instr = fuword32((caddr_t)va);
748
749                         if (DELAYBRANCH(trapframe->cause)) {    /* Check BD bit */
750                                 locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0,
751                                     0);
752                         } else {
753                                 locr0->pc += sizeof(int);
754                         }
755                         addr = va;
756                         i = SIGEMT;     /* Stuff it with something for now */
757                         break;
758                 }
759
760         case T_RES_INST + T_USER:
761                 log_illegal_instruction("RES_INST", trapframe);
762                 i = SIGILL;
763                 addr = trapframe->pc;
764                 break;
765         case T_C2E:
766         case T_C2E + T_USER:
767                 goto err;
768                 break;
769         case T_COP_UNUSABLE:
770                 goto err;
771                 break;
772         case T_COP_UNUSABLE + T_USER:
773 #if !defined(CPU_HAVEFPU)
774                 /* FP (COP1) instruction */
775                 if ((trapframe->cause & MIPS_CR_COP_ERR) == 0x10000000) {
776                         log_illegal_instruction("COP1_UNUSABLE", trapframe);
777                         i = SIGILL;
778                         break;
779                 }
780 #endif
781                 if ((trapframe->cause & MIPS_CR_COP_ERR) != 0x10000000) {
782                         log_illegal_instruction("COPn_UNUSABLE", trapframe);
783                         i = SIGILL;     /* only FPU instructions allowed */
784                         break;
785                 }
786                 addr = trapframe->pc;
787                 MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame);
788                 PCPU_SET(fpcurthread, td);
789                 td->td_frame->sr |= MIPS_SR_COP_1_BIT;
790                 td->td_md.md_flags |= MDTD_FPUSED;
791                 goto out;
792
793         case T_FPE:
794 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
795                 trapDump("fpintr");
796 #else
797                 printf("FPU Trap: PC %#jx CR %x SR %x\n",
798                     (intmax_t)trapframe->pc, (unsigned)trapframe->cause, (unsigned)trapframe->sr);
799                 goto err;
800 #endif
801
802         case T_FPE + T_USER:
803                 MipsFPTrap(trapframe->sr, trapframe->cause, trapframe->pc);
804                 goto out;
805
806         case T_OVFLOW + T_USER:
807                 i = SIGFPE;
808                 addr = trapframe->pc;
809                 break;
810
811         case T_ADDR_ERR_LD:     /* misaligned access */
812         case T_ADDR_ERR_ST:     /* misaligned access */
813 #ifdef TRAP_DEBUG
814                 if (trap_debug) {
815                         printf("+++ ADDR_ERR: type = %d, badvaddr = %#jx\n", type,
816                             (intmax_t)trapframe->badvaddr);
817                 }
818 #endif
819                 /* Only allow emulation on a user address */
820                 if (allow_unaligned_acc &&
821                     ((vm_offset_t)trapframe->badvaddr < VM_MAXUSER_ADDRESS)) {
822                         int mode;
823
824                         if (type == T_ADDR_ERR_LD)
825                                 mode = VM_PROT_READ;
826                         else
827                                 mode = VM_PROT_WRITE;
828
829                         access_type = emulate_unaligned_access(trapframe, mode);
830                         if (access_type != 0)
831                                 return (trapframe->pc);
832                 }
833                 /* FALLTHROUGH */
834
835         case T_BUS_ERR_LD_ST:   /* BERR asserted to cpu */
836                 if (td->td_pcb->pcb_onfault != NULL) {
837                         pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
838                         td->td_pcb->pcb_onfault = NULL;
839                         return (pc);
840                 }
841
842                 /* FALLTHROUGH */
843
844         default:
845 err:
846
847 #if !defined(SMP) && defined(DEBUG)
848                 stacktrace(!usermode ? trapframe : td->td_frame);
849                 trapDump("trap");
850 #endif
851 #ifdef SMP
852                 printf("cpu:%d-", PCPU_GET(cpuid));
853 #endif
854                 printf("Trap cause = %d (%s - ", type,
855                     trap_type[type & (~T_USER)]);
856
857                 if (type & T_USER)
858                         printf("user mode)\n");
859                 else
860                         printf("kernel mode)\n");
861
862 #ifdef TRAP_DEBUG
863                 if (trap_debug)
864                         printf("badvaddr = %#jx, pc = %#jx, ra = %#jx, sr = %#jxx\n",
865                                (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
866                                (intmax_t)trapframe->sr);
867 #endif
868
869 #ifdef KDB
870                 if (debugger_on_panic || kdb_active) {
871                         kdb_trap(type, 0, trapframe);
872                 }
873 #endif
874                 panic("trap");
875         }
876         td->td_frame->pc = trapframe->pc;
877         td->td_frame->cause = trapframe->cause;
878         td->td_frame->badvaddr = trapframe->badvaddr;
879         ksiginfo_init_trap(&ksi);
880         ksi.ksi_signo = i;
881         ksi.ksi_code = ucode;
882         ksi.ksi_addr = (void *)addr;
883         ksi.ksi_trapno = type;
884         trapsignal(td, &ksi);
885 out:
886
887         /*
888          * Note: we should only get here if returning to user mode.
889          */
890         userret(td, trapframe);
891         mtx_assert(&Giant, MA_NOTOWNED);
892         return (trapframe->pc);
893 }
894
895 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
896 void
897 trapDump(char *msg)
898 {
899         register_t s;
900         int i;
901
902         s = intr_disable();
903         printf("trapDump(%s)\n", msg);
904         for (i = 0; i < TRAPSIZE; i++) {
905                 if (trp == trapdebug) {
906                         trp = &trapdebug[TRAPSIZE - 1];
907                 } else {
908                         trp--;
909                 }
910
911                 if (trp->cause == 0)
912                         break;
913
914                 printf("%s: ADR %jx PC %jx CR %jx SR %jx\n",
915                     trap_type[(trp->cause & MIPS3_CR_EXC_CODE) >> 
916                         MIPS_CR_EXC_CODE_SHIFT],
917                     (intmax_t)trp->vadr, (intmax_t)trp->pc,
918                     (intmax_t)trp->cause, (intmax_t)trp->status);
919
920                 printf("   RA %jx SP %jx code %d\n", (intmax_t)trp->ra,
921                     (intmax_t)trp->sp, (int)trp->code);
922         }
923         intr_restore(s);
924 }
925 #endif
926
927
928 /*
929  * Return the resulting PC as if the branch was executed.
930  */
931 uintptr_t
932 MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR,
933     uintptr_t instptr)
934 {
935         InstFmt inst;
936         register_t *regsPtr = (register_t *) framePtr;
937         uintptr_t retAddr = 0;
938         int condition;
939
940 #define GetBranchDest(InstPtr, inst) \
941         (InstPtr + 4 + ((short)inst.IType.imm << 2))
942
943
944         if (instptr) {
945                 if (instptr < MIPS_KSEG0_START)
946                         inst.word = fuword32((void *)instptr);
947                 else
948                         inst = *(InstFmt *) instptr;
949         } else {
950                 if ((vm_offset_t)instPC < MIPS_KSEG0_START)
951                         inst.word = fuword32((void *)instPC);
952                 else
953                         inst = *(InstFmt *) instPC;
954         }
955
956         switch ((int)inst.JType.op) {
957         case OP_SPECIAL:
958                 switch ((int)inst.RType.func) {
959                 case OP_JR:
960                 case OP_JALR:
961                         retAddr = regsPtr[inst.RType.rs];
962                         break;
963
964                 default:
965                         retAddr = instPC + 4;
966                         break;
967                 }
968                 break;
969
970         case OP_BCOND:
971                 switch ((int)inst.IType.rt) {
972                 case OP_BLTZ:
973                 case OP_BLTZL:
974                 case OP_BLTZAL:
975                 case OP_BLTZALL:
976                         if ((int)(regsPtr[inst.RType.rs]) < 0)
977                                 retAddr = GetBranchDest(instPC, inst);
978                         else
979                                 retAddr = instPC + 8;
980                         break;
981
982                 case OP_BGEZ:
983                 case OP_BGEZL:
984                 case OP_BGEZAL:
985                 case OP_BGEZALL:
986                         if ((int)(regsPtr[inst.RType.rs]) >= 0)
987                                 retAddr = GetBranchDest(instPC, inst);
988                         else
989                                 retAddr = instPC + 8;
990                         break;
991
992                 case OP_TGEI:
993                 case OP_TGEIU:
994                 case OP_TLTI:
995                 case OP_TLTIU:
996                 case OP_TEQI:
997                 case OP_TNEI:
998                         retAddr = instPC + 4;   /* Like syscall... */
999                         break;
1000
1001                 default:
1002                         panic("MipsEmulateBranch: Bad branch cond");
1003                 }
1004                 break;
1005
1006         case OP_J:
1007         case OP_JAL:
1008                 retAddr = (inst.JType.target << 2) |
1009                     ((unsigned)(instPC + 4) & 0xF0000000);
1010                 break;
1011
1012         case OP_BEQ:
1013         case OP_BEQL:
1014                 if (regsPtr[inst.RType.rs] == regsPtr[inst.RType.rt])
1015                         retAddr = GetBranchDest(instPC, inst);
1016                 else
1017                         retAddr = instPC + 8;
1018                 break;
1019
1020         case OP_BNE:
1021         case OP_BNEL:
1022                 if (regsPtr[inst.RType.rs] != regsPtr[inst.RType.rt])
1023                         retAddr = GetBranchDest(instPC, inst);
1024                 else
1025                         retAddr = instPC + 8;
1026                 break;
1027
1028         case OP_BLEZ:
1029         case OP_BLEZL:
1030                 if ((int)(regsPtr[inst.RType.rs]) <= 0)
1031                         retAddr = GetBranchDest(instPC, inst);
1032                 else
1033                         retAddr = instPC + 8;
1034                 break;
1035
1036         case OP_BGTZ:
1037         case OP_BGTZL:
1038                 if ((int)(regsPtr[inst.RType.rs]) > 0)
1039                         retAddr = GetBranchDest(instPC, inst);
1040                 else
1041                         retAddr = instPC + 8;
1042                 break;
1043
1044         case OP_COP1:
1045                 switch (inst.RType.rs) {
1046                 case OP_BCx:
1047                 case OP_BCy:
1048                         if ((inst.RType.rt & COPz_BC_TF_MASK) == COPz_BC_TRUE)
1049                                 condition = fpcCSR & MIPS_FPU_COND_BIT;
1050                         else
1051                                 condition = !(fpcCSR & MIPS_FPU_COND_BIT);
1052                         if (condition)
1053                                 retAddr = GetBranchDest(instPC, inst);
1054                         else
1055                                 retAddr = instPC + 8;
1056                         break;
1057
1058                 default:
1059                         retAddr = instPC + 4;
1060                 }
1061                 break;
1062
1063         default:
1064                 retAddr = instPC + 4;
1065         }
1066         return (retAddr);
1067 }
1068
1069
1070 #if defined(DDB) || defined(DEBUG)
1071 /*
1072  * Print a stack backtrace.
1073  */
1074 void
1075 stacktrace(struct trapframe *regs)
1076 {
1077         stacktrace_subr(regs->pc, regs->sp, regs->ra, printf);
1078 }
1079 #endif
1080
1081 static void
1082 log_frame_dump(struct trapframe *frame)
1083 {
1084         log(LOG_ERR, "Trapframe Register Dump:\n");
1085         log(LOG_ERR, "\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1086             (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1087
1088         log(LOG_ERR, "\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1089             (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1090
1091         log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1092             (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1093
1094         log(LOG_ERR, "\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1095             (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1096
1097         log(LOG_ERR, "\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1098             (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1099
1100         log(LOG_ERR, "\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1101             (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1102
1103         log(LOG_ERR, "\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1104             (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1105
1106         log(LOG_ERR, "\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1107             (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1108
1109         log(LOG_ERR, "\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1110             (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1111
1112 #ifdef IC_REG
1113         log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
1114             (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
1115 #else
1116         log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\n",
1117             (intmax_t)frame->cause, (intmax_t)frame->pc);
1118 #endif
1119 }
1120
1121 #ifdef TRAP_DEBUG
1122 static void
1123 trap_frame_dump(struct trapframe *frame)
1124 {
1125         printf("Trapframe Register Dump:\n");
1126         printf("\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1127             (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1128
1129         printf("\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1130             (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1131
1132         printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1133             (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1134
1135         printf("\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1136             (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1137
1138         printf("\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1139             (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1140
1141         printf("\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1142             (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1143
1144         printf("\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1145             (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1146
1147         printf("\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1148             (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1149
1150         printf("\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1151             (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1152
1153 #ifdef IC_REG
1154         printf("\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
1155             (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
1156 #else
1157         printf("\tcause: %#jx\tpc: %#jx\n",
1158             (intmax_t)frame->cause, (intmax_t)frame->pc);
1159 #endif
1160 }
1161
1162 #endif
1163
1164
1165 static void
1166 get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp)
1167 {
1168         pt_entry_t *ptep;
1169         pd_entry_t *pdep;
1170         struct proc *p = curproc;
1171
1172         pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[(va >> SEGSHIFT) & (NPDEPG - 1)]));
1173         if (*pdep)
1174                 ptep = pmap_pte(&p->p_vmspace->vm_pmap, va);
1175         else
1176                 ptep = (pt_entry_t *)0;
1177
1178         *pdepp = pdep;
1179         *ptepp = ptep;
1180 }
1181
1182 static void
1183 log_illegal_instruction(const char *msg, struct trapframe *frame)
1184 {
1185         pt_entry_t *ptep;
1186         pd_entry_t *pdep;
1187         unsigned int *addr;
1188         struct proc *p = curproc;
1189         register_t pc;
1190
1191 #ifdef SMP
1192         printf("cpuid = %d\n", PCPU_GET(cpuid));
1193 #endif
1194         pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1195         log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %#jx ra %#jx\n",
1196             msg, p->p_pid, p->p_comm,
1197             p->p_ucred ? p->p_ucred->cr_uid : -1,
1198             (intmax_t)pc,
1199             (intmax_t)frame->ra);
1200
1201         /* log registers in trap frame */
1202         log_frame_dump(frame);
1203
1204         get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1205
1206         /*
1207          * Dump a few words around faulting instruction, if the addres is
1208          * valid.
1209          */
1210         if (!(pc & 3) &&
1211             useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1212                 /* dump page table entry for faulting instruction */
1213                 log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n",
1214                     (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1215
1216                 addr = (unsigned int *)(intptr_t)pc;
1217                 log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1218                     addr);
1219                 log(LOG_ERR, "%08x %08x %08x %08x\n",
1220                     addr[0], addr[1], addr[2], addr[3]);
1221         } else {
1222                 log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1223                     (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1224         }
1225 }
1226
1227 static void
1228 log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
1229 {
1230         pt_entry_t *ptep;
1231         pd_entry_t *pdep;
1232         unsigned int *addr;
1233         struct proc *p = curproc;
1234         char *read_or_write;
1235         register_t pc;
1236
1237         trap_type &= ~T_USER;
1238
1239 #ifdef SMP
1240         printf("cpuid = %d\n", PCPU_GET(cpuid));
1241 #endif
1242         switch (trap_type) {
1243         case T_TLB_ST_MISS:
1244         case T_ADDR_ERR_ST:
1245                 read_or_write = "write";
1246                 break;
1247         case T_TLB_LD_MISS:
1248         case T_ADDR_ERR_LD:
1249         case T_BUS_ERR_IFETCH:
1250                 read_or_write = "read";
1251                 break;
1252         default:
1253                 read_or_write = "";
1254         }
1255
1256         pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1257         log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %#jx got a %s fault at %#jx\n",
1258             msg, p->p_pid, p->p_comm,
1259             p->p_ucred ? p->p_ucred->cr_uid : -1,
1260             (intmax_t)pc,
1261             read_or_write,
1262             (intmax_t)frame->badvaddr);
1263
1264         /* log registers in trap frame */
1265         log_frame_dump(frame);
1266
1267         get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1268
1269         /*
1270          * Dump a few words around faulting instruction, if the addres is
1271          * valid.
1272          */
1273         if (!(pc & 3) && (pc != frame->badvaddr) &&
1274             (trap_type != T_BUS_ERR_IFETCH) &&
1275             useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1276                 /* dump page table entry for faulting instruction */
1277                 log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n",
1278                     (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1279
1280                 addr = (unsigned int *)(intptr_t)pc;
1281                 log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1282                     addr);
1283                 log(LOG_ERR, "%08x %08x %08x %08x\n",
1284                     addr[0], addr[1], addr[2], addr[3]);
1285         } else {
1286                 log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1287                     (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1288         }
1289
1290         get_mapping_info((vm_offset_t)frame->badvaddr, &pdep, &ptep);
1291         log(LOG_ERR, "Page table info for bad address %#jx: pde = %p, pte = %#jx\n",
1292             (intmax_t)frame->badvaddr, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1293 }
1294
1295
1296 /*
1297  * Unaligned load/store emulation
1298  */
1299 static int
1300 mips_unaligned_load_store(struct trapframe *frame, int mode, register_t addr, register_t pc)
1301 {
1302         register_t *reg = (register_t *) frame;
1303         u_int32_t inst = *((u_int32_t *)(intptr_t)pc);
1304         register_t value_msb, value;
1305         unsigned size;
1306
1307         /*
1308          * ADDR_ERR faults have higher priority than TLB
1309          * Miss faults.  Therefore, it is necessary to
1310          * verify that the faulting address is a valid
1311          * virtual address within the process' address space
1312          * before trying to emulate the unaligned access.
1313          */
1314         switch (MIPS_INST_OPCODE(inst)) {
1315         case OP_LHU: case OP_LH:
1316         case OP_SH:
1317                 size = 2;
1318                 break;
1319         case OP_LWU: case OP_LW:
1320         case OP_SW:
1321                 size = 4;
1322                 break;
1323         case OP_LD:
1324         case OP_SD:
1325                 size = 8;
1326                 break;
1327         default:
1328                 printf("%s: unhandled opcode in address error: %#x\n", __func__, MIPS_INST_OPCODE(inst));
1329                 return (0);
1330         }
1331
1332         if (!useracc((void *)((vm_offset_t)addr & ~(size - 1)), size * 2, mode))
1333                 return (0);
1334
1335         /*
1336          * XXX
1337          * Handle LL/SC LLD/SCD.
1338          */
1339         switch (MIPS_INST_OPCODE(inst)) {
1340         case OP_LHU:
1341                 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1342                 lbu_macro(value_msb, addr);
1343                 addr += 1;
1344                 lbu_macro(value, addr);
1345                 value |= value_msb << 8;
1346                 reg[MIPS_INST_RT(inst)] = value;
1347                 return (MIPS_LHU_ACCESS);
1348
1349         case OP_LH:
1350                 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1351                 lb_macro(value_msb, addr);
1352                 addr += 1;
1353                 lbu_macro(value, addr);
1354                 value |= value_msb << 8;
1355                 reg[MIPS_INST_RT(inst)] = value;
1356                 return (MIPS_LH_ACCESS);
1357
1358         case OP_LWU:
1359                 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1360                 lwl_macro(value, addr);
1361                 addr += 3;
1362                 lwr_macro(value, addr);
1363                 value &= 0xffffffff;
1364                 reg[MIPS_INST_RT(inst)] = value;
1365                 return (MIPS_LWU_ACCESS);
1366
1367         case OP_LW:
1368                 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1369                 lwl_macro(value, addr);
1370                 addr += 3;
1371                 lwr_macro(value, addr);
1372                 reg[MIPS_INST_RT(inst)] = value;
1373                 return (MIPS_LW_ACCESS);
1374
1375 #if defined(__mips_n32) || defined(__mips_n64)
1376         case OP_LD:
1377                 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1378                 ldl_macro(value, addr);
1379                 addr += 7;
1380                 ldr_macro(value, addr);
1381                 reg[MIPS_INST_RT(inst)] = value;
1382                 return (MIPS_LD_ACCESS);
1383 #endif
1384
1385         case OP_SH:
1386                 KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1387                 value = reg[MIPS_INST_RT(inst)];
1388                 value_msb = value >> 8;
1389                 sb_macro(value_msb, addr);
1390                 addr += 1;
1391                 sb_macro(value, addr);
1392                 return (MIPS_SH_ACCESS);
1393
1394         case OP_SW:
1395                 KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1396                 value = reg[MIPS_INST_RT(inst)];
1397                 swl_macro(value, addr);
1398                 addr += 3;
1399                 swr_macro(value, addr);
1400                 return (MIPS_SW_ACCESS);
1401
1402 #if defined(__mips_n32) || defined(__mips_n64)
1403         case OP_SD:
1404                 KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1405                 value = reg[MIPS_INST_RT(inst)];
1406                 sdl_macro(value, addr);
1407                 addr += 7;
1408                 sdr_macro(value, addr);
1409                 return (MIPS_SD_ACCESS);
1410 #endif
1411         }
1412         panic("%s: should not be reached.", __func__);
1413 }
1414
1415
1416 static int
1417 emulate_unaligned_access(struct trapframe *frame, int mode)
1418 {
1419         register_t pc;
1420         int access_type = 0;
1421
1422         pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1423
1424         /*
1425          * Fall through if it's instruction fetch exception
1426          */
1427         if (!((pc & 3) || (pc == frame->badvaddr))) {
1428
1429                 /*
1430                  * Handle unaligned load and store
1431                  */
1432
1433                 /*
1434                  * Return access type if the instruction was emulated.
1435                  * Otherwise restore pc and fall through.
1436                  */
1437                 access_type = mips_unaligned_load_store(frame,
1438                     mode, frame->badvaddr, pc);
1439
1440                 if (access_type) {
1441                         if (DELAYBRANCH(frame->cause))
1442                                 frame->pc = MipsEmulateBranch(frame, frame->pc,
1443                                     0, 0);
1444                         else
1445                                 frame->pc += 4;
1446
1447                         log(LOG_INFO, "Unaligned %s: pc=%#jx, badvaddr=%#jx\n",
1448                             access_name[access_type - 1], (intmax_t)pc,
1449                             (intmax_t)frame->badvaddr);
1450                 }
1451         }
1452         return access_type;
1453 }