diff options
Diffstat (limited to 'sys/arch/mvme68k/mvme68k/trap.c')
-rw-r--r-- | sys/arch/mvme68k/mvme68k/trap.c | 1040 |
1 files changed, 522 insertions, 518 deletions
diff --git a/sys/arch/mvme68k/mvme68k/trap.c b/sys/arch/mvme68k/mvme68k/trap.c index 65a105f9c46..823c8b02e5b 100644 --- a/sys/arch/mvme68k/mvme68k/trap.c +++ b/sys/arch/mvme68k/mvme68k/trap.c @@ -1,7 +1,8 @@ -/* $OpenBSD: trap.c,v 1.22 1999/09/27 20:30:32 smurph Exp $ */ +/* $OpenBSD: trap.c,v 1.23 2000/01/06 03:21:43 smurph Exp $ */ /* * Copyright (c) 1995 Theo de Raadt + * Copyright (c) 1999 Steve Murphree, Jr. (68060 support) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -102,7 +103,7 @@ extern struct emul emul_sunos; #include <compat/hpux/hpux.h> #endif -char *trap_type[] = { +char *trap_type[] = { "Bus error", "Address error", "Illegal instruction", @@ -118,31 +119,33 @@ char *trap_type[] = { "Coprocessor violation", "Async system trap" }; -int trap_types = sizeof trap_type / sizeof trap_type[0]; +int trap_types = sizeof trap_type / sizeof trap_type[0]; /* * Size of various exception stack frames (minus the standard 8 bytes) */ -short exframesize[] = { - FMT0SIZE, /* type 0 - normal (68020/030/040) */ +short exframesize[] = { + FMT0SIZE, /* type 0 - normal (68020/030/040/060) */ FMT1SIZE, /* type 1 - throwaway (68020/030/040) */ - FMT2SIZE, /* type 2 - normal 6-word (68020/030/040) */ - FMT3SIZE, /* type 3 - FP post-instruction (68040) */ - -1, -1, -1, /* type 4-6 - undefined */ + FMT2SIZE, /* type 2 - normal 6-word (68020/030/040/060) */ + FMT3SIZE, /* type 3 - FP post-instruction (68040/060) */ + FMT4SIZE, /* type 4 - access error/fp disabled (68060) */ + -1, -1, /* type 5-6 - undefined */ FMT7SIZE, /* type 7 - access error (68040) */ - 58, /* type 8 - bus fault (68010) */ + 58, /* type 8 - bus fault (68010) */ FMT9SIZE, /* type 9 - coprocessor mid-instruction (68020/030) */ FMTASIZE, /* type A - short bus fault (68020/030) */ FMTBSIZE, /* type B - long bus fault (68020/030) */ -1, -1, -1, -1 /* type C-F - undefined */ }; -#ifdef M68040 -#define KDFAULT(c) (mmutype == MMU_68040 ? \ - ((c) & SSW4_TMMASK) == SSW4_TMKD : \ + +#if defined(M68040) || defined(M68060) +#define KDFAULT(c) (mmutype == MMU_68060 ? ((c) & FSLW_TM_SV) : \ + mmutype == MMU_68040 ? ((c) & SSW4_TMMASK) == SSW4_TMKD : \ ((c) & (SSW_DF|FC_SUPERD)) == (SSW_DF|FC_SUPERD)) -#define WRFAULT(c) (mmutype == MMU_68040 ? \ - ((c) & SSW4_RW) == 0 : \ +#define WRFAULT(c) (mmutype == MMU_68060 ? ((c) & FSLW_RW_W) : \ + mmutype == MMU_68040 ? ((c) & SSW4_RW) == 0 : \ ((c) & (SSW_DF|SSW_RW)) == SSW_DF) #else #define KDFAULT(c) (((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD)) @@ -163,9 +166,10 @@ void (*sir_routines[NSIR])(); void *sir_args[NSIR]; u_char next_sir; -int writeback __P((struct frame *fp, int docachepush)); +int writeback __P((struct frame *fp, int docachepush)); + static inline void userret __P((struct proc *p, struct frame *fp, - u_quad_t oticks, u_int faultaddr, int fromtrap)); + u_quad_t oticks, u_int faultaddr, int fromtrap)); /* * trap and syscall both need the following work done before returning @@ -173,17 +177,17 @@ static inline void userret __P((struct proc *p, struct frame *fp, */ static inline void userret(p, fp, oticks, faultaddr, fromtrap) - register struct proc *p; - register struct frame *fp; - u_quad_t oticks; - u_int faultaddr; - int fromtrap; +register struct proc *p; +register struct frame *fp; +u_quad_t oticks; +u_int faultaddr; +int fromtrap; { int sig, s; -#ifdef M68040 +#if defined(M68040) || defined(M68060) int beenhere = 0; -again: + again: #endif /* take pending signals */ while ((sig = CURSIG(p)) != 0) @@ -213,10 +217,10 @@ again: if (p->p_flag & P_PROFIL) { extern int psratio; - addupc_task(p, fp->f_pc, - (int)(p->p_sticks - oticks) * psratio); + addupc_task(p, fp->f_pc, + (int)(p->p_sticks - oticks) * psratio); } -#ifdef M68040 +#if defined(M68040) /* * Deal with user mode writebacks (from trap, or from sigreturn). * If any writeback fails, go back and attempt signal delivery. @@ -230,9 +234,9 @@ again: #ifdef DEBUG if (mmudebug & MDB_WBFAILED) printf(fromtrap ? - "pid %d(%s): writeback aborted, pc=%x, fa=%x\n" : - "pid %d(%s): writeback aborted in sigreturn, pc=%x\n", - p->p_pid, p->p_comm, fp->f_pc, faultaddr); + "pid %d(%s): writeback aborted, pc=%x, fa=%x\n" : + "pid %d(%s): writeback aborted in sigreturn, pc=%x\n", + p->p_pid, p->p_comm, fp->f_pc, faultaddr); #endif } else if (sig = writeback(fp, fromtrap)) { register union sigval sv; @@ -251,14 +255,14 @@ again: /* * Trap is called from locore to handle most types of processor traps, * including events such as simulated software interrupts/AST's. - * System calls are broken out for efficiency. + * System calls are broken out for efficiency. T_ADDRERR */ /*ARGSUSED*/ trap(type, code, v, frame) - int type; - unsigned code; - register unsigned v; - struct frame frame; +int type; +unsigned code; +register unsigned v; +struct frame frame; { extern char fubail[], subail[]; register struct proc *p; @@ -283,379 +287,379 @@ trap(type, code, v, frame) p->p_md.md_regs = frame.f_regs; } switch (type) { - - default: -dopanic: - printf("trap type %d, code = %x, v = %x\n", type, code, v); + default: + dopanic: + printf("trap type %d, code = %x, v = %x\n", type, code, v); #ifdef DDB - if (kdb_trap(type, &frame)) - return; + if (kdb_trap(type, &frame)) + return; #endif - regdump(&frame, 128); - type &= ~T_USER; - if ((unsigned)type < trap_types) - panic(trap_type[type]); - panic("trap"); - - case T_BUSERR: /* kernel bus error */ - if (!p || !p->p_addr->u_pcb.pcb_onfault) - goto dopanic; - /* - * If we have arranged to catch this fault in any of the - * copy to/from user space routines, set PC to return to - * indicated location and set flag informing buserror code - * that it may need to clean up stack frame. - */ + regdump(&frame, 128); + type &= ~T_USER; + if ((unsigned)type < trap_types) + panic(trap_type[type]); + panic("trap"); + + case T_BUSERR: /* kernel bus error */ + if (!p || !p->p_addr->u_pcb.pcb_onfault) + goto dopanic; + /* + * If we have arranged to catch this fault in any of the + * copy to/from user space routines, set PC to return to + * indicated location and set flag informing buserror code + * that it may need to clean up stack frame. + */ copyfault: - frame.f_stackadj = exframesize[frame.f_format]; - frame.f_format = frame.f_vector = 0; - frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault; - return; + frame.f_stackadj = exframesize[frame.f_format]; + frame.f_format = frame.f_vector = 0; + frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault; + return; + + case T_BUSERR|T_USER: /* bus error */ + typ = BUS_OBJERR; + ucode = code & ~T_USER; + i = SIGBUS; + break; + case T_ADDRERR|T_USER: /* address error */ + typ = BUS_ADRALN; + ucode = code & ~T_USER; + i = SIGBUS; + break; - case T_BUSERR|T_USER: /* bus error */ - typ = BUS_OBJERR; - ucode = code & ~T_USER; - i = SIGBUS; - break; - case T_ADDRERR|T_USER: /* address error */ - typ = BUS_ADRALN; - ucode = code & ~T_USER; - i = SIGBUS; - break; - - case T_COPERR: /* kernel coprocessor violation */ - case T_FMTERR|T_USER: /* do all RTE errors come in as T_USER? */ - case T_FMTERR: /* ...just in case... */ - /* - * The user has most likely trashed the RTE or FP state info - * in the stack frame of a signal handler. - */ - printf("pid %d: kernel %s exception\n", p->p_pid, - type==T_COPERR ? "coprocessor" : "format"); - type |= T_USER; - p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL; - i = sigmask(SIGILL); - p->p_sigignore &= ~i; - p->p_sigcatch &= ~i; - p->p_sigmask &= ~i; - i = SIGILL; - ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */ - typ = ILL_COPROC; - v = frame.f_pc; - break; - - case T_COPERR|T_USER: /* user coprocessor violation */ - /* What is a proper response here? */ - typ = FPE_FLTINV; - ucode = 0; - i = SIGFPE; - break; - - case T_FPERR|T_USER: /* 68881 exceptions */ - /* - * We pass along the 68881 status register which locore stashed - * in code for us. Note that there is a possibility that the - * bit pattern of this register will conflict with one of the - * FPE_* codes defined in signal.h. Fortunately for us, the - * only such codes we use are all in the range 1-7 and the low - * 3 bits of the status register are defined as 0 so there is - * no clash. - */ - typ = FPE_FLTRES; - ucode = code; - i = SIGFPE; - v = frame.f_pc; - break; - -#ifdef M68040 - case T_FPEMULI|T_USER: /* unimplemented FP instuction */ - case T_FPEMULD|T_USER: /* unimplemented FP data type */ - /* XXX need to FSAVE */ - printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n", - p->p_pid, p->p_comm, - frame.f_format == 2 ? "instruction" : "data type", - frame.f_pc, frame.f_fmt2.f_iaddr); - /* XXX need to FRESTORE */ - typ = FPE_FLTINV; - i = SIGFPE; - v = frame.f_pc; - break; + case T_COPERR: /* kernel coprocessor violation */ + case T_FMTERR|T_USER: /* do all RTE errors come in as T_USER? */ + case T_FMTERR: /* ...just in case... */ + /* + * The user has most likely trashed the RTE or FP state info + * in the stack frame of a signal handler. + */ + printf("pid %d: kernel %s exception\n", p->p_pid, + type==T_COPERR ? "coprocessor" : "format"); + type |= T_USER; + p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL; + i = sigmask(SIGILL); + p->p_sigignore &= ~i; + p->p_sigcatch &= ~i; + p->p_sigmask &= ~i; + i = SIGILL; + ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */ + typ = ILL_COPROC; + v = frame.f_pc; + break; + + case T_COPERR|T_USER: /* user coprocessor violation */ + /* What is a proper response here? */ + typ = FPE_FLTINV; + ucode = 0; + i = SIGFPE; + break; + + case T_FPERR|T_USER: /* 68881 exceptions */ + /* + * We pass along the 68881 status register which locore stashed + * in code for us. Note that there is a possibility that the + * bit pattern of this register will conflict with one of the + * FPE_* codes defined in signal.h. Fortunately for us, the + * only such codes we use are all in the range 1-7 and the low + * 3 bits of the status register are defined as 0 so there is + * no clash. + */ + typ = FPE_FLTRES; + ucode = code; + i = SIGFPE; + v = frame.f_pc; + break; + +#if defined(M68040) || defined(M68060) + case T_FPEMULI|T_USER: /* unimplemented FP instuction */ + case T_FPEMULD|T_USER: /* unimplemented FP data type */ + /* XXX need to FSAVE */ + printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n", + p->p_pid, p->p_comm, + frame.f_format == 2 ? "instruction" : "data type", + frame.f_pc, frame.f_fmt2.f_iaddr); + /* XXX need to FRESTORE */ + typ = FPE_FLTINV; + i = SIGFPE; + v = frame.f_pc; + break; #endif - case T_ILLINST|T_USER: /* illegal instruction fault */ + case T_ILLINST|T_USER: /* illegal instruction fault */ #ifdef COMPAT_HPUX - if (p->p_emul == &emul_hpux) { - typ = 0; - ucode = HPUX_ILL_ILLINST_TRAP; + if (p->p_emul == &emul_hpux) { + typ = 0; + ucode = HPUX_ILL_ILLINST_TRAP; + i = SIGILL; + break; + } +#endif + ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ + typ = ILL_ILLOPC; i = SIGILL; + v = frame.f_pc; break; - } -#endif - ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ - typ = ILL_ILLOPC; - i = SIGILL; - v = frame.f_pc; - break; - case T_PRIVINST|T_USER: /* privileged instruction fault */ + case T_PRIVINST|T_USER: /* privileged instruction fault */ #ifdef COMPAT_HPUX - if (p->p_emul == &emul_hpux) - ucode = HPUX_ILL_PRIV_TRAP; - else + if (p->p_emul == &emul_hpux) + ucode = HPUX_ILL_PRIV_TRAP; + else #endif - ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ - typ = ILL_PRVOPC; - i = SIGILL; - v = frame.f_pc; - break; + ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ + typ = ILL_PRVOPC; + i = SIGILL; + v = frame.f_pc; + break; - case T_ZERODIV|T_USER: /* Divide by zero */ + case T_ZERODIV|T_USER: /* Divide by zero */ #ifdef COMPAT_HPUX - if (p->p_emul == &emul_hpux) - ucode = HPUX_FPE_INTDIV_TRAP; - else + if (p->p_emul == &emul_hpux) + ucode = HPUX_FPE_INTDIV_TRAP; + else #endif - ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */ - typ = FPE_INTDIV; - i = SIGFPE; - v = frame.f_pc; - break; + ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */ + typ = FPE_INTDIV; + i = SIGFPE; + v = frame.f_pc; + break; - case T_CHKINST|T_USER: /* CHK instruction trap */ + case T_CHKINST|T_USER: /* CHK instruction trap */ #ifdef COMPAT_HPUX - if (p->p_emul == &emul_hpux) { - /* handled differently under hp-ux */ - i = SIGILL; - ucode = HPUX_ILL_CHK_TRAP; - break; - } + if (p->p_emul == &emul_hpux) { + /* handled differently under hp-ux */ + i = SIGILL; + ucode = HPUX_ILL_CHK_TRAP; + break; + } #endif - ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */ - typ = FPE_FLTSUB; - i = SIGFPE; - v = frame.f_pc; - break; + ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */ + typ = FPE_FLTSUB; + i = SIGFPE; + v = frame.f_pc; + break; - case T_TRAPVINST|T_USER: /* TRAPV instruction trap */ + case T_TRAPVINST|T_USER: /* TRAPV instruction trap */ #ifdef COMPAT_HPUX - if (p->p_emul == &emul_hpux) { - /* handled differently under hp-ux */ + if (p->p_emul == &emul_hpux) { + /* handled differently under hp-ux */ + i = SIGILL; + ucode = HPUX_ILL_TRAPV_TRAP; + break; + } +#endif + ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */ + typ = ILL_ILLTRP; i = SIGILL; - ucode = HPUX_ILL_TRAPV_TRAP; + v = frame.f_pc; break; - } -#endif - ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */ - typ = ILL_ILLTRP; - i = SIGILL; - v = frame.f_pc; - break; - /* - * XXX: Trace traps are a nightmare. - * - * HP-UX uses trap #1 for breakpoints, - * HPBSD uses trap #2, - * SUN 3.x uses trap #15, - * KGDB uses trap #15 (for kernel breakpoints; handled elsewhere). - * - * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE. - * SUN 3.x traps get passed through as T_TRAP15 and are not really - * supported yet. - */ - case T_TRACE: /* kernel trace trap */ - case T_TRAP15: /* SUN trace trap */ + /* + * XXX: Trace traps are a nightmare. + * + * HP-UX uses trap #1 for breakpoints, + * HPBSD uses trap #2, + * SUN 3.x uses trap #15, + * KGDB uses trap #15 (for kernel breakpoints; handled elsewhere). + * + * HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE. + * SUN 3.x traps get passed through as T_TRAP15 and are not really + * supported yet. + */ + case T_TRACE: /* kernel trace trap */ + case T_TRAP15: /* SUN trace trap */ #ifdef DDB - if (kdb_trap(type, &frame)) - return; + if (kdb_trap(type, &frame)) + return; #endif - frame.f_sr &= ~PSL_T; - i = SIGTRAP; - typ = TRAP_TRACE; - break; + frame.f_sr &= ~PSL_T; + i = SIGTRAP; + typ = TRAP_TRACE; + break; - case T_TRACE|T_USER: /* user trace trap */ - case T_TRAP15|T_USER: /* SUN user trace trap */ + case T_TRACE|T_USER: /* user trace trap */ + case T_TRAP15|T_USER: /* SUN user trace trap */ #ifdef COMPAT_SUNOS - /* - * SunOS uses Trap #2 for a "CPU cache flush" - * Just flush the on-chip caches and return. - * XXX - Too bad m68k BSD uses trap 2... - */ - if (p->p_emul == &emul_sunos) { - ICIA(); - DCIU(); - /* get out fast */ - return; - } + /* + * SunOS uses Trap #2 for a "CPU cache flush" + * Just flush the on-chip caches and return. + * XXX - Too bad m68k BSD uses trap 2... + */ + if (p->p_emul == &emul_sunos) { + ICIA(); + DCIU(); + /* get out fast */ + return; + } #endif - frame.f_sr &= ~PSL_T; - i = SIGTRAP; - typ = TRAP_TRACE; - break; + frame.f_sr &= ~PSL_T; + i = SIGTRAP; + typ = TRAP_TRACE; + break; - case T_ASTFLT: /* system async trap, cannot happen */ - goto dopanic; + case T_ASTFLT: /* system async trap, cannot happen */ + goto dopanic; - case T_ASTFLT|T_USER: /* user async trap */ - astpending = 0; - /* - * We check for software interrupts first. This is because - * they are at a higher level than ASTs, and on a VAX would - * interrupt the AST. We assume that if we are processing - * an AST that we must be at IPL0 so we don't bother to - * check. Note that we ensure that we are at least at SIR - * IPL while processing the SIR. - */ - spl1(); - /* fall into... */ - - case T_SSIR: /* software interrupt */ - case T_SSIR|T_USER: - while (bit = ffs(ssir)) { - --bit; - ssir &= ~(1 << bit); - cnt.v_soft++; - if (sir_routines[bit]) - sir_routines[bit](sir_args[bit]); - } - /* - * If this was not an AST trap, we are all done. - */ - if (type != (T_ASTFLT|T_USER)) { - cnt.v_trap--; - return; - } - spl0(); - if (p->p_flag & P_OWEUPC) { - p->p_flag &= ~P_OWEUPC; - ADDUPROF(p); - } - goto out; + case T_ASTFLT|T_USER: /* user async trap */ + astpending = 0; + /* + * We check for software interrupts first. This is because + * they are at a higher level than ASTs, and on a VAX would + * interrupt the AST. We assume that if we are processing + * an AST that we must be at IPL0 so we don't bother to + * check. Note that we ensure that we are at least at SIR + * IPL while processing the SIR. + */ + spl1(); + /* fall into... */ + + case T_SSIR: /* software interrupt */ + case T_SSIR|T_USER: + while (bit = ffs(ssir)) { + --bit; + ssir &= ~(1 << bit); + cnt.v_soft++; + if (sir_routines[bit]) + sir_routines[bit](sir_args[bit]); + } + /* + * If this was not an AST trap, we are all done. + */ + if (type != (T_ASTFLT|T_USER)) { + cnt.v_trap--; + return; + } + spl0(); + if (p->p_flag & P_OWEUPC) { + p->p_flag &= ~P_OWEUPC; + ADDUPROF(p); + } + goto out; - case T_MMUFLT: /* kernel mode page fault */ - /* - * If we were doing profiling ticks or other user mode - * stuff from interrupt code, Just Say No. - */ - if (p && (p->p_addr->u_pcb.pcb_onfault == fubail || - p->p_addr->u_pcb.pcb_onfault == subail)) - goto copyfault; - /* fall into ... */ - - case T_MMUFLT|T_USER: /* page fault */ - { - register vm_offset_t va; - register struct vmspace *vm = NULL; - register vm_map_t map; - int rv; - vm_prot_t ftype, vftype; - extern vm_map_t kernel_map; - - /* vmspace only significant if T_USER */ - if (p) - vm = p->p_vmspace; + case T_MMUFLT: /* kernel mode page fault */ + /* + * If we were doing profiling ticks or other user mode + * stuff from interrupt code, Just Say No. + */ + if (p && (p->p_addr->u_pcb.pcb_onfault == fubail || + p->p_addr->u_pcb.pcb_onfault == subail)) { + goto copyfault; + } + /* fall into ... */ + + case T_MMUFLT|T_USER: /* page fault */ + { + register vm_offset_t va; + register struct vmspace *vm = NULL; + register vm_map_t map; + int rv; + vm_prot_t ftype, vftype; + extern vm_map_t kernel_map; + + /* vmspace only significant if T_USER */ + if (p) + vm = p->p_vmspace; #ifdef DEBUG - if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) - printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n", - p->p_pid, code, v, frame.f_pc, frame.f_sr); + if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) + printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n", + p->p_pid, code, v, frame.f_pc, frame.f_sr); #endif - /* - * It is only a kernel address space fault iff: - * 1. (type & T_USER) == 0 and - * 2. pcb_onfault not set or - * 3. pcb_onfault set but supervisor space data fault - * The last can occur during an exec() copyin where the - * argument space is lazy-allocated. - */ - if (type == T_MMUFLT && - ((p && !p->p_addr->u_pcb.pcb_onfault) || KDFAULT(code))) - map = kernel_map; - else - map = &vm->vm_map; - if (WRFAULT(code)) { - vftype = VM_PROT_WRITE; - ftype = VM_PROT_READ | VM_PROT_WRITE; - } else - vftype = ftype = VM_PROT_READ; - va = trunc_page((vm_offset_t)v); - - if (map == kernel_map && va == 0) { - printf("trap: bad kernel access at %x\n", v); - goto dopanic; - } + /* + * It is only a kernel address space fault iff: + * 1. (type & T_USER) == 0 and + * 2. pcb_onfault not set or + * 3. pcb_onfault set but supervisor space data fault + * The last can occur during an exec() copyin where the + * argument space is lazy-allocated. + */ + if (type == T_MMUFLT && + ((p && !p->p_addr->u_pcb.pcb_onfault) || KDFAULT(code))) + map = kernel_map; + else + map = &vm->vm_map; + if (WRFAULT(code)) { + vftype = VM_PROT_WRITE; + ftype = VM_PROT_READ | VM_PROT_WRITE; + } else + vftype = ftype = VM_PROT_READ; + va = trunc_page((vm_offset_t)v); + + if (map == kernel_map && va == 0) { + printf("trap: bad kernel access at %x\n", v); + goto dopanic; + } #ifdef COMPAT_HPUX - if (ISHPMMADDR(va)) { - vm_offset_t bva; - - rv = pmap_mapmulti(map->pmap, va); - if (rv != KERN_SUCCESS) { - bva = HPMMBASEADDR(va); - rv = vm_fault(map, bva, ftype, FALSE); - if (rv == KERN_SUCCESS) - (void) pmap_mapmulti(map->pmap, va); - } - } else + if (ISHPMMADDR(va)) { + vm_offset_t bva; + + rv = pmap_mapmulti(map->pmap, va); + if (rv != KERN_SUCCESS) { + bva = HPMMBASEADDR(va); + rv = vm_fault(map, bva, ftype, FALSE); + if (rv == KERN_SUCCESS) + (void) pmap_mapmulti(map->pmap, va); + } + } else #endif - rv = vm_fault(map, va, ftype, FALSE); + rv = vm_fault(map, va, ftype, FALSE); #ifdef DEBUG - if (rv && MDB_ISPID(p->p_pid)) - printf("vm_fault(%x, %x, %x, 0) -> %x\n", - map, va, ftype, rv); + if (rv && MDB_ISPID(p->p_pid)) + printf("vm_fault(%x, %x, %x, 0) -> %x\n", + map, va, ftype, rv); #endif - /* - * If this was a stack access we keep track of the maximum - * accessed stack size. Also, if vm_fault gets a protection - * failure it is due to accessing the stack region outside - * the current limit and we need to reflect that as an access - * error. - */ - if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) { - if (rv == KERN_SUCCESS) { - unsigned nss; - - nss = clrnd(btoc(USRSTACK-(unsigned)va)); - if (nss > vm->vm_ssize) - vm->vm_ssize = nss; - } else if (rv == KERN_PROTECTION_FAILURE) - rv = KERN_INVALID_ADDRESS; - } - if (rv == KERN_SUCCESS) { - if (type == T_MMUFLT) { + /* + * If this was a stack access we keep track of the maximum + * accessed stack size. Also, if vm_fault gets a protection + * failure it is due to accessing the stack region outside + * the current limit and we need to reflect that as an access + * error. + */ + if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) { + if (rv == KERN_SUCCESS) { + unsigned nss; + + nss = clrnd(btoc(USRSTACK-(unsigned)va)); + if (nss > vm->vm_ssize) + vm->vm_ssize = nss; + } else if (rv == KERN_PROTECTION_FAILURE) + rv = KERN_INVALID_ADDRESS; + } + if (rv == KERN_SUCCESS) { + if (type == T_MMUFLT) { #if defined(M68040) - if (mmutype == MMU_68040) - (void) writeback(&frame, 1); + if (mmutype == MMU_68040) + (void) writeback(&frame, 1); #endif - return; + return; + } + goto out; + } + if (type == T_MMUFLT) { + if (p && p->p_addr->u_pcb.pcb_onfault) + goto copyfault; + printf("vm_fault(%x, %x, %x, 0) -> %x\n", + map, va, ftype, rv); + printf(" type %x, code [mmu,,ssw]: %x\n", + type, code); + goto dopanic; + } + frame.f_pad = code & 0xffff; + ucode = vftype; + typ = SEGV_MAPERR; + i = SIGSEGV; + break; } - goto out; - } - if (type == T_MMUFLT) { - if (p && p->p_addr->u_pcb.pcb_onfault) - goto copyfault; - printf("vm_fault(%x, %x, %x, 0) -> %x\n", - map, va, ftype, rv); - printf(" type %x, code [mmu,,ssw]: %x\n", - type, code); - goto dopanic; - } - frame.f_pad = code & 0xffff; - ucode = vftype; - typ = SEGV_MAPERR; - i = SIGSEGV; - break; - } } sv.sival_int = v; trapsignal(p, i, ucode, typ, sv); if ((type & T_USER) == 0) return; -out: + out: userret(p, &frame, sticks, v, 1); } -#ifdef M68040 +#if defined(M68040) #ifdef DEBUG struct writebackstats { int calls; @@ -665,18 +669,18 @@ struct writebackstats { int wbsize[4]; } wbstats; -char *f7sz[] = { "longword", "byte", "word", "line" }; -char *f7tt[] = { "normal", "MOVE16", "AFC", "ACK" }; +char *f7sz[] = { "longword", "byte", "word", "line"}; +char *f7tt[] = { "normal", "MOVE16", "AFC", "ACK"}; char *f7tm[] = { "d-push", "u-data", "u-code", "M-data", - "M-code", "k-data", "k-code", "RES" }; + "M-code", "k-data", "k-code", "RES"}; char wberrstr[] = - "WARNING: pid %d(%s) writeback [%s] failed, pc=%x fa=%x wba=%x wbd=%x\n"; +"WARNING: pid %d(%s) writeback [%s] failed, pc=%x fa=%x wba=%x wbd=%x\n"; #endif int writeback(fp, docachepush) - struct frame *fp; - int docachepush; +struct frame *fp; +int docachepush; { register struct fmt7 *f = &fp->f_fmt7; register struct proc *p = curproc; @@ -703,11 +707,11 @@ writeback(fp, docachepush) #ifdef DEBUG if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) { printf(" pushing %s to PA %x, data %x", - f7sz[(f->f_ssw & SSW4_SZMASK) >> 5], - f->f_fa, f->f_pd0); + f7sz[(f->f_ssw & SSW4_SZMASK) >> 5], + f->f_fa, f->f_pd0); if ((f->f_ssw & SSW4_SZMASK) == SSW4_SZLN) printf("/%x/%x/%x", - f->f_pd1, f->f_pd2, f->f_pd3); + f->f_pd1, f->f_pd2, f->f_pd3); printf("\n"); } if (f->f_wb1s & SSW4_WBSV) @@ -720,15 +724,15 @@ writeback(fp, docachepush) */ if (docachepush) { pmap_enter(pmap_kernel(), (vm_offset_t)vmmap, - trunc_page(f->f_fa), VM_PROT_WRITE, TRUE, VM_PROT_WRITE); + trunc_page(f->f_fa), VM_PROT_WRITE, TRUE, VM_PROT_WRITE); fa = (u_int)&vmmap[(f->f_fa & PGOFSET) & ~0xF]; bcopy((caddr_t)&f->f_pd0, (caddr_t)fa, 16); DCFL(pmap_extract(pmap_kernel(), (vm_offset_t)fa)); pmap_remove(pmap_kernel(), (vm_offset_t)vmmap, - (vm_offset_t)&vmmap[NBPG]); + (vm_offset_t)&vmmap[NBPG]); } else printf("WARNING: pid %d(%s) uid %d: CPUSH not done\n", - p->p_pid, p->p_comm, p->p_ucred->cr_uid); + p->p_pid, p->p_comm, p->p_ucred->cr_uid); } else if ((f->f_ssw & (SSW4_RW|SSW4_TTMASK)) == SSW4_TTM16) { /* * MOVE16 fault. @@ -738,8 +742,8 @@ writeback(fp, docachepush) #ifdef DEBUG if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) printf(" MOVE16 to VA %x(%x), data %x/%x/%x/%x\n", - f->f_fa, f->f_fa & ~0xF, f->f_pd0, f->f_pd1, - f->f_pd2, f->f_pd3); + f->f_fa, f->f_fa & ~0xF, f->f_pd0, f->f_pd1, + f->f_pd2, f->f_pd3); if (f->f_wb1s & SSW4_WBSV) panic("writeback: MOVE16 with WB1S valid"); wbstats.move16s++; @@ -753,8 +757,8 @@ writeback(fp, docachepush) #ifdef DEBUG if (mmudebug & MDB_WBFAILED) printf(wberrstr, p->p_pid, p->p_comm, - "MOVE16", fp->f_pc, f->f_fa, - f->f_fa & ~0xF, f->f_pd0); + "MOVE16", fp->f_pc, f->f_fa, + f->f_fa & ~0xF, f->f_pd0); #endif } } else if (f->f_wb1s & SSW4_WBSV) { @@ -773,40 +777,40 @@ writeback(fp, docachepush) #endif off = (f->f_wb1a & 3) * 8; switch (f->f_wb1s & SSW4_SZMASK) { - case SSW4_SZLW: - if (off) - wb1d = (wb1d >> (32 - off)) | (wb1d << off); - if (KDFAULT(f->f_wb1s)) - *(long *)f->f_wb1a = wb1d; - else - err = suword((caddr_t)f->f_wb1a, wb1d); - break; - case SSW4_SZB: - off = 24 - off; - if (off) - wb1d >>= off; - if (KDFAULT(f->f_wb1s)) - *(char *)f->f_wb1a = wb1d; - else - err = subyte((caddr_t)f->f_wb1a, wb1d); - break; - case SSW4_SZW: - off = (off + 16) % 32; - if (off) - wb1d = (wb1d >> (32 - off)) | (wb1d << off); - if (KDFAULT(f->f_wb1s)) - *(short *)f->f_wb1a = wb1d; - else - err = susword((caddr_t)f->f_wb1a, wb1d); - break; + case SSW4_SZLW: + if (off) + wb1d = (wb1d >> (32 - off)) | (wb1d << off); + if (KDFAULT(f->f_wb1s)) + *(long *)f->f_wb1a = wb1d; + else + err = suword((caddr_t)f->f_wb1a, wb1d); + break; + case SSW4_SZB: + off = 24 - off; + if (off) + wb1d >>= off; + if (KDFAULT(f->f_wb1s)) + *(char *)f->f_wb1a = wb1d; + else + err = subyte((caddr_t)f->f_wb1a, wb1d); + break; + case SSW4_SZW: + off = (off + 16) % 32; + if (off) + wb1d = (wb1d >> (32 - off)) | (wb1d << off); + if (KDFAULT(f->f_wb1s)) + *(short *)f->f_wb1a = wb1d; + else + err = susword((caddr_t)f->f_wb1a, wb1d); + break; } if (err) { fa = f->f_wb1a; #ifdef DEBUG if (mmudebug & MDB_WBFAILED) printf(wberrstr, p->p_pid, p->p_comm, - "#1", fp->f_pc, f->f_fa, - f->f_wb1a, f->f_wb1d); + "#1", fp->f_pc, f->f_fa, + f->f_wb1a, f->f_wb1d); #endif } } @@ -817,7 +821,7 @@ writeback(fp, docachepush) * a MOVE16 was already dealt with above. Ignore it. */ if (err == 0 && (f->f_wb2s & SSW4_WBSV) && - (f->f_wb2s & SSW4_SZMASK) != SSW4_SZLN) { + (f->f_wb2s & SSW4_SZMASK) != SSW4_SZLN) { #ifdef DEBUG if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); @@ -825,32 +829,32 @@ writeback(fp, docachepush) wbstats.wbsize[(f->f_wb2s&SSW4_SZMASK)>>5]++; #endif switch (f->f_wb2s & SSW4_SZMASK) { - case SSW4_SZLW: - if (KDFAULT(f->f_wb2s)) - *(long *)f->f_wb2a = f->f_wb2d; - else - err = suword((caddr_t)f->f_wb2a, f->f_wb2d); - break; - case SSW4_SZB: - if (KDFAULT(f->f_wb2s)) - *(char *)f->f_wb2a = f->f_wb2d; - else - err = subyte((caddr_t)f->f_wb2a, f->f_wb2d); - break; - case SSW4_SZW: - if (KDFAULT(f->f_wb2s)) - *(short *)f->f_wb2a = f->f_wb2d; - else - err = susword((caddr_t)f->f_wb2a, f->f_wb2d); - break; + case SSW4_SZLW: + if (KDFAULT(f->f_wb2s)) + *(long *)f->f_wb2a = f->f_wb2d; + else + err = suword((caddr_t)f->f_wb2a, f->f_wb2d); + break; + case SSW4_SZB: + if (KDFAULT(f->f_wb2s)) + *(char *)f->f_wb2a = f->f_wb2d; + else + err = subyte((caddr_t)f->f_wb2a, f->f_wb2d); + break; + case SSW4_SZW: + if (KDFAULT(f->f_wb2s)) + *(short *)f->f_wb2a = f->f_wb2d; + else + err = susword((caddr_t)f->f_wb2a, f->f_wb2d); + break; } if (err) { fa = f->f_wb2a; #ifdef DEBUG if (mmudebug & MDB_WBFAILED) { printf(wberrstr, p->p_pid, p->p_comm, - "#2", fp->f_pc, f->f_fa, - f->f_wb2a, f->f_wb2d); + "#2", fp->f_pc, f->f_fa, + f->f_wb2a, f->f_wb2d); dumpssw(f->f_ssw); dumpwb(2, f->f_wb2s, f->f_wb2a, f->f_wb2d); } @@ -865,27 +869,27 @@ writeback(fp, docachepush) wbstats.wbsize[(f->f_wb3s&SSW4_SZMASK)>>5]++; #endif switch (f->f_wb3s & SSW4_SZMASK) { - case SSW4_SZLW: - if (KDFAULT(f->f_wb3s)) - *(long *)f->f_wb3a = f->f_wb3d; - else - err = suword((caddr_t)f->f_wb3a, f->f_wb3d); - break; - case SSW4_SZB: - if (KDFAULT(f->f_wb3s)) - *(char *)f->f_wb3a = f->f_wb3d; - else - err = subyte((caddr_t)f->f_wb3a, f->f_wb3d); - break; - case SSW4_SZW: - if (KDFAULT(f->f_wb3s)) - *(short *)f->f_wb3a = f->f_wb3d; - else - err = susword((caddr_t)f->f_wb3a, f->f_wb3d); - break; + case SSW4_SZLW: + if (KDFAULT(f->f_wb3s)) + *(long *)f->f_wb3a = f->f_wb3d; + else + err = suword((caddr_t)f->f_wb3a, f->f_wb3d); + break; + case SSW4_SZB: + if (KDFAULT(f->f_wb3s)) + *(char *)f->f_wb3a = f->f_wb3d; + else + err = subyte((caddr_t)f->f_wb3a, f->f_wb3d); + break; + case SSW4_SZW: + if (KDFAULT(f->f_wb3s)) + *(short *)f->f_wb3a = f->f_wb3d; + else + err = susword((caddr_t)f->f_wb3a, f->f_wb3d); + break; #ifdef DEBUG - case SSW4_SZLN: - panic("writeback: wb3s indicates LINE write"); + case SSW4_SZLN: + panic("writeback: wb3s indicates LINE write"); #endif } if (err) { @@ -893,8 +897,8 @@ writeback(fp, docachepush) #ifdef DEBUG if (mmudebug & MDB_WBFAILED) printf(wberrstr, p->p_pid, p->p_comm, - "#3", fp->f_pc, f->f_fa, - f->f_wb3a, f->f_wb3d); + "#3", fp->f_pc, f->f_fa, + f->f_wb3a, f->f_wb3d); #endif } } @@ -904,12 +908,12 @@ writeback(fp, docachepush) */ if (err) err = SIGSEGV; - return(err); + return (err); } #ifdef DEBUG dumpssw(ssw) - register u_short ssw; +register u_short ssw; { printf(" SSW: %x: ", ssw); if (ssw & SSW4_CP) @@ -929,22 +933,22 @@ dumpssw(ssw) if (ssw & SSW4_RW) printf("RW,"); printf(" SZ=%s, TT=%s, TM=%s\n", - f7sz[(ssw & SSW4_SZMASK) >> 5], - f7tt[(ssw & SSW4_TTMASK) >> 3], - f7tm[ssw & SSW4_TMMASK]); + f7sz[(ssw & SSW4_SZMASK) >> 5], + f7tt[(ssw & SSW4_TTMASK) >> 3], + f7tm[ssw & SSW4_TMMASK]); } dumpwb(num, s, a, d) - int num; - u_short s; - u_int a, d; +int num; +u_short s; +u_int a, d; { register struct proc *p = curproc; vm_offset_t pa; printf(" writeback #%d: VA %x, data %x, SZ=%s, TT=%s, TM=%s\n", - num, a, d, f7sz[(s & SSW4_SZMASK) >> 5], - f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]); + num, a, d, f7sz[(s & SSW4_SZMASK) >> 5], + f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]); printf(" PA "); pa = pmap_extract(&p->p_vmspace->vm_pmap, (vm_offset_t)a); if (pa == 0) @@ -960,8 +964,8 @@ dumpwb(num, s, a, d) * Process a system call. */ syscall(code, frame) - register_t code; - struct frame frame; +register_t code; +struct frame frame; { register caddr_t params; register struct sysent *callp; @@ -1018,42 +1022,42 @@ syscall(code, frame) params = (caddr_t)frame.f_regs[SP] + sizeof(int); switch (code) { - case SYS_syscall: - /* - * Code is first argument, followed by actual args. - */ - code = fuword(params); - params += sizeof(int); - /* - * XXX sigreturn requires special stack manipulation - * that is only done if entered via the sigreturn - * trap. Cannot allow it here so make sure we fail. - */ - if (code == SYS_sigreturn) - code = nsys; - break; - case SYS___syscall: - /* - * Like syscall, but code is a quad, so as to maintain - * quad alignment for the rest of the arguments. - */ - if (callp != sysent) + case SYS_syscall: + /* + * Code is first argument, followed by actual args. + */ + code = fuword(params); + params += sizeof(int); + /* + * XXX sigreturn requires special stack manipulation + * that is only done if entered via the sigreturn + * trap. Cannot allow it here so make sure we fail. + */ + if (code == SYS_sigreturn) + code = nsys; + break; + case SYS___syscall: + /* + * Like syscall, but code is a quad, so as to maintain + * quad alignment for the rest of the arguments. + */ + if (callp != sysent) + break; + code = fuword(params + _QUAD_LOWWORD * sizeof(int)); + params += sizeof(quad_t); + break; + default: break; - code = fuword(params + _QUAD_LOWWORD * sizeof(int)); - params += sizeof(quad_t); - break; - default: - break; } if (code < 0 || code >= nsys) callp += p->p_emul->e_nosys; /* illegal */ else - callp += code; + callp += code; argsize = callp->sy_argsize; if (argsize) error = copyin(params, (caddr_t)args, argsize); else - error = 0; + error = 0; #ifdef SYSCALL_DEBUG scdebug_call(p, code, args); #endif @@ -1067,28 +1071,28 @@ syscall(code, frame) rval[1] = frame.f_regs[D1]; error = (*callp->sy_call)(p, args, rval); switch (error) { - case 0: - frame.f_regs[D0] = rval[0]; - frame.f_regs[D1] = rval[1]; - frame.f_sr &= ~PSL_C; /* carry bit */ - break; - case ERESTART: - /* - * We always enter through a `trap' instruction, which is 2 - * bytes, so adjust the pc by that amount. - */ - frame.f_pc = opc - 2; - break; - case EJUSTRETURN: - /* nothing to do */ - break; - default: - bad: - if (p->p_emul->e_errno) - error = p->p_emul->e_errno[error]; - frame.f_regs[D0] = error; - frame.f_sr |= PSL_C; /* carry bit */ - break; + case 0: + frame.f_regs[D0] = rval[0]; + frame.f_regs[D1] = rval[1]; + frame.f_sr &= ~PSL_C; /* carry bit */ + break; + case ERESTART: + /* + * We always enter through a `trap' instruction, which is 2 + * bytes, so adjust the pc by that amount. + */ + frame.f_pc = opc - 2; + break; + case EJUSTRETURN: + /* nothing to do */ + break; + default: + bad: + if (p->p_emul->e_errno) + error = p->p_emul->e_errno[error]; + frame.f_regs[D0] = error; + frame.f_sr |= PSL_C; /* carry bit */ + break; } #ifdef SYSCALL_DEBUG @@ -1108,8 +1112,8 @@ syscall(code, frame) void child_return(p, frame) - struct proc *p; - struct frame frame; +struct proc *p; +struct frame frame; { frame.f_regs[D0] = 0; @@ -1128,8 +1132,8 @@ child_return(p, frame) */ u_long allocate_sir(proc, arg) - void (*proc)(); - void *arg; +void (*proc)(); +void *arg; { int bit; @@ -1160,9 +1164,9 @@ struct intrhand *intrs[256]; #ifndef INTR_ASM int hardintr(pc, evec, frame) - int pc; - int evec; - void *frame; +int pc; +int evec; +void *frame; { int vec = (evec & 0xfff) >> 2; /* XXX should be m68k macro? */ extern u_long intrcnt[]; /* XXX from locore */ @@ -1195,7 +1199,7 @@ hardintr(pc, evec, frame) */ int intr_findvec(start, end) - int start, end; +int start, end; { extern u_long *vectab[], hardtrap, badtrap; int vec; @@ -1216,8 +1220,8 @@ intr_findvec(start, end) */ int intr_establish(vec, ih) - int vec; - struct intrhand *ih; +int vec; +struct intrhand *ih; { extern u_long *vectab[], hardtrap, badtrap; struct intrhand *ihx; @@ -1252,8 +1256,8 @@ db_prom_cmd() } struct db_command db_machine_cmds[] = { - { "prom", db_prom_cmd, 0, 0 }, - { (char *)0, } + { "prom", db_prom_cmd, 0, 0}, + { (char *)0,} }; void |