141475Smckusick /* 241475Smckusick * Copyright (c) 1988 University of Utah. 341475Smckusick * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. 441475Smckusick * All rights reserved. 541475Smckusick * 641475Smckusick * This code is derived from software contributed to Berkeley by 741475Smckusick * the Systems Programming Group of the University of Utah Computer 841475Smckusick * Science Department. 941475Smckusick * 1041475Smckusick * %sccs.include.redist.c% 1141475Smckusick * 12*53933Shibler * from: Utah $Hdr: trap.c 1.35 91/12/26$ 1341475Smckusick * 14*53933Shibler * @(#)trap.c 7.20 (Berkeley) 06/05/92 1541475Smckusick */ 1641475Smckusick 1748465Skarels #include "param.h" 1848465Skarels #include "systm.h" 1948465Skarels #include "proc.h" 2048465Skarels #include "acct.h" 2148465Skarels #include "kernel.h" 2248465Skarels #include "signalvar.h" 2348465Skarels #include "resourcevar.h" 2448465Skarels #include "syslog.h" 2548465Skarels #include "user.h" 2648465Skarels #ifdef KTRACE 2748465Skarels #include "ktrace.h" 2848465Skarels #endif 2948465Skarels 3049125Skarels #include "../include/psl.h" 3148465Skarels #include "../include/trap.h" 3245788Sbostic #include "../include/cpu.h" 3345788Sbostic #include "../include/reg.h" 3445788Sbostic #include "../include/mtpr.h" 3541475Smckusick 3648465Skarels #include "vm/vm.h" 3745788Sbostic #include "vm/pmap.h" 3845751Smckusick 3941475Smckusick #ifdef HPUXCOMPAT 40*53933Shibler #include "hp/hpux/hpux.h" 4141475Smckusick #endif 4241475Smckusick 4341475Smckusick struct sysent sysent[]; 4441475Smckusick int nsysent; 4541475Smckusick 4641475Smckusick char *trap_type[] = { 4741475Smckusick "Bus error", 4841475Smckusick "Address error", 4941475Smckusick "Illegal instruction", 5041475Smckusick "Zero divide", 5141475Smckusick "CHK instruction", 5241475Smckusick "TRAPV instruction", 5341475Smckusick "Privilege violation", 5441475Smckusick "Trace trap", 5541475Smckusick "MMU fault", 5641475Smckusick "SSIR trap", 5741475Smckusick "Format error", 5841475Smckusick "68881 exception", 5941475Smckusick "Coprocessor violation", 6041475Smckusick "Async system trap" 6141475Smckusick }; 6241475Smckusick #define TRAP_TYPES (sizeof trap_type / sizeof trap_type[0]) 6341475Smckusick 6449317Shibler /* 6549317Shibler * Size of various exception stack frames (minus the standard 8 bytes) 6649317Shibler */ 6749317Shibler short exframesize[] = { 6849317Shibler FMT0SIZE, /* type 0 - normal (68020/030/040) */ 6949317Shibler FMT1SIZE, /* type 1 - throwaway (68020/030/040) */ 7049317Shibler FMT2SIZE, /* type 2 - normal 6-word (68020/030/040) */ 71*53933Shibler FMT3SIZE, /* type 3 - FP post-instruction (68040) */ 7249317Shibler -1, -1, -1, /* type 4-6 - undefined */ 73*53933Shibler FMT7SIZE, /* type 7 - access error (68040) */ 7449317Shibler 58, /* type 8 - bus fault (68010) */ 7549317Shibler FMT9SIZE, /* type 9 - coprocessor mid-instruction (68020/030) */ 7649317Shibler FMTASIZE, /* type A - short bus fault (68020/030) */ 7749317Shibler FMTBSIZE, /* type B - long bus fault (68020/030) */ 7849317Shibler -1, -1, -1, -1 /* type C-F - undefined */ 7949317Shibler }; 8049317Shibler 81*53933Shibler #if defined(HP380) 82*53933Shibler #define KDFAULT(c) (mmutype == MMU_68040 ? \ 83*53933Shibler ((c) & SSW4_TMMASK) == SSW4_TMKD : \ 84*53933Shibler ((c) & (SSW_DF|FC_SUPERD)) == (SSW_DF|FC_SUPERD)) 85*53933Shibler #define WRFAULT(c) (mmutype == MMU_68040 ? \ 86*53933Shibler ((c) & SSW4_RW) == 0 : \ 87*53933Shibler ((c) & (SSW_DF|SSW_RW)) == SSW_DF) 88*53933Shibler #else 89*53933Shibler #define KDFAULT(c) (((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD)) 90*53933Shibler #define WRFAULT(c) (((c) & (SSW_DF|SSW_RW)) == SSW_DF) 91*53933Shibler #endif 92*53933Shibler 9341475Smckusick #ifdef DEBUG 9441475Smckusick int mmudebug = 0; 95*53933Shibler int mmupid = -1; 96*53933Shibler #define MDB_FOLLOW 1 97*53933Shibler #define MDB_WBFOLLOW 2 98*53933Shibler #define MDB_WBFAILED 4 99*53933Shibler #define MDB_ISPID(p) (p) == mmupid 10041475Smckusick #endif 10141475Smckusick 10241475Smckusick /* 10349531Skarels * Trap is called from locore to handle most types of processor traps, 10449531Skarels * including events such as simulated software interrupts/AST's. 10549531Skarels * System calls are broken out for efficiency. 10641475Smckusick */ 10741475Smckusick /*ARGSUSED*/ 10841475Smckusick trap(type, code, v, frame) 10941475Smckusick int type; 11041475Smckusick unsigned code; 11141475Smckusick register unsigned v; 11241475Smckusick struct frame frame; 11341475Smckusick { 11441475Smckusick register int i; 11541475Smckusick unsigned ucode = 0; 11648465Skarels register struct proc *p = curproc; 11741475Smckusick struct timeval syst; 11841475Smckusick unsigned ncode; 11950753Skarels int s; 120*53933Shibler #if defined(HP380) 121*53933Shibler int beenhere = 0; 122*53933Shibler #endif 12341475Smckusick 12441475Smckusick cnt.v_trap++; 12548465Skarels syst = p->p_stime; 12641475Smckusick if (USERMODE(frame.f_sr)) { 12749531Skarels type |= T_USER; 12852380Smckusick p->p_md.md_regs = frame.f_regs; 12941475Smckusick } 13041475Smckusick switch (type) { 13141475Smckusick 13241475Smckusick default: 13341475Smckusick dopanic: 13441475Smckusick printf("trap type %d, code = %x, v = %x\n", type, code, v); 13541475Smckusick regdump(frame.f_regs, 128); 13649531Skarels type &= ~T_USER; 13741475Smckusick if ((unsigned)type < TRAP_TYPES) 13841475Smckusick panic(trap_type[type]); 13941475Smckusick panic("trap"); 14041475Smckusick 14141475Smckusick case T_BUSERR: /* kernel bus error */ 14249125Skarels if (!p->p_addr->u_pcb.pcb_onfault) 14341475Smckusick goto dopanic; 14441475Smckusick /* 14541475Smckusick * If we have arranged to catch this fault in any of the 14641475Smckusick * copy to/from user space routines, set PC to return to 14741475Smckusick * indicated location and set flag informing buserror code 14841475Smckusick * that it may need to clean up stack frame. 14941475Smckusick */ 15041475Smckusick copyfault: 15149317Shibler frame.f_stackadj = exframesize[frame.f_format]; 15249317Shibler frame.f_format = frame.f_vector = 0; 15349125Skarels frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault; 15441475Smckusick return; 15541475Smckusick 15649531Skarels case T_BUSERR|T_USER: /* bus error */ 15749531Skarels case T_ADDRERR|T_USER: /* address error */ 158*53933Shibler ucode = v; 15941475Smckusick i = SIGBUS; 16041475Smckusick break; 16141475Smckusick 16241475Smckusick #ifdef FPCOPROC 16341475Smckusick case T_COPERR: /* kernel coprocessor violation */ 16441475Smckusick #endif 165*53933Shibler case T_FMTERR|T_USER: /* do all RTE errors come in as T_USER? */ 166*53933Shibler case T_FMTERR: /* ...just in case... */ 16741475Smckusick /* 16841475Smckusick * The user has most likely trashed the RTE or FP state info 16941475Smckusick * in the stack frame of a signal handler. 17041475Smckusick */ 17149531Skarels type |= T_USER; 17248465Skarels printf("pid %d: kernel %s exception\n", p->p_pid, 17341475Smckusick type==T_COPERR ? "coprocessor" : "format"); 17448465Skarels p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL; 17541475Smckusick i = sigmask(SIGILL); 17641475Smckusick p->p_sigignore &= ~i; 17741475Smckusick p->p_sigcatch &= ~i; 17841475Smckusick p->p_sigmask &= ~i; 17942370Skarels i = SIGILL; 18041475Smckusick ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */ 18142370Skarels break; 18241475Smckusick 18341475Smckusick #ifdef FPCOPROC 18449531Skarels case T_COPERR|T_USER: /* user coprocessor violation */ 18541475Smckusick /* What is a proper response here? */ 18641475Smckusick ucode = 0; 18741475Smckusick i = SIGFPE; 18841475Smckusick break; 18941475Smckusick 19049531Skarels case T_FPERR|T_USER: /* 68881 exceptions */ 19141475Smckusick /* 19241475Smckusick * We pass along the 68881 status register which locore stashed 19341475Smckusick * in code for us. Note that there is a possibility that the 19441475Smckusick * bit pattern of this register will conflict with one of the 19541475Smckusick * FPE_* codes defined in signal.h. Fortunately for us, the 19641475Smckusick * only such codes we use are all in the range 1-7 and the low 19741475Smckusick * 3 bits of the status register are defined as 0 so there is 19841475Smckusick * no clash. 19941475Smckusick */ 20041475Smckusick ucode = code; 20141475Smckusick i = SIGFPE; 20241475Smckusick break; 20341475Smckusick #endif 20441475Smckusick 205*53933Shibler #if defined(HP380) 206*53933Shibler case T_FPEMULI|T_USER: /* unimplemented FP instuction */ 207*53933Shibler case T_FPEMULD|T_USER: /* unimplemented FP data type */ 208*53933Shibler /* XXX need to FSAVE */ 209*53933Shibler printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n", 210*53933Shibler p->p_pid, p->p_comm, 211*53933Shibler frame.f_format == 2 ? "instruction" : "data type", 212*53933Shibler frame.f_pc, frame.f_fmt2.f_iaddr); 213*53933Shibler /* XXX need to FRESTORE */ 214*53933Shibler i = SIGFPE; 215*53933Shibler break; 216*53933Shibler #endif 217*53933Shibler 21849531Skarels case T_ILLINST|T_USER: /* illegal instruction fault */ 21941475Smckusick #ifdef HPUXCOMPAT 22048465Skarels if (p->p_flag & SHPUX) { 22141475Smckusick ucode = HPUX_ILL_ILLINST_TRAP; 22241475Smckusick i = SIGILL; 22341475Smckusick break; 22441475Smckusick } 22541475Smckusick /* fall through */ 22641475Smckusick #endif 22749531Skarels case T_PRIVINST|T_USER: /* privileged instruction fault */ 22841475Smckusick #ifdef HPUXCOMPAT 22948465Skarels if (p->p_flag & SHPUX) 23041475Smckusick ucode = HPUX_ILL_PRIV_TRAP; 23141475Smckusick else 23241475Smckusick #endif 23341475Smckusick ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ 23441475Smckusick i = SIGILL; 23541475Smckusick break; 23641475Smckusick 23749531Skarels case T_ZERODIV|T_USER: /* Divide by zero */ 23841475Smckusick #ifdef HPUXCOMPAT 23948465Skarels if (p->p_flag & SHPUX) 24041475Smckusick ucode = HPUX_FPE_INTDIV_TRAP; 24141475Smckusick else 24241475Smckusick #endif 24341475Smckusick ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */ 24441475Smckusick i = SIGFPE; 24541475Smckusick break; 24641475Smckusick 24749531Skarels case T_CHKINST|T_USER: /* CHK instruction trap */ 24841475Smckusick #ifdef HPUXCOMPAT 24948465Skarels if (p->p_flag & SHPUX) { 25041475Smckusick /* handled differently under hp-ux */ 25141475Smckusick i = SIGILL; 25241475Smckusick ucode = HPUX_ILL_CHK_TRAP; 25341475Smckusick break; 25441475Smckusick } 25541475Smckusick #endif 25641475Smckusick ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */ 25741475Smckusick i = SIGFPE; 25841475Smckusick break; 25941475Smckusick 26049531Skarels case T_TRAPVINST|T_USER: /* TRAPV instruction trap */ 26141475Smckusick #ifdef HPUXCOMPAT 26248465Skarels if (p->p_flag & SHPUX) { 26341475Smckusick /* handled differently under hp-ux */ 26441475Smckusick i = SIGILL; 26541475Smckusick ucode = HPUX_ILL_TRAPV_TRAP; 26641475Smckusick break; 26741475Smckusick } 26841475Smckusick #endif 26941475Smckusick ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */ 27041475Smckusick i = SIGFPE; 27141475Smckusick break; 27241475Smckusick 27341475Smckusick /* 27441475Smckusick * XXX: Trace traps are a nightmare. 27541475Smckusick * 27641475Smckusick * HP-UX uses trap #1 for breakpoints, 27741475Smckusick * HPBSD uses trap #2, 27841475Smckusick * SUN 3.x uses trap #15, 27948465Skarels * KGDB uses trap #15 (for kernel breakpoints; handled elsewhere). 28041475Smckusick * 28141475Smckusick * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE. 28241475Smckusick * SUN 3.x traps get passed through as T_TRAP15 and are not really 28348465Skarels * supported yet. 28441475Smckusick */ 28541475Smckusick case T_TRACE: /* kernel trace trap */ 28648465Skarels case T_TRAP15: /* SUN trace trap */ 28741475Smckusick frame.f_sr &= ~PSL_T; 28841475Smckusick i = SIGTRAP; 28941475Smckusick break; 29041475Smckusick 29149531Skarels case T_TRACE|T_USER: /* user trace trap */ 29249531Skarels case T_TRAP15|T_USER: /* SUN user trace trap */ 29341475Smckusick frame.f_sr &= ~PSL_T; 29441475Smckusick i = SIGTRAP; 29541475Smckusick break; 29641475Smckusick 29743413Shibler case T_ASTFLT: /* system async trap, cannot happen */ 29841475Smckusick goto dopanic; 29941475Smckusick 30049531Skarels case T_ASTFLT|T_USER: /* user async trap */ 30149125Skarels astpending = 0; 30241475Smckusick /* 30341475Smckusick * We check for software interrupts first. This is because 30441475Smckusick * they are at a higher level than ASTs, and on a VAX would 30541475Smckusick * interrupt the AST. We assume that if we are processing 30641475Smckusick * an AST that we must be at IPL0 so we don't bother to 30741475Smckusick * check. Note that we ensure that we are at least at SIR 30841475Smckusick * IPL while processing the SIR. 30941475Smckusick */ 31041475Smckusick spl1(); 31141475Smckusick /* fall into... */ 31241475Smckusick 31341475Smckusick case T_SSIR: /* software interrupt */ 31449531Skarels case T_SSIR|T_USER: 31541475Smckusick if (ssir & SIR_NET) { 31641475Smckusick siroff(SIR_NET); 31741475Smckusick cnt.v_soft++; 31841475Smckusick netintr(); 31941475Smckusick } 32041475Smckusick if (ssir & SIR_CLOCK) { 32141475Smckusick siroff(SIR_CLOCK); 32241475Smckusick cnt.v_soft++; 32341475Smckusick softclock((caddr_t)frame.f_pc, (int)frame.f_sr); 32441475Smckusick } 32541475Smckusick /* 32641475Smckusick * If this was not an AST trap, we are all done. 32741475Smckusick */ 32850753Skarels if (type != (T_ASTFLT|T_USER)) { 32941475Smckusick cnt.v_trap--; 33041475Smckusick return; 33141475Smckusick } 33241475Smckusick spl0(); 33341475Smckusick #ifndef PROFTIMER 33448465Skarels if ((p->p_flag&SOWEUPC) && p->p_stats->p_prof.pr_scale) { 33548465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, 1); 33648465Skarels p->p_flag &= ~SOWEUPC; 33741475Smckusick } 33841475Smckusick #endif 33941475Smckusick goto out; 34041475Smckusick 34141475Smckusick case T_MMUFLT: /* kernel mode page fault */ 34241475Smckusick /* fall into ... */ 34341475Smckusick 34449531Skarels case T_MMUFLT|T_USER: /* page fault */ 34545751Smckusick { 34645751Smckusick register vm_offset_t va; 34748465Skarels register struct vmspace *vm = p->p_vmspace; 34845751Smckusick register vm_map_t map; 34945751Smckusick int rv; 35045751Smckusick vm_prot_t ftype; 35145751Smckusick extern vm_map_t kernel_map; 35245751Smckusick 353*53933Shibler #ifdef DEBUG 354*53933Shibler if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 355*53933Shibler printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n", 356*53933Shibler p->p_pid, code, v, frame.f_pc, frame.f_sr); 357*53933Shibler #endif 35841475Smckusick /* 35945751Smckusick * It is only a kernel address space fault iff: 36049531Skarels * 1. (type & T_USER) == 0 and 36145751Smckusick * 2. pcb_onfault not set or 36245751Smckusick * 3. pcb_onfault set but supervisor space data fault 36345751Smckusick * The last can occur during an exec() copyin where the 36445751Smckusick * argument space is lazy-allocated. 36541475Smckusick */ 36645751Smckusick if (type == T_MMUFLT && 367*53933Shibler (!p->p_addr->u_pcb.pcb_onfault || KDFAULT(code))) 36845751Smckusick map = kernel_map; 36945751Smckusick else 37048465Skarels map = &vm->vm_map; 371*53933Shibler if (WRFAULT(code)) 37245751Smckusick ftype = VM_PROT_READ | VM_PROT_WRITE; 37345751Smckusick else 37445751Smckusick ftype = VM_PROT_READ; 37545751Smckusick va = trunc_page((vm_offset_t)v); 37641475Smckusick #ifdef DEBUG 37745751Smckusick if (map == kernel_map && va == 0) { 37845751Smckusick printf("trap: bad kernel access at %x\n", v); 37941475Smckusick goto dopanic; 38041475Smckusick } 38141475Smckusick #endif 38249317Shibler rv = vm_fault(map, va, ftype, FALSE); 383*53933Shibler #ifdef DEBUG 384*53933Shibler if (rv && MDB_ISPID(p->p_pid)) 385*53933Shibler printf("vm_fault(%x, %x, %x, 0) -> %x\n", 386*53933Shibler map, va, ftype, rv); 387*53933Shibler #endif 38841475Smckusick /* 38949317Shibler * If this was a stack access we keep track of the maximum 39049317Shibler * accessed stack size. Also, if vm_fault gets a protection 39149317Shibler * failure it is due to accessing the stack region outside 39249317Shibler * the current limit and we need to reflect that as an access 39349317Shibler * error. 39441475Smckusick */ 39548465Skarels if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) { 39649317Shibler if (rv == KERN_SUCCESS) { 39749317Shibler unsigned nss; 39849317Shibler 39949317Shibler nss = clrnd(btoc(USRSTACK-(unsigned)va)); 40049317Shibler if (nss > vm->vm_ssize) 40149317Shibler vm->vm_ssize = nss; 40249317Shibler } else if (rv == KERN_PROTECTION_FAILURE) 40349317Shibler rv = KERN_INVALID_ADDRESS; 40441475Smckusick } 40545751Smckusick if (rv == KERN_SUCCESS) { 406*53933Shibler if (type == T_MMUFLT) { 407*53933Shibler #if defined(HP380) 408*53933Shibler if (mmutype == MMU_68040) 409*53933Shibler (void) writeback(&frame, 1); 410*53933Shibler #endif 41141475Smckusick return; 412*53933Shibler } 41341475Smckusick goto out; 41441475Smckusick } 41545751Smckusick if (type == T_MMUFLT) { 41649125Skarels if (p->p_addr->u_pcb.pcb_onfault) 41745751Smckusick goto copyfault; 41845751Smckusick printf("vm_fault(%x, %x, %x, 0) -> %x\n", 41945751Smckusick map, va, ftype, rv); 42045751Smckusick printf(" type %x, code [mmu,,ssw]: %x\n", 42145751Smckusick type, code); 42245751Smckusick goto dopanic; 42345751Smckusick } 42448465Skarels ucode = v; 42545751Smckusick i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV; 42645751Smckusick break; 42745751Smckusick } 42841475Smckusick } 42948465Skarels trapsignal(p, i, ucode); 43049531Skarels if ((type & T_USER) == 0) 43141475Smckusick return; 43241475Smckusick out: 43348465Skarels while (i = CURSIG(p)) 43442370Skarels psig(i); 43541475Smckusick p->p_pri = p->p_usrpri; 43648465Skarels if (want_resched) { 43741475Smckusick /* 43848465Skarels * Since we are curproc, clock will normally just change 43941475Smckusick * our priority without moving us from one queue to another 44041475Smckusick * (since the running process is not on a queue.) 44141475Smckusick * If that happened after we setrq ourselves but before we 44241475Smckusick * swtch()'ed, we might not be on the queue indicated by 44341475Smckusick * our priority. 44441475Smckusick */ 44550753Skarels s = splclock(); 44641475Smckusick setrq(p); 44748465Skarels p->p_stats->p_ru.ru_nivcsw++; 44841475Smckusick swtch(); 44950753Skarels splx(s); 45048465Skarels while (i = CURSIG(p)) 45142370Skarels psig(i); 45241475Smckusick } 45348465Skarels if (p->p_stats->p_prof.pr_scale) { 45441475Smckusick int ticks; 45548465Skarels struct timeval *tv = &p->p_stime; 45641475Smckusick 45741475Smckusick ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + 45841475Smckusick (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); 45941475Smckusick if (ticks) { 46041475Smckusick #ifdef PROFTIMER 46141475Smckusick extern int profscale; 46248465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, 46348465Skarels ticks * profscale); 46441475Smckusick #else 46548465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, ticks); 46641475Smckusick #endif 46741475Smckusick } 46841475Smckusick } 469*53933Shibler #if defined(HP380) 470*53933Shibler /* 471*53933Shibler * Deal with user mode writebacks. 472*53933Shibler * If any writeback fails, go back and attempt signal delivery. 473*53933Shibler * unless we have already been here and attempted the writeback 474*53933Shibler * (e.g. bad address with user ignoring SIGSEGV). In that case 475*53933Shibler * we just return to the user without sucessfully completing 476*53933Shibler * the writebacks. Maybe we should just drop the sucker? 477*53933Shibler */ 478*53933Shibler if (mmutype == MMU_68040 && frame.f_format == FMT7) { 479*53933Shibler if (beenhere) { 480*53933Shibler #ifdef DEBUG 481*53933Shibler if (mmudebug & MDB_WBFAILED) 482*53933Shibler printf("pid %d(%s): writeback aborted, pc=%x, fa=%x\n", 483*53933Shibler p->p_pid, p->p_comm, frame.f_pc, v); 484*53933Shibler #endif 485*53933Shibler ; 486*53933Shibler } else if (i = writeback(&frame, 1)) { 487*53933Shibler beenhere++; 488*53933Shibler ucode = v; 489*53933Shibler syst = p->p_stime; 490*53933Shibler trapsignal(p, i, ucode); 491*53933Shibler goto out; 492*53933Shibler } 493*53933Shibler } 494*53933Shibler #endif 49541475Smckusick curpri = p->p_pri; 49641475Smckusick } 49741475Smckusick 498*53933Shibler #if defined(HP380) 499*53933Shibler #ifdef DEBUG 500*53933Shibler struct writebackstats { 501*53933Shibler int calls; 502*53933Shibler int cpushes; 503*53933Shibler int move16s; 504*53933Shibler int wb1s, wb2s, wb3s; 505*53933Shibler int wbsize[4]; 506*53933Shibler } wbstats; 507*53933Shibler 508*53933Shibler char *f7sz[] = { "longword", "byte", "word", "line" }; 509*53933Shibler char *f7tt[] = { "normal", "MOVE16", "AFC", "ACK" }; 510*53933Shibler char *f7tm[] = { "d-push", "u-data", "u-code", "M-data", 511*53933Shibler "M-code", "k-data", "k-code", "RES" }; 512*53933Shibler char wberrstr[] = 513*53933Shibler "WARNING: pid %d(%s) writeback [%s] failed, pc=%x fa=%x wba=%x wbd=%x\n"; 514*53933Shibler #endif 515*53933Shibler 516*53933Shibler writeback(fp, docachepush) 517*53933Shibler struct frame *fp; 518*53933Shibler int docachepush; 519*53933Shibler { 520*53933Shibler register struct fmt7 *f = &fp->f_fmt7; 521*53933Shibler register struct proc *p = curproc; 522*53933Shibler int err = 0; 523*53933Shibler u_int fa; 524*53933Shibler caddr_t oonfault = p->p_addr->u_pcb.pcb_onfault; 525*53933Shibler 526*53933Shibler #ifdef DEBUG 527*53933Shibler if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) { 528*53933Shibler printf(" pid=%d, fa=%x,", p->p_pid, f->f_fa); 529*53933Shibler dumpssw(f->f_ssw); 530*53933Shibler } 531*53933Shibler wbstats.calls++; 532*53933Shibler #endif 533*53933Shibler /* 534*53933Shibler * Deal with special cases first. 535*53933Shibler */ 536*53933Shibler if ((f->f_ssw & SSW4_TMMASK) == SSW4_TMDCP) { 537*53933Shibler /* 538*53933Shibler * Dcache push fault. 539*53933Shibler * Line-align the address and write out the push data to 540*53933Shibler * the indicated physical address. 541*53933Shibler */ 542*53933Shibler #ifdef DEBUG 543*53933Shibler if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) { 544*53933Shibler printf(" pushing %s to PA %x, data %x", 545*53933Shibler f7sz[(f->f_ssw & SSW4_SZMASK) >> 5], 546*53933Shibler f->f_fa, f->f_pd0); 547*53933Shibler if ((f->f_ssw & SSW4_SZMASK) == SSW4_SZLN) 548*53933Shibler printf("/%x/%x/%x", 549*53933Shibler f->f_pd1, f->f_pd2, f->f_pd3); 550*53933Shibler printf("\n"); 551*53933Shibler } 552*53933Shibler if (f->f_wb1s & SSW4_WBSV) 553*53933Shibler panic("writeback: cache push with WB1S valid"); 554*53933Shibler wbstats.cpushes++; 555*53933Shibler #endif 556*53933Shibler /* 557*53933Shibler * XXX there are security problems if we attempt to do a 558*53933Shibler * cache push after a signal handler has been called. 559*53933Shibler */ 560*53933Shibler if (docachepush) { 561*53933Shibler pmap_enter(kernel_pmap, (vm_offset_t)vmmap, 562*53933Shibler trunc_page(f->f_fa), VM_PROT_WRITE, TRUE); 563*53933Shibler fa = (u_int)&vmmap[(f->f_fa & PGOFSET) & ~0xF]; 564*53933Shibler bcopy((caddr_t)&f->f_pd0, (caddr_t)fa, 16); 565*53933Shibler DCFL(pmap_extract(kernel_pmap, (vm_offset_t)fa)); 566*53933Shibler pmap_remove(kernel_pmap, (vm_offset_t)vmmap, 567*53933Shibler (vm_offset_t)&vmmap[NBPG]); 568*53933Shibler } else 569*53933Shibler printf("WARNING: pid %d(%s) uid %d: CPUSH not done\n", 570*53933Shibler p->p_pid, p->p_comm, p->p_ucred->cr_uid); 571*53933Shibler } else if ((f->f_ssw & (SSW4_RW|SSW4_TTMASK)) == SSW4_TTM16) { 572*53933Shibler /* 573*53933Shibler * MOVE16 fault. 574*53933Shibler * Line-align the address and write out the push data to 575*53933Shibler * the indicated virtual address. 576*53933Shibler */ 577*53933Shibler #ifdef DEBUG 578*53933Shibler if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 579*53933Shibler printf(" MOVE16 to VA %x(%x), data %x/%x/%x/%x\n", 580*53933Shibler f->f_fa, f->f_fa & ~0xF, f->f_pd0, f->f_pd1, 581*53933Shibler f->f_pd2, f->f_pd3); 582*53933Shibler if (f->f_wb1s & SSW4_WBSV) 583*53933Shibler panic("writeback: MOVE16 with WB1S valid"); 584*53933Shibler wbstats.move16s++; 585*53933Shibler #endif 586*53933Shibler if (KDFAULT(f->f_wb1s)) 587*53933Shibler bcopy((caddr_t)&f->f_pd0, (caddr_t)(f->f_fa & ~0xF), 16); 588*53933Shibler else 589*53933Shibler err = suline((caddr_t)(f->f_fa & ~0xF), (caddr_t)&f->f_pd0); 590*53933Shibler if (err) { 591*53933Shibler fa = f->f_fa & ~0xF; 592*53933Shibler #ifdef DEBUG 593*53933Shibler if (mmudebug & MDB_WBFAILED) 594*53933Shibler printf(wberrstr, p->p_pid, p->p_comm, 595*53933Shibler "MOVE16", fp->f_pc, f->f_fa, 596*53933Shibler f->f_fa & ~0xF, f->f_pd0); 597*53933Shibler #endif 598*53933Shibler } 599*53933Shibler } else if (f->f_wb1s & SSW4_WBSV) { 600*53933Shibler /* 601*53933Shibler * Writeback #1. 602*53933Shibler * Position the "memory-aligned" data and write it out. 603*53933Shibler */ 604*53933Shibler register u_int wb1d = f->f_wb1d; 605*53933Shibler register int off; 606*53933Shibler 607*53933Shibler #ifdef DEBUG 608*53933Shibler if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 609*53933Shibler dumpwb(1, f->f_wb1s, f->f_wb1a, f->f_wb1d); 610*53933Shibler wbstats.wb1s++; 611*53933Shibler wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++; 612*53933Shibler #endif 613*53933Shibler off = (f->f_wb1a & 3) * 8; 614*53933Shibler switch (f->f_wb1s & SSW4_SZMASK) { 615*53933Shibler case SSW4_SZLW: 616*53933Shibler if (off) 617*53933Shibler wb1d = (wb1d >> (32 - off)) | (wb1d << off); 618*53933Shibler if (KDFAULT(f->f_wb1s)) 619*53933Shibler *(long *)f->f_wb1a = wb1d; 620*53933Shibler else 621*53933Shibler err = suword((caddr_t)f->f_wb1a, wb1d); 622*53933Shibler break; 623*53933Shibler case SSW4_SZB: 624*53933Shibler off = 24 - off; 625*53933Shibler if (off) 626*53933Shibler wb1d >>= off; 627*53933Shibler if (KDFAULT(f->f_wb1s)) 628*53933Shibler *(char *)f->f_wb1a = wb1d; 629*53933Shibler else 630*53933Shibler err = subyte((caddr_t)f->f_wb1a, wb1d); 631*53933Shibler break; 632*53933Shibler case SSW4_SZW: 633*53933Shibler off = (off + 16) % 32; 634*53933Shibler if (off) 635*53933Shibler wb1d = (wb1d >> (32 - off)) | (wb1d << off); 636*53933Shibler if (KDFAULT(f->f_wb1s)) 637*53933Shibler *(short *)f->f_wb1a = wb1d; 638*53933Shibler else 639*53933Shibler err = susword((caddr_t)f->f_wb1a, wb1d); 640*53933Shibler break; 641*53933Shibler } 642*53933Shibler if (err) { 643*53933Shibler fa = f->f_wb1a; 644*53933Shibler #ifdef DEBUG 645*53933Shibler if (mmudebug & MDB_WBFAILED) 646*53933Shibler printf(wberrstr, p->p_pid, p->p_comm, 647*53933Shibler "#1", fp->f_pc, f->f_fa, 648*53933Shibler f->f_wb1a, f->f_wb1d); 649*53933Shibler #endif 650*53933Shibler } 651*53933Shibler } 652*53933Shibler /* 653*53933Shibler * Deal with the "normal" writebacks. 654*53933Shibler * 655*53933Shibler * XXX writeback2 is known to reflect a LINE size writeback after 656*53933Shibler * a MOVE16 was already dealt with above. Ignore it. 657*53933Shibler */ 658*53933Shibler if (err == 0 && (f->f_wb2s & SSW4_WBSV) && 659*53933Shibler (f->f_wb2s & SSW4_SZMASK) != SSW4_SZLN) { 660*53933Shibler #ifdef DEBUG 661*53933Shibler if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 662*53933Shibler dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); 663*53933Shibler wbstats.wb2s++; 664*53933Shibler wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++; 665*53933Shibler #endif 666*53933Shibler switch (f->f_wb2s & SSW4_SZMASK) { 667*53933Shibler case SSW4_SZLW: 668*53933Shibler if (KDFAULT(f->f_wb2s)) 669*53933Shibler *(long *)f->f_wb2a = f->f_wb2d; 670*53933Shibler else 671*53933Shibler err = suword((caddr_t)f->f_wb2a, f->f_wb2d); 672*53933Shibler break; 673*53933Shibler case SSW4_SZB: 674*53933Shibler if (KDFAULT(f->f_wb2s)) 675*53933Shibler *(char *)f->f_wb2a = f->f_wb2d; 676*53933Shibler else 677*53933Shibler err = subyte((caddr_t)f->f_wb2a, f->f_wb2d); 678*53933Shibler break; 679*53933Shibler case SSW4_SZW: 680*53933Shibler if (KDFAULT(f->f_wb2s)) 681*53933Shibler *(short *)f->f_wb2a = f->f_wb2d; 682*53933Shibler else 683*53933Shibler err = susword((caddr_t)f->f_wb2a, f->f_wb2d); 684*53933Shibler break; 685*53933Shibler } 686*53933Shibler if (err) { 687*53933Shibler fa = f->f_wb2a; 688*53933Shibler #ifdef DEBUG 689*53933Shibler if (mmudebug & MDB_WBFAILED) { 690*53933Shibler printf(wberrstr, p->p_pid, p->p_comm, 691*53933Shibler "#2", fp->f_pc, f->f_fa, 692*53933Shibler f->f_wb2a, f->f_wb2d); 693*53933Shibler dumpssw(f->f_ssw); 694*53933Shibler dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); 695*53933Shibler } 696*53933Shibler #endif 697*53933Shibler } 698*53933Shibler } 699*53933Shibler if (err == 0 && (f->f_wb3s & SSW4_WBSV)) { 700*53933Shibler #ifdef DEBUG 701*53933Shibler if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) 702*53933Shibler dumpwb(3, f->f_wb3s, f->f_wb3a, f->f_wb3d); 703*53933Shibler wbstats.wb3s++; 704*53933Shibler wbstats.wbsize[(f->f_wb3s&SSW4_SZMASK)>>5]++; 705*53933Shibler #endif 706*53933Shibler switch (f->f_wb3s & SSW4_SZMASK) { 707*53933Shibler case SSW4_SZLW: 708*53933Shibler if (KDFAULT(f->f_wb3s)) 709*53933Shibler *(long *)f->f_wb3a = f->f_wb3d; 710*53933Shibler else 711*53933Shibler err = suword((caddr_t)f->f_wb3a, f->f_wb3d); 712*53933Shibler break; 713*53933Shibler case SSW4_SZB: 714*53933Shibler if (KDFAULT(f->f_wb3s)) 715*53933Shibler *(char *)f->f_wb3a = f->f_wb3d; 716*53933Shibler else 717*53933Shibler err = subyte((caddr_t)f->f_wb3a, f->f_wb3d); 718*53933Shibler break; 719*53933Shibler case SSW4_SZW: 720*53933Shibler if (KDFAULT(f->f_wb3s)) 721*53933Shibler *(short *)f->f_wb3a = f->f_wb3d; 722*53933Shibler else 723*53933Shibler err = susword((caddr_t)f->f_wb3a, f->f_wb3d); 724*53933Shibler break; 725*53933Shibler #ifdef DEBUG 726*53933Shibler case SSW4_SZLN: 727*53933Shibler panic("writeback: wb3s indicates LINE write"); 728*53933Shibler #endif 729*53933Shibler } 730*53933Shibler if (err) { 731*53933Shibler fa = f->f_wb3a; 732*53933Shibler #ifdef DEBUG 733*53933Shibler if (mmudebug & MDB_WBFAILED) 734*53933Shibler printf(wberrstr, p->p_pid, p->p_comm, 735*53933Shibler "#3", fp->f_pc, f->f_fa, 736*53933Shibler f->f_wb3a, f->f_wb3d); 737*53933Shibler #endif 738*53933Shibler } 739*53933Shibler } 740*53933Shibler p->p_addr->u_pcb.pcb_onfault = oonfault; 741*53933Shibler /* 742*53933Shibler * Determine the cause of the failure if any translating to 743*53933Shibler * a signal. If the corresponding VA is valid and RO it is 744*53933Shibler * a protection fault (SIGBUS) otherwise consider it an 745*53933Shibler * illegal reference (SIGSEGV). 746*53933Shibler */ 747*53933Shibler if (err) { 748*53933Shibler if (vm_map_check_protection(&p->p_vmspace->vm_map, 749*53933Shibler trunc_page(fa), round_page(fa), 750*53933Shibler VM_PROT_READ) && 751*53933Shibler !vm_map_check_protection(&p->p_vmspace->vm_map, 752*53933Shibler trunc_page(fa), round_page(fa), 753*53933Shibler VM_PROT_WRITE)) 754*53933Shibler err = SIGBUS; 755*53933Shibler else 756*53933Shibler err = SIGSEGV; 757*53933Shibler } 758*53933Shibler return(err); 759*53933Shibler } 760*53933Shibler 761*53933Shibler #ifdef DEBUG 762*53933Shibler dumpssw(ssw) 763*53933Shibler register u_short ssw; 764*53933Shibler { 765*53933Shibler printf(" SSW: %x: ", ssw); 766*53933Shibler if (ssw & SSW4_CP) 767*53933Shibler printf("CP,"); 768*53933Shibler if (ssw & SSW4_CU) 769*53933Shibler printf("CU,"); 770*53933Shibler if (ssw & SSW4_CT) 771*53933Shibler printf("CT,"); 772*53933Shibler if (ssw & SSW4_CM) 773*53933Shibler printf("CM,"); 774*53933Shibler if (ssw & SSW4_MA) 775*53933Shibler printf("MA,"); 776*53933Shibler if (ssw & SSW4_ATC) 777*53933Shibler printf("ATC,"); 778*53933Shibler if (ssw & SSW4_LK) 779*53933Shibler printf("LK,"); 780*53933Shibler if (ssw & SSW4_RW) 781*53933Shibler printf("RW,"); 782*53933Shibler printf(" SZ=%s, TT=%s, TM=%s\n", 783*53933Shibler f7sz[(ssw & SSW4_SZMASK) >> 5], 784*53933Shibler f7tt[(ssw & SSW4_TTMASK) >> 3], 785*53933Shibler f7tm[ssw & SSW4_TMMASK]); 786*53933Shibler } 787*53933Shibler 788*53933Shibler dumpwb(num, s, a, d) 789*53933Shibler int num; 790*53933Shibler u_short s; 791*53933Shibler u_int a, d; 792*53933Shibler { 793*53933Shibler register struct proc *p = curproc; 794*53933Shibler vm_offset_t pa; 795*53933Shibler 796*53933Shibler printf(" writeback #%d: VA %x, data %x, SZ=%s, TT=%s, TM=%s\n", 797*53933Shibler num, a, d, f7sz[(s & SSW4_SZMASK) >> 5], 798*53933Shibler f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]); 799*53933Shibler printf(" PA "); 800*53933Shibler pa = pmap_extract(&p->p_vmspace->vm_pmap, (vm_offset_t)a); 801*53933Shibler if (pa == 0) 802*53933Shibler printf("<invalid address>"); 803*53933Shibler else 804*53933Shibler printf("%x, current value %x", pa, fuword((caddr_t)a)); 805*53933Shibler printf("\n"); 806*53933Shibler } 807*53933Shibler 808*53933Shibler #ifdef HPFPLIB 809*53933Shibler fppanic(frame) 810*53933Shibler struct fppanicframe { 811*53933Shibler int fpsaveframe; 812*53933Shibler int regs[16]; 813*53933Shibler int fpregs[8*3]; 814*53933Shibler int fpcregs[3]; 815*53933Shibler int hole[5]; 816*53933Shibler int oa6; 817*53933Shibler short sr; 818*53933Shibler int pc; 819*53933Shibler short vector; 820*53933Shibler } frame; 821*53933Shibler { 822*53933Shibler printf("FP exception: pid %d(%s): no busy frame, ft=%x pc=%x vec=%x\n", 823*53933Shibler curproc->p_pid, curproc->p_comm, 824*53933Shibler frame.fpsaveframe, frame.pc, frame.vector); 825*53933Shibler panic("bad FP exception"); 826*53933Shibler } 827*53933Shibler #endif 828*53933Shibler #endif 829*53933Shibler #endif 830*53933Shibler 83141475Smckusick /* 83249531Skarels * Proces a system call. 83341475Smckusick */ 83441475Smckusick syscall(code, frame) 83553029Shibler volatile unsigned code; 83641475Smckusick struct frame frame; 83741475Smckusick { 83841475Smckusick register caddr_t params; 83941475Smckusick register int i; 84041475Smckusick register struct sysent *callp; 84148465Skarels register struct proc *p = curproc; 84250753Skarels int error, opc, numsys, s; 84344018Skarels struct args { 84444018Skarels int i[8]; 84544018Skarels } args; 84644018Skarels int rval[2]; 84741475Smckusick struct timeval syst; 84841475Smckusick struct sysent *systab; 849*53933Shibler #if defined(HP380) 850*53933Shibler int beenhere = 0; 851*53933Shibler #endif 85241475Smckusick #ifdef HPUXCOMPAT 85341475Smckusick extern struct sysent hpuxsysent[]; 85441475Smckusick extern int hpuxnsysent, notimp(); 85541475Smckusick #endif 85641475Smckusick 85741475Smckusick cnt.v_syscall++; 85848465Skarels syst = p->p_stime; 85941475Smckusick if (!USERMODE(frame.f_sr)) 86041475Smckusick panic("syscall"); 86152380Smckusick p->p_md.md_regs = frame.f_regs; 86241475Smckusick opc = frame.f_pc - 2; 86341475Smckusick systab = sysent; 86441475Smckusick numsys = nsysent; 86541475Smckusick #ifdef HPUXCOMPAT 86642370Skarels if (p->p_flag & SHPUX) { 86741475Smckusick systab = hpuxsysent; 86841475Smckusick numsys = hpuxnsysent; 86941475Smckusick } 87041475Smckusick #endif 87149531Skarels params = (caddr_t)frame.f_regs[SP] + sizeof(int); 87242370Skarels if (code == 0) { /* indir */ 87342370Skarels code = fuword(params); 87449531Skarels params += sizeof(int); 87542370Skarels } 87642370Skarels if (code >= numsys) 87742370Skarels callp = &systab[0]; /* indir (illegal) */ 87842370Skarels else 87942370Skarels callp = &systab[code]; 88041475Smckusick if ((i = callp->sy_narg * sizeof (int)) && 88144018Skarels (error = copyin(params, (caddr_t)&args, (u_int)i))) { 88241475Smckusick #ifdef HPUXCOMPAT 88341475Smckusick if (p->p_flag & SHPUX) 88442370Skarels error = bsdtohpuxerrno(error); 88541475Smckusick #endif 88649362Skarels frame.f_regs[D0] = error; 88741475Smckusick frame.f_sr |= PSL_C; /* carry bit */ 88841475Smckusick #ifdef KTRACE 88943641Skarels if (KTRPOINT(p, KTR_SYSCALL)) 89044018Skarels ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); 89141475Smckusick #endif 89241475Smckusick goto done; 89341475Smckusick } 89441475Smckusick #ifdef KTRACE 89543641Skarels if (KTRPOINT(p, KTR_SYSCALL)) 89644018Skarels ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i); 89741475Smckusick #endif 89843641Skarels rval[0] = 0; 89943641Skarels rval[1] = frame.f_regs[D1]; 90041475Smckusick #ifdef HPUXCOMPAT 90142370Skarels /* debug kludge */ 90242370Skarels if (callp->sy_call == notimp) 90348465Skarels error = notimp(p, args.i, rval, code, callp->sy_narg); 90442370Skarels else 90541475Smckusick #endif 90648465Skarels error = (*callp->sy_call)(p, &args, rval); 90742370Skarels if (error == ERESTART) 90842370Skarels frame.f_pc = opc; 90942370Skarels else if (error != EJUSTRETURN) { 91042370Skarels if (error) { 91141475Smckusick #ifdef HPUXCOMPAT 91242370Skarels if (p->p_flag & SHPUX) 91342370Skarels error = bsdtohpuxerrno(error); 91441475Smckusick #endif 91549362Skarels frame.f_regs[D0] = error; 91642370Skarels frame.f_sr |= PSL_C; /* carry bit */ 91741475Smckusick } else { 91843641Skarels frame.f_regs[D0] = rval[0]; 91943641Skarels frame.f_regs[D1] = rval[1]; 92041475Smckusick frame.f_sr &= ~PSL_C; 92141475Smckusick } 92242370Skarels } 92342370Skarels /* else if (error == EJUSTRETURN) */ 92441475Smckusick /* nothing to do */ 92542370Skarels 92641475Smckusick done: 92741475Smckusick /* 92842370Skarels * Reinitialize proc pointer `p' as it may be different 92942370Skarels * if this is a child returning from fork syscall. 93042370Skarels */ 93148465Skarels p = curproc; 93249317Shibler while (i = CURSIG(p)) 93349317Shibler psig(i); 93441475Smckusick p->p_pri = p->p_usrpri; 93548465Skarels if (want_resched) { 93641475Smckusick /* 93748465Skarels * Since we are curproc, clock will normally just change 93841475Smckusick * our priority without moving us from one queue to another 93941475Smckusick * (since the running process is not on a queue.) 94041475Smckusick * If that happened after we setrq ourselves but before we 94141475Smckusick * swtch()'ed, we might not be on the queue indicated by 94241475Smckusick * our priority. 94341475Smckusick */ 94450753Skarels s = splclock(); 94541475Smckusick setrq(p); 94648465Skarels p->p_stats->p_ru.ru_nivcsw++; 94741475Smckusick swtch(); 94850753Skarels splx(s); 94949317Shibler while (i = CURSIG(p)) 95049317Shibler psig(i); 95141475Smckusick } 95248465Skarels if (p->p_stats->p_prof.pr_scale) { 95341475Smckusick int ticks; 95448465Skarels struct timeval *tv = &p->p_stime; 95541475Smckusick 95641475Smckusick ticks = ((tv->tv_sec - syst.tv_sec) * 1000 + 95741475Smckusick (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000); 95841475Smckusick if (ticks) { 95941475Smckusick #ifdef PROFTIMER 96041475Smckusick extern int profscale; 96148465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, 96248465Skarels ticks * profscale); 96341475Smckusick #else 96448465Skarels addupc(frame.f_pc, &p->p_stats->p_prof, ticks); 96541475Smckusick #endif 96641475Smckusick } 96741475Smckusick } 968*53933Shibler #if defined(HP380) 969*53933Shibler /* 970*53933Shibler * Deal with writebacks when returning from sigreturn. 971*53933Shibler * They may generate another signal to be processed. 972*53933Shibler * Again, we don't attempt the writeback if we have already 973*53933Shibler * tried and failed (see comment in trap). 974*53933Shibler */ 975*53933Shibler if (mmutype == MMU_68040 && frame.f_format == FMT7) { 976*53933Shibler if (beenhere) { 977*53933Shibler #ifdef DEBUG 978*53933Shibler if (mmudebug & MDB_WBFAILED) 979*53933Shibler printf("pid %d(%s): writeback aborted in sigreturn, pc=%x\n", 980*53933Shibler p->p_pid, p->p_comm, frame.f_pc); 981*53933Shibler #endif 982*53933Shibler ; 983*53933Shibler } else if (i = writeback(&frame, 0)) { 984*53933Shibler beenhere++; 985*53933Shibler syst = p->p_stime; 986*53933Shibler trapsignal(p, i, 0); 987*53933Shibler goto done; 988*53933Shibler } 989*53933Shibler } 990*53933Shibler #endif 99141475Smckusick curpri = p->p_pri; 99241475Smckusick #ifdef KTRACE 99343641Skarels if (KTRPOINT(p, KTR_SYSRET)) 99443641Skarels ktrsysret(p->p_tracep, code, error, rval[0]); 99541475Smckusick #endif 99641475Smckusick } 997