⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 machdep.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
#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 + -