📄 machdep.c
字号:
#endif#ifndef HP330 case HP_330:#endif#if !defined(HP360) && !defined(HP370) case HP_340: case HP_360: case HP_370:#endif#if !defined(HP380) case HP_380: case HP_433:#endif panic("CPU type not configured"); default: break; }}/* * machine dependent system variables. */cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) int *name; u_int namelen; void *oldp; size_t *oldlenp; void *newp; size_t newlen; struct proc *p;{ /* all sysctl names at this level are terminal */ if (namelen != 1) return (ENOTDIR); /* overloaded */ switch (name[0]) { case CPU_CONSDEV: return (sysctl_rdstruct(oldp, oldlenp, newp, &cn_tty->t_dev, sizeof cn_tty->t_dev)); default: return (EOPNOTSUPP); } /* NOTREACHED */}#ifdef USELEDS#include <hp300/hp300/led.h>int inledcontrol = 0; /* 1 if we are in ledcontrol already, cheap mutex */char *ledaddr;/* * Map the LED page and setup the KVA to access it. */ledinit(){ extern caddr_t ledbase; pmap_enter(kernel_pmap, (vm_offset_t)ledbase, (vm_offset_t)LED_ADDR, VM_PROT_READ|VM_PROT_WRITE, TRUE); ledaddr = (char *) ((int)ledbase | (LED_ADDR & PGOFSET));}/* * Do lights: * `ons' is a mask of LEDs to turn on, * `offs' is a mask of LEDs to turn off, * `togs' is a mask of LEDs to toggle. * Note we don't use splclock/splx for mutual exclusion. * They are expensive and we really don't need to be that precise. * Besides we would like to be able to profile this routine. */ledcontrol(ons, offs, togs) register int ons, offs, togs;{ static char currentleds; register char leds; inledcontrol = 1; leds = currentleds; if (ons) leds |= ons; if (offs) leds &= ~offs; if (togs) leds ^= togs; currentleds = leds; *ledaddr = ~leds; inledcontrol = 0;}#endif#define SS_RTEFRAME 1#define SS_FPSTATE 2#define SS_USERREGS 4struct sigstate { int ss_flags; /* which of the following are valid */ struct frame ss_frame; /* original exception frame */ struct fpframe ss_fpstate; /* 68881/68882 state info */};/* * WARNING: code in locore.s assumes the layout shown for sf_signum * thru sf_handler so... don't screw with them! */struct sigframe { int sf_signum; /* signo for handler */ int sf_code; /* additional info for handler */ struct sigcontext *sf_scp; /* context ptr for handler */ sig_t sf_handler; /* handler addr for u_sigc */ struct sigstate sf_state; /* state of the hardware */ struct sigcontext sf_sc; /* actual context */};#ifdef HPUXCOMPATstruct hpuxsigcontext { int hsc_syscall; char hsc_action; char hsc_pad1; char hsc_pad2; char hsc_onstack; int hsc_mask; int hsc_sp; short hsc_ps; int hsc_pc;/* the rest aren't part of the context but are included for our convenience */ short hsc_pad; u_int hsc_magic; /* XXX sigreturn: cookie */ struct sigcontext *hsc_realsc; /* XXX sigreturn: ptr to BSD context */};/* * For an HP-UX process, a partial hpuxsigframe follows the normal sigframe. * Tremendous waste of space, but some HP-UX applications (e.g. LCL) need it. */struct hpuxsigframe { int hsf_signum; int hsf_code; struct sigcontext *hsf_scp; struct hpuxsigcontext hsf_sc; int hsf_regs[15];};#endif#ifdef DEBUGint sigdebug = 0;int sigpid = 0;#define SDB_FOLLOW 0x01#define SDB_KSTACK 0x02#define SDB_FPSTATE 0x04#endif/* * Send an interrupt to process. */voidsendsig(catcher, sig, mask, code) sig_t catcher; int sig, mask; unsigned code;{ register struct proc *p = curproc; register struct sigframe *fp, *kfp; register struct frame *frame; register struct sigacts *psp = p->p_sigacts; register short ft; int oonstack, fsize; extern char sigcode[], esigcode[]; frame = (struct frame *)p->p_md.md_regs; ft = frame->f_format; oonstack = psp->ps_sigstk.ss_flags & SA_ONSTACK; /* * Allocate and validate space for the signal handler * context. Note that if the stack is in P0 space, the * call to grow() is a nop, and the useracc() check * will fail if the process has not already allocated * the space with a `brk'. */#ifdef HPUXCOMPAT if (p->p_md.md_flags & MDP_HPUX) fsize = sizeof(struct sigframe) + sizeof(struct hpuxsigframe); else#endif fsize = sizeof(struct sigframe); if ((psp->ps_flags & SAS_ALTSTACK) && (psp->ps_sigstk.ss_flags & SA_ONSTACK) == 0 && (psp->ps_sigonstack & sigmask(sig))) { fp = (struct sigframe *)(psp->ps_sigstk.ss_base + psp->ps_sigstk.ss_size - fsize); psp->ps_sigstk.ss_flags |= SA_ONSTACK; } else fp = (struct sigframe *)(frame->f_regs[SP] - fsize); if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize)) (void)grow(p, (unsigned)fp);#ifdef DEBUG if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sendsig(%d): sig %d ssp %x usp %x scp %x ft %d\n", p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft);#endif if (useracc((caddr_t)fp, fsize, B_WRITE) == 0) {#ifdef DEBUG if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sendsig(%d): useracc failed on sig %d\n", p->p_pid, sig);#endif /* * Process has trashed its stack; give it an illegal * instruction to halt it in its tracks. */ SIGACTION(p, SIGILL) = SIG_DFL; sig = sigmask(SIGILL); p->p_sigignore &= ~sig; p->p_sigcatch &= ~sig; p->p_sigmask &= ~sig; psignal(p, SIGILL); return; } kfp = (struct sigframe *)malloc((u_long)fsize, M_TEMP, M_WAITOK); /* * Build the argument list for the signal handler. */ kfp->sf_signum = sig; kfp->sf_code = code; kfp->sf_scp = &fp->sf_sc; kfp->sf_handler = catcher; /* * Save necessary hardware state. Currently this includes: * - general registers * - original exception frame (if not a "normal" frame) * - FP coprocessor state */ kfp->sf_state.ss_flags = SS_USERREGS; bcopy((caddr_t)frame->f_regs, (caddr_t)kfp->sf_state.ss_frame.f_regs, sizeof frame->f_regs); if (ft >= FMT7) {#ifdef DEBUG if (ft > 15 || exframesize[ft] < 0) panic("sendsig: bogus frame type");#endif kfp->sf_state.ss_flags |= SS_RTEFRAME; kfp->sf_state.ss_frame.f_format = frame->f_format; kfp->sf_state.ss_frame.f_vector = frame->f_vector; bcopy((caddr_t)&frame->F_u, (caddr_t)&kfp->sf_state.ss_frame.F_u, exframesize[ft]); /* * Leave an indicator that we need to clean up the kernel * stack. We do this by setting the "pad word" above the * hardware stack frame to the amount the stack must be * adjusted by. * * N.B. we increment rather than just set f_stackadj in * case we are called from syscall when processing a * sigreturn. In that case, f_stackadj may be non-zero. */ frame->f_stackadj += exframesize[ft]; frame->f_format = frame->f_vector = 0;#ifdef DEBUG if (sigdebug & SDB_FOLLOW) printf("sendsig(%d): copy out %d of frame %d\n", p->p_pid, exframesize[ft], ft);#endif }#ifdef FPCOPROC kfp->sf_state.ss_flags |= SS_FPSTATE; m68881_save(&kfp->sf_state.ss_fpstate);#ifdef DEBUG if ((sigdebug & SDB_FPSTATE) && *(char *)&kfp->sf_state.ss_fpstate) printf("sendsig(%d): copy out FP state (%x) to %x\n", p->p_pid, *(u_int *)&kfp->sf_state.ss_fpstate, &kfp->sf_state.ss_fpstate);#endif#endif /* * Build the signal context to be used by sigreturn. */ kfp->sf_sc.sc_onstack = oonstack; kfp->sf_sc.sc_mask = mask; kfp->sf_sc.sc_sp = frame->f_regs[SP]; kfp->sf_sc.sc_fp = frame->f_regs[A6]; kfp->sf_sc.sc_ap = (int)&fp->sf_state; kfp->sf_sc.sc_pc = frame->f_pc; kfp->sf_sc.sc_ps = frame->f_sr;#ifdef HPUXCOMPAT /* * Create an HP-UX style sigcontext structure and associated goo */ if (p->p_md.md_flags & MDP_HPUX) { register struct hpuxsigframe *hkfp; hkfp = (struct hpuxsigframe *)&kfp[1]; hkfp->hsf_signum = bsdtohpuxsig(kfp->sf_signum); hkfp->hsf_code = kfp->sf_code; hkfp->hsf_scp = (struct sigcontext *) &((struct hpuxsigframe *)(&fp[1]))->hsf_sc; hkfp->hsf_sc.hsc_syscall = 0; /* XXX */ hkfp->hsf_sc.hsc_action = 0; /* XXX */ hkfp->hsf_sc.hsc_pad1 = hkfp->hsf_sc.hsc_pad2 = 0; hkfp->hsf_sc.hsc_onstack = kfp->sf_sc.sc_onstack; hkfp->hsf_sc.hsc_mask = kfp->sf_sc.sc_mask; hkfp->hsf_sc.hsc_sp = kfp->sf_sc.sc_sp; hkfp->hsf_sc.hsc_ps = kfp->sf_sc.sc_ps; hkfp->hsf_sc.hsc_pc = kfp->sf_sc.sc_pc; hkfp->hsf_sc.hsc_pad = 0; hkfp->hsf_sc.hsc_magic = 0xdeadbeef; hkfp->hsf_sc.hsc_realsc = kfp->sf_scp; bcopy((caddr_t)frame->f_regs, (caddr_t)hkfp->hsf_regs, sizeof (hkfp->hsf_regs)); kfp->sf_signum = hkfp->hsf_signum; kfp->sf_scp = hkfp->hsf_scp; }#endif (void) copyout((caddr_t)kfp, (caddr_t)fp, fsize); frame->f_regs[SP] = (int)fp;#ifdef DEBUG if (sigdebug & SDB_FOLLOW) printf("sendsig(%d): sig %d scp %x fp %x sc_sp %x sc_ap %x\n", p->p_pid, sig, kfp->sf_scp, fp, kfp->sf_sc.sc_sp, kfp->sf_sc.sc_ap);#endif /* * Signal trampoline code is at base of user stack. */ frame->f_pc = (int)PS_STRINGS - (esigcode - sigcode);#ifdef DEBUG if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sendsig(%d): sig %d returns\n", p->p_pid, sig);#endif free((caddr_t)kfp, M_TEMP);}/* * System call to cleanup state after a signal * has been taken. Reset signal mask and * stack state from context left by sendsig (above). * Return to previous pc and psl as specified by * context left by sendsig. Check carefully to * make sure that the user has not modified the * psl to gain improper priviledges or to cause * a machine fault. */struct sigreturn_args { struct sigcontext *sigcntxp;};/* ARGSUSED */sigreturn(p, uap, retval) struct proc *p; struct sigreturn_args *uap; int *retval;{ register struct sigcontext *scp; register struct frame *frame; register int rf; struct sigcontext tsigc; struct sigstate tstate; int flags; scp = uap->sigcntxp;#ifdef DEBUG if (sigdebug & SDB_FOLLOW) printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);#endif if ((int)scp & 1) return (EINVAL);#ifdef HPUXCOMPAT /* * Grab context as an HP-UX style context and determine if it * was one that we contructed in sendsig. */ if (p->p_md.md_flags & MDP_HPUX) { struct hpuxsigcontext *hscp = (struct hpuxsigcontext *)scp; struct hpuxsigcontext htsigc; if (useracc((caddr_t)hscp, sizeof (*hscp), B_WRITE) == 0 || copyin((caddr_t)hscp, (caddr_t)&htsigc, sizeof htsigc)) return (EINVAL); /* * If not generated by sendsig or we cannot restore the * BSD-style sigcontext, just restore what we can -- state * will be lost, but them's the breaks. */ hscp = &htsigc; if (hscp->hsc_magic != 0xdeadbeef || (scp = hscp->hsc_realsc) == 0 || useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 || copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc)) { if (hscp->hsc_onstack & 01) p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK; else p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK; p->p_sigmask = hscp->hsc_mask &~ sigcantmask; frame = (struct frame *) p->p_md.md_regs; frame->f_regs[SP] = hscp->hsc_sp; frame->f_pc = hscp->hsc_pc; frame->f_sr = hscp->hsc_ps &~ PSL_USERCLR; return (EJUSTRETURN); } /* * Otherwise, overlay BSD context with possibly modified * HP-UX values. */ tsigc.sc_onstack = hscp->hsc_onstack; tsigc.sc_mask = hscp->hsc_mask; tsigc.sc_sp = hscp->hsc_sp; tsigc.sc_ps = hscp->hsc_ps; tsigc.sc_pc = hscp->hsc_pc; } else#endif /* * Test and fetch the context structure. * We grab it all at once for speed. */ if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 || copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc)) return (EINVAL); scp = &tsigc; if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0) return (EINVAL); /* * Restore the user supplied information */ if (scp->sc_onstack & 01) p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK; else p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK; p->p_sigmask = scp->sc_mask &~ sigcantmask; frame = (struct frame *) p->p_md.md_regs; frame->f_regs[SP] = scp->sc_sp; frame->f_regs[A6] = scp->sc_fp; frame->f_pc = scp->sc_pc; frame->f_sr = scp->sc_ps; /* * Grab pointer to hardware state information. * If zero, the user is probably doing a longjmp. */ if ((rf = scp->sc_ap) == 0) return (EJUSTRETURN); /* * See if there is anything to do before we go to the * expense of copying in close to 1/2K of data */ flags = fuword((caddr_t)rf);#ifdef DEBUG if (sigdebug & SDB_FOLLOW) printf("sigreturn(%d): sc_ap %x flags %x\n", p->p_pid, rf, flags);#endif /* * fuword failed (bogus sc_ap value). */ if (flags == -1) return (EINVAL); if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate)) return (EJUSTRETURN);#ifdef DEBUG if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sigreturn(%d): ssp %x usp %x scp %x ft %d\n", p->p_pid, &flags, scp->sc_sp, uap->sigcntxp, (flags&SS_RTEFRAME) ? tstate.ss_frame.f_format : -1);#endif /* * Restore most of the users registers except for A6 and SP * which were handled above. */ if (flags & SS_USERREGS) bcopy((caddr_t)tstate.ss_frame.f_regs, (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW); /* * Restore long stack frames. Note that we do not copy * back the saved SR or PC, they were picked up above from * the sigcontext structure. */ if (flags & SS_RTEFRAME) { register int sz; /* grab frame type and validate */ sz = tstate.ss_frame.f_format; if (sz > 15 || (sz = exframesize[sz]) < 0) return (EINVAL); frame->f_stackadj -= sz; frame->f_format = tstate.ss_frame.f_format; frame->f_vector = tstate.ss_frame.f_vector; bcopy((caddr_t)&tstate.ss_frame.F_u, (caddr_t)&frame->F_u, sz);#ifdef DEBUG if (sigdebug & SDB_FOLLOW) printf("sigreturn(%d): copy in %d of frame type %d\n", p->p_pid, sz, tstate.ss_frame.f_format);#endif }#ifdef FPCOPROC /* * Finally we restore the original FP context */ if (flags & SS_FPSTATE) m68881_restore(&tstate.ss_fpstate);#ifdef DEBUG if ((sigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate) printf("sigreturn(%d): copied in FP state (%x) at %x\n", p->p_pid, *(u_int *)&tstate.ss_fpstate, &tstate.ss_fpstate);#endif#endif#ifdef DEBUG if ((sigdebug & SDB_FOLLOW) || ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)) printf("sigreturn(%d): returns\n", p->p_pid);#endif return (EJUSTRETURN);}int waittime = -1;boot(howto) register int howto;{ /* take a snap shot before clobbering any registers */ if (curproc && curproc->p_addr) savectx(curproc->p_addr, 0); boothowto = howto; if ((howto&RB_NOSYNC) == 0 && waittime < 0) { register struct buf *bp; int iter, nbusy; waittime = 0; (void) spl0(); printf("syncing disks... "); /* * Release vnodes held by texts before sync. */ if (panicstr == 0) vnode_pager_umount(NULL);#ifdef notdef#include "vn.h"#if NVN > 0 vnshutdown();#endif#endif sync(&proc0, (void *)NULL, (int *)NULL); for (iter = 0; iter < 20; iter++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -