1 /* $OpenBSD: trap.c,v 1.19 1998/09/30 12:40:41 pefo Exp $ */
4 * Copyright (c) 1988 University of Utah.
5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved.
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.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
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.
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
36 * from: Utah Hdr: trap.c 1.32 91/04/06
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
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
44 #include "opt_compat.h"
46 #include "opt_global.h"
47 #include "opt_ktrace.h"
48 #include "opt_kdtrace.h"
50 #define NO_REG_DEFS 1 /* Prevent asm.h from including regdef.h */
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/sysent.h>
55 #include <sys/kernel.h>
56 #include <sys/signalvar.h>
57 #include <sys/syscall.h>
60 #include <vm/vm_extern.h>
61 #include <vm/vm_kern.h>
62 #include <vm/vm_page.h>
63 #include <vm/vm_map.h>
64 #include <vm/vm_param.h>
65 #include <sys/vmmeter.h>
66 #include <sys/ptrace.h>
69 #include <sys/vnode.h>
70 #include <sys/pioctl.h>
71 #include <sys/sysctl.h>
72 #include <sys/syslog.h>
75 #include <sys/ktrace.h>
77 #include <net/netisr.h>
79 #include <machine/trap.h>
80 #include <machine/cpu.h>
81 #include <machine/pte.h>
82 #include <machine/pmap.h>
83 #include <machine/md_var.h>
84 #include <machine/mips_opcode.h>
85 #include <machine/frame.h>
86 #include <machine/regnum.h>
87 #include <machine/tls.h>
88 #include <machine/asm.h>
91 #include <machine/db_machdep.h>
92 #include <ddb/db_sym.h>
98 #include <sys/dtrace_bsd.h>
101 * This is a hook which is initialised by the dtrace module
102 * to handle traps which might occur during DTrace probe
105 dtrace_trap_func_t dtrace_trap_func;
107 dtrace_doubletrap_func_t dtrace_doubletrap_func;
110 * This is a hook which is initialised by the systrace module
111 * when it is loaded. This keeps the DTrace syscall provider
112 * implementation opaque.
114 systrace_probe_func_t systrace_probe_func;
117 * These hooks are necessary for the pid, usdt and fasttrap providers.
119 dtrace_fasttrap_probe_ptr_t dtrace_fasttrap_probe_ptr;
120 dtrace_pid_probe_ptr_t dtrace_pid_probe_ptr;
121 dtrace_return_probe_ptr_t dtrace_return_probe_ptr;
126 SYSCTL_INT(_machdep, OID_AUTO, trap_debug, CTLFLAG_RW,
127 &trap_debug, 0, "Debug information on all traps");
130 static void log_illegal_instruction(const char *, struct trapframe *);
131 static void log_bad_page_fault(char *, struct trapframe *, int);
132 static void log_frame_dump(struct trapframe *frame);
133 static void get_mapping_info(vm_offset_t, pd_entry_t **, pt_entry_t **);
136 static void trap_frame_dump(struct trapframe *frame);
139 void (*machExceptionTable[]) (void)= {
141 * The kernel exception handlers.
143 MipsKernIntr, /* external interrupt */
144 MipsKernGenException, /* TLB modification */
145 MipsTLBInvalidException,/* TLB miss (load or instr. fetch) */
146 MipsTLBInvalidException,/* TLB miss (store) */
147 MipsKernGenException, /* address error (load or I-fetch) */
148 MipsKernGenException, /* address error (store) */
149 MipsKernGenException, /* bus error (I-fetch) */
150 MipsKernGenException, /* bus error (load or store) */
151 MipsKernGenException, /* system call */
152 MipsKernGenException, /* breakpoint */
153 MipsKernGenException, /* reserved instruction */
154 MipsKernGenException, /* coprocessor unusable */
155 MipsKernGenException, /* arithmetic overflow */
156 MipsKernGenException, /* trap exception */
157 MipsKernGenException, /* virtual coherence exception inst */
158 MipsKernGenException, /* floating point exception */
159 MipsKernGenException, /* reserved */
160 MipsKernGenException, /* reserved */
161 MipsKernGenException, /* reserved */
162 MipsKernGenException, /* reserved */
163 MipsKernGenException, /* reserved */
164 MipsKernGenException, /* reserved */
165 MipsKernGenException, /* reserved */
166 MipsKernGenException, /* watch exception */
167 MipsKernGenException, /* reserved */
168 MipsKernGenException, /* reserved */
169 MipsKernGenException, /* reserved */
170 MipsKernGenException, /* reserved */
171 MipsKernGenException, /* reserved */
172 MipsKernGenException, /* reserved */
173 MipsKernGenException, /* reserved */
174 MipsKernGenException, /* virtual coherence exception data */
176 * The user exception handlers.
178 MipsUserIntr, /* 0 */
179 MipsUserGenException, /* 1 */
180 MipsTLBInvalidException,/* 2 */
181 MipsTLBInvalidException,/* 3 */
182 MipsUserGenException, /* 4 */
183 MipsUserGenException, /* 5 */
184 MipsUserGenException, /* 6 */
185 MipsUserGenException, /* 7 */
186 MipsUserGenException, /* 8 */
187 MipsUserGenException, /* 9 */
188 MipsUserGenException, /* 10 */
189 MipsUserGenException, /* 11 */
190 MipsUserGenException, /* 12 */
191 MipsUserGenException, /* 13 */
192 MipsUserGenException, /* 14 */
193 MipsUserGenException, /* 15 */
194 MipsUserGenException, /* 16 */
195 MipsUserGenException, /* 17 */
196 MipsUserGenException, /* 18 */
197 MipsUserGenException, /* 19 */
198 MipsUserGenException, /* 20 */
199 MipsUserGenException, /* 21 */
200 MipsUserGenException, /* 22 */
201 MipsUserGenException, /* 23 */
202 MipsUserGenException, /* 24 */
203 MipsUserGenException, /* 25 */
204 MipsUserGenException, /* 26 */
205 MipsUserGenException, /* 27 */
206 MipsUserGenException, /* 28 */
207 MipsUserGenException, /* 29 */
208 MipsUserGenException, /* 20 */
209 MipsUserGenException, /* 31 */
212 char *trap_type[] = {
213 "external interrupt",
215 "TLB miss (load or instr. fetch)",
217 "address error (load or I-fetch)",
218 "address error (store)",
219 "bus error (I-fetch)",
220 "bus error (load or store)",
223 "reserved instruction",
224 "coprocessor unusable",
225 "arithmetic overflow",
227 "virtual coherency instruction",
244 "virtual coherency data",
247 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
248 struct trapdebug trapdebug[TRAPSIZE], *trp = trapdebug;
251 #if defined(DDB) || defined(DEBUG)
252 void stacktrace(struct trapframe *);
253 void logstacktrace(struct trapframe *);
256 #define KERNLAND(x) ((vm_offset_t)(x) >= VM_MIN_KERNEL_ADDRESS && (vm_offset_t)(x) < VM_MAX_KERNEL_ADDRESS)
257 #define DELAYBRANCH(x) ((int)(x) < 0)
260 * MIPS load/store access type
273 char *access_name[] = {
274 "Load Halfword Unsigned",
276 "Load Word Unsigned",
285 #include <machine/octeon_cop2.h>
288 static int allow_unaligned_acc = 1;
290 SYSCTL_INT(_vm, OID_AUTO, allow_unaligned_acc, CTLFLAG_RW,
291 &allow_unaligned_acc, 0, "Allow unaligned accesses");
294 * FP emulation is assumed to work on O32, but the code is outdated and crufty
295 * enough that it's a more sensible default to have it disabled when using
296 * other ABIs. At the very least, it needs a lot of help in using
297 * type-semantic ABI-oblivious macros for everything it does.
299 #if defined(__mips_o32)
300 static int emulate_fp = 1;
302 static int emulate_fp = 0;
304 SYSCTL_INT(_machdep, OID_AUTO, emulate_fp, CTLFLAG_RW,
305 &emulate_fp, 0, "Emulate unimplemented FPU instructions");
307 static int emulate_unaligned_access(struct trapframe *frame, int mode);
309 extern void fswintrberr(void); /* XXX */
312 cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
314 struct trapframe *locr0 = td->td_frame;
315 struct sysentvec *se;
318 bzero(sa->args, sizeof(sa->args));
320 /* compute next PC after syscall instruction */
321 td->td_pcb->pcb_tpc = sa->trapframe->pc; /* Remember if restart */
322 if (DELAYBRANCH(sa->trapframe->cause)) /* Check BD bit */
323 locr0->pc = MipsEmulateBranch(locr0, sa->trapframe->pc, 0, 0);
325 locr0->pc += sizeof(int);
326 sa->code = locr0->v0;
332 * This is an indirect syscall, in which the code is the first argument.
334 #if (!defined(__mips_n32) && !defined(__mips_n64)) || defined(COMPAT_FREEBSD32)
335 if (sa->code == SYS___syscall && SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
337 * Like syscall, but code is a quad, so as to maintain alignment
338 * for the rest of the arguments.
340 if (_QUAD_LOWWORD == 0)
341 sa->code = locr0->a0;
343 sa->code = locr0->a1;
344 sa->args[0] = locr0->a2;
345 sa->args[1] = locr0->a3;
351 * This is either not a quad syscall, or is a quad syscall with a
352 * new ABI in which quads fit in a single register.
354 sa->code = locr0->a0;
355 sa->args[0] = locr0->a1;
356 sa->args[1] = locr0->a2;
357 sa->args[2] = locr0->a3;
359 #if defined(__mips_n32) || defined(__mips_n64)
360 #ifdef COMPAT_FREEBSD32
361 if (!SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
364 * Non-o32 ABIs support more arguments in registers.
366 sa->args[3] = locr0->t4;
367 sa->args[4] = locr0->t5;
368 sa->args[5] = locr0->t6;
369 sa->args[6] = locr0->t7;
371 #ifdef COMPAT_FREEBSD32
378 * A direct syscall, arguments are just parameters to the syscall.
380 sa->args[0] = locr0->a0;
381 sa->args[1] = locr0->a1;
382 sa->args[2] = locr0->a2;
383 sa->args[3] = locr0->a3;
385 #if defined (__mips_n32) || defined(__mips_n64)
386 #ifdef COMPAT_FREEBSD32
387 if (!SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
390 * Non-o32 ABIs support more arguments in registers.
392 sa->args[4] = locr0->t4;
393 sa->args[5] = locr0->t5;
394 sa->args[6] = locr0->t6;
395 sa->args[7] = locr0->t7;
397 #ifdef COMPAT_FREEBSD32
406 printf("SYSCALL #%d pid:%u\n", sa->code, td->td_proc->p_pid);
409 se = td->td_proc->p_sysent;
412 * Shouldn't this go before switching on the code?
415 sa->code &= se->sv_mask;
417 if (sa->code >= se->sv_size)
418 sa->callp = &se->sv_table[0];
420 sa->callp = &se->sv_table[sa->code];
422 sa->narg = sa->callp->sy_narg;
424 if (sa->narg > nsaved) {
425 #if defined(__mips_n32) || defined(__mips_n64)
428 * Is this right for new ABIs? I think the 4 there
429 * should be 8, size there are 8 registers to skip,
430 * not 4, but I'm not certain.
432 #ifdef COMPAT_FREEBSD32
433 if (!SV_PROC_FLAG(td->td_proc, SV_ILP32))
435 printf("SYSCALL #%u pid:%u, narg (%u) > nsaved (%u).\n",
436 sa->code, td->td_proc->p_pid, sa->narg, nsaved);
438 #if (defined(__mips_n32) || defined(__mips_n64)) && defined(COMPAT_FREEBSD32)
439 if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
443 error = 0; /* XXX GCC is awful. */
444 for (i = nsaved; i < sa->narg; i++) {
445 error = copyin((caddr_t)(intptr_t)(locr0->sp +
446 (4 + (i - nsaved)) * sizeof(int32_t)),
447 (caddr_t)&arg, sizeof arg);
454 error = copyin((caddr_t)(intptr_t)(locr0->sp +
455 4 * sizeof(register_t)), (caddr_t)&sa->args[nsaved],
456 (u_int)(sa->narg - nsaved) * sizeof(register_t));
465 td->td_retval[0] = 0;
466 td->td_retval[1] = locr0->v1;
474 #include "../../kern/subr_syscall.c"
477 * Handle an exception.
478 * Called from MipsKernGenException() or MipsUserGenException()
479 * when a processor trap occurs.
480 * In the case of a kernel trap, we return the pc where to resume if
481 * p->p_addr->u_pcb.pcb_onfault is set, otherwise, return old pc.
484 trap(struct trapframe *trapframe)
489 struct thread *td = curthread;
490 struct proc *p = curproc;
499 register_t *frame_regs;
501 trapdebug_enter(trapframe, 0);
503 type = (trapframe->cause & MIPS_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT;
504 if (TRAPF_USERMODE(trapframe)) {
512 * Enable hardware interrupts if they were on before the trap. If it
513 * was off disable all so we don't accidently enable it when doing a
514 * return to userland.
516 if (trapframe->sr & MIPS_SR_INT_IE) {
517 set_intr_mask(trapframe->sr & MIPS_SR_INT_MASK);
525 static vm_offset_t last_badvaddr = 0;
526 static vm_offset_t this_badvaddr = 0;
527 static int count = 0;
530 printf("trap type %x (%s - ", type,
531 trap_type[type & (~T_USER)]);
534 printf("user mode)\n");
536 printf("kernel mode)\n");
539 printf("cpuid = %d\n", PCPU_GET(cpuid));
541 pid = mips_rd_entryhi() & TLBHI_ASID_MASK;
542 printf("badaddr = %#jx, pc = %#jx, ra = %#jx, sp = %#jx, sr = %jx, pid = %d, ASID = %u\n",
543 (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
544 (intmax_t)trapframe->sp, (intmax_t)trapframe->sr,
545 (curproc ? curproc->p_pid : -1), pid);
547 switch (type & ~T_USER) {
553 this_badvaddr = trapframe->badvaddr;
556 this_badvaddr = trapframe->ra;
559 this_badvaddr = trapframe->pc;
562 if ((last_badvaddr == this_badvaddr) &&
563 ((type & ~T_USER) != T_SYSCALL)) {
565 trap_frame_dump(trapframe);
566 panic("too many faults at %p\n", (void *)last_badvaddr);
569 last_badvaddr = this_badvaddr;
577 * A trap can occur while DTrace executes a probe. Before
578 * executing the probe, DTrace blocks re-scheduling and sets
579 * a flag in it's per-cpu flags to indicate that it doesn't
580 * want to fault. On returning from the probe, the no-fault
581 * flag is cleared and finally re-scheduling is enabled.
583 * If the DTrace kernel module has registered a trap handler,
584 * call it and if it returns non-zero, assume that it has
585 * handled the trap and modified the trap frame so that this
586 * function can return normally.
589 * XXXDTRACE: add fasttrap and pid probes handlers here (if ever)
592 if (dtrace_trap_func != NULL && (*dtrace_trap_func)(trapframe, type))
593 return (trapframe->pc);
600 kdb_trap(type, 0, trapframe);
605 /* check for kernel address */
606 if (KERNLAND(trapframe->badvaddr)) {
607 if (pmap_emulate_modified(kernel_pmap,
608 trapframe->badvaddr) != 0) {
609 ftype = VM_PROT_WRITE;
612 return (trapframe->pc);
616 case T_TLB_MOD + T_USER:
617 pmap = &p->p_vmspace->vm_pmap;
618 if (pmap_emulate_modified(pmap, trapframe->badvaddr) != 0) {
619 ftype = VM_PROT_WRITE;
623 return (trapframe->pc);
628 ftype = (type == T_TLB_ST_MISS) ? VM_PROT_WRITE : VM_PROT_READ;
629 /* check for kernel address */
630 if (KERNLAND(trapframe->badvaddr)) {
635 va = trunc_page((vm_offset_t)trapframe->badvaddr);
636 rv = vm_fault(kernel_map, va, ftype, VM_FAULT_NORMAL);
637 if (rv == KERN_SUCCESS)
638 return (trapframe->pc);
639 if (td->td_pcb->pcb_onfault != NULL) {
640 pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
641 td->td_pcb->pcb_onfault = NULL;
648 * It is an error for the kernel to access user space except
649 * through the copyin/copyout routines.
651 if (td->td_pcb->pcb_onfault == NULL)
654 /* check for fuswintr() or suswintr() getting a page fault */
655 /* XXX There must be a nicer way to do this. */
656 if (td->td_pcb->pcb_onfault == fswintrberr) {
657 pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
658 td->td_pcb->pcb_onfault = NULL;
664 case T_TLB_LD_MISS + T_USER:
665 ftype = VM_PROT_READ;
668 case T_TLB_ST_MISS + T_USER:
669 ftype = VM_PROT_WRITE;
679 va = trunc_page((vm_offset_t)trapframe->badvaddr);
680 if (KERNLAND(trapframe->badvaddr)) {
682 * Don't allow user-mode faults in kernel
689 * Keep swapout from messing with us during this
696 rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
702 * XXXDTRACE: add dtrace_doubletrap_func here?
705 printf("vm_fault(%p (pmap %p), %p (%p), %x, %d) -> %x at pc %p\n",
706 map, &vm->vm_pmap, (void *)va, (void *)(intptr_t)trapframe->badvaddr,
707 ftype, VM_FAULT_NORMAL, rv, (void *)(intptr_t)trapframe->pc);
710 if (rv == KERN_SUCCESS) {
712 return (trapframe->pc);
718 if (td->td_pcb->pcb_onfault != NULL) {
719 pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
720 td->td_pcb->pcb_onfault = NULL;
726 i = ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
727 addr = trapframe->pc;
729 msg = "BAD_PAGE_FAULT";
730 log_bad_page_fault(msg, trapframe, type);
735 case T_ADDR_ERR_LD + T_USER: /* misaligned or kseg access */
736 case T_ADDR_ERR_ST + T_USER: /* misaligned or kseg access */
737 if (trapframe->badvaddr < 0 ||
738 trapframe->badvaddr >= VM_MAXUSER_ADDRESS) {
739 msg = "ADDRESS_SPACE_ERR";
740 } else if (allow_unaligned_acc) {
743 if (type == (T_ADDR_ERR_LD + T_USER))
746 mode = VM_PROT_WRITE;
748 access_type = emulate_unaligned_access(trapframe, mode);
749 if (access_type != 0)
751 msg = "ALIGNMENT_FIX_ERR";
758 case T_BUS_ERR_IFETCH + T_USER: /* BERR asserted to cpu */
759 case T_BUS_ERR_LD_ST + T_USER: /* BERR asserted to cpu */
760 ucode = 0; /* XXX should be VM_PROT_something */
762 addr = trapframe->pc;
765 log_bad_page_fault(msg, trapframe, type);
768 case T_SYSCALL + T_USER:
770 struct syscall_args sa;
773 sa.trapframe = trapframe;
774 error = syscallenter(td, &sa);
776 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
777 if (trp == trapdebug)
778 trapdebug[TRAPSIZE - 1].code = sa.code;
780 trp[-1].code = sa.code;
782 trapdebug_enter(td->td_frame, -sa.code);
785 * The sync'ing of I & D caches for SYS_ptrace() is
786 * done by procfs_domem() through procfs_rwmem()
787 * instead of being done here under a special check
790 syscallret(td, error, &sa);
791 return (trapframe->pc);
796 kdb_trap(type, 0, trapframe);
797 return (trapframe->pc);
800 case T_BREAK + T_USER:
805 /* compute address of break instruction */
807 if (DELAYBRANCH(trapframe->cause))
810 /* read break instruction */
811 instr = fuword32((caddr_t)va);
813 printf("trap: %s (%d) breakpoint %x at %x: (adr %x ins %x)\n",
814 p->p_comm, p->p_pid, instr, trapframe->pc,
815 p->p_md.md_ss_addr, p->p_md.md_ss_instr); /* XXX */
817 if (td->td_md.md_ss_addr != va ||
818 instr != MIPS_BREAK_SSTEP) {
820 addr = trapframe->pc;
824 * The restoration of the original instruction and
825 * the clearing of the berakpoint will be done later
826 * by the call to ptrace_clear_single_step() in
827 * issignal() when SIGTRAP is processed.
829 addr = trapframe->pc;
834 case T_IWATCH + T_USER:
835 case T_DWATCH + T_USER:
839 /* compute address of trapped instruction */
841 if (DELAYBRANCH(trapframe->cause))
843 printf("watch exception @ %p\n", (void *)va);
849 case T_TRAP + T_USER:
853 struct trapframe *locr0 = td->td_frame;
855 /* compute address of trap instruction */
857 if (DELAYBRANCH(trapframe->cause))
859 /* read break instruction */
860 instr = fuword32((caddr_t)va);
862 if (DELAYBRANCH(trapframe->cause)) { /* Check BD bit */
863 locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0,
866 locr0->pc += sizeof(int);
869 i = SIGEMT; /* Stuff it with something for now */
873 case T_RES_INST + T_USER:
876 inst = *(InstFmt *)(intptr_t)trapframe->pc;
877 switch (inst.RType.op) {
879 switch (inst.RType.func) {
881 /* Register 29 used for TLS */
882 if (inst.RType.rd == 29) {
883 frame_regs = &(trapframe->zero);
884 frame_regs[inst.RType.rt] = (register_t)(intptr_t)td->td_md.md_tls;
885 #if defined(__mips_n64) && defined(COMPAT_FREEBSD32)
886 if (SV_PROC_FLAG(td->td_proc, SV_ILP32))
887 frame_regs[inst.RType.rt] += TLS_TP_OFFSET + TLS_TCB_SIZE32;
890 frame_regs[inst.RType.rt] += TLS_TP_OFFSET + TLS_TCB_SIZE;
891 trapframe->pc += sizeof(int);
899 log_illegal_instruction("RES_INST", trapframe);
901 addr = trapframe->pc;
910 cop = (trapframe->cause & MIPS_CR_COP_ERR) >> MIPS_CR_COP_ERR_SHIFT;
911 /* Handle only COP2 exception */
915 addr = trapframe->pc;
916 /* save userland cop2 context if it has been touched */
917 if ((td->td_md.md_flags & MDTD_COP2USED) &&
918 (td->td_md.md_cop2owner == COP2_OWNER_USERLAND)) {
919 if (td->td_md.md_ucop2)
920 octeon_cop2_save(td->td_md.md_ucop2);
922 panic("COP2 was used in user mode but md_ucop2 is NULL");
925 if (td->td_md.md_cop2 == NULL) {
926 td->td_md.md_cop2 = octeon_cop2_alloc_ctx();
927 if (td->td_md.md_cop2 == NULL)
928 panic("Failed to allocate COP2 context");
929 memset(td->td_md.md_cop2, 0, sizeof(*td->td_md.md_cop2));
932 octeon_cop2_restore(td->td_md.md_cop2);
934 /* Make userland re-request its context */
935 td->td_frame->sr &= ~MIPS_SR_COP_2_BIT;
936 td->td_md.md_flags |= MDTD_COP2USED;
937 td->td_md.md_cop2owner = COP2_OWNER_KERNEL;
938 /* Enable COP2, it will be disabled in cpu_switch */
939 mips_wr_status(mips_rd_status() | MIPS_SR_COP_2_BIT);
940 return (trapframe->pc);
946 case T_COP_UNUSABLE + T_USER:
947 cop = (trapframe->cause & MIPS_CR_COP_ERR) >> MIPS_CR_COP_ERR_SHIFT;
949 #if !defined(CPU_HAVEFPU)
950 /* FP (COP1) instruction */
951 log_illegal_instruction("COP1_UNUSABLE", trapframe);
955 addr = trapframe->pc;
956 MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame);
957 PCPU_SET(fpcurthread, td);
958 td->td_frame->sr |= MIPS_SR_COP_1_BIT;
959 td->td_md.md_flags |= MDTD_FPUSED;
965 addr = trapframe->pc;
966 if ((td->td_md.md_flags & MDTD_COP2USED) &&
967 (td->td_md.md_cop2owner == COP2_OWNER_KERNEL)) {
968 if (td->td_md.md_cop2)
969 octeon_cop2_save(td->td_md.md_cop2);
971 panic("COP2 was used in kernel mode but md_cop2 is NULL");
974 if (td->td_md.md_ucop2 == NULL) {
975 td->td_md.md_ucop2 = octeon_cop2_alloc_ctx();
976 if (td->td_md.md_ucop2 == NULL)
977 panic("Failed to allocate userland COP2 context");
978 memset(td->td_md.md_ucop2, 0, sizeof(*td->td_md.md_ucop2));
981 octeon_cop2_restore(td->td_md.md_ucop2);
983 td->td_frame->sr |= MIPS_SR_COP_2_BIT;
984 td->td_md.md_flags |= MDTD_COP2USED;
985 td->td_md.md_cop2owner = COP2_OWNER_USERLAND;
990 log_illegal_instruction("COPn_UNUSABLE", trapframe);
991 i = SIGILL; /* only FPU instructions allowed */
996 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
999 printf("FPU Trap: PC %#jx CR %x SR %x\n",
1000 (intmax_t)trapframe->pc, (unsigned)trapframe->cause, (unsigned)trapframe->sr);
1004 case T_FPE + T_USER:
1007 addr = trapframe->pc;
1010 MipsFPTrap(trapframe->sr, trapframe->cause, trapframe->pc);
1013 case T_OVFLOW + T_USER:
1015 addr = trapframe->pc;
1018 case T_ADDR_ERR_LD: /* misaligned access */
1019 case T_ADDR_ERR_ST: /* misaligned access */
1022 printf("+++ ADDR_ERR: type = %d, badvaddr = %#jx\n", type,
1023 (intmax_t)trapframe->badvaddr);
1026 /* Only allow emulation on a user address */
1027 if (allow_unaligned_acc &&
1028 ((vm_offset_t)trapframe->badvaddr < VM_MAXUSER_ADDRESS)) {
1031 if (type == T_ADDR_ERR_LD)
1032 mode = VM_PROT_READ;
1034 mode = VM_PROT_WRITE;
1036 access_type = emulate_unaligned_access(trapframe, mode);
1037 if (access_type != 0)
1038 return (trapframe->pc);
1042 case T_BUS_ERR_LD_ST: /* BERR asserted to cpu */
1043 if (td->td_pcb->pcb_onfault != NULL) {
1044 pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
1045 td->td_pcb->pcb_onfault = NULL;
1054 #if !defined(SMP) && defined(DEBUG)
1055 stacktrace(!usermode ? trapframe : td->td_frame);
1059 printf("cpu:%d-", PCPU_GET(cpuid));
1061 printf("Trap cause = %d (%s - ", type,
1062 trap_type[type & (~T_USER)]);
1065 printf("user mode)\n");
1067 printf("kernel mode)\n");
1071 printf("badvaddr = %#jx, pc = %#jx, ra = %#jx, sr = %#jxx\n",
1072 (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
1073 (intmax_t)trapframe->sr);
1077 if (debugger_on_panic || kdb_active) {
1078 kdb_trap(type, 0, trapframe);
1083 td->td_frame->pc = trapframe->pc;
1084 td->td_frame->cause = trapframe->cause;
1085 td->td_frame->badvaddr = trapframe->badvaddr;
1086 ksiginfo_init_trap(&ksi);
1088 ksi.ksi_code = ucode;
1089 ksi.ksi_addr = (void *)addr;
1090 ksi.ksi_trapno = type;
1091 trapsignal(td, &ksi);
1095 * Note: we should only get here if returning to user mode.
1097 userret(td, trapframe);
1098 return (trapframe->pc);
1101 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
1109 printf("trapDump(%s)\n", msg);
1110 for (i = 0; i < TRAPSIZE; i++) {
1111 if (trp == trapdebug) {
1112 trp = &trapdebug[TRAPSIZE - 1];
1117 if (trp->cause == 0)
1120 printf("%s: ADR %jx PC %jx CR %jx SR %jx\n",
1121 trap_type[(trp->cause & MIPS_CR_EXC_CODE) >>
1122 MIPS_CR_EXC_CODE_SHIFT],
1123 (intmax_t)trp->vadr, (intmax_t)trp->pc,
1124 (intmax_t)trp->cause, (intmax_t)trp->status);
1126 printf(" RA %jx SP %jx code %d\n", (intmax_t)trp->ra,
1127 (intmax_t)trp->sp, (int)trp->code);
1135 * Return the resulting PC as if the branch was executed.
1138 MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR,
1142 register_t *regsPtr = (register_t *) framePtr;
1143 uintptr_t retAddr = 0;
1146 #define GetBranchDest(InstPtr, inst) \
1147 (InstPtr + 4 + ((short)inst.IType.imm << 2))
1151 if (instptr < MIPS_KSEG0_START)
1152 inst.word = fuword32((void *)instptr);
1154 inst = *(InstFmt *) instptr;
1156 if ((vm_offset_t)instPC < MIPS_KSEG0_START)
1157 inst.word = fuword32((void *)instPC);
1159 inst = *(InstFmt *) instPC;
1162 switch ((int)inst.JType.op) {
1164 switch ((int)inst.RType.func) {
1167 retAddr = regsPtr[inst.RType.rs];
1171 retAddr = instPC + 4;
1177 switch ((int)inst.IType.rt) {
1182 if ((int)(regsPtr[inst.RType.rs]) < 0)
1183 retAddr = GetBranchDest(instPC, inst);
1185 retAddr = instPC + 8;
1192 if ((int)(regsPtr[inst.RType.rs]) >= 0)
1193 retAddr = GetBranchDest(instPC, inst);
1195 retAddr = instPC + 8;
1204 retAddr = instPC + 4; /* Like syscall... */
1208 panic("MipsEmulateBranch: Bad branch cond");
1214 retAddr = (inst.JType.target << 2) |
1215 ((unsigned)(instPC + 4) & 0xF0000000);
1220 if (regsPtr[inst.RType.rs] == regsPtr[inst.RType.rt])
1221 retAddr = GetBranchDest(instPC, inst);
1223 retAddr = instPC + 8;
1228 if (regsPtr[inst.RType.rs] != regsPtr[inst.RType.rt])
1229 retAddr = GetBranchDest(instPC, inst);
1231 retAddr = instPC + 8;
1236 if ((int)(regsPtr[inst.RType.rs]) <= 0)
1237 retAddr = GetBranchDest(instPC, inst);
1239 retAddr = instPC + 8;
1244 if ((int)(regsPtr[inst.RType.rs]) > 0)
1245 retAddr = GetBranchDest(instPC, inst);
1247 retAddr = instPC + 8;
1251 switch (inst.RType.rs) {
1254 if ((inst.RType.rt & COPz_BC_TF_MASK) == COPz_BC_TRUE)
1255 condition = fpcCSR & MIPS_FPU_COND_BIT;
1257 condition = !(fpcCSR & MIPS_FPU_COND_BIT);
1259 retAddr = GetBranchDest(instPC, inst);
1261 retAddr = instPC + 8;
1265 retAddr = instPC + 4;
1270 retAddr = instPC + 4;
1276 #if defined(DDB) || defined(DEBUG)
1278 * Print a stack backtrace.
1281 stacktrace(struct trapframe *regs)
1283 stacktrace_subr(regs->pc, regs->sp, regs->ra, printf);
1288 log_frame_dump(struct trapframe *frame)
1290 log(LOG_ERR, "Trapframe Register Dump:\n");
1291 log(LOG_ERR, "\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1292 (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1294 log(LOG_ERR, "\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1295 (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1297 log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1298 (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1300 log(LOG_ERR, "\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1301 (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1303 log(LOG_ERR, "\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1304 (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1306 log(LOG_ERR, "\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1307 (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1309 log(LOG_ERR, "\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1310 (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1312 log(LOG_ERR, "\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1313 (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1315 log(LOG_ERR, "\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1316 (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1319 log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
1320 (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
1322 log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\n",
1323 (intmax_t)frame->cause, (intmax_t)frame->pc);
1329 trap_frame_dump(struct trapframe *frame)
1331 printf("Trapframe Register Dump:\n");
1332 printf("\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
1333 (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
1335 printf("\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
1336 (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
1338 printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
1339 (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
1341 printf("\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
1342 (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
1344 printf("\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
1345 (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
1347 printf("\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
1348 (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
1350 printf("\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
1351 (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
1353 printf("\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
1354 (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
1356 printf("\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
1357 (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
1360 printf("\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
1361 (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
1363 printf("\tcause: %#jx\tpc: %#jx\n",
1364 (intmax_t)frame->cause, (intmax_t)frame->pc);
1372 get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp)
1376 struct proc *p = curproc;
1378 pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[(va >> SEGSHIFT) & (NPDEPG - 1)]));
1380 ptep = pmap_pte(&p->p_vmspace->vm_pmap, va);
1382 ptep = (pt_entry_t *)0;
1389 log_illegal_instruction(const char *msg, struct trapframe *frame)
1402 printf("cpuid = %d\n", PCPU_GET(cpuid));
1404 pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1405 log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx ra %#jx\n",
1406 msg, p->p_pid, (long)td->td_tid, p->p_comm,
1407 p->p_ucred ? p->p_ucred->cr_uid : -1,
1409 (intmax_t)frame->ra);
1411 /* log registers in trap frame */
1412 log_frame_dump(frame);
1414 get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1417 * Dump a few words around faulting instruction, if the addres is
1421 useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1422 /* dump page table entry for faulting instruction */
1423 log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n",
1424 (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1426 addr = (unsigned int *)(intptr_t)pc;
1427 log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1429 log(LOG_ERR, "%08x %08x %08x %08x\n",
1430 addr[0], addr[1], addr[2], addr[3]);
1432 log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1433 (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1438 log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
1445 char *read_or_write;
1448 trap_type &= ~T_USER;
1454 printf("cpuid = %d\n", PCPU_GET(cpuid));
1456 switch (trap_type) {
1459 read_or_write = "write";
1463 case T_BUS_ERR_IFETCH:
1464 read_or_write = "read";
1467 read_or_write = "unknown";
1470 pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1471 log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx got a %s fault "
1472 "(type %#x) at %#jx\n",
1473 msg, p->p_pid, (long)td->td_tid, p->p_comm,
1474 p->p_ucred ? p->p_ucred->cr_uid : -1,
1478 (intmax_t)frame->badvaddr);
1480 /* log registers in trap frame */
1481 log_frame_dump(frame);
1483 get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
1486 * Dump a few words around faulting instruction, if the addres is
1489 if (!(pc & 3) && (pc != frame->badvaddr) &&
1490 (trap_type != T_BUS_ERR_IFETCH) &&
1491 useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
1492 /* dump page table entry for faulting instruction */
1493 log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n",
1494 (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1496 addr = (unsigned int *)(intptr_t)pc;
1497 log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
1499 log(LOG_ERR, "%08x %08x %08x %08x\n",
1500 addr[0], addr[1], addr[2], addr[3]);
1502 log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n",
1503 (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1506 get_mapping_info((vm_offset_t)frame->badvaddr, &pdep, &ptep);
1507 log(LOG_ERR, "Page table info for bad address %#jx: pde = %p, pte = %#jx\n",
1508 (intmax_t)frame->badvaddr, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0));
1513 * Unaligned load/store emulation
1516 mips_unaligned_load_store(struct trapframe *frame, int mode, register_t addr, register_t pc)
1518 register_t *reg = (register_t *) frame;
1519 u_int32_t inst = *((u_int32_t *)(intptr_t)pc);
1520 register_t value_msb, value;
1524 * ADDR_ERR faults have higher priority than TLB
1525 * Miss faults. Therefore, it is necessary to
1526 * verify that the faulting address is a valid
1527 * virtual address within the process' address space
1528 * before trying to emulate the unaligned access.
1530 switch (MIPS_INST_OPCODE(inst)) {
1531 case OP_LHU: case OP_LH:
1535 case OP_LWU: case OP_LW:
1544 printf("%s: unhandled opcode in address error: %#x\n", __func__, MIPS_INST_OPCODE(inst));
1548 if (!useracc((void *)((vm_offset_t)addr & ~(size - 1)), size * 2, mode))
1553 * Handle LL/SC LLD/SCD.
1555 switch (MIPS_INST_OPCODE(inst)) {
1557 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1558 lbu_macro(value_msb, addr);
1560 lbu_macro(value, addr);
1561 value |= value_msb << 8;
1562 reg[MIPS_INST_RT(inst)] = value;
1563 return (MIPS_LHU_ACCESS);
1566 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1567 lb_macro(value_msb, addr);
1569 lbu_macro(value, addr);
1570 value |= value_msb << 8;
1571 reg[MIPS_INST_RT(inst)] = value;
1572 return (MIPS_LH_ACCESS);
1575 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1576 lwl_macro(value, addr);
1578 lwr_macro(value, addr);
1579 value &= 0xffffffff;
1580 reg[MIPS_INST_RT(inst)] = value;
1581 return (MIPS_LWU_ACCESS);
1584 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1585 lwl_macro(value, addr);
1587 lwr_macro(value, addr);
1588 reg[MIPS_INST_RT(inst)] = value;
1589 return (MIPS_LW_ACCESS);
1591 #if defined(__mips_n32) || defined(__mips_n64)
1593 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction."));
1594 ldl_macro(value, addr);
1596 ldr_macro(value, addr);
1597 reg[MIPS_INST_RT(inst)] = value;
1598 return (MIPS_LD_ACCESS);
1602 KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1603 value = reg[MIPS_INST_RT(inst)];
1604 value_msb = value >> 8;
1605 sb_macro(value_msb, addr);
1607 sb_macro(value, addr);
1608 return (MIPS_SH_ACCESS);
1611 KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1612 value = reg[MIPS_INST_RT(inst)];
1613 swl_macro(value, addr);
1615 swr_macro(value, addr);
1616 return (MIPS_SW_ACCESS);
1618 #if defined(__mips_n32) || defined(__mips_n64)
1620 KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction."));
1621 value = reg[MIPS_INST_RT(inst)];
1622 sdl_macro(value, addr);
1624 sdr_macro(value, addr);
1625 return (MIPS_SD_ACCESS);
1628 panic("%s: should not be reached.", __func__);
1633 emulate_unaligned_access(struct trapframe *frame, int mode)
1636 int access_type = 0;
1638 pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
1641 * Fall through if it's instruction fetch exception
1643 if (!((pc & 3) || (pc == frame->badvaddr))) {
1646 * Handle unaligned load and store
1650 * Return access type if the instruction was emulated.
1651 * Otherwise restore pc and fall through.
1653 access_type = mips_unaligned_load_store(frame,
1654 mode, frame->badvaddr, pc);
1657 if (DELAYBRANCH(frame->cause))
1658 frame->pc = MipsEmulateBranch(frame, frame->pc,
1663 log(LOG_INFO, "Unaligned %s: pc=%#jx, badvaddr=%#jx\n",
1664 access_name[access_type - 1], (intmax_t)pc,
1665 (intmax_t)frame->badvaddr);