Exemple #1
0
/*
 * add an address to s's zseg; s is qlocked.
 * wakeup any reader if it's waiting.
 */
int
zputaddr(Segment *s, uintptr_t va)
{
	Zseg *zs;

	zs = &s->zseg;
	if((s->type&SG_ZIO) == 0)
		return -1;
	if((s->type&SG_KZIO) != 0){
		DBG("zputaddr: zmapfree %#ullx\n", va);
		zmapfree(s->zseg.map, va);
		dumpzseg(s);
		return 0;
	}
	if(zs->end == zs->naddr)
		zgrow(s);
	zs->addr[zs->end++] = va;
	if(zs->end == 1)
		wakeup(&zs->rr);	/* in case anyone was waiting */
	DBG("zputaddr %#ullx\n", va);
	dumpzseg(s);
	return 0;
}
Exemple #2
0
/*
 * Find an address in s's zseg; s is qlocked
 */
uintptr_t
zgetaddr(Segment *s)
{
	Zseg *zs;
	uintptr_t va;

	zs = &s->zseg;
	if(zs->end == 0)
		return 0ULL;
	va = zs->addr[0];
	zs->end--;
	if(zs->end > 0)
		zs->addr[0] = zs->addr[zs->end];
	DBG("zgetaddr: %#ullx\n", va);
	dumpzseg(s);
	return va;
}
Exemple #3
0
/*
 * Called from putseg, when the segment is being destroyed.
 */
void
freezseg(Segment *s)
{
	Zseg *zs;
	ZMap *zp;
	Map *mp;

	DBG("freezseg: ");
	dumpzseg(s);
	zs = &s->zseg;
	zp = zs->map;
	if(zp == nil)
		return;
	while(zp->map != nil){
		mp = zp->map;
		zp->map = mp->next;
		free(mp);
	}
	free(zp);
}
Exemple #4
0
static long
segmentwrite(Chan *c, void *a, long n, vlong voff)
{
	Cmdbuf *cb;
	Globalseg *g;
	uintptr va, len, top;
	int i;
	struct{
		char *name;
		int type;
	}segs[] = {
		{"kmsg", SG_SHARED|SG_ZIO|SG_KZIO},
		{"umsg", SG_SHARED|SG_ZIO},
		{"addr", SG_SHARED},
	};

	if(c->qid.type == QTDIR)
		error(Eperm);

	switch(TYPE(c)){
	case Qfree:
		error(Eperm);
		break;
	case Qctl:
		g = c->aux;
		cb = parsecmd(a, n);
		for(i = 0; i < nelem(segs); i++)
			if(strcmp(cb->f[0], segs[i].name) == 0)
				break;
		if(i < nelem(segs)){
			if(g->s != nil)
				error("already has a virtual address");
			if(cb->nf < 3)
				cmderror(cb, Ebadarg);
			va = strtoul(cb->f[1], 0, 0);
			len = strtoul(cb->f[2], 0, 0);
			if(va == 0)
				va = placeseg(len);
			top = BIGPGROUND(va + len);
			va = va&~(BIGPGSZ-1);
			len = (top - va) / BIGPGSZ;
			if(len == 0)
				cmderror(cb, "empty segment");

			g->s = newseg(segs[i].type, va, len);
			if(i == 0)
				newzmap(g->s);
			else if(i == 1)
				zgrow(g->s);
			DBG("newseg %s base %#ullx len %#ullx\n",
				cb->f[0], va, len*BIGPGSZ);
			if(i == 0 || i == 1)
				dumpzseg(g->s);
		}else if(strcmp(cb->f[0], "heap") == 0){
			if(g == nil)
				error("no globalseg");
			if(g->s == nil)
				error("no segment");
			if(heapseg)
				error("heap already set");
			else
				heapseg = g->s;
		}else
			error(Ebadctl);
		break;
	case Qdata:
		g = c->aux;
		if(voff < 0)
			error(Enegoff);
		if(voff + n > g->s->top - g->s->base){
			n = g->s->top - voff;
			if(n <= 0)
				break;
		}
		qlock(&g->l);
		if(waserror()){
			qunlock(&g->l);
			nexterror();
		}

		g->off = voff + g->s->base;
		g->data = smalloc(n);
		if(waserror()){
			free(g->data);
			nexterror();
		}
		g->dlen = n;
		memmove(g->data, a, g->dlen);
		docmd(g, Cwrite);
		poperror();
		free(g->data);

		poperror();
		qunlock(&g->l);
		break;
	default:
		panic("segmentwrite");
	}
	return n;
}