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