The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/mips/mips/trap.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: f1b5fe4f8c0e94055fc497a1b8d8fe06


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.