Esempio n. 1
0
File: devcons.c Progetto: 8l/inferno
static long
conswrite(Chan *c, void *va, long n, vlong offset)
{
	vlong t;
	long l, bp;
	char *a = va;
	Cmdbuf *cb;
	Cmdtab *ct;
	char buf[256];
	int x;

	switch((ulong)c->qid.path){
	case Qcons:
		/*
		 * Can't page fault in putstrn, so copy the data locally.
		 */
		l = n;
		while(l > 0){
			bp = l;
			if(bp > sizeof buf)
				bp = sizeof buf;
			memmove(buf, a, bp);
			putstrn0(a, bp, 1);
			a += bp;
			l -= bp;
		}
		break;

	case Qconsctl:
		if(n >= sizeof(buf))
			n = sizeof(buf)-1;
		strncpy(buf, a, n);
		buf[n] = 0;
		for(a = buf; a;){
			if(strncmp(a, "rawon", 5) == 0){
				qlock(&kbd);
				flushkbdline(kbdq);
				kbd.raw = 1;
				qunlock(&kbd);
			} else if(strncmp(a, "rawoff", 6) == 0){
				qlock(&kbd);
				kbd.raw = 0;
				kbd.x = 0;
				qunlock(&kbd);
			}
			if(a = strchr(a, ' '))
				a++;
		}
		break;

	case Qkeyboard:
		for(x=0; x<n; ) {
			Rune r;
			x += chartorune(&r, &a[x]);
			kbdputc(kbdq, r);
		}
		break;
	
	case Qtime:
		if(n >= sizeof(buf))
			n = sizeof(buf)-1;
		strncpy(buf, a, n);
		buf[n] = 0;
		t = strtoll(buf, 0, 0)/1000000;
		boottime = t - TK2SEC(MACHP(0)->ticks);
		break;

	case Qhostowner:
		if(!iseve())
			error(Eperm);
		if(offset != 0 || n >= sizeof(buf))
			error(Ebadarg);
		memmove(buf, a, n);
		buf[n] = '\0';
		if(n > 0 && buf[n-1] == '\n')
			buf[--n] = 0;
		if(n <= 0)
			error(Ebadarg);
		renameuser(eve, buf);
		renameproguser(eve, buf);
		kstrdup(&eve, buf);
		kstrdup(&up->env->user, buf);
		break;

	case Quser:
		if(!iseve())
			error(Eperm);
		if(offset != 0)
			error(Ebadarg);
		if(n <= 0 || n >= sizeof(buf))
			error(Ebadarg);
		strncpy(buf, a, n);
		buf[n] = 0;
		if(buf[n-1] == '\n')
			buf[n-1] = 0;
		kstrdup(&up->env->user, buf);
		break;

	case Qjit:
		if(n >= sizeof(buf))
			n = sizeof(buf)-1;
		strncpy(buf, va, n);
		buf[n] = '\0';
		x = atoi(buf);
		if(x < 0 || x > 9)
			error(Ebadarg);
		cflag = x;
		return n;

	case Qnull:
		break;

	case Qsysname:
		if(offset != 0)
			error(Ebadarg);
		if(n <= 0 || n >= sizeof(buf))
			error(Ebadarg);
		strncpy(buf, a, n);
		buf[n] = 0;
		if(buf[n-1] == '\n')
			buf[n-1] = 0;
		kstrdup(&sysname, buf);
		break;

	case Qsysctl:
		if(!iseve())
			error(Eperm);
		cb = parsecmd(a, n);
		if(waserror()){
			free(cb);
			nexterror();
		}
		ct = lookupcmd(cb, sysctlcmd, nelem(sysctlcmd));
		switch(ct->index){
		case CMreboot:
			reboot();
			break;
		case CMhalt:
			halt();
			break;
		case CMpanic:
			panic("sysctl");
		case CMconsole:
			consoleprint = strcmp(cb->f[1], "off") != 0;
			break;
		case CMbroken:
			keepbroken = 1;
			break;
		case CMnobroken:
			keepbroken = 0;
			break;
		}
		poperror();
		free(cb);
		break;

	default:
		print("conswrite: %llud\n", c->qid.path);
		error(Egreg);
	}
	return n;
}
Esempio n. 2
0
static void
vgactl(Cmdbuf *cb)
{
    int align, i, size, x, y, z;
    char *chanstr, *p;
    ulong chan;
    Cmdtab *ct;
    VGAscr *scr;
    extern VGAdev *vgadev[];
    extern VGAcur *vgacur[];

    scr = &vgascreen[0];
    ct = lookupcmd(cb, vgactlmsg, nelem(vgactlmsg));
    switch(ct->index) {
    case CMhwgc:
        if(strcmp(cb->f[1], "off") == 0) {
            lock(&cursor);
            if(scr->cur) {
                if(scr->cur->disable)
                    scr->cur->disable(scr);
                scr->cur = nil;
            }
            unlock(&cursor);
            return;
        }
        if(strcmp(cb->f[1], "soft") == 0) {
            lock(&cursor);
            swcursorinit();
            if(scr->cur && scr->cur->disable)
                scr->cur->disable(scr);
            scr->cur = &swcursor;
            if(scr->cur->enable)
                scr->cur->enable(scr);
            unlock(&cursor);
            return;
        }
        for(i = 0; vgacur[i]; i++) {
            if(strcmp(cb->f[1], vgacur[i]->name))
                continue;
            lock(&cursor);
            if(scr->cur && scr->cur->disable)
                scr->cur->disable(scr);
            scr->cur = vgacur[i];
            if(scr->cur->enable)
                scr->cur->enable(scr);
            unlock(&cursor);
            return;
        }
        break;

    case CMtype:
        for(i = 0; vgadev[i]; i++) {
            if(strcmp(cb->f[1], vgadev[i]->name))
                continue;
            if(scr->dev && scr->dev->disable)
                scr->dev->disable(scr);
            scr->dev = vgadev[i];
            if(scr->dev->enable)
                scr->dev->enable(scr);
            return;
        }
        break;

    case CMtextmode:
        screeninit();
        return;

    case CMsize:

        x = strtoul(cb->f[1], &p, 0);
        if(x == 0 || x > 10240)
            error(Ebadarg);
        if(*p)
            p++;

        y = strtoul(p, &p, 0);
        if(y == 0 || y > 10240)
            error(Ebadarg);
        if(*p)
            p++;

        z = strtoul(p, &p, 0);

        chanstr = cb->f[2];
        if((chan = strtochan(chanstr)) == 0)
            error("bad channel");

        if(chantodepth(chan) != z)
            error("depth, channel do not match");

        cursoroff(1);
        deletescreenimage();
        if(screensize(x, y, z, chan))
            error(Egreg);
        vgascreenwin(scr);
        resetscreenimage();
        cursoron(1);
        return;

    case CMactualsize:
        if(scr->gscreen == nil)
            error("set the screen size first");

        x = strtoul(cb->f[1], &p, 0);
        if(x == 0 || x > 2048)
            error(Ebadarg);
        if(*p)
            p++;

        y = strtoul(p, nil, 0);
        if(y == 0 || y > 2048)
            error(Ebadarg);

        if(x > scr->gscreen->r.max.x || y > scr->gscreen->r.max.y)
            error("physical screen bigger than virtual");

        physgscreenr = Rect(0,0,x,y);
        scr->gscreen->clipr = physgscreenr;
        return;

    case CMpalettedepth:
        x = strtoul(cb->f[1], &p, 0);
        if(x != 8 && x != 6)
            error(Ebadarg);

        scr->palettedepth = x;
        return;

    case CMdrawinit:
        memimagedraw(scr->gscreen, scr->gscreen->r, memblack, ZP, nil, ZP, S);
        if(scr && scr->dev && scr->dev->drawinit)
            scr->dev->drawinit(scr);
        return;

    case CMlinear:
        if(cb->nf!=2 && cb->nf!=3)
            error(Ebadarg);
        size = strtoul(cb->f[1], 0, 0);
        if(cb->nf == 2)
            align = 0;
        else
            align = strtoul(cb->f[2], 0, 0);
        if(screenaperture(size, align) < 0)
            error("not enough free address space");
        return;
    /*
    	case CMmemset:
    		memset((void*)strtoul(cb->f[1], 0, 0), atoi(cb->f[2]), atoi(cb->f[3]));
    		return;
    */

    case CMblank:
        drawblankscreen(1);
        return;

    case CMunblank:
        drawblankscreen(0);
        return;

    case CMblanktime:
        blanktime = strtoul(cb->f[1], 0, 0);
        return;

    case CMpanning:
        if(strcmp(cb->f[1], "on") == 0) {
            if(scr == nil || scr->cur == nil)
                error("set screen first");
            if(!scr->cur->doespanning)
                error("panning not supported");
            scr->gscreen->clipr = scr->gscreen->r;
            panning = 1;
        }
        else if(strcmp(cb->f[1], "off") == 0) {
            scr->gscreen->clipr = physgscreenr;
            panning = 0;
        } else
            break;
        return;

    case CMhwaccel:
        if(strcmp(cb->f[1], "on") == 0)
            hwaccel = 1;
        else if(strcmp(cb->f[1], "off") == 0)
            hwaccel = 0;
        else
            break;
        return;

    case CMhwblank:
        if(strcmp(cb->f[1], "on") == 0)
            hwblank = 1;
        else if(strcmp(cb->f[1], "off") == 0)
            hwblank = 0;
        else
            break;
        return;
    }

    cmderror(cb, "bad VGA control message");
}
Esempio n. 3
0
File: devcmd.c Progetto: 8l/inferno
static long
cmdwrite(Chan *ch, void *a, long n, vlong offset)
{
	int i, r;
	Conv *c;
	Cmdbuf *cb;
	Cmdtab *ct;

	USED(offset);

	switch(TYPE(ch->qid)) {
	default:
		error(Eperm);
	case Qctl:
		c = cmd.conv[CONV(ch->qid)];
		cb = parsecmd(a, n);
		if(waserror()){
			free(cb);
			nexterror();
		}
		ct = lookupcmd(cb, cmdtab, nelem(cmdtab));
		switch(ct->index){
		case CMdir:
			kstrdup(&c->dir, cb->f[1]);
			break;
		case CMexec:
			poperror();	/* cb */
			qlock(&c->l);
			if(waserror()){
				qunlock(&c->l);
				free(cb);
				nexterror();
			}
			if(c->child != nil || c->cmd != nil)
				error(Einuse);
			for(i = 0; i < nelem(c->fd); i++)
				if(c->fd[i] != -1)
					error(Einuse);
			if(cb->nf < 1)
				error(Etoosmall);
			kproc("cmdproc", cmdproc, c, 0);	/* cmdproc held back until unlock below */
			free(c->cmd);
			c->cmd = cb;	/* don't free cb */
			c->state = "Execute";
			poperror();
			qunlock(&c->l);
			while(waserror())
				;
			Sleep(&c->startr, cmdstarted, c);
			poperror();
			if(c->error)
				error(c->error);
			return n;	/* avoid free(cb) below */
		case CMkill:
			qlock(&c->l);
			if(waserror()){
				qunlock(&c->l);
				nexterror();
			}
			if(c->child == nil)
				error("not started");
			if(oscmdkill(c->child) < 0)
				oserror();
			poperror();
			qunlock(&c->l);
			break;
		case CMnice:
			c->nice = cb->nf > 1? atoi(cb->f[1]): 1;
			break;
		case CMkillonclose:
			c->killonclose = 1;
			break;
		}
		poperror();
		free(cb);
		break;
	case Qdata:
		c = cmd.conv[CONV(ch->qid)];
		qlock(&c->l);
		if(c->fd[0] == -1){
			qunlock(&c->l);
			error(Ehungup);
		}
		qunlock(&c->l);
		osenter();
		r = write(c->fd[0], a, n);
		osleave();
		if(r == 0)
			error(Ehungup);
		if(r < 0) {
			/* XXX perhaps should kill writer "write on closed pipe" here, 2nd time around? */
			oserror();
		}
		return r;
	}
	return n;
}
Esempio n. 4
0
static int32_t
acpiwrite(Chan *c, void *a, int32_t n, int64_t off)
{
	Mach *m = machp();
	Cmdtab *ct;
	Cmdbuf *cb;
	Reg *r;
	uint rno, fun, dev, bus, i;

	if(c->qid.path == Qio){
		if(reg == nil)
			error("region not configured");
		return regio(reg, a, n, off, 1);
	}
	if(c->qid.path != Qctl)
		error(Eperm);

	cb = parsecmd(a, n);
	if(waserror()){
		free(cb);
		nexterror();
	}
	ct = lookupcmd(cb, ctls, nelem(ctls));
	DBG("acpi ctl %s\n", cb->f[0]);
	switch(ct->index){
	case CMregion:
		r = reg;
		if(r == nil){
			r = smalloc(sizeof(Reg));
			r->name = nil;
		}
		kstrdup(&r->name, cb->f[1]);
		r->spc = acpiregid(cb->f[2]);
		if(r->spc < 0){
			free(r);
			reg = nil;
			error("bad region type");
		}
		if(r->spc == Rpcicfg || r->spc == Rpcibar){
			rno = r->base>>Rpciregshift & Rpciregmask;
			fun = r->base>>Rpcifunshift & Rpcifunmask;
			dev = r->base>>Rpcidevshift & Rpcidevmask;
			bus = r->base>>Rpcibusshift & Rpcibusmask;
			r->tbdf = MKBUS(BusPCI, bus, dev, fun);
			r->base = rno;	/* register ~ our base addr */
		}
		r->base = strtoull(cb->f[3], nil, 0);
		r->len = strtoull(cb->f[4], nil, 0);
		r->accsz = strtoul(cb->f[5], nil, 0);
		if(r->accsz < 1 || r->accsz > 4){
			free(r);
			reg = nil;
			error("bad region access size");
		}
		reg = r;
		DBG("region %s %s %llux %llux sz%d",
			r->name, acpiregstr(r->spc), r->base, r->len, r->accsz);
		break;
	case CMgpe:
		i = strtoul(cb->f[1], nil, 0);
		if(i >= ngpes)
			error("gpe out of range");
		kstrdup(&gpes[i].obj, cb->f[2]);
		DBG("gpe %d %s\n", i, gpes[i].obj);
		setgpeen(i, 1);
		break;
	default:
		panic("acpi: unknown ctl");
	}
Esempio n. 5
0
static long
conswrite(Chan *c, void *va, long n, vlong off)
{
	char buf[256];
	long l, bp;
	char *a;
	Mach *mp;
	int id, fd;
	Chan *swc;
	ulong offset;
	Cmdbuf *cb;
	Cmdtab *ct;

	a = va;
	offset = off;

	switch((ulong)c->qid.path){
	case Qcons:
		/*
		 * Can't page fault in putstrn, so copy the data locally.
		 */
		l = n;
		while(l > 0){
			bp = l;
			if(bp > sizeof buf)
				bp = sizeof buf;
			memmove(buf, a, bp);
			putstrn0(buf, bp, 1);
			a += bp;
			l -= bp;
		}
		break;

	case Qconsctl:
		error(Egreg);

	case Qtime:
		if(!iseve())
			error(Eperm);
		return writetime(a, n);

	case Qbintime:
		if(!iseve())
			error(Eperm);
		return writebintime(a, n);

	case Qhostowner:
		return hostownerwrite(a, n);

	case Qhostdomain:
		return hostdomainwrite(a, n);

	case Quser:
		return userwrite(a, n);

	case Qnull:
		break;

	case Qconfig:
		error(Eperm);
		break;

	case Qreboot:
		if(!iseve())
			error(Eperm);
		cb = parsecmd(a, n);

		if(waserror()) {
			free(cb);
			nexterror();
		}
		ct = lookupcmd(cb, rebootmsg, nelem(rebootmsg));
		switch(ct->index) {
		case CMhalt:
			reboot(nil, 0, 0);
			break;
		case CMreboot:
			rebootcmd(cb->nf-1, cb->f+1);
			break;
		case CMpanic:
			*(ulong*)0=0;
			panic("/dev/reboot");
		case CMrdb:
			if(consdebug == nil)
				consdebug = rdb;
			consdebug();
			break;
		}
		poperror();
		free(cb);
		break;

	case Qsysstat:
		for(id = 0; id < 32; id++) {
			if(active.machs & (1<<id)) {
				mp = MACHP(id);
				mp->cs = 0;
				mp->intr = 0;
				mp->syscall = 0;
				mp->pfault = 0;
				mp->tlbfault = 0;
				mp->tlbpurge = 0;
			}
		}
		break;

	case Qswap:
		if(n >= sizeof buf)
			error(Egreg);
		memmove(buf, va, n);	/* so we can NUL-terminate */
		buf[n] = 0;
		/* start a pager if not already started */
		if(strncmp(buf, "start", 5) == 0){
			kickpager();
			break;
		}
		if(!iseve())
			error(Eperm);
		if(buf[0]<'0' || '9'<buf[0])
			error(Ebadarg);
		fd = strtoul(buf, 0, 0);
		swc = fdtochan(fd, -1, 1, 1);
		setswapchan(swc);
		break;

	case Qsysname:
		if(offset != 0)
			error(Ebadarg);
		if(n <= 0 || n >= sizeof buf)
			error(Ebadarg);
		strncpy(buf, a, n);
		buf[n] = 0;
		if(buf[n-1] == '\n')
			buf[n-1] = 0;
		kstrdup(&sysname, buf);
		break;
	
	case Qmordor:
		error("one does not simply write into mordor");
		return 0;

	default:
		print("conswrite: %#llux\n", c->qid.path);
		error(Egreg);
	}
	return n;
}
Esempio n. 6
0
static long
devlogfswrite(Chan *c, void *buf, long n, vlong off)
{
	int instance, qid, qt, i;
	Cmdbuf *cmd;
	Cmdtab *ct;

	if(n <= 0)
		return 0;
	SPLITPATH(c->qid.path, c->qid.type, instance, qid, qt);
#ifdef CALLTRACE
	print("devlogfswrite(c = 0x%.8lux, buf = 0x%.8lux, n = %ld, instance = %d, qid = %d, qt = %d) - start\n",
		(ulong)c, (ulong)buf, n, instance, qid, qt);
#endif
	USED(instance);
	if(DATAQID(qid, qt)){
		if (qid == Qfsboot) {
			Devlogfs *l = c->aux;
			qlock(&l->bootqlock);
			if (waserror()) {
				qunlock(&l->bootqlock);
				nexterror();
			}
			smartio((SMARTIOFN *)logfsbootio, l->lb, buf, n, off, logfsbootgetiosize(l->lb), 1);
			poperror();
			qunlock(&l->bootqlock);
			return n;
		}
		else if (qid == Qfs) {
			Devlogfs *d = c->aux;
			lfssrvwrite(d, buf, n);
			return n;
		}
		error(Eio);
	}
	else if (qid == Qctl) {
		Devlogfs *l = nil;
		int a;

		cmd = parsecmd(buf, n);
		if(waserror()){
			free(cmd);
			nexterror();
		}
		i = cmd->nf;
		if(0){print("i=%d", i); for(i=0; i<cmd->nf; i++)print(" %q", cmd->f[i]); print("\n");}
		if (i <= 0)
			error(Ebadarg);
		if (i == 3 && strcmp(cmd->f[0], "uname") == 0) {
			switch (cmd->f[2][0]) {
			default:
				errorany(logfsisgroupcreate(is, cmd->f[1], cmd->f[2]));
				break;
			case ':':
				errorany(logfsisgroupcreate(is, cmd->f[1], cmd->f[2] + 1));
				break;
			case '%':
				errorany(logfsisgrouprename(is, cmd->f[1], cmd->f[2] + 1));
				break;
			case '=':
				errorany(logfsisgroupsetleader(is, cmd->f[1], cmd->f[2] + 1));
				break;
			case '+':
				errorany(logfsisgroupaddmember(is, cmd->f[1], cmd->f[2] + 1));
				break;
			case '-':
				errorany(logfsisgroupremovemember(is, cmd->f[1], cmd->f[2] + 1));
				break;
			}
			i = 0;
		}
		if (i == 4 && strcmp(cmd->f[0], "fsys") == 0 && strcmp(cmd->f[2], "config") == 0) {
			l = devlogfsconfig(cmd->f[1], cmd->f[3]);
			i = 0;
		}
		else if (i >= 2 && strcmp(cmd->f[0], "fsys") == 0) {
			l = devlogfssetdefname(cmd->f[1]);
			if (l == nil)
				errorf("file system %q not configured", cmd->f[1]);
			i -= 2;
			cmd->f += 2;
			cmd->nf = i;
		}
		if (i != 0) {
			ct = lookupcmd(cmd, fscmds, nelem(fscmds));
			if (l == nil)
				l = devlogfssetdefname(nil);
			if(l == nil && ct->index != CMleakaudit)
				error("file system not configured");
			switch(ct->index){
			case CMopen:
				for (a = 1; a < i; a++)
					if (cmd->f[a][0] == '-')
						switch (cmd->f[a][1]) {
						case 'P':
							l->openflags |= LogfsOpenFlagNoPerm;
							break;
						case 'W':
							l->openflags |= LogfsOpenFlagWstatAllow;
							break;
						default:
							error(Ebadarg);
						}
				devlogfsllopen(l);
				break;
			case CMformat:
				devlogfsllformat(l, strtol(cmd->f[1], nil, 0));
				break;
			case CMsweep:
				devlogfsserverlogsweep(l, 0);
				break;
			case CMsweepone:
				devlogfsserverlogsweep(l, 1);
				break;
			case CMtrace:
				l->logfstrace = i > 1 ? strtol(cmd->f[1], nil, 0) : 0;
				if (l->server)
					logfsservertrace(l->server, l->logfstrace);
				if (l->lb)
					logfsboottrace(l->lb, l->logfstrace);
				break;
			case CMunconfig:
				if (l->ref.ref > 0)
					error(Einuse);
				devlogfsunconfig(l);
				break;
			case CMextent:
				if(i < 2)
					error(Ebadarg);
				devlogfsdumpinit(l, extentdumpinit, extentdumpread, i - 1, cmd->f + 1);
				break;
			case CMtest:
				if(i < 2)
					error(Ebadarg);
				errorany(logfsservertestcmd(l->server, i - 1, cmd->f + 1));
				break;
			case CMleakaudit:
#ifdef LEAKHUNT
				leakaudit();
#endif
				break;
			case CMsync:
				devlogfsserversync(l);
				break;
			default:
				error(Ebadarg);
			}
		}
		poperror();
		free(cmd);
		return n;
	}
	error(Egreg);
	return 0;		/* not reached */
}
Esempio n. 7
0
static int32_t
conswrite(Chan *c, void *va, int32_t n, int64_t off)
{
	Proc *up = externup();
	char buf[256];
	int32_t l, bp;
	char *a;
	Mach *mp;
	int i;
	uint32_t offset;
	Cmdbuf *cb;
	Cmdtab *ct;
	a = va;
	offset = off;
	extern int printallsyscalls;

	switch((uint32_t)c->qid.path){
	case Qcons:
		/*
		 * Can't page fault in putstrn, so copy the data locally.
		 */
		l = n;
		while(l > 0){
			bp = l;
			if(bp > sizeof buf)
				bp = sizeof buf;
			memmove(buf, a, bp);
			putstrn0(buf, bp, 1);
			a += bp;
			l -= bp;
		}
		break;

	case Qconsctl:
		print("consctl\n");
		if(n >= sizeof(buf))
			n = sizeof(buf)-1;
		strncpy(buf, a, n);
		buf[n] = 0;
		for(a = buf; a;){
			if(strncmp(a, "sys", 3) == 0) {
				printallsyscalls = ! printallsyscalls;
				print("%sracing syscalls\n", printallsyscalls ? "T" : "Not t");
			}
			if(a = strchr(a, ' '))
				a++;
		}
		break;

	case Qtime:
		if(!iseve())
			error(Eperm);
		return writetime(a, n);

	case Qbintime:
		if(!iseve())
			error(Eperm);
		return writebintime(a, n);

	case Qhostowner:
		return hostownerwrite(a, n);

	case Qhostdomain:
		return hostdomainwrite(a, n);

	case Quser:
		return userwrite(a, n);

	case Qnull:
		break;

	case Qreboot:
		if(!iseve())
			error(Eperm);
		cb = parsecmd(a, n);

		if(waserror()) {
			free(cb);
			nexterror();
		}
		ct = lookupcmd(cb, rebootmsg, nelem(rebootmsg));
		switch(ct->index) {
		case CMhalt:
			reboot(nil, 0, 0);
			break;
		case CMreboot:
			rebootcmd(cb->nf-1, cb->f+1);
			break;
		case CMpanic:
			*(uint32_t*)0=0;
			panic("/dev/reboot");
		}
		poperror();
		free(cb);
		break;

	case Qsysstat:
		for(i = 0; i < MACHMAX; i++)
			if((mp = sys->machptr[i]) != nil && mp->online){
				mp = sys->machptr[i];
				mp->cs = 0;
				mp->intr = 0;
				mp->syscall = 0;
				mp->pfault = 0;
				mp->tlbfault = 0;	/* not updated */
				mp->tlbpurge = 0;	/* # mmuflushtlb */
			}
		break;

	case Qswap:
		if(n >= sizeof buf)
			error(Egreg);
		memmove(buf, va, n);	/* so we can NUL-terminate */
		buf[n] = 0;
		if(!iseve())
			error(Eperm);
		if(buf[0]<'0' || '9'<buf[0])
			error(Ebadarg);
		if(strncmp(buf, "start", 5) == 0){
			print("request to start pager ignored\n");
			break;
		}
		break;

	case Qsysname:
		if(offset != 0)
			error(Ebadarg);
		if(n <= 0 || n >= sizeof buf)
			error(Ebadarg);
		strncpy(buf, a, n);
		buf[n] = 0;
		if(buf[n-1] == '\n')
			buf[n-1] = 0;
		kstrdup(&sysname, buf);
		break;

	case Qdebug:
		if(n >= sizeof(buf))
			n = sizeof(buf)-1;
		strncpy(buf, a, n);
		buf[n] = 0;
		if(n > 0 && buf[n-1] == '\n')
			buf[n-1] = 0;
		error(Ebadctl);
		break;
	default:
		print("conswrite: %#llux\n", c->qid.path);
		error(Egreg);
	}
	return n;
}
Esempio n. 8
0
static int32_t
pmcwrite(Chan *c, void *a, int32_t n, int64_t mm)
{
	Proc *up = externup();
	Cmdbuf *cb;
	Cmdtab *ct;
	uint32_t type;
	char str[64];	/* 0x0000000000000000\0 */
	AcPmcArg p;
	AcCtrArg ctr;
	uint64_t coreno;
	Mach *mp;

	if (c->qid.type == QTDIR)
		error(Eperm);
	if (c->qid.path == Qgctl)
		error(Eperm);
	if (n >= sizeof(str))
		error(Ebadctl);

	pmcnull(&p);
	coreno = (uint64_t)c->aux;
	p.coreno = coreno;
	type = PMCTYPE(c->qid.path);
	p.regno = PMCID(c->qid.path);
	memmove(str, a, n);
	str[n] = '\0';
	mp = up->ac;

	ctr.coreno = coreno;
	ctr.regno = p.regno;
	if (type == Qdata) {
		/* I am a handler for a proc in the core, run an RPC*/
		if (mp != nil && mp->machno == coreno) {
			if (runac(mp, acpmcsetctr, 0, &ctr, sizeof(AcCtrArg)) < 0)
				n = -1;
		} else {
		if (pmcsetctr(coreno, strtoull(str, 0, 0), p.regno) < 0)
			n = -1;
		}
		return n;
	}


	/* TODO: should iterate through multiple lines */
	if (strncmp(str, "set ", 4) == 0){
		memmove(p.descstr, (char *)str + 4, n - 4);
		p.descstr[n - 4] = '\0';
		p.nodesc = 0;
	} else {
		cb = parsecmd(a, n);
		if(waserror()){
			free(cb);
			nexterror();
		}
		ct = lookupcmd(cb, pmcctlmsg, nelem(pmcctlmsg));
		switch(ct->index){
		case Enable:
			p.enab = 1;
			break;
		case Disable:
			p.enab = 0;
			break;
		case User:
			p.user = 1;
			break;
		case Os:
			p.os = 1;
			break;
		case NoUser:
			p.user = 0;
			break;
		case NoOs:
			p.os = 0;
			break;
		case Reset:
			p.reset = 1;
			break;
		case Debug:
			pmcdebug = ~pmcdebug;
			break;
		default:
			cmderror(cb, "invalid ctl");
		break;
		}
		free(cb);
		poperror();
	}
	/* I am a handler for a proc in the core, run an RPC*/
	if (mp != nil && mp->machno == coreno) {
		if (runac(mp, acpmcsetctl, 0, &p, sizeof(AcPmcArg)) < 0)
			n = -1;
	} else {
		if (pmcsetctl(coreno, &p, p.regno) < 0)
			n = -1;
	}
	return n;
}
Esempio n. 9
0
static long conswrite(struct chan *c, void *va, long n, int64_t off)
{
    ERRSTACK(1);
    char buf[256], ch;
    long l, bp;
    char *a;
    //Mach *mp;
    int id, fd;
    struct chan *swc;
    uint32_t offset;
    struct cmdbuf *cb;
    struct cmdtab *ct;
    int x;
    uint64_t rip, rsp, cr3, flags, vcpu;
    int ret;
    struct vmctl vmctl;

    a = va;
    offset = off;

    switch ((uint32_t) c->qid.path) {
    case Qcons:
        /*
         * Can't page fault in putstrn, so copy the data locally.
         */
        l = n;
        while (l > 0) {
            bp = l;
            if (bp > sizeof buf)
                bp = sizeof buf;
            memmove(buf, a, bp);
            putstrn0(buf, bp, 1);
            a += bp;
            l -= bp;
        }
        break;

    case Qconsctl:
        if (n >= sizeof(buf))
            n = sizeof(buf) - 1;
        strncpy(buf, a, n);
        buf[n] = 0;
        for (a = buf; a;) {
            if (strncmp(a, "rawon", 5) == 0) {
                kbd.raw = 1;
                /* clumsy hack - wake up reader */
                ch = 0;
                qwrite(kbdq, &ch, 1);
            } else if (strncmp(a, "rawoff", 6) == 0) {
                kbd.raw = 0;
            } else if (strncmp(a, "ctlpon", 6) == 0) {
                kbd.ctlpoff = 0;
            } else if (strncmp(a, "ctlpoff", 7) == 0) {
                kbd.ctlpoff = 1;
            }
            if ((a = strchr(a, ' ')) != NULL)
                a++;
        }
        break;

    case Qtime:
        if (!iseve())
            error(EPERM, "Hodie Natus Est Radici Frater");
        return writetime(a, n);

    case Qbintime:
        if (!iseve())
            error(EPERM, ERROR_FIXME);
        return writebintime(a, n);

#if 0
    case Qhostowner:
        return hostownerwrite(a, n);

    case Qhostdomain:
        return hostdomainwrite(a, n);

    case Quser:
        return userwrite(a, n);
#endif

    case Qnull:
        break;

    case Qconfig:
        error(EPERM, "Cannot write to config QID");
        break;

    case Qsysctl:
        //if (!iseve()) error(EPERM, ERROR_FIXME);
        cb = parsecmd(a, n);
        if (cb->nf > 1)
            printd("cons sysctl cmd %s\n", cb->f[0]);

    case Qreboot:
        if (!iseve())
            error(EPERM, ERROR_FIXME);
        cb = parsecmd(a, n);

        if (waserror()) {
            kfree(cb);
            nexterror();
        }
        ct = lookupcmd(cb, rebootmsg, ARRAY_SIZE(rebootmsg));
        switch (ct->index) {
        case CMhalt:
            cpu_halt();
            break;
        case CMbroken:
            keepbroken = 1;
            break;
        case CMnobroken:
            keepbroken = 0;
            break;
        case CMreboot:
            reboot();
            break;
        case CMpanic:
            *(uint32_t *) 0 = 0;
            panic("/dev/reboot");
        }
        poperror();
        kfree(cb);
        break;

#if 0
    case Qsysstat:
        for (id = 0; id < 32; id++) {
            if (active.machs & (1 << id)) {
                mp = MACHP(id);
                mp->cs = 0;
                mp->intr = 0;
                mp->syscall = 0;
                mp->pfault = 0;
                mp->tlbfault = 0;
                mp->tlbpurge = 0;
            }
        }
        break;

    case Qswap:
        if (n >= sizeof buf)
            error(EINVAL, "n is bigger than sizeof buf for Qswap");
        memmove(buf, va, n);	/* so we can NUL-terminate */
        buf[n] = 0;
        /* start a pager if not already started */
        if (strncmp(buf, "start", 5) == 0) {
            kickpager();
            break;
        }
        if (!iseve())
            error(EPERM, ERROR_FIXME);
        if (buf[0] < '0' || '9' < buf[0])
            error(EINVAL, ERROR_FIXME);
        fd = strtoul(buf, 0, 0);
        swc = fdtochan(fd, -1, 1, 1);
        setswapchan(swc);
        break;
#endif

    case Qsysname:
        if (offset != 0)
            error(EINVAL, ERROR_FIXME);
        if (n <= 0 || n >= sizeof buf)
            error(EINVAL, ERROR_FIXME);
        strncpy(buf, a, n);
        buf[n] = 0;
        if (buf[n - 1] == '\n')
            buf[n - 1] = 0;
        kstrdup(&sysname, buf);
        break;

    default:
        printd("conswrite: %#llux\n", c->qid.path);
        error(EINVAL, "bad QID in conswrite");
    }
    return n;
}
Esempio n. 10
0
static long	 
flashwrite(Chan *c, void *buf, long n, vlong offset)
{
	Cmdbuf *cb;
	Cmdtab *ct;
	ulong addr, start, end;
	char *e;
	Flashpart *fp;
	Flashregion *r;
	Flash *f;

	f = flash.card[c->dev];
	fp = &f->part[PART(c->qid.path)];
	if(fp->name == nil)
		error(Egreg);
	switch(TYPE(c->qid.path)){
	case Qdata:
		if(f->write == nil)
			error(Eperm);
		offset += fp->start;
		if(offset >= fp->end)
			return 0;
		if(offset+n > fp->end)
			n = fp->end - offset;
		n = writeflash(f, offset, buf, n);
		if(n < 0)
			error(Eio);
		return n;
	case Qctl:
		cb = parsecmd(buf, n);
		if(waserror()){
			free(cb);
			nexterror();
		}
		ct = lookupcmd(cb, flashcmds, nelem(flashcmds));
		switch(ct->index){
		case CMerase:
			if(strcmp(cb->f[1], "all") != 0){
				addr = flashaddr(f, fp, cb->f[1]);
				r = flashregion(f, addr);
				if(r == nil)
					error("nonexistent flash region");
				if(addr%r->erasesize != 0)
					error("invalid erase block address");
				eraseflash(f, r, addr);
			}else if(fp->start == 0 && fp->end == f->size &&
			    f->eraseall != nil){
				eraseflash(f, nil, 0);
			}else{
				for(addr = fp->start; addr < fp->end;
				    addr += r->erasesize){
					r = flashregion(f, addr);
					if(r == nil)
						error("nonexistent flash region");
					if(addr%r->erasesize != 0)
						error("invalid erase block address");
					eraseflash(f, r, addr);
				}
			}
			break;
		case CMadd:
			if(cb->nf < 3)
				error(Ebadarg);
			start = flashaddr(f, fp, cb->f[2]);
			if(cb->nf > 3 && strcmp(cb->f[3], "end") != 0)
				end = flashaddr(f, fp, cb->f[3]);
			else
				end = fp->end;
			if(start > end || start >= fp->end || end > fp->end)
				error(Ebadarg);
			e = flashnewpart(f, cb->f[1], start, end);
			if(e != nil)
				error(e);
			break;
		case CMremove:
			/* TO DO */
			break;
		case CMprotectboot:
			if(cb->nf > 1 && strcmp(cb->f[1], "off") == 0)
				f->protect = 0;
			else
				f->protect = 1;
			break;
		case CMsync:
			/* TO DO? */
			break;
		default:
			error(Ebadarg);
		}
		poperror();
		free(cb);
		return n;
	}
	error(Egreg);
	return 0;		/* not reached */
}
Esempio n. 11
0
static long
floppywrite(Chan *c, void *a, long n, vlong off)
{
	FDrive *dp;
	long rv, i;
	char *aa = a;
	Cmdbuf *cb;
	Cmdtab *ct;
	ulong offset = off;

	rv = 0;
	dp = &fl.d[c->qid.path & ~Qmask];
	switch ((int)(c->qid.path & Qmask)) {
	case Qdata:
		islegal(offset, n, dp);
		qlock(&fl);
		if(waserror()){
			qunlock(&fl);
			nexterror();
		}
		floppyon(dp);
		changed(c, dp);
		for(rv = 0; rv < n; rv += i){
			floppypos(dp, offset+rv);
			if(dp->tcyl == dp->ccyl)
				dp->ccyl = -1;
			i = floppyxfer(dp, Fwrite, aa+rv, offset+rv, n-rv);
			if(i < 0)
				break;
			if(i == 0)
				error(Eio);
		}
		qunlock(&fl);
		poperror();
		break;
	case Qctl:
		rv = n;
		cb = parsecmd(a, n);
		if(waserror()){
			free(cb);
			nexterror();
		}
		qlock(&fl);
		if(waserror()){
			qunlock(&fl);
			nexterror();
		}
		ct = lookupcmd(cb, floppyctlmsg, nelem(floppyctlmsg));
		switch(ct->index){
		case CMeject:
			floppyeject(dp);
			break;
		case CMformat:
			floppyformat(dp, cb);
			break;
		case CMreset:
			fl.confused = 1;
			floppyon(dp);
			break;
		case CMdebug:
			floppydebug = 1;
			break;
		case CMnodebug:
			floppydebug = 0;
			break;
		}
		poperror();
		qunlock(&fl);
		poperror();
		free(cb);
		break;
	default:
		panic("floppywrite: bad qid");
	}

	return rv;
}
Esempio n. 12
0
static long
mousewrite(Chan *c, void *va, long n, vlong offset)
{
	char *p;
	Point pt;
	Cmdbuf *cb;
	Cmdtab *ct;
	char buf[64];
	int nn;

	p = va;
	switch((ulong)c->qid.path){
	case Qdir:
		error(Eisdir);

	case Qcursor:
		if(n < 2*4+2*2*16){
			curs = arrow;
			Cursortocursor(&arrow);
		}else{
			n = 2*4+2*2*16;
			curs.offset.x = BGLONG(p+0);
			curs.offset.y = BGLONG(p+4);
			memmove(curs.clr, p+8, 2*16);
			memmove(curs.set, p+40, 2*16);
			Cursortocursor(&curs);
		}
		qlock(&mouse.qlk);
		mouse.redraw = 1;
		qunlock(&mouse.qlk);
		return n;

	case Qmousectl:
		cb = parsecmd(va, n);
		if(waserror()){
			free(cb);
			nexterror();
		}

		ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));

		switch(ct->index){
		case CMswap:
			if(mouseswap)
				setbuttonmap("123");
			else
				setbuttonmap("321");
			mouseswap ^= 1;
			break;

		case CMscrollswap:
			scrollswap ^= 1;
			break;

		case CMbuttonmap:
			if(cb->nf == 1)
				setbuttonmap("123");
			else
				setbuttonmap(cb->f[1]);
			break;
		}

		free(cb);
		poperror();
		return n;

	case Qmouse:
		if(n > sizeof buf-1)
			n = sizeof buf -1;
		memmove(buf, va, n);
		buf[n] = 0;
		p = 0;
		pt.x = strtoul(buf+1, &p, 0);
		if(p == 0)
			error(Eshort);
		pt.y = strtoul(p, 0, 0);
		qlock(&mouse.qlk);
		if(ptinrect(pt, mouserect)){
			mouse.mstate.xy = pt;
			mouse.redraw = 1;
			mouse.track = 1;
		}
		qunlock(&mouse.qlk);
		setmouse(pt);
		return n;
	
	case Qsnarf:
		if(offset+n >= SnarfSize)
			error("too much snarf");
		if(n == 0)
			return 0;
		assert(mousedir[Qsnarf].qid.path == Qsnarf);
		mousedir[Qsnarf].qid.vers++;
		if(c->aux == nil)
			nn = 0;
		else
			nn = strlen(c->aux);
		if(offset+n > nn){
			nn = offset+n;
			p = smalloc(nn+1);
			if(c->aux){
				strcpy(p, c->aux);
				free(c->aux);
			}
			c->aux = p;
		}
		memmove(c->aux+offset, va, n);
		return n;
	}

	error(Egreg);
	return -1;
}
Esempio n. 13
0
File: devprog.c Progetto: 8l/inferno
static long
progwrite(Chan *c, void *va, long n, vlong offset)
{
	Prog *p, *f;
	Heapqry *hq;
	char buf[512];
	Progctl *ctl;
	char *b;
	int i, pc;
	Cmdbuf *cb;
	Cmdtab *ct;

	USED(offset);
	USED(va);

	if(c->qid.type & QTDIR)
		error(Eisdir);

	acquire();
	if(waserror()) {
		release();
		nexterror();
	}
	p = progpid(PID(c->qid));
	if(p == nil)
		error(Ethread);

	switch(QID(c->qid)){
	case Qctl:
		cb = parsecmd(va, n);
		if(waserror()){
			free(cb);
			nexterror();
		}
		ct = lookupcmd(cb, progcmd, nelem(progcmd));
		switch(ct->index){
		case CMkillgrp:
			killgrp(p, "killed");
			break;
		case CMkill:
			killprog(p, "killed");
			break;
		case CMrestricted:
			p->flags |= Prestrict;
			break;
		case CMexceptions:
			if(p->group->id != p->pid)
				error(Eperm);
			if(strcmp(cb->f[1], "propagate") == 0)
				p->flags |= Ppropagate;
			else if(strcmp(cb->f[1], "notifyleader") == 0)
				p->flags |= Pnotifyleader;
			else
				error(Ebadctl);
			break;
		case CMprivate:
			p->group->flags |= Pprivatemem;
			break;
		}
		poperror();
		free(cb);
		break;
	case Qdbgctl:
		cb = parsecmd(va, n);
		if(waserror()){
			free(cb);
			nexterror();
		}
		if(cb->nf == 1 && strncmp(cb->f[0], "step", 4) == 0)
			ct = progdbgcmd;
		else
			ct = lookupcmd(cb, progdbgcmd, nelem(progdbgcmd));
		switch(ct->index){
		case CDstep:
			if(cb->nf == 1)
				i = strtoul(cb->f[0]+4, nil, 0);
			else
				i = strtoul(cb->f[1], nil, 0);
			dbgstep(c->aux, p, i);
			break;
		case CDtoret:
			f = currun();
			i = calldepth(&p->R);
			while(f->kill == nil) {
				dbgstep(c->aux, p, 1024);
				if(i > calldepth(&p->R))
					break;
			}
			break;
		case CDcont:
			f = currun();
			while(f->kill == nil)
				dbgstep(c->aux, p, 1024);
			break;
		case CDstart:
			dbgstart(p);
			break;
		case CDstop:
			ctl = c->aux;
			ctl->stop = 1;
			break;
		case CDunstop:
			ctl = c->aux;
			ctl->stop = 0;
			break;
		case CDbpt:
			pc = strtoul(cb->f[3], nil, 10);
			ctl = c->aux;
			if(strcmp(cb->f[1], "set") == 0)
				ctl->bpts = setbpt(ctl->bpts, cb->f[2], pc);
			else if(strcmp(cb->f[1], "del") == 0)
				ctl->bpts = delbpt(ctl->bpts, cb->f[2], pc);
			else
				error(Ebadctl);
			break;
		case CDmaim:
			p->kill = "maim";
			break;
		}
		poperror();
		free(cb);
		break;
	case Qheap:
		/*
		 * Heap query:
		 *	addr.Fn
		 *	pc+module.In
		 */
		i = n;
		if(i > sizeof(buf)-1)
			i = sizeof(buf)-1;
		memmove(buf, va, i);
		buf[i] = '\0';
		hq = c->aux;
		hq->addr = strtoul(buf, &b, 0);
		if(*b == '+')
			hq->module = strtoul(b, &b, 0);
		if(*b++ != '.')
			error(Ebadctl);
		hq->fmt = *b++;
		hq->count = strtoul(b, nil, 0);
		break;
	default:
		print("unknown qid in procwrite\n");
		error(Egreg);
	}
	poperror();
	release();
	return n;
}
Esempio n. 14
0
static int32_t
cmdwrite(Chan *ch, void *a, int32_t n, int64_t offset)
{
	Proc *up = externup();
	int i, r = 0;
	Conv *c;
	Segment *s;
	Cmdbuf *cb;
	Cmdtab *ct;

	USED(offset);

	switch(TYPE(ch->qid)) {
	default:
		error(Eperm);
	case Qctl:
		c = cmd.conv[CONV(ch->qid)];
		cb = parsecmd(a, n);
		if(waserror()){
			free(cb);
			nexterror();
		}
		ct = lookupcmd(cb, cmdtab, nelem(cmdtab));
		switch(ct->index){
		case CMdir:
			kstrdup(&c->dir, cb->f[1]);
			break;
		case CMstart:
			// so what do we do with this?
			// we need to do the process.
			if(cb->nf < 2)
				error(Ebadctl);
			c = cmd.conv[CONV(ch->qid)];
			s = c->p->seg[TSEG];
			// XXX: set the text name?
			//kstrdup(&c->p->text, cb->f[1]);
			kforkexecac(c->p, atoi(cb->f[2]), nil, cb->f+3);
			break;
		case CMexec:
			poperror();	/* cb */
			qlock(&c->l);
			if(waserror()){
				qunlock(&c->l);
				free(cb);
				nexterror();
			}
			if(c->child != nil || c->cmd != nil)
				error(Einuse);
			for(i = 0; i < nelem(c->fd); i++)
				if(c->fd[i] != -1)
					error(Einuse);
			if(cb->nf < 1)
				error(Etoosmall);
//			kproc("cmdproc", cmdproc, c, 0);	/* cmdproc held back until unlock below */
			free(c->cmd);
			c->cmd = cb;	/* don't free cb */
			c->state = "Execute";
			poperror();
			qunlock(&c->l);
			while(waserror())
				;
//			Sleep(&c->startr, cmdstarted, c);
			poperror();
			if(c->error)
				error(c->error);
			return n;	/* avoid free(cb) below */
		}
		poperror();
		free(cb);
		break;
	case Qexec:
		c = cmd.conv[CONV(ch->qid)];
		s = c->p->seg[TSEG];
		if(s->base+offset+n > s->top)
			error(Etoobig);
		memmove((void*)(s->base + offset), a, n);
		if(offset+n > c->esz)
			c->esz = offset+n;
		// XXX: can this every not be n?
		return n;
	case Qdata:
		c = cmd.conv[CONV(ch->qid)];
		qlock(&c->l);
		if(c->fd[0] == -1){
			qunlock(&c->l);
			error(Ehungup);
		}
		qunlock(&c->l);
//		osenter();
//		r = write(c->fd[0], a, n);
//		osleave();
		if(r == 0)
			error(Ehungup);
		if(r < 0) {
			/* XXX perhaps should kill writer "write on closed pipe" here, 2nd time around? */
//			oserror();
		}
		return r;
	}
	return n;
}