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