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

📄 machdep.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
		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)		stacktrace();#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 notdef#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 (callv != &callvec) {		if (howto & RB_HALT)			(*callv->rex)('h');		else {			if (howto & RB_DUMP)				dumpsys();			(*callv->rex)('b');		}	} else if (howto & RB_HALT) {		volatile void (*f)() = (volatile void (*)())DEC_PROM_REINIT;		(*f)();	/* jump back to prom monitor */	} else {		volatile void (*f)() = (volatile void (*)())DEC_PROM_AUTOBOOT;		if (howto & RB_DUMP)			dumpsys();		(*f)();	/* jump back to prom monitor and do 'auto' cmd */	}	/*NOTREACHED*/}int	dumpmag = (int)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");	}}/* * 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(){	register volatile struct chiptime *c;	int i;	/* disable clock interrupts (until startrtclock()) */	c = Mach_clock_addr;	c->regb = REGB_DATA_MODE | REGB_HOURS_FORMAT;	i = c->regc;	spl0();		/* safe to turn interrupts on now */	return (i);}/* * 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;		}	}	/* 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;	}/* * Fill in the pmax addresses by hand. */static struct pmax_address {	char	*pmax_name;	char	*pmax_addr;	int	pmax_pri;} pmax_addresses[] = {	{ "pm",	(char *)MACH_PHYS_TO_CACHED(KN01_PHYS_FBUF_START),	3 },	{ "dc",	(char *)MACH_PHYS_TO_UNCACHED(KN01_SYS_DZ),		2 },	{ "le",	(char *)MACH_PHYS_TO_UNCACHED(KN01_SYS_LANCE),		1 },	{ "sii",(char *)MACH_PHYS_TO_UNCACHED(KN01_SYS_SII),		0 },	{ (char *)0, },};voidpmax_slot_hand_fill(){	register struct pmax_ctlr *cp;	register struct driver *drp;	register struct pmax_address *pmap;	/*	 * Find the device driver entry and fill in the address.	 */	for (cp = pmax_cinit; drp = cp->pmax_driver; cp++) {		for (pmap = pmax_addresses; pmap->pmax_name; pmap++) {			if (strcmp(drp->d_name, pmap->pmax_name))				continue;			if (cp->pmax_addr == (char *)QUES) {				cp->pmax_addr = pmap->pmax_addr;				cp->pmax_pri = pmap->pmax_pri;				continue;			}		}	}}#ifdef DS5000/*  * Mach Operating System * Copyright (c) 1991,1990,1989 Carnegie Mellon University * All Rights Reserved. *  * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. *  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. *  * Carnegie Mellon requests users of this software to return to *  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU *  School of Computer Science *  Carnegie Mellon University *  Pittsburgh PA 15213-3890 *  * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. *//* * Driver map: associates a device driver to an option type. * Drivers name are (arbitrarily) defined in each driver and * used in the various config tables. */struct drivers_map {	char	module_name[TC_ROM_LLEN];	/* from ROM, literally! */	char	*driver_name;			/* in bus_??_init[] tables */} tc_drivers_map[] = {	{ "KN02    ",	"dc"},		/* (*) 3max system board (with DC) */	{ "PMAD-AA ",	"le"},		/* Ether */	{ "PMAZ-AA ",	"asc"},		/* SCSI */	{ "PMAG-AA ",	"mfb"},		/* Mono Frame Buffer */	{ "PMAG-BA ",	"cfb"},		/* Color Frame Buffer */	{ "PMAG-CA ",	"ga"},		/* 2D graphic board */	{ "PMAG-DA ",	"gq"},		/* 3D graphic board (LM) */	{ "PMAG-FA ",	"gq"},		/* 3D graphic board (HE) */	{ "PMAG-DV ",	"xcfb"},	/* (*) maxine Color Frame Buffer */	{ "Z8530   ",	"scc"},		/* (*) 3min/maxine serial lines */	{ "ASIC    ",	"asic"},	/* (*) 3min/maxine DMA controller */	{ "XINE-FDC",	"fdc"},		/* (*) maxine floppy controller */	{ "DTOP    ",	"dtop"},	/* (*) maxine desktop bus */	{ "AMD79c30",	"isdn"},	/* (*) maxine ISDN chip */	{ "XINE-FRC",	"frc"},		/* (*) maxine free-running counter */	{ "", 0}			/* list end */};/* * Identify an option on the TC.  Looks at the mandatory * info in the option's ROM and checks it. */#ifdef DEBUGint tc_verbose = 0;#endifstatic inttc_identify_option(addr, slot, complain)	tc_rommap_t	*addr;	tc_option_t	*slot;	int		complain;{	register int	i;	unsigned char   width;	char            firmwr[TC_ROM_LLEN+1], vendor[TC_ROM_LLEN+1],			module[TC_ROM_LLEN+1], host_type[TC_ROM_SLEN+1];	/*	 * We do not really use the 'width' info, but take advantage	 * of the restriction that the spec impose on the portion	 * of the ROM that maps between +0x3e0 and +0x470, which	 * is the only piece we need to look at.	 */	width = addr->rom_width.value;	switch (width) {	case 1:	case 2:	case 4:		break;	default:#ifdef DEBUG		if (tc_verbose && complain)			printf("%s (x%x) at x%x\n", "Invalid ROM width",			       width, addr);#endif		return (0);	}	if (addr->rom_stride.value != 4) {#ifdef DEBUG		if (tc_verbose && complain)			printf("%s (x%x) at x%x\n", "Invalid ROM stride",			       addr->rom_stride.value, addr);#endif		return (0);	}	if ((addr->test_data[0] != 0x55) ||	    (addr->test_data[4] != 0x00) ||	    (addr->test_data[8] != 0xaa) ||	    (addr->test_data[12] != 0xff)) {#ifdef DEBUG		if (tc_verbose && complain)			printf("%s x%x\n", "Test pattern failed, option at",			       addr);#endif		return (0);	}	for (i = 0; i < TC_ROM_LLEN; i++) {		firmwr[i] = addr->firmware_rev[i].value;		vendor[i] = addr->vendor_name[i].value;		module[i] = addr->module_name[i].value;		if (i >= TC_ROM_SLEN)			continue;		host_type[i] = addr->host_firmware_type[i].value;	}	firmwr[TC_ROM_LLEN] = vendor[TC_ROM_LLEN] =	module[TC_ROM_LLEN] = host_type[TC_ROM_SLEN] = '\0';#ifdef DEBUG	if (tc_verbose)		printf("%s %s '%s' at 0x%x\n %s %s %s '%s'\n %s %d %s %d %s\n",		"Found a", vendor, module, addr,		"Firmware rev.", firmwr,		"diagnostics for a", host_type,		"ROM size is", addr->rom_size.value << 3,		"Kbytes, uses", addr->slot_size.value, "TC slot(s)");#endif	bcopy(module, slot->module_name, TC_ROM_LLEN);	bcopy(vendor, slot->module_id, TC_ROM_LLEN);	bcopy(firmwr, &slot->module_id[TC_ROM_LLEN], TC_ROM_LLEN);	slot->slot_size = addr->slot_size.value;	slot->rom_width = width;	return (1);}

⌨️ 快捷键说明

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