Ejemplo n.º 1
0
/*
 * try to confirm sane operation
 */
void
dmatest(void)
{
	int n, done;
	uchar *bp;
	static ulong pat = 0x87654321;
	static Rendez trendez;

	if (up == nil)
		panic("dmatest: up not set yet");
	bp = (uchar *)KADDR(PHYSDRAM + 128*MB);
	memset(bp, Testbyte, Scratch);
	done = 0;
	dmastart((void *)PADDR(bp), Postincr, (void *)PADDR(&pat), Const,
		Testsize, &trendez, &done);
	sleep(&trendez, istestdmadone, &done);
	cachedinvse(bp, Scratch);

	if (((ulong *)bp)[0] != pat)
		panic("dmainit: copied incorrect data %#lux != %#lux",
			((ulong *)bp)[0], pat);
	for (n = Testsize; n < Scratch && bp[n] != Testbyte; n++)
		;
	if (n >= Scratch)
		panic("dmainit: ran wild over memory, clobbered ≥%,d bytes", n);
	if (bp[n] == Testbyte && n != Testsize)
		iprint("dma: %d-byte dma stopped after %d bytes!\n",
			Testsize, n);
}
Ejemplo n.º 2
0
void
spirw(uint cs, void *buf, int len)
{
	Spiregs *r;

	assert(cs <= 2);
	assert(len < (1<<16));
	qlock(&spi.lock);
	if(waserror()){
		qunlock(&spi.lock);
		nexterror();
	}
	if(spi.regs == 0)
		spiinit();
	r = spi.regs;
	r->dlen = len;
	r->cs = (cs << Csshift) | Rxclear | Txclear | Dmaen | Adcs | Ta;
	/*
	 * Start write channel before read channel - cache wb before inv
	 */
	dmastart(DmaChanSpiTx, DmaDevSpiTx, DmaM2D,
		buf, &r->data, len);
	dmastart(DmaChanSpiRx, DmaDevSpiRx, DmaD2M,
		&r->data, buf, len);
	if(dmawait(DmaChanSpiRx) < 0)
		error(Eio);
	cachedinvse(buf, len);
	r->cs = 0;
	qunlock(&spi.lock);
	poperror();
}
Ejemplo n.º 3
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));
		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->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);
		cachedinvse(b->rp, BLEN(b));
		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;
}
Ejemplo n.º 4
0
static void
receive(Ether *ether)
{
	int i;
	ulong n;
	Block *b;
	Ctlr *ctlr = ether->ctlr;
	Rx *r;

	ethercheck(ether);
	for (i = Nrx-2; i > 0; i--) {
		r = &ctlr->rx[ctlr->rxhead];	/* *r is uncached */
		assert(((uintptr)r & (Descralign - 1)) == 0);
		if(r->cs & RCSdmaown)		/* descriptor busy? */
			break;

		b = ctlr->rxb[ctlr->rxhead];	/* got input buffer? */
		if (b == nil)
			panic("ether1116: nil ctlr->rxb[ctlr->rxhead] "
				"in receive");
		ctlr->rxb[ctlr->rxhead] = nil;
		ctlr->rxhead = NEXT(ctlr->rxhead, Nrx);

		if((r->cs & (RCSfirst|RCSlast)) != (RCSfirst|RCSlast)) {
			ctlr->nofirstlast++;	/* partial packet */
			freeb(b);
			continue;
		}
		if(r->cs & RCSmacerr) {
			freeb(b);
			continue;
		}

		n = r->countsize >> 16;		/* TODO includes 2 pad bytes? */
		assert(n >= 2 && n < 2048);

		/* clear any cached packet or part thereof */
		l2cacheuinvse(b->rp, n+2);
		cachedinvse(b->rp, n+2);
		b->wp = b->rp + n;
		/*
		 * skip hardware padding intended to align ipv4 address
		 * in memory (mv-s104860-u0 §8.3.4.1)
		 */
		b->rp += 2;
		etheriq(ether, b, 1);
		etheractive(ether);
		if (i % (Nrx / 2) == 0) {
			rxreplenish(ctlr);
			rxkick(ctlr);
		}
	}
	rxreplenish(ctlr);
	rxkick(ctlr);
}
Ejemplo n.º 5
0
static void
emmcio(int write, uchar *buf, int len)
{
	u32int *r;
	int i;

	r = (u32int*)EMMCREGS;
	assert((len&3) == 0);
	okay(1);
	if(waserror()){
		okay(0);
		nexterror();
	}
	if(write)
		dmastart(DmaChanEmmc, DmaDevEmmc, DmaM2D,
			buf, &r[Data], len);
	else
		dmastart(DmaChanEmmc, DmaDevEmmc, DmaD2M,
			&r[Data], buf, len);
	if(dmawait(DmaChanEmmc) < 0)
		error(Eio);
	if(!write)
		cachedinvse(buf, len);
	WR(Irpten, Datadone|Err);
	tsleep(&emmc.r, datadone, 0, 3000);
	WR(Irpten, 0);
	emmc.datadone = 0;
	i = r[Interrupt];
	if((i & Datadone) == 0){
		print("emmcio: %d timeout intr %ux stat %ux\n",
			write, i, r[Status]);
		WR(Interrupt, i);
		error(Eio);
	}
	if(i & Err){
		print("emmcio: %d error intr %ux stat %ux\n",
			write, r[Interrupt], r[Status]);
		WR(Interrupt, i);
		error(Eio);
	}
	if(i)
		WR(Interrupt, i);
	poperror();
	okay(0);
}
Ejemplo n.º 6
0
/*
 * called on a cpu other than 0 from cpureset in l.s,
 * from _vrst in lexception.s.
 * mmu and l1 (and system-wide l2) caches and coherency (smpon) are on,
 * but interrupts are disabled.
 * our mmu is using an exact copy of cpu0's l1 page table
 * as it was after userinit ran.
 */
void
cpustart(void)
{
	int ms;
	ulong *evp;
	Power *pwr;

	up = nil;
	if (active.machs & (1<<m->machno)) {
		serialputc('?');
		serialputc('r');
		panic("cpu%d: resetting after start", m->machno);
	}
	assert(m->machno != 0);

	errata();
	cortexa9cachecfg();
	memdiag(&testmem);

	machinit();			/* bumps nmach, adds bit to machs */
	machoff(m->machno);		/* not ready to go yet */

	/* clock signals and scu are system-wide and already on */
	clockshutdown();		/* kill any watch-dog timer */

	trapinit();
	clockinit();			/* sets loop delay */
	timersinit();
	cpuidprint();

	/*
	 * notify cpu0 that we're up so it can proceed to l1diag.
	 */
	evp = (ulong *)soc.exceptvec;	/* magic */
	*evp = m->machno;
	coherence();

	l1diag();		/* contend with other cpus to verify sanity */

	/*
	 * pwr->noiopwr == 0
	 * pwr->detect == 0x1ff (default, all disabled)
	 */
	pwr = (Power *)soc.power;
	assert(pwr->gatests == MASK(7)); /* everything has power */

	/*
	 * 8169 has to initialise before we get past this, thus cpu0
	 * has to schedule processes first.
	 */
	if (Debug)
		iprint("cpu%d: waiting for 8169\n", m->machno);
	for (ms = 0; !l1ptstable.word && ms < 5000; ms += 10) {
		delay(10);
		cachedinvse(&l1ptstable.word, sizeof l1ptstable.word);
	}
	if (!l1ptstable.word)
		iprint("cpu%d: 8169 unreasonably slow; proceeding\n", m->machno);
	/* now safe to copy cpu0's l1 pt in mmuinit */

	mmuinit();			/* update our l1 pt from cpu0's */
	fpon();
	machon(m->machno);		/* now ready to go and be scheduled */

	if (Debug)
		iprint("cpu%d: scheding\n", m->machno);
	schedinit();
	panic("cpu%d: schedinit returned", m->machno);
}