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

📄 machdep.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * call to grow() is a nop, and the copyout()	 * will fail if the process has not already allocated	 * the space with a `brk'.	 */	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 *)(regs[SP] - fsize);	if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize)) 		(void)grow(p, (unsigned)fp);#ifdef DEBUG	if ((sigdebug & SDB_FOLLOW) ||	    (sigdebug & SDB_KSTACK) && p->p_pid == sigpid)		printf("sendsig(%d): sig %d ssp %x usp %x scp %x\n",		       p->p_pid, sig, &oonstack, fp, &fp->sf_sc);#endif	/*	 * Build the signal context to be used by sigreturn.	 */	ksc.sc_onstack = oonstack;	ksc.sc_mask = mask;	ksc.sc_pc = regs[PC];	ksc.sc_regs[ZERO] = 0xACEDBADE;		/* magic number */	bcopy((caddr_t)&regs[1], (caddr_t)&ksc.sc_regs[1],		sizeof(ksc.sc_regs) - sizeof(int));	ksc.sc_fpused = p->p_md.md_flags & MDP_FPUSED;	if (ksc.sc_fpused) {		extern struct proc *machFPCurProcPtr;		/* if FPU has current state, save it first */		if (p == machFPCurProcPtr)			MachSaveCurFPState(p);		bcopy((caddr_t)&p->p_md.md_regs[F0], (caddr_t)ksc.sc_fpregs,			sizeof(ksc.sc_fpregs));	}	if (copyout((caddr_t)&ksc, (caddr_t)&fp->sf_sc, sizeof(ksc))) {		/*		 * 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;	}	/* 	 * Build the argument list for the signal handler.	 */	regs[A0] = sig;	regs[A1] = code;	regs[A2] = (int)&fp->sf_sc;	regs[A3] = (int)catcher;	regs[PC] = (int)catcher;	regs[SP] = (int)fp;	/*	 * Signal trampoline code is at base of user stack.	 */	regs[RA] = (int)PS_STRINGS - (esigcode - sigcode);#ifdef DEBUG	if ((sigdebug & SDB_FOLLOW) ||	    (sigdebug & SDB_KSTACK) && p->p_pid == sigpid)		printf("sendsig(%d): sig %d returns\n",		       p->p_pid, sig);#endif}/* * 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 int *regs;	struct sigcontext ksc;	int error;	scp = uap->sigcntxp;#ifdef DEBUG	if (sigdebug & SDB_FOLLOW)		printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);#endif	regs = p->p_md.md_regs;	/*	 * Test and fetch the context structure.	 * We grab it all at once for speed.	 */	error = copyin((caddr_t)scp, (caddr_t)&ksc, sizeof(ksc));	if (error || ksc.sc_regs[ZERO] != 0xACEDBADE) {#ifdef DEBUG		if (!(sigdebug & SDB_FOLLOW))			printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);		printf("  old sp %x ra %x pc %x\n",			regs[SP], regs[RA], regs[PC]);		printf("  new sp %x ra %x pc %x err %d z %x\n",			ksc.sc_regs[SP], ksc.sc_regs[RA], ksc.sc_regs[PC],			error, ksc.sc_regs[ZERO]);#endif		return (EINVAL);	}	scp = &ksc;	/*	 * 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;	regs[PC] = scp->sc_pc;	bcopy((caddr_t)&scp->sc_regs[1], (caddr_t)&regs[1],		sizeof(scp->sc_regs) - sizeof(int));	if (scp->sc_fpused)		bcopy((caddr_t)scp->sc_fpregs, (caddr_t)&p->p_md.md_regs[F0],			sizeof(scp->sc_fpregs));	return (EJUSTRETURN);}int	waittime = -1;boot(howto)	register int howto;{	/* take a snap shot before clobbering any registers */	if (curproc)		savectx(curproc->p_addr, 0);#ifdef DEBUG	if (panicstr)		traceback();#endif	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 notyet#include "fd.h"#if NFD > 0		fdshutdown();#endif#endif		sync(&proc0, (void *)NULL, (int *)NULL);		for (iter = 0; iter < 20; iter++) {			nbusy = 0;			for (bp = &buf[nbuf]; --bp >= buf; )				if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY)					nbusy++;			if (nbusy == 0)				break;			printf("%d ", nbusy);			DELAY(40000 * iter);		}		if (nbusy)			printf("giving up\n");		else			printf("done\n");		/*		 * If we've been adjusting the clock, the todr		 * will be out of synch; adjust it now.		 */		resettodr();	}	(void) splhigh();		/* extreme priority */	if (howto & RB_HALT) {		halt(howto);		/*NOTREACHED*/	} else {		if (howto & RB_DUMP)			dumpsys();		halt(howto);		/*NOTREACHED*/	}	/*NOTREACHED*/}halt(howto)	int howto;{	if (*(volatile u_char *)DIP_SWITCH & 0x20)		howto |= RB_HALT;	to_monitor(howto);	/*NOTREACHED*/}int	dumpmag = 0x8fca0101;	/* magic number for savecore */int	dumpsize = 0;		/* also for savecore */long	dumplo = 0;dumpconf(){	int nblks;	dumpsize = physmem;	if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) {		nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);		if (dumpsize > btoc(dbtob(nblks - dumplo)))			dumpsize = btoc(dbtob(nblks - dumplo));		else if (dumplo == 0)			dumplo = nblks - btodb(ctob(physmem));	}	/*	 * Don't dump on the first CLBYTES (why CLBYTES?)	 * in case the dump device includes a disk label.	 */	if (dumplo < btodb(CLBYTES))		dumplo = btodb(CLBYTES);}/* * Doadump comes here after turning off memory management and * getting on the dump stack, either when called above, or by * the auto-restart code. */dumpsys(){	int error;	msgbufmapped = 0;	if (dumpdev == NODEV)		return;	/*	 * For dumps during autoconfiguration,	 * if dump device has already configured...	 */	if (dumpsize == 0)		dumpconf();	if (dumplo < 0)		return;	printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);	printf("dump ");	switch (error = (*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {	case ENXIO:		printf("device bad\n");		break;	case EFAULT:		printf("device not ready\n");		break;	case EINVAL:		printf("area improper\n");		break;	case EIO:		printf("i/o error\n");		break;	default:		printf("error %d\n", error);		break;	case 0:		printf("succeeded\n");	}}/* * 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;{	extern dev_t consdev;	/* 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, &consdev,		    sizeof consdev));	default:		return (EOPNOTSUPP);	}	/* NOTREACHED */}/* * Return the best possible estimate of the time in the timeval * to which tvp points.  Unfortunately, we can't read the hardware registers. * We guarantee that the time will be greater than the value obtained by a * previous call. */microtime(tvp)	register struct timeval *tvp;{	int s = splclock();	static struct timeval lasttime;	*tvp = time;#ifdef notdef	tvp->tv_usec += clkread();	while (tvp->tv_usec > 1000000) {		tvp->tv_sec++;		tvp->tv_usec -= 1000000;	}#endif	if (tvp->tv_sec == lasttime.tv_sec &&	    tvp->tv_usec <= lasttime.tv_usec &&	    (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) {		tvp->tv_sec++;		tvp->tv_usec -= 1000000;	}	lasttime = *tvp;	splx(s);}initcpu(){	/*	 * clear LEDs	 */	*(char*)DEBUG_PORT = (char)DP_WRITE|DP_LED0|DP_LED1|DP_LED2|DP_LED3;	/*	 * clear all interrupts	 */	*(char*)INTCLR0 = 0;	*(char*)INTCLR1 = 0;	/*	 * It's not a time to enable timer yet.	 *	 *	INTEN0:  PERR ABORT BERR TIMER KBD  MS    CFLT CBSY	 *		  o     o    o     x    o    o     x    x	 *	INTEN1:  BEEP SCC  LANCE DMA  SLOT1 SLOT3 EXT1 EXT3	 *		  x     o    o     o    o    o     x    x	 */	*(char*)INTEN0 = (char) INTEN0_PERR|INTEN0_ABORT|INTEN0_BERR|				INTEN0_KBDINT|INTEN0_MSINT;	*(char*)INTEN1 = (char) INTEN1_SCC|INTEN1_LANCE|INTEN1_DMA|				INTEN1_SLOT1|INTEN1_SLOT3;	spl0();		/* safe to turn interrupts on now */}/* * Convert an ASCII string into an integer. */intatoi(s)	char *s;{	int c;	unsigned base = 10, d;	int neg = 0, val = 0;	if (s == 0 || (c = *s++) == 0)		goto out;	/* skip spaces if any */	while (c == ' ' || c == '\t')		c = *s++;	/* parse sign, allow more than one (compat) */	while (c == '-') {		neg = !neg;		c = *s++;	}	/* parse base specification, if any */	if (c == '0') {		c = *s++;		switch (c) {		case 'X':		case 'x':			base = 16;			break;		case 'B':		case 'b':			base = 2;			break;		default:			base = 8;			break;		}	}	/* parse number proper */	for (;;) {		if (c >= '0' && c <= '9')			d = c - '0';		else if (c >= 'a' && c <= 'z')			d = c - 'a' + 10;		else if (c >= 'A' && c <= 'Z')			d = c - 'A' + 10;		else			break;		val *= base;		val += d;		c = *s++;	}	if (neg)		val = -val;out:	return val;	}#ifdef CPU_SINGLE/* * small ring buffers for keyboard/mouse */struct ring_buf {	u_char head;	u_char tail;	u_char count;	u_char buf[13];} ring_buf[2];xputc(c, chan)	u_char c;	int chan;{	register struct ring_buf *p = &ring_buf[chan];	int s = splhigh();	if (p->count >= sizeof (p->buf)) {		(void) splx(s);		return (-1);	}	p->buf[p->head] = c;	if (++p->head >= sizeof (p->buf))		p->head = 0;	p->count++;	(void) splx(s);	return (c);}xgetc(chan)	int chan;{	register struct ring_buf *p = &ring_buf[chan];	int c;	int s = splhigh();	if (p->count == 0) {		(void) splx(s);		return (-1);	}	c = p->buf[p->tail];	if (++p->tail >= sizeof (p->buf))		p->tail = 0;	p->count--;	(void) splx(s);	return (c);}#endif /* CPU_SINGLE */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -