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

📄 sem.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	dev = ht_lookup(devbasetab, intern(buf));	if (dev == NULL || dev->d_major == NODEV) {		error("%s: can't make %s device from `%s'",		    name, what, nv->nv_str);		return (1);	}	nv->nv_name = dev->d_name;	nv->nv_int = makedev(dev->d_major, unit * 16 + part);	return (0);}static intlresolve(nvp, name, what, dflt, part)	register struct nvlist **nvp;	const char *name, *what;	struct nvlist *dflt;	int part;{	int err;	while ((err = resolve(nvp, name, what, dflt, part)) == 0 &&	    (*nvp)->nv_next != NULL)		nvp = &(*nvp)->nv_next;	return (err);}/* * Add a completed configuration to the list. */voidaddconf(cf0)	register struct config *cf0;{	register struct config *cf;	register struct nvlist *nv;	const char *name;	name = cf0->cf_name;	cf = emalloc(sizeof *cf);	if (ht_insert(cfhashtab, name, cf)) {		error("configuration `%s' already defined", name);		free(cf);		goto bad;	}	*cf = *cf0;	*nextcf = cf;	nextcf = &cf->cf_next;	return;bad:	nvfreel(cf0->cf_root);	nvfreel(cf0->cf_swap);	nvfreel(cf0->cf_dump);}voidsetconf(npp, what, v)	register struct nvlist **npp;	const char *what;	struct nvlist *v;{	if (*npp != NULL) {		error("duplicate %s specification", what);		nvfreel(v);	} else		*npp = v;}static struct devi *newdevi(name, unit, d)	const char *name;	int unit;	struct devbase *d;{	register struct devi *i;	i = emalloc(sizeof *i);	i->i_name = name;	i->i_unit = unit;	i->i_base = d;	i->i_next = NULL;	i->i_bsame = NULL;	i->i_asame = NULL;	i->i_alias = NULL;	i->i_at = NULL;	i->i_atattr = NULL;	i->i_atdev = NULL;	i->i_atdeva = NULL;	i->i_locs = NULL;	i->i_cfflags = 0;	i->i_cfindex = -1;	i->i_lineno = currentline();	if (unit >= d->d_umax)		d->d_umax = unit + 1;	return (i);}/* * Enable an already declared but disabled device. */voidenabledev(name, at)	const char *name, *at;{	struct devbase *ib, *ab;	char atbuf[NAMESIZE];	struct attr *attr;	struct nvlist *nv;	struct devi *i;	const char *cp;	int atunit;	i = ht_lookup(devitab, name);	if (i == NULL) {		error("invalid device `%s'", name);		return;	}	ib = i->i_base;	if (split(at, strlen(at), atbuf, sizeof atbuf, &atunit)) {		error("invalid attachment name `%s'", at);		return;	}	cp = intern(atbuf);	ab = ht_lookup(devbasetab, cp);	if (ab == NULL) {		error("invalid attachment device `%s'", cp);		return;	}	for (nv = ab->d_attrs; nv != NULL; nv = nv->nv_next) {		attr = nv->nv_ptr;		if (onlist(attr->a_devs, ib))			goto foundattachment;	}	error("%s's cannot attach to %s's", ib->d_name, atbuf);	return;foundattachment:	while (i && i->i_atdev != ab)		i = i->i_alias;	if (i == NULL) {		error("%s at %s not found", name, at);		return;	} else		i->i_disable = 0; /* Enable */}/* * Add the named device as attaching to the named attribute (or perhaps * another device instead) plus unit number. */voidadddev(name, at, loclist, flags, disable)	const char *name, *at;	struct nvlist *loclist;	int flags, disable;{	register struct devi *i;	/* the new instance */	register struct attr *attr;	/* attribute that allows attach */	register struct devbase *ib;	/* i->i_base */	register struct devbase *ab;	/* not NULL => at another dev */	register struct nvlist *nv;	register struct deva *iba;	/* devbase attachment used */	const char *cp;	int atunit;	char atbuf[NAMESIZE];	int hit;	ab = NULL;	iba = NULL;	if (at == NULL) {		/* "at root" */		if ((i = getdevi(name)) == NULL)			goto bad;		/*		 * Must warn about i_unit > 0 later, after taking care of		 * the STAR cases (we could do non-star's here but why		 * bother?).  Make sure this device can be at root.		 */		ib = i->i_base;		hit = 0;		for (iba = ib->d_ahead; iba != NULL; iba = iba->d_bsame)			if (onlist(iba->d_atlist, NULL)) {				hit = 1;				break;			}		if (!hit) {			error("%s's cannot attach to the root", ib->d_name);			goto bad;		}		attr = &errattr;	/* a convenient "empty" attr */	} else {		if (split(at, strlen(at), atbuf, sizeof atbuf, &atunit)) {			error("invalid attachment name `%s'", at);			/* (void)getdevi(name); -- ??? */			goto bad;		}		if ((i = getdevi(name)) == NULL)			goto bad;		ib = i->i_base;		cp = intern(atbuf);		/*		 * Devices can attach to two types of things: Attributes,		 * and other devices (which have the appropriate attributes		 * to allow attachment).		 *		 * (1) If we're attached to an attribute, then we don't need		 *     look at the parent base device to see what attributes		 *     it has, and make sure that we can attach to them.    		 *		 * (2) If we're attached to a real device (i.e. named in		 *     the config file), we want to remember that so that		 *     at cross-check time, if the device we're attached to		 *     is missing but other devices which also provide the		 *     attribute are present, we don't get a false "OK."		 *		 * (3) If the thing we're attached to is an attribute		 *     but is actually named in the config file, we still		 *     have to remember its devbase.		 */		/* Figure out parent's devbase, to satisfy case (3). */		ab = ht_lookup(devbasetab, cp);		/* Find out if it's an attribute. */		attr = ht_lookup(attrtab, cp);		/* Make sure we're _really_ attached to the attr.  Case (1). */		if (attr != NULL && onlist(attr->a_devs, ib))			goto findattachment;		/*		 * Else a real device, and not just an attribute.  Case (2).		 *		 * Have to work a bit harder to see whether we have		 * something like "tg0 at esp0" (where esp is merely		 * not an attribute) or "tg0 at nonesuch0" (where		 * nonesuch is not even a device).		 */		if (ab == NULL) {			error("%s at %s: `%s' unknown",			    name, at, atbuf);			goto bad;		}		/*		 * See if the named parent carries an attribute		 * that allows it to supervise device ib.		 */		for (nv = ab->d_attrs; nv != NULL; nv = nv->nv_next) {			attr = nv->nv_ptr;			if (onlist(attr->a_devs, ib))				goto findattachment;		}		error("%s's cannot attach to %s's", ib->d_name, atbuf);		goto bad;findattachment:		/* find out which attachment it uses */		hit = 0;		for (iba = ib->d_ahead; iba != NULL; iba = iba->d_bsame)			if (onlist(iba->d_atlist, attr)) {				hit = 1;				break;			}		if (!hit)			panic("adddev: can't figure out attachment");	}	if ((i->i_locs = fixloc(name, attr, loclist)) == NULL)		goto bad;	i->i_at = at;	i->i_atattr = attr;	i->i_atdev = ab;	i->i_atdeva = iba;	i->i_atunit = atunit;	i->i_cfflags = flags;	i->i_disable = disable;	*iba->d_ipp = i;	iba->d_ipp = &i->i_asame;	selectbase(ib, iba);	/* all done, fall into ... */bad:	nvfreel(loclist);	return;}voidaddpseudo(name, number)	const char *name;	int number;{	register struct devbase *d;	register struct devi *i;	d = ht_lookup(devbasetab, name);	if (d == NULL) {		error("undefined pseudo-device %s", name);		return;	}	if (!d->d_ispseudo) {		error("%s is a real device, not a pseudo-device", name);		return;	}	if (ht_lookup(devitab, name) != NULL) {		fprintf(stderr, "warning: duplicate definition of `%s', will use latest definition", name);		d->d_umax = number;		return;	}	i = newdevi(name, number - 1, d);	/* foo 16 => "foo0..foo15" */	if (ht_insert(devitab, name, i))		panic("addpseudo(%s)", name);	selectbase(d, NULL);	*nextpseudo = i;	nextpseudo = &i->i_next;	npseudo++;}/* * Define a new instance of a specific device. */static struct devi *getdevi(name)	const char *name;{	register struct devi *i, *firsti;	register struct devbase *d;	int unit;	char base[NAMESIZE];	if (split(name, strlen(name), base, sizeof base, &unit)) {		error("invalid device name `%s'", name);		return (NULL);	}	d = ht_lookup(devbasetab, intern(base));	if (d == NULL) {		error("%s: unknown device `%s'", name, base);		return (NULL);	}	if (d->d_ispseudo) {		error("%s: %s is a pseudo-device", name, base);		return (NULL);	}	firsti = ht_lookup(devitab, name);	i = newdevi(name, unit, d);	if (firsti == NULL) {		if (ht_insert(devitab, name, i))			panic("getdevi(%s)", name);		*d->d_ipp = i;		d->d_ipp = &i->i_bsame;	} else {		while (firsti->i_alias)			firsti = firsti->i_alias;		firsti->i_alias = i;	}	*nextdevi = i;	nextdevi = &i->i_next;	ndevi++;	return (i);}static const char *concat(name, c)	const char *name;	int c;{	size_t len;	char buf[NAMESIZE];	len = strlen(name);	if (len + 2 > sizeof(buf)) {		error("device name `%s%c' too long", name, c);		len = sizeof(buf) - 2;	}	bcopy(name, buf, len);	buf[len] = c;	buf[len + 1] = 0;	return (intern(buf));}const char *starref(name)	const char *name;{	return (concat(name, '*'));}const char *wildref(name)	const char *name;{	return (concat(name, '?'));}/* * Split a name like "foo0" into base name (foo) and unit number (0). * Return 0 on success.  To make this useful for names like "foo0a", * the length of the "foo0" part is one of the arguments. */static intsplit(name, nlen, base, bsize, aunit)	register const char *name;	size_t nlen;	char *base;	size_t bsize;	int *aunit;{	register const char *cp;	register int c;	size_t l;	l = nlen;	if (l < 2 || l >= bsize || isdigit(*name))		return (1);	c = (u_char)name[--l];	if (!isdigit(c)) {		if (c == '*')			*aunit = STAR;		else if (c == '?')			*aunit = WILD;		else			return (1);	} else {		cp = &name[l];		while (isdigit(cp[-1]))			l--, cp--;		*aunit = atoi(cp);	}	bcopy(name, base, l);	base[l] = 0;	return (0);}/* * We have an instance of the base foo, so select it and all its * attributes for "optional foo". */static voidselectbase(d, da)	register struct devbase *d;	register struct deva *da;{	register struct attr *a;	register struct nvlist *nv;	(void)ht_insert(selecttab, d->d_name, (char *)d->d_name);	for (nv = d->d_attrs; nv != NULL; nv = nv->nv_next) {		a = nv->nv_ptr;		(void)ht_insert(selecttab, a->a_name, (char *)a->a_name);	}	if (da != NULL) {		(void)ht_insert(selecttab, da->d_name, (char *)da->d_name);		for (nv = da->d_attrs; nv != NULL; nv = nv->nv_next) {			a = nv->nv_ptr;			(void)ht_insert(selecttab, a->a_name,			    (char *)a->a_name);		}	}}/* * Is the given pointer on the given list of pointers? */static intonlist(nv, ptr)	register struct nvlist *nv;	register void *ptr;{	for (; nv != NULL; nv = nv->nv_next)		if (nv->nv_ptr == ptr)			return (1);	return (0);}static char *extend(p, name)	register char *p;	const char *name;{	register int l;	l = strlen(name);	bcopy(name, p, l);	p += l;	*p++ = ',';	*p++ = ' ';	return (p);}/* * Check that we got all required locators, and default any that are * given as "?" and have defaults.  Return 0 on success. */static const char **fixloc(name, attr, got)	const char *name;	register struct attr *attr;	register struct nvlist *got;{	register struct nvlist *m, *n;	register int ord;	register const char **lp;	int nmissing, nextra, nnodefault;	char *mp, *ep, *ndp;	char missing[1000], extra[1000], nodefault[1000];	static const char *nullvec[1];	/*	 * Look for all required locators, and number the given ones	 * according to the required order.  While we are numbering,	 * set default values for defaulted locators.	 */	if (attr->a_loclen == 0)	/* e.g., "at root" */		lp = nullvec;	else		lp = emalloc((attr->a_loclen + 1) * sizeof(const char *));	for (n = got; n != NULL; n = n->nv_next)		n->nv_int = -1;	nmissing = 0;	mp = missing;	/* yes, this is O(mn), but m and n should be small */	for (ord = 0, m = attr->a_locs; m != NULL; m = m->nv_next, ord++) {		for (n = got; n != NULL; n = n->nv_next) {			if (n->nv_name == m->nv_name) {				n->nv_int = ord;				break;			}		}		if (n == NULL && m->nv_int == 0) {			nmissing++;			mp = extend(mp, m->nv_name);		}		lp[ord] = m->nv_str;	}	if (ord != attr->a_loclen)		panic("fixloc");	lp[ord] = NULL;	nextra = 0;	ep = extra;	nnodefault = 0;	ndp = nodefault;	for (n = got; n != NULL; n = n->nv_next) {		if (n->nv_int >= 0) {			if (n->nv_str != NULL)				lp[n->nv_int] = n->nv_str;			else if (lp[n->nv_int] == NULL) {				nnodefault++;				ndp = extend(ndp, n->nv_name);			}		} else {			nextra++;			ep = extend(ep, n->nv_name);		}	}	if (nextra) {		ep[-2] = 0;	/* kill ", " */		error("%s: extraneous locator%s: %s",		    name, nextra > 1 ? "s" : "", extra);	}	if (nmissing) {		mp[-2] = 0;		error("%s: must specify %s", name, missing);	}	if (nnodefault) {		ndp[-2] = 0;		error("%s: cannot wildcard %s", name, nodefault);	}	if (nmissing || nnodefault) {		free(lp);		lp = NULL;	}	return (lp);}

⌨️ 快捷键说明

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