示例#1
0
文件: tcore.c 项目: Harvey-OS/harvey
/*
 * Move the current process to an application core.
 * This is performed at the end of execac(), and
 * we pretend to be returning to user-space, but instead we
 * dispatch the process to another core.
 * 1. We do the final bookkeeping that syscall() would do after
 *    a return from sysexec(), because we are not returning.
 * 2. We dispatch the process to an AC using an ICC.
 *
 * This function won't return unless the process is reclaimed back
 * to the time-sharing core, and is the handler for the process
 * to deal with traps and system calls until the process dies.
 *
 * Remember that this function is the "line" between user and kernel
 * space, it's not expected to raise|handle any error.
 *
 * We install a safety error label, just in case we raise errors,
 * which we shouldn't. (noerrorsleft knows that for exotic processes
 * there is an error label pushed by us).
 */
void
runacore(void)
{
	Proc *up = externup();
	Ureg *ureg;
	void (*fn)(void);
	int rc, flush, s;
	char *n;
	uint64_t t1;

	if(waserror())
		panic("runacore: error: %s\n", up->errstr);
	ureg = up->dbgreg;
	fakeretfromsyscall(ureg);
	fpusysrfork(ureg);

	procpriority(up, PriKproc, 1);
	rc = runac(up->ac, actouser, 1, nil, 0);
	procpriority(up, PriNormal, 0);
	for(;;){
		t1 = fastticks(nil);
		flush = 0;
		fn = nil;
		switch(rc){
		case ICCTRAP:
			s = splhi();
			machp()->MMU.cr2 = up->ac->MMU.cr2;
			DBG("runacore: trap %llu cr2 %#llx ureg %#p\n",
				ureg->type, machp()->MMU.cr2, ureg);
			switch(ureg->type){
			case IdtIPI:
				if(up->procctl || up->nnote)
					notify(up->dbgreg);
				if(up->ac == nil)
					goto ToTC;
				kexit(up->dbgreg);
				break;
			case IdtNM:
			case IdtMF:
			case IdtXF:
				/* these are handled in the AC;
				 * If we get here, they left in m->NIX.icc->data
				 * a note to be posted to the process.
				 * Post it, and make the vector a NOP.
				 */
				n = up->ac->NIX.icc->note;
				if(n != nil)
					postnote(up, 1, n, NDebug);
				ureg->type = IdtIPI;		/* NOP */
				break;
			default:
				cr3put(machp()->MMU.pml4->pa);
				if(0 && ureg->type == IdtPF){
					print("before PF:\n");
					print("AC:\n");
					dumpptepg(4, up->ac->MMU.pml4->pa);
					print("\n%s:\n", rolename[NIXTC]);
					dumpptepg(4, machp()->MMU.pml4->pa);
				}
				trap(ureg);
			}
			splx(s);
			flush = 1;
			fn = actrapret;
			break;
		case ICCSYSCALL:
			DBG("runacore: syscall ax %#llx ureg %#p\n",
				ureg->ax, ureg);
			cr3put(machp()->MMU.pml4->pa);
			//syscall(ureg->ax, ureg);
			flush = 1;
			fn = acsysret;
			if(0)
			if(up->nqtrap > 2 || up->nsyscall > 1)
				goto ToTC;
			if(up->ac == nil)
				goto ToTC;
			break;
		default:
			panic("runacore: unexpected rc = %d", rc);
		}
		up->tctime += fastticks2us(fastticks(nil) - t1);
		procpriority(up, PriExtra, 1);
		rc = runac(up->ac, fn, flush, nil, 0);
		procpriority(up, PriNormal, 0);
	}
ToTC:
	/*
	 *  to procctl, then syscall,  to
	 *  be back in the TC
	 */
	DBG("runacore: up %#p: return\n", up);
}
示例#2
0
文件: devpmc.c 项目: qioixiy/harvey
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;
}