1 /* $NetBSD: trap.c,v 1.38 2002/09/11 01:46:35 mycroft Exp $ */ 2 3 /* 4 * This file was taken from mvme68k/mvme68k/trap.c 5 * should probably be re-synced when needed. 6 * Darrin B. Jewell <jewell@mit.edu> Tue Aug 3 10:53:12 UTC 1999 7 * original cvs id: NetBSD: trap.c,v 1.32 1999/08/03 10:52:06 dbj Exp 8 */ 9 10 /* 11 * Copyright (c) 1988 University of Utah. 12 * Copyright (c) 1982, 1986, 1990, 1993 13 * The Regents of the University of California. All rights reserved. 14 * 15 * This code is derived from software contributed to Berkeley by 16 * the Systems Programming Group of the University of Utah Computer 17 * Science Department. 18 * 19 * Redistribution and use in source and binary forms, with or without 20 * modification, are permitted provided that the following conditions 21 * are met: 22 * 1. Redistributions of source code must retain the above copyright 23 * notice, this list of conditions and the following disclaimer. 24 * 2. Redistributions in binary form must reproduce the above copyright 25 * notice, this list of conditions and the following disclaimer in the 26 * documentation and/or other materials provided with the distribution. 27 * 3. All advertising materials mentioning features or use of this software 28 * must display the following acknowledgement: 29 * This product includes software developed by the University of 30 * California, Berkeley and its contributors. 31 * 4. Neither the name of the University nor the names of its contributors 32 * may be used to endorse or promote products derived from this software 33 * without specific prior written permission. 34 * 35 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 36 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 38 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 39 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 45 * SUCH DAMAGE. 46 * 47 * from: Utah $Hdr: trap.c 1.37 92/12/20$ 48 * 49 * @(#)trap.c 8.5 (Berkeley) 1/4/94 50 */ 51 52 #include "opt_ddb.h" 53 #include "opt_execfmt.h" 54 #include "opt_kgdb.h" 55 #include "opt_compat_sunos.h" 56 #include "opt_compat_hpux.h" 57 58 #include <sys/param.h> 59 #include <sys/systm.h> 60 #include <sys/proc.h> 61 #include <sys/acct.h> 62 #include <sys/kernel.h> 63 #include <sys/signalvar.h> 64 #include <sys/resourcevar.h> 65 #include <sys/syscall.h> 66 #include <sys/syslog.h> 67 #include <sys/user.h> 68 69 #ifdef DEBUG 70 #include <dev/cons.h> 71 #endif 72 73 #include <machine/db_machdep.h> 74 #include <machine/psl.h> 75 #include <machine/trap.h> 76 #include <machine/cpu.h> 77 #include <machine/reg.h> 78 79 #include <m68k/cacheops.h> 80 81 #include <uvm/uvm_extern.h> 82 83 #ifdef COMPAT_HPUX 84 #include <compat/hpux/hpux.h> 85 #endif 86 87 #ifdef COMPAT_SUNOS 88 #include <compat/sunos/sunos_syscall.h> 89 extern struct emul emul_sunos; 90 #endif 91 92 #ifdef KGDB 93 #include <sys/kgdb.h> 94 #endif 95 96 int writeback __P((struct frame *fp, int docachepush)); 97 void trap __P((int type, u_int code, u_int v, struct frame frame)); 98 99 #ifdef DEBUG 100 void dumpssw __P((u_short)); 101 void dumpwb __P((int, u_short, u_int, u_int)); 102 #endif 103 104 static inline void userret __P((struct proc *p, struct frame *fp, 105 u_quad_t oticks, u_int faultaddr, int fromtrap)); 106 107 int astpending; 108 109 char *trap_type[] = { 110 "Bus error", 111 "Address error", 112 "Illegal instruction", 113 "Zero divide", 114 "CHK instruction", 115 "TRAPV instruction", 116 "Privilege violation", 117 "Trace trap", 118 "MMU fault", 119 "SSIR trap", 120 "Format error", 121 "68881 exception", 122 "Coprocessor violation", 123 "Async system trap" 124 }; 125 int trap_types = sizeof trap_type / sizeof trap_type[0]; 126 127 /* 128 * Size of various exception stack frames (minus the standard 8 bytes) 129 */ 130 short exframesize[] = { 131 FMT0SIZE, /* type 0 - normal (68020/030/040/060) */ 132 FMT1SIZE, /* type 1 - throwaway (68020/030/040) */ 133 FMT2SIZE, /* type 2 - normal 6-word (68020/030/040/060) */ 134 FMT3SIZE, /* type 3 - FP post-instruction (68040/060) */ 135 FMT4SIZE, /* type 4 - access error/fp disabled (68060) */ 136 -1, -1, /* type 5-6 - undefined */ 137 FMT7SIZE, /* type 7 - access error (68040) */ 138 58, /* type 8 - bus fault (68010) */ 139 FMT9SIZE, /* type 9 - coprocessor mid-instruction (68020/030) */ 140 FMTASIZE, /* type A - short bus fault (68020/030) */ 141 FMTBSIZE, /* type B - long bus fault (68020/030) */ 142 -1, -1, -1, -1 /* type C-F - undefined */ 143 }; 144 145 #ifdef M68060 146 #define KDFAULT_060(c) (cputype == CPU_68060 && ((c) & FSLW_TM_SV)) 147 #define WRFAULT_060(c) (cputype == CPU_68060 && ((c) & FSLW_RW_W)) 148 #else 149 #define KDFAULT_060(c) 0 150 #define WRFAULT_060(c) 0 151 #endif 152 153 #ifdef M68040 154 #define KDFAULT_040(c) (cputype == CPU_68040 && \ 155 ((c) & SSW4_TMMASK) == SSW4_TMKD) 156 #define WRFAULT_040(c) (cputype == CPU_68040 && \ 157 ((c) & SSW4_RW) == 0) 158 #else 159 #define KDFAULT_040(c) 0 160 #define WRFAULT_040(c) 0 161 #endif 162 163 #if defined(M68030) || defined(M68020) 164 #define KDFAULT_OTH(c) (cputype <= CPU_68030 && \ 165 ((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD)) 166 #define WRFAULT_OTH(c) (cputype <= CPU_68030 && \ 167 ((c) & (SSW_DF|SSW_RW)) == SSW_DF) 168 #else 169 #define KDFAULT_OTH(c) 0 170 #define WRFAULT_OTH(c) 0 171 #endif 172 173 #define KDFAULT(c) (KDFAULT_060(c) || KDFAULT_040(c) || KDFAULT_OTH(c)) 174 #define WRFAULT(c) (WRFAULT_060(c) || WRFAULT_040(c) || WRFAULT_OTH(c)) 175 176 #ifdef DEBUG 177 int mmudebug = 0; 178 int mmupid = -1; 179 #define MDB_FOLLOW 1 180 #define MDB_WBFOLLOW 2 181 #define MDB_WBFAILED 4 182 #define MDB_ISPID(p) ((p) == mmupid) 183 #endif 184 185 186 #define NSIR 32 187 void (*sir_routines[NSIR])(void *); 188 void *sir_args[NSIR]; 189 int next_sir; 190 191 /* 192 * trap and syscall both need the following work done before returning 193 * to user mode. 194 */ 195 static inline void 196 userret(p, fp, oticks, faultaddr, fromtrap) 197 struct proc *p; 198 struct frame *fp; 199 u_quad_t oticks; 200 u_int faultaddr; 201 int fromtrap; 202 { 203 int sig; 204 #ifdef M68040 205 int beenhere = 0; 206 207 again: 208 #endif 209 /* take pending signals */ 210 while ((sig = CURSIG(p)) != 0) 211 postsig(sig); 212 p->p_priority = p->p_usrpri; 213 if (want_resched) { 214 /* 215 * We are being preempted. 216 */ 217 preempt(NULL); 218 while ((sig = CURSIG(p)) != 0) 219 postsig(sig); 220 } 221 222 /* 223 * If profiling, charge system time to the trapped pc. 224 */ 225 if (p->p_flag & P_PROFIL) { 226 extern int psratio; 227 228 addupc_task(p, fp->f_pc, 229 (int)(p->p_sticks - oticks) * psratio); 230 } 231 #ifdef M68040 232 /* 233 * Deal with user mode writebacks (from trap, or from sigreturn). 234 * If any writeback fails, go back and attempt signal delivery. 235 * unless we have already been here and attempted the writeback 236 * (e.g. bad address with user ignoring SIGSEGV). In that case 237 * we just return to the user without sucessfully completing 238 * the writebacks. Maybe we should just drop the sucker? 239 */ 240 if (cputype == CPU_68040 && fp->f_format == FMT7) { 241 if (beenhere) { 242 #ifdef DEBUG 243 if (mmudebug & MDB_WBFAILED) 244 printf(fromtrap ? 245 "pid %d(%s): writeback aborted, pc=%x, fa=%x\n" : 246 "pid %d(%s): writeback aborted in sigreturn, pc=%x\n", 247 p->p_pid, p->p_comm, fp->f_pc, faultaddr); 248 #endif 249 } else if ((sig = writeback(fp, fromtrap))) { 250 beenhere = 1; 251 oticks = p->p_sticks; 252 trapsignal(p, sig, faultaddr); 253 goto again; 254 } 255 } 256 #endif 257 curcpu()->ci_schedstate.spc_curpriority = p->p_priority; 258 } 259 260 /* 261 * Used by the common m68k syscall() and child_return() functions. 262 * XXX: Temporary until all m68k ports share common trap()/userret() code. 263 */ 264 void machine_userret(struct proc *, struct frame *, u_quad_t); 265 266 void 267 machine_userret(p, f, t) 268 struct proc *p; 269 struct frame *f; 270 u_quad_t t; 271 { 272 273 userret(p, f, t, 0, 0); 274 } 275 276 /* 277 * Trap is called from locore to handle most types of processor traps, 278 * including events such as simulated software interrupts/AST's. 279 * System calls are broken out for efficiency. 280 */ 281 /*ARGSUSED*/ 282 void 283 trap(type, code, v, frame) 284 int type; 285 unsigned code; 286 unsigned v; 287 struct frame frame; 288 { 289 extern char fubail[], subail[]; 290 struct proc *p; 291 int i, s; 292 u_int ucode; 293 u_quad_t sticks = 0 /* XXX initialiser works around compiler bug */; 294 int bit; 295 static int panicing = 0; 296 297 uvmexp.traps++; 298 p = curproc; 299 ucode = 0; 300 301 /* I have verified that this DOES happen! -gwr */ 302 if (p == NULL) 303 p = &proc0; 304 #ifdef DIAGNOSTIC 305 if (p->p_addr == NULL) 306 panic("trap: no pcb"); 307 #endif 308 309 if (USERMODE(frame.f_sr)) { 310 type |= T_USER; 311 sticks = p->p_sticks; 312 p->p_md.md_regs = frame.f_regs; 313 } 314 switch (type) { 315 316 default: 317 dopanic: 318 /* 319 * Let the kernel debugger see the trap frame that 320 * caused us to panic. This is a convenience so 321 * one can see registers at the point of failure. 322 */ 323 s = splhigh(); 324 panicing = 1; 325 printf("trap type %d, code = 0x%x, v = 0x%x\n", type, code, v); 326 printf("%s program counter = 0x%x\n", 327 (type & T_USER) ? "user" : "kernel", frame.f_pc); 328 #ifdef KGDB 329 /* If connected, step or cont returns 1 */ 330 if (kgdb_trap(type, (db_regs_t *)&frame)) 331 goto kgdb_cont; 332 #endif 333 #ifdef DDB 334 (void)kdb_trap(type, (db_regs_t *)&frame); 335 #endif 336 #ifdef KGDB 337 kgdb_cont: 338 #endif 339 splx(s); 340 if (panicstr) { 341 printf("trap during panic!\n"); 342 #ifdef DEBUG 343 /* XXX should be a machine-dependent hook */ 344 printf("(press a key)\n"); (void)cngetc(); 345 #endif 346 } 347 regdump((struct trapframe *)&frame, 128); 348 type &= ~T_USER; 349 if ((u_int)type < trap_types) 350 panic(trap_type[type]); 351 panic("trap"); 352 353 case T_BUSERR: /* kernel bus error */ 354 if (p->p_addr->u_pcb.pcb_onfault == 0) 355 goto dopanic; 356 /* FALLTHROUGH */ 357 358 copyfault: 359 /* 360 * If we have arranged to catch this fault in any of the 361 * copy to/from user space routines, set PC to return to 362 * indicated location and set flag informing buserror code 363 * that it may need to clean up stack frame. 364 */ 365 frame.f_stackadj = exframesize[frame.f_format]; 366 frame.f_format = frame.f_vector = 0; 367 frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault; 368 return; 369 370 case T_BUSERR|T_USER: /* bus error */ 371 case T_ADDRERR|T_USER: /* address error */ 372 ucode = v; 373 i = SIGBUS; 374 break; 375 376 case T_COPERR: /* kernel coprocessor violation */ 377 case T_FMTERR|T_USER: /* do all RTE errors come in as T_USER? */ 378 case T_FMTERR: /* ...just in case... */ 379 /* 380 * The user has most likely trashed the RTE or FP state info 381 * in the stack frame of a signal handler. 382 */ 383 printf("pid %d: kernel %s exception\n", p->p_pid, 384 type==T_COPERR ? "coprocessor" : "format"); 385 type |= T_USER; 386 SIGACTION(p, SIGILL).sa_handler = SIG_DFL; 387 sigdelset(&p->p_sigctx.ps_sigignore, SIGILL); 388 sigdelset(&p->p_sigctx.ps_sigcatch, SIGILL); 389 sigdelset(&p->p_sigctx.ps_sigmask, SIGILL); 390 i = SIGILL; 391 ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */ 392 break; 393 394 case T_COPERR|T_USER: /* user coprocessor violation */ 395 /* What is a proper response here? */ 396 ucode = 0; 397 i = SIGFPE; 398 break; 399 400 case T_FPERR|T_USER: /* 68881 exceptions */ 401 /* 402 * We pass along the 68881 status register which locore stashed 403 * in code for us. Note that there is a possibility that the 404 * bit pattern of this register will conflict with one of the 405 * FPE_* codes defined in signal.h. Fortunately for us, the 406 * only such codes we use are all in the range 1-7 and the low 407 * 3 bits of the status register are defined as 0 so there is 408 * no clash. 409 */ 410 ucode = code; 411 i = SIGFPE; 412 break; 413 414 #ifdef M68040 415 case T_FPEMULI|T_USER: /* unimplemented FP instuction */ 416 case T_FPEMULD|T_USER: /* unimplemented FP data type */ 417 /* XXX need to FSAVE */ 418 printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n", 419 p->p_pid, p->p_comm, 420 frame.f_format == 2 ? "instruction" : "data type", 421 frame.f_pc, frame.f_fmt2.f_iaddr); 422 /* XXX need to FRESTORE */ 423 i = SIGFPE; 424 break; 425 #endif 426 427 case T_ILLINST|T_USER: /* illegal instruction fault */ 428 #ifdef COMPAT_HPUX 429 if (p->p_emul == &emul_hpux) { 430 ucode = HPUX_ILL_ILLINST_TRAP; 431 i = SIGILL; 432 break; 433 } 434 /* fall through */ 435 #endif 436 case T_PRIVINST|T_USER: /* privileged instruction fault */ 437 #ifdef COMPAT_HPUX 438 if (p->p_emul == &emul_hpux) 439 ucode = HPUX_ILL_PRIV_TRAP; 440 else 441 #endif 442 ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ 443 i = SIGILL; 444 break; 445 446 case T_ZERODIV|T_USER: /* Divide by zero */ 447 #ifdef COMPAT_HPUX 448 if (p->p_emul == &emul_hpux) 449 ucode = HPUX_FPE_INTDIV_TRAP; 450 else 451 #endif 452 ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */ 453 i = SIGFPE; 454 break; 455 456 case T_CHKINST|T_USER: /* CHK instruction trap */ 457 #ifdef COMPAT_HPUX 458 if (p->p_emul == &emul_hpux) { 459 /* handled differently under hp-ux */ 460 i = SIGILL; 461 ucode = HPUX_ILL_CHK_TRAP; 462 break; 463 } 464 #endif 465 ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */ 466 i = SIGFPE; 467 break; 468 469 case T_TRAPVINST|T_USER: /* TRAPV instruction trap */ 470 #ifdef COMPAT_HPUX 471 if (p->p_emul == &emul_hpux) { 472 /* handled differently under hp-ux */ 473 i = SIGILL; 474 ucode = HPUX_ILL_TRAPV_TRAP; 475 break; 476 } 477 #endif 478 ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */ 479 i = SIGFPE; 480 break; 481 482 /* 483 * XXX: Trace traps are a nightmare. 484 * 485 * HP-UX uses trap #1 for breakpoints, 486 * NetBSD/m68k uses trap #2, 487 * SUN 3.x uses trap #15, 488 * DDB and KGDB uses trap #15 (for kernel breakpoints; 489 * handled elsewhere). 490 * 491 * NetBSD and HP-UX traps both get mapped by locore.s into T_TRACE. 492 * SUN 3.x traps get passed through as T_TRAP15 and are not really 493 * supported yet. 494 * 495 * XXX: We should never get kernel-mode T_TRAP15 496 * XXX: because locore.s now gives them special treatment. 497 */ 498 case T_TRAP15: /* kernel breakpoint */ 499 #ifdef DEBUG 500 printf("unexpected kernel trace trap, type = %d\n", type); 501 printf("program counter = 0x%x\n", frame.f_pc); 502 #endif 503 frame.f_sr &= ~PSL_T; 504 return; 505 506 case T_TRACE|T_USER: /* user trace trap */ 507 #ifdef COMPAT_SUNOS 508 /* 509 * SunOS uses Trap #2 for a "CPU cache flush". 510 * Just flush the on-chip caches and return. 511 */ 512 if (p->p_emul == &emul_sunos) { 513 ICIA(); 514 DCIU(); 515 return; 516 } 517 #endif 518 /* FALLTHROUGH */ 519 case T_TRACE: /* tracing a trap instruction */ 520 case T_TRAP15|T_USER: /* SUN user trace trap */ 521 frame.f_sr &= ~PSL_T; 522 i = SIGTRAP; 523 break; 524 525 case T_ASTFLT: /* system async trap, cannot happen */ 526 goto dopanic; 527 528 case T_ASTFLT|T_USER: /* user async trap */ 529 astpending = 0; 530 /* 531 * We check for software interrupts first. This is because 532 * they are at a higher level than ASTs, and on a VAX would 533 * interrupt the AST. We assume that if we are processing 534 * an AST that we must be at IPL0 so we don't bother to 535 * check. Note that we ensure that we are at least at SIR 536 * IPL while processing the SIR. 537 */ 538 spl1(); 539 /* fall into... */ 540 541 case T_SSIR: /* software interrupt */ 542 case T_SSIR|T_USER: 543 while ((bit = ffs(ssir))) { 544 --bit; 545 ssir &= ~(1 << bit); 546 uvmexp.softs++; 547 if (sir_routines[bit]) 548 sir_routines[bit](sir_args[bit]); 549 } 550 /* 551 * If this was not an AST trap, we are all done. 552 */ 553 if (type != (T_ASTFLT|T_USER)) { 554 uvmexp.traps--; 555 return; 556 } 557 spl0(); 558 if (p->p_flag & P_OWEUPC) { 559 p->p_flag &= ~P_OWEUPC; 560 ADDUPROF(p); 561 } 562 goto out; 563 564 case T_MMUFLT: /* kernel mode page fault */ 565 /* 566 * If we were doing profiling ticks or other user mode 567 * stuff from interrupt code, Just Say No. 568 */ 569 if (p->p_addr->u_pcb.pcb_onfault == fubail || 570 p->p_addr->u_pcb.pcb_onfault == subail) 571 goto copyfault; 572 /* fall into ... */ 573 574 case T_MMUFLT|T_USER: /* page fault */ 575 { 576 vaddr_t va; 577 struct vmspace *vm = p->p_vmspace; 578 struct vm_map *map; 579 int rv; 580 vm_prot_t ftype; 581 extern struct vm_map *kernel_map; 582 583 #ifdef DEBUG 584 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 585 printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n", 586 p->p_pid, code, v, frame.f_pc, frame.f_sr); 587 #endif 588 /* 589 * It is only a kernel address space fault iff: 590 * 1. (type & T_USER) == 0 and 591 * 2. pcb_onfault not set or 592 * 3. pcb_onfault set but supervisor space data fault 593 * The last can occur during an exec() copyin where the 594 * argument space is lazy-allocated. 595 */ 596 if ((type & T_USER) == 0 && 597 ((p->p_addr->u_pcb.pcb_onfault == 0) || KDFAULT(code))) 598 map = kernel_map; 599 else 600 map = vm ? &vm->vm_map : kernel_map; 601 602 if (WRFAULT(code)) 603 ftype = VM_PROT_WRITE; 604 else 605 ftype = VM_PROT_READ; 606 607 va = trunc_page((vaddr_t)v); 608 609 if (map == kernel_map && va == 0) { 610 printf("trap: bad kernel %s access at 0x%x\n", 611 (ftype & VM_PROT_WRITE) ? "read/write" : 612 "read", v); 613 goto dopanic; 614 } 615 616 #ifdef DIAGNOSTIC 617 if (interrupt_depth && !panicing) { 618 printf("trap: calling uvm_fault() from interrupt!\n"); 619 goto dopanic; 620 } 621 #endif 622 623 #ifdef COMPAT_HPUX 624 if (ISHPMMADDR(va)) { 625 int pmap_mapmulti __P((pmap_t, vaddr_t)); 626 vaddr_t bva; 627 628 rv = pmap_mapmulti(map->pmap, va); 629 if (rv != 0) { 630 bva = HPMMBASEADDR(va); 631 rv = uvm_fault(map, bva, 0, ftype); 632 if (rv == 0) 633 (void) pmap_mapmulti(map->pmap, va); 634 } 635 } else 636 #endif 637 rv = uvm_fault(map, va, 0, ftype); 638 #ifdef DEBUG 639 if (rv && MDB_ISPID(p->p_pid)) 640 printf("uvm_fault(%p, 0x%lx, 0, 0x%x) -> 0x%x\n", 641 map, va, ftype, rv); 642 #endif 643 /* 644 * If this was a stack access we keep track of the maximum 645 * accessed stack size. Also, if vm_fault gets a protection 646 * failure it is due to accessing the stack region outside 647 * the current limit and we need to reflect that as an access 648 * error. 649 */ 650 if ((vm != NULL && (caddr_t)va >= vm->vm_maxsaddr) 651 && map != kernel_map) { 652 if (rv == 0) { 653 unsigned nss; 654 655 nss = btoc(USRSTACK-(unsigned)va); 656 if (nss > vm->vm_ssize) 657 vm->vm_ssize = nss; 658 } else if (rv == EACCES) 659 rv = EFAULT; 660 } 661 if (rv == 0) { 662 if (type == T_MMUFLT) { 663 #ifdef M68040 664 if (cputype == CPU_68040) 665 (void) writeback(&frame, 1); 666 #endif 667 return; 668 } 669 goto out; 670 } 671 if (type == T_MMUFLT) { 672 if (p->p_addr->u_pcb.pcb_onfault) 673 goto copyfault; 674 printf("uvm_fault(%p, 0x%lx, 0, 0x%x) -> 0x%x\n", 675 map, va, ftype, rv); 676 printf(" type %x, code [mmu,,ssw]: %x\n", 677 type, code); 678 goto dopanic; 679 } 680 ucode = v; 681 if (rv == ENOMEM) { 682 printf("UVM: pid %d (%s), uid %d killed: out of swap\n", 683 p->p_pid, p->p_comm, 684 p->p_cred && p->p_ucred ? 685 p->p_ucred->cr_uid : -1); 686 i = SIGKILL; 687 } else { 688 i = SIGSEGV; 689 } 690 break; 691 } 692 } 693 trapsignal(p, i, ucode); 694 if ((type & T_USER) == 0) 695 return; 696 out: 697 userret(p, &frame, sticks, v, 1); 698 } 699 700 #ifdef M68040 701 #ifdef DEBUG 702 struct writebackstats { 703 int calls; 704 int cpushes; 705 int move16s; 706 int wb1s, wb2s, wb3s; 707 int wbsize[4]; 708 } wbstats; 709 710 char *f7sz[] = { "longword", "byte", "word", "line" }; 711 char *f7tt[] = { "normal", "MOVE16", "AFC", "ACK" }; 712 char *f7tm[] = { "d-push", "u-data", "u-code", "M-data", 713 "M-code", "k-data", "k-code", "RES" }; 714 char wberrstr[] = 715 "WARNING: pid %d(%s) writeback [%s] failed, pc=%x fa=%x wba=%x wbd=%x\n"; 716 #endif 717 718 int 719 writeback(fp, docachepush) 720 struct frame *fp; 721 int docachepush; 722 { 723 struct fmt7 *f = &fp->f_fmt7; 724 struct proc *p = curproc; 725 int err = 0; 726 u_int fa; 727 caddr_t oonfault = p->p_addr->u_pcb.pcb_onfault; 728 paddr_t pa; 729 730 #ifdef DEBUG 731 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) { 732 printf(" pid=%d, fa=%x,", p->p_pid, f->f_fa); 733 dumpssw(f->f_ssw); 734 } 735 wbstats.calls++; 736 #endif 737 /* 738 * Deal with special cases first. 739 */ 740 if ((f->f_ssw & SSW4_TMMASK) == SSW4_TMDCP) { 741 /* 742 * Dcache push fault. 743 * Line-align the address and write out the push data to 744 * the indicated physical address. 745 */ 746 #ifdef DEBUG 747 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) { 748 printf(" pushing %s to PA %x, data %x", 749 f7sz[(f->f_ssw & SSW4_SZMASK) >> 5], 750 f->f_fa, f->f_pd0); 751 if ((f->f_ssw & SSW4_SZMASK) == SSW4_SZLN) 752 printf("/%x/%x/%x", 753 f->f_pd1, f->f_pd2, f->f_pd3); 754 printf("\n"); 755 } 756 if (f->f_wb1s & SSW4_WBSV) 757 panic("writeback: cache push with WB1S valid"); 758 wbstats.cpushes++; 759 #endif 760 /* 761 * XXX there are security problems if we attempt to do a 762 * cache push after a signal handler has been called. 763 */ 764 if (docachepush) { 765 pmap_enter(pmap_kernel(), (vaddr_t)vmmap, 766 trunc_page(f->f_fa), VM_PROT_WRITE, 767 VM_PROT_WRITE|PMAP_WIRED); 768 pmap_update(pmap_kernel()); 769 fa = (u_int)&vmmap[(f->f_fa & PGOFSET) & ~0xF]; 770 bcopy((caddr_t)&f->f_pd0, (caddr_t)fa, 16); 771 (void) pmap_extract(pmap_kernel(), (vaddr_t)fa, &pa); 772 DCFL(pa); 773 pmap_remove(pmap_kernel(), (vaddr_t)vmmap, 774 (vaddr_t)&vmmap[NBPG]); 775 pmap_update(pmap_kernel()); 776 } else 777 printf("WARNING: pid %d(%s) uid %d: CPUSH not done\n", 778 p->p_pid, p->p_comm, p->p_ucred->cr_uid); 779 } else if ((f->f_ssw & (SSW4_RW|SSW4_TTMASK)) == SSW4_TTM16) { 780 /* 781 * MOVE16 fault. 782 * Line-align the address and write out the push data to 783 * the indicated virtual address. 784 */ 785 #ifdef DEBUG 786 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 787 printf(" MOVE16 to VA %x(%x), data %x/%x/%x/%x\n", 788 f->f_fa, f->f_fa & ~0xF, f->f_pd0, f->f_pd1, 789 f->f_pd2, f->f_pd3); 790 if (f->f_wb1s & SSW4_WBSV) 791 panic("writeback: MOVE16 with WB1S valid"); 792 wbstats.move16s++; 793 #endif 794 if (KDFAULT(f->f_wb1s)) 795 bcopy((caddr_t)&f->f_pd0, (caddr_t)(f->f_fa & ~0xF), 16); 796 else 797 err = suline((caddr_t)(f->f_fa & ~0xF), (caddr_t)&f->f_pd0); 798 if (err) { 799 fa = f->f_fa & ~0xF; 800 #ifdef DEBUG 801 if (mmudebug & MDB_WBFAILED) 802 printf(wberrstr, p->p_pid, p->p_comm, 803 "MOVE16", fp->f_pc, f->f_fa, 804 f->f_fa & ~0xF, f->f_pd0); 805 #endif 806 } 807 } else if (f->f_wb1s & SSW4_WBSV) { 808 /* 809 * Writeback #1. 810 * Position the "memory-aligned" data and write it out. 811 */ 812 u_int wb1d = f->f_wb1d; 813 int off; 814 815 #ifdef DEBUG 816 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 817 dumpwb(1, f->f_wb1s, f->f_wb1a, f->f_wb1d); 818 wbstats.wb1s++; 819 wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++; 820 #endif 821 off = (f->f_wb1a & 3) * 8; 822 switch (f->f_wb1s & SSW4_SZMASK) { 823 case SSW4_SZLW: 824 if (off) 825 wb1d = (wb1d >> (32 - off)) | (wb1d << off); 826 if (KDFAULT(f->f_wb1s)) 827 *(long *)f->f_wb1a = wb1d; 828 else 829 err = suword((caddr_t)f->f_wb1a, wb1d); 830 break; 831 case SSW4_SZB: 832 off = 24 - off; 833 if (off) 834 wb1d >>= off; 835 if (KDFAULT(f->f_wb1s)) 836 *(char *)f->f_wb1a = wb1d; 837 else 838 err = subyte((caddr_t)f->f_wb1a, wb1d); 839 break; 840 case SSW4_SZW: 841 off = (off + 16) % 32; 842 if (off) 843 wb1d = (wb1d >> (32 - off)) | (wb1d << off); 844 if (KDFAULT(f->f_wb1s)) 845 *(short *)f->f_wb1a = wb1d; 846 else 847 err = susword((caddr_t)f->f_wb1a, wb1d); 848 break; 849 } 850 if (err) { 851 fa = f->f_wb1a; 852 #ifdef DEBUG 853 if (mmudebug & MDB_WBFAILED) 854 printf(wberrstr, p->p_pid, p->p_comm, 855 "#1", fp->f_pc, f->f_fa, 856 f->f_wb1a, f->f_wb1d); 857 #endif 858 } 859 } 860 /* 861 * Deal with the "normal" writebacks. 862 * 863 * XXX writeback2 is known to reflect a LINE size writeback after 864 * a MOVE16 was already dealt with above. Ignore it. 865 */ 866 if (err == 0 && (f->f_wb2s & SSW4_WBSV) && 867 (f->f_wb2s & SSW4_SZMASK) != SSW4_SZLN) { 868 #ifdef DEBUG 869 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 870 dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); 871 wbstats.wb2s++; 872 wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++; 873 #endif 874 switch (f->f_wb2s & SSW4_SZMASK) { 875 case SSW4_SZLW: 876 if (KDFAULT(f->f_wb2s)) 877 *(long *)f->f_wb2a = f->f_wb2d; 878 else 879 err = suword((caddr_t)f->f_wb2a, f->f_wb2d); 880 break; 881 case SSW4_SZB: 882 if (KDFAULT(f->f_wb2s)) 883 *(char *)f->f_wb2a = f->f_wb2d; 884 else 885 err = subyte((caddr_t)f->f_wb2a, f->f_wb2d); 886 break; 887 case SSW4_SZW: 888 if (KDFAULT(f->f_wb2s)) 889 *(short *)f->f_wb2a = f->f_wb2d; 890 else 891 err = susword((caddr_t)f->f_wb2a, f->f_wb2d); 892 break; 893 } 894 if (err) { 895 fa = f->f_wb2a; 896 #ifdef DEBUG 897 if (mmudebug & MDB_WBFAILED) { 898 printf(wberrstr, p->p_pid, p->p_comm, 899 "#2", fp->f_pc, f->f_fa, 900 f->f_wb2a, f->f_wb2d); 901 dumpssw(f->f_ssw); 902 dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); 903 } 904 #endif 905 } 906 } 907 if (err == 0 && (f->f_wb3s & SSW4_WBSV)) { 908 #ifdef DEBUG 909 if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 910 dumpwb(3, f->f_wb3s, f->f_wb3a, f->f_wb3d); 911 wbstats.wb3s++; 912 wbstats.wbsize[(f->f_wb3s&SSW4_SZMASK)>>5]++; 913 #endif 914 switch (f->f_wb3s & SSW4_SZMASK) { 915 case SSW4_SZLW: 916 if (KDFAULT(f->f_wb3s)) 917 *(long *)f->f_wb3a = f->f_wb3d; 918 else 919 err = suword((caddr_t)f->f_wb3a, f->f_wb3d); 920 break; 921 case SSW4_SZB: 922 if (KDFAULT(f->f_wb3s)) 923 *(char *)f->f_wb3a = f->f_wb3d; 924 else 925 err = subyte((caddr_t)f->f_wb3a, f->f_wb3d); 926 break; 927 case SSW4_SZW: 928 if (KDFAULT(f->f_wb3s)) 929 *(short *)f->f_wb3a = f->f_wb3d; 930 else 931 err = susword((caddr_t)f->f_wb3a, f->f_wb3d); 932 break; 933 #ifdef DEBUG 934 case SSW4_SZLN: 935 panic("writeback: wb3s indicates LINE write"); 936 #endif 937 } 938 if (err) { 939 fa = f->f_wb3a; 940 #ifdef DEBUG 941 if (mmudebug & MDB_WBFAILED) 942 printf(wberrstr, p->p_pid, p->p_comm, 943 "#3", fp->f_pc, f->f_fa, 944 f->f_wb3a, f->f_wb3d); 945 #endif 946 } 947 } 948 p->p_addr->u_pcb.pcb_onfault = oonfault; 949 if (err) 950 err = SIGSEGV; 951 return (err); 952 } 953 954 #ifdef DEBUG 955 void 956 dumpssw(ssw) 957 u_short ssw; 958 { 959 printf(" SSW: %x: ", ssw); 960 if (ssw & SSW4_CP) 961 printf("CP,"); 962 if (ssw & SSW4_CU) 963 printf("CU,"); 964 if (ssw & SSW4_CT) 965 printf("CT,"); 966 if (ssw & SSW4_CM) 967 printf("CM,"); 968 if (ssw & SSW4_MA) 969 printf("MA,"); 970 if (ssw & SSW4_ATC) 971 printf("ATC,"); 972 if (ssw & SSW4_LK) 973 printf("LK,"); 974 if (ssw & SSW4_RW) 975 printf("RW,"); 976 printf(" SZ=%s, TT=%s, TM=%s\n", 977 f7sz[(ssw & SSW4_SZMASK) >> 5], 978 f7tt[(ssw & SSW4_TTMASK) >> 3], 979 f7tm[ssw & SSW4_TMMASK]); 980 } 981 982 void 983 dumpwb(num, s, a, d) 984 int num; 985 u_short s; 986 u_int a, d; 987 { 988 struct proc *p = curproc; 989 paddr_t pa; 990 991 printf(" writeback #%d: VA %x, data %x, SZ=%s, TT=%s, TM=%s\n", 992 num, a, d, f7sz[(s & SSW4_SZMASK) >> 5], 993 f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]); 994 printf(" PA "); 995 if (pmap_extract(p->p_vmspace->vm_map.pmap, (vaddr_t)a, &pa) == FALSE) 996 printf("<invalid address>"); 997 else 998 printf("%lx, current value %lx", pa, fuword((caddr_t)a)); 999 printf("\n"); 1000 } 1001 #endif 1002 #endif 1003 1004 /* 1005 * Allocation routines for software interrupts. 1006 */ 1007 u_long 1008 allocate_sir(proc, arg) 1009 void (*proc)(void *); 1010 void *arg; 1011 { 1012 int bit; 1013 1014 if( next_sir >= NSIR ) 1015 panic("allocate_sir: none left"); 1016 bit = next_sir++; 1017 sir_routines[bit] = proc; 1018 sir_args[bit] = arg; 1019 return (1 << bit); 1020 } 1021 1022 void 1023 init_sir() 1024 { 1025 extern void netintr(void); 1026 1027 sir_routines[0] = (void (*)(void *))netintr; 1028 sir_routines[1] = softclock; 1029 next_sir = 2; 1030 } 1031