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