Exemplo n.º 1
0
static long
ctltrans(Ep *ep, uchar *req, long n)
{
	Hostchan *hc;
	Epio *epio;
	Block *b;
	uchar *data;
	int datalen;

	epio = ep->aux;
	if(epio->cb != nil){
		freeb(epio->cb);
		epio->cb = nil;
	}
	if(n < Rsetuplen)
		error(Ebadlen);
	if(req[Rtype] & Rd2h){
		datalen = GET2(req+Rcount);
		if(datalen <= 0 || datalen > Maxctllen)
			error(Ebadlen);
		/* XXX cache madness */
               	epio->cb = b = allocb(ROUND(datalen, ep->maxpkt) + CACHELINESZ);
               	b->wp = (uchar*)ROUND((uintptr)b->wp, CACHELINESZ);
		//epio->cb = b = allocb(ROUND(datalen, ep->maxpkt));
		//assert(((uintptr)b->wp & (BLOCKALIGN-1)) == 0);
		memset(b->wp, 0x55, b->lim - b->wp);
		cachedwbinvse(b->wp, b->lim - b->wp);
		data = b->wp;
	}else{
		b = nil;
		datalen = n - Rsetuplen;
		data = req + Rsetuplen;
	}
	hc = chanalloc(ep);
	if(waserror()){
		chanrelease(ep, hc);
		if(strcmp(up->env->errstr, Estalled) == 0)
			return 0;
		nexterror();
	}
	chansetup(hc, ep);
	chanio(ep, hc, Epout, SETUP, req, Rsetuplen);
	if(req[Rtype] & Rd2h){
		if(ep->dev->hub <= 1){
			ep->toggle[Read] = DATA1;
			b->wp += multitrans(ep, hc, Read, data, datalen);
		}else
			b->wp += chanio(ep, hc, Epin, DATA1, data, datalen);
		chanio(ep, hc, Epout, DATA1, nil, 0);
		n = Rsetuplen;
	}else{
		if(datalen > 0)
			chanio(ep, hc, Epout, DATA1, data, datalen);
		chanio(ep, hc, Epin, DATA1, nil, 0);
		n = Rsetuplen + datalen;
	}
	chanrelease(ep, hc);
	poperror();
	return n;
}
Exemplo n.º 2
0
void*
mmuuncache(void* v, usize size)
{
	int x;
	PTE *pte;
	uintptr va;

	/*
	 * Simple helper for ucalloc().
	 * Uncache a Section, must already be
	 * valid in the MMU.
	 */
	va = PTR2UINT(v);
	assert(!(va & (1*MiB-1)) && size == 1*MiB);

	x = L1X(va);
	pte = &m->mmul1[x];
	if((*pte & (Fine|Section|Coarse)) != Section)
		return nil;
	*pte &= ~(Cached|Buffered);
	mmuinvalidateaddr(va);
	cachedwbinvse(pte, 4);

	return v;
}
Exemplo n.º 3
0
/* go to user space */
void
kexit(Ureg*)
{
	uvlong t;
	Tos *tos;

	/* precise time accounting, kernel exit */
	tos = (Tos*)(USTKTOP-sizeof(Tos));
	t = fastticks(nil);
	tos->kcycles += t - up->kentry;
	tos->pcycles = up->pcycles;
	tos->cyclefreq = Frequency;
	tos->pid = up->pid;

	/* make visible immediately to user proc */
	cachedwbinvse(tos, sizeof *tos);
}
Exemplo n.º 4
0
static int
vcreq(int tag, void *buf, int vallen, int rsplen)
{
	uintptr r;
	int n;
	Prophdr *prop;
	uintptr aprop;
	static int busaddr = 1;

	if(rsplen < vallen)
		rsplen = vallen;
	rsplen = (rsplen+3) & ~3;
	prop = (Prophdr*)(VCBUFFER);
	n = sizeof(Prophdr) + rsplen + 8;
	memset(prop, 0, n);
	prop->len = n;
	prop->req = Req;
	prop->tag = tag;
	prop->tagbuflen = rsplen;
	prop->taglen = vallen;
	if(vallen > 0)
		memmove(prop->data, buf, vallen);
	cachedwbinvse(prop, prop->len);
	for(;;){
		aprop = busaddr? dmaaddr(prop) : PTR2UINT(prop);
		vcwrite(ChanProps, aprop);
		r = vcread(ChanProps);
		if(r == aprop)
			break;
		if(!busaddr)
			return -1;
		busaddr = 0;
	}
	if(prop->req == RspOk &&
	   prop->tag == tag &&
	   (prop->taglen&TagResp)) {
		if((n = prop->taglen & ~TagResp) < rsplen)
			rsplen = n;
		memmove(buf, prop->data, rsplen);
	}else
		rsplen = -1;

	return rsplen;
}
Exemplo n.º 5
0
static int
vcreq(int tag, void *buf, int vallen, int rsplen)
{
	uintptr r;
	int n;
	Prophdr *prop;
	static uintptr base = BUSDRAM;

	if(rsplen < vallen)
		rsplen = vallen;
	rsplen = (rsplen+3) & ~3;
	prop = (Prophdr*)(VCBUFFER);
	n = sizeof(Prophdr) + rsplen + 8;
	memset(prop, 0, n);
	prop->len = n;
	prop->req = Req;
	prop->tag = tag;
	prop->tagbuflen = rsplen;
	prop->taglen = vallen;
	if(vallen > 0)
		memmove(prop->data, buf, vallen);
	cachedwbinvse(prop, prop->len);
	for(;;){
		vcwrite(ChanProps, PADDR(prop) + base);
		r = vcread(ChanProps);
		if(r == PADDR(prop) + base)
			break;
		if(base == 0)
			return -1;
		base = 0;
	}
	if(prop->req == RspOk &&
	   prop->tag == tag &&
	   (prop->taglen&TagResp)) {
		if((n = prop->taglen & ~TagResp) < rsplen)
			rsplen = n;
		memmove(buf, prop->data, rsplen);
	}else
		rsplen = -1;

	return rsplen;
}
Exemplo n.º 6
0
uintptr
mmukunmap(uintptr va, uintptr pa, usize size)
{
	int x;
	PTE *pte;

	/*
	 * Stub.
	 */
	assert(!(va & (1*MiB-1)) && !(pa & (1*MiB-1)) && size == 1*MiB);

	x = L1X(va);
	pte = &m->mmul1[x];
	if(*pte != (pa|Dom0|L1AP(Krw)|Section))
		return 0;
	*pte = Fault;
	mmuinvalidateaddr(va);
	cachedwbinvse(pte, 4);

	return va;
}
Exemplo n.º 7
0
void*
fbinit(int set, int *width, int *height, int *depth)
{
	Fbinfo *fi;
	uintptr va;

	if(!set)
		fbdefault(width, height, depth);
	/* Screen width must be a multiple of 16 */
	*width &= ~0xF;
	fi = (Fbinfo*)(VCBUFFER);
	memset(fi, 0, sizeof(*fi));
	fi->xres = fi->xresvirtual = *width;
	fi->yres = fi->yresvirtual = *height;
	fi->bpp = *depth;
	cachedwbinvse(fi, sizeof(*fi));
	vcwrite(ChanFb, DMAADDR(fi));
	if(vcread(ChanFb) != 0)
		return 0;
	va = mmukmap(FRAMEBUFFER, PADDR(fi->base), fi->screensize);
	if(va)
		memset((char*)va, 0x7F, fi->screensize);
	return (void*)va;
}
Exemplo n.º 8
0
Arquivo: clock.c Projeto: CoryXie/NxM
void
clockinit(void)
{
	int i, s;
	Timerregs *tn;

	clockshutdown();

	/* turn cycle counter on */
	cpwrsc(0, CpCLD, CpCLDena, CpCLDenacyc, 1<<31);

	/* turn all counters on and clear the cycle counter */
	cpwrsc(0, CpCLD, CpCLDena, CpCLDenapmnc, 1<<2 | 1);

	/* let users read the cycle counter directly */
	cpwrsc(0, CpCLD, CpCLDena, CpCLDenapmnc, 1);

	ilock(&clklck);
	m->fastclock = 1;
	m->ticks = ticks = 0;

	/*
	 * T0 is a freerunning timer (cycle counter); it wraps,
	 * automatically reloads, and does not dispatch interrupts.
	 */
	tn = (Timerregs *)Tn0;
	tn->tcrr = Freebase;			/* count up to 0 */
	tn->tldr = Freebase;
	coherence();
	tn->tclr = Ar | St;
	iunlock(&clklck);

	/*
	 * T1 is the interrupting timer and does not participate
	 * in measuring time.  It is initially set to HZ.
	 */
	tn = (Timerregs *)Tn1;
	irqenable(Tn0irq+1, clockintr, tn, "clock");
	ilock(&clklck);
	tn->tcrr = -Tcycles;			/* approx.; count up to 0 */
	tn->tldr = -Tcycles;
	coherence();
	tn->tclr = Ar | St;
	coherence();
	tn->tier = Ovf_it;
	coherence();
	iunlock(&clklck);

	/*
	 * verify sanity of timer1
	 */
	s = spllo();			/* risky */
	for (i = 0; i < 5 && ticks == 0; i++) {
		delay(10);
		cachedwbinvse(&ticks, sizeof ticks);
	}
	splx(s);
	if (ticks == 0) {
		if (tn->tcrr == 0)
			panic("clock not interrupting");
		else if (tn->tcrr == tn->tldr)
			panic("clock not ticking at all");
#ifdef PARANOID
		else
			panic("clock running very slowly");
#endif
	}

	guessmips(issue1loop, "single");
	if (Debug)
		iprint(", ");
	guessmips(issue2loop, "dual");
	if (Debug)
		iprint("\n");

	/*
	 * m->delayloop should be the number of delay loop iterations
	 * needed to consume 1 ms.  2 is min. instructions in the delay loop.
	 */
	m->delayloop = m->cpuhz / (1000 * 2);
//	iprint("m->delayloop = %lud\n", m->delayloop);

	/*
	 *  desynchronize the processor clocks so that they all don't
	 *  try to resched at the same time.
	 */
	delay(m->machno*2);
}
Exemplo n.º 9
0
void
segflush(void* p, ulong n) {
	cachedwbinvse(p,n);
	cacheiinvse(p,n);
}
Exemplo n.º 10
0
void
dmastart(int chan, int dev, int dir, void *src, void *dst, int len)
{
	Ctlr *ctlr;
	Cb *cb;
	int ti;

	ctlr = &dma[chan];
	if(ctlr->regs == nil){
		ctlr->regs = (u32int*)(DMAREGS + chan*Regsize);
		ctlr->cb = xspanalloc(sizeof(Cb), Cbalign, 0);
		assert(ctlr->cb != nil);
		dmaregs[Enable] |= 1<<chan;
		ctlr->regs[Cs] = Reset;
		while(ctlr->regs[Cs] & Reset)
			;
		intrenable(IRQDMA(chan), dmainterrupt, ctlr, 0, "dma");
	}
	cb = ctlr->cb;
	ti = 0;
	switch(dir){
	case DmaD2M:
		cachedwbinvse(dst, len);
		ti = Srcdreq | Destinc;
		cb->sourcead = DMAIO(src);
		cb->destad = DMAADDR(dst);
		break;
	case DmaM2D:
		cachedwbse(src, len);
		ti = Destdreq | Srcinc;
		cb->sourcead = DMAADDR(src);
		cb->destad = DMAIO(dst);
		break;
	case DmaM2M:
		cachedwbse(src, len);
		cachedwbinvse(dst, len);
		ti = Srcinc | Destinc;
		cb->sourcead = DMAADDR(src);
		cb->destad = DMAADDR(dst);
		break;
	}
	cb->ti = ti | dev<<Permapshift | Inten;
	cb->txfrlen = len;
	cb->stride = 0;
	cb->nextconbk = 0;
	cachedwbse(cb, sizeof(Cb));
	ctlr->regs[Cs] = 0;
	microdelay(1);
	ctlr->regs[Conblkad] = DMAADDR(cb);
	DBG print("dma start: %ux %ux %ux %ux %ux %ux\n",
		cb->ti, cb->sourcead, cb->destad, cb->txfrlen,
		cb->stride, cb->nextconbk);
	DBG print("intstatus %ux\n", dmaregs[Intstatus]);
	dmaregs[Intstatus] = 0;
	ctlr->regs[Cs] = Int;
	microdelay(1);
	coherence();
	DBG dumpdregs("before Active", ctlr->regs);
	ctlr->regs[Cs] = Active;
	DBG dumpdregs("after Active", ctlr->regs);
}