Exemple #1
0
Fichier : mmu.c Projet : 8l/inferno
/*
 * flush data in a given address range to memory
 * and invalidate the region in the instruction cache.
 */
int
segflush(void *a, ulong n)
{
	dcflush(a, n);
	icflushall();	/* can't be more precise */
	return 0;
}
Exemple #2
0
Fichier : mmu.c Projet : 8l/inferno
int
segflush(void *a, ulong n)
{
	/* flush dcache then invalidate icache */
	dcflush(a, n);
	icflush(a, n);
	return 0;
}
Exemple #3
0
void
dcrcompile(void)
{
	ulong *p;
	int i;

	for(i=0; i<MAXDCR; i++){
		p = _getdcr[i];
		p[0] = MFDCR(i, 3);
		p[1] = RETURN;
		p = _putdcr[i];
		p[0] = MTDCR(3, i);
		p[1] = RETURN;
	}
	dcflush(PTR2UINT(_getdcr), sizeof(_getdcr));
	dcflush(PTR2UINT(_putdcr), sizeof(_putdcr));
	/* no need to flush icache since they won't be there */
}
Exemple #4
0
static void
txstart(Ether *ether)
{
	int len;
	Ctlr *ctlr;
	Block *b;
	BD *dre;

	ctlr = ether->ctlr;
	if(ctlr->init)
		return;
	while(ctlr->ntq < Ntdre-1){
		b = qget(ether->oq);
		if(b == 0)
			break;

		dre = &ctlr->tdr[ctlr->tdrh];
		dczap(dre, sizeof(BD));
		if(dre->status & BDReady)
			panic("ether: txstart");

		/*
		 * Give ownership of the descriptor to the chip, increment the
		 * software ring descriptor pointer and tell the chip to poll.
		 */
		len = BLEN(b);
		if(ctlr->txb[ctlr->tdrh] != nil)
			panic("fcc/ether: txstart");
		ctlr->txb[ctlr->tdrh] = b;
		if((ulong)b->rp&1)
			panic("fcc/ether: txstart align");	/* TO DO: ensure alignment */
		dre->addr = PADDR(b->rp);
		dre->length = len;
		dcflush(b->rp, len);
		dcflush(dre, sizeof(BD));
		dre->status = (dre->status & BDWrap) | BDReady|TxPad|BDInt|BDLast|TxTC;
		dcflush(dre, sizeof(BD));
/*		ctlr->fcc->ftodr = 1<<15;	/* transmit now; Don't do this according to errata */
		ctlr->ntq++;
		ctlr->tdrh = NEXT(ctlr->tdrh, Ntdre);
	}
}
Exemple #5
0
Fichier : mmu.c Projet : 8l/inferno
/*
 * return an uncached alias for the memory at a
 */
void*
mmucacheinhib(void *a, ulong nb)
{
	ulong p;

	if(a == nil)
		return nil;
	dcflush(a, nb);
	p = PADDR(a);
	return kmapphys((void*)(KSEG1|p), p, nb, TLBWR | TLBI | TLBG, 0);
}
Exemple #6
0
Fichier : cpm.c Projet : 8l/inferno
/*
 * initialise receive and transmit buffer rings.
 */
int
ioringinit(Ring* r, int nrdre, int ntdre, int bufsize)
{
	int i, x;

	/* the ring entries must be aligned on sizeof(BD) boundaries */
	r->nrdre = nrdre;
	if(r->rdr == nil)
		r->rdr = bdalloc(nrdre);
	/* the buffer size must align with cache lines since the cache doesn't snoop */
	bufsize = (bufsize+CACHELINESZ-1)&~(CACHELINESZ-1);
	if(r->rrb == nil)
		r->rrb = malloc(nrdre*bufsize);
	if(r->rdr == nil || r->rrb == nil)
		return -1;
	dcflush(r->rrb, nrdre*bufsize);
	x = PADDR(r->rrb);
	for(i = 0; i < nrdre; i++){
		r->rdr[i].length = 0;
		r->rdr[i].addr = x;
		r->rdr[i].status = BDEmpty|BDInt;
		x += bufsize;
	}
	r->rdr[i-1].status |= BDWrap;
	r->rdrx = 0;

	r->ntdre = ntdre;
	if(r->tdr == nil)
		r->tdr = bdalloc(ntdre);
	if(r->txb == nil)
		r->txb = malloc(ntdre*sizeof(Block*));
	if(r->tdr == nil || r->txb == nil)
		return -1;
	for(i = 0; i < ntdre; i++){
		r->txb[i] = nil;
		r->tdr[i].addr = 0;
		r->tdr[i].length = 0;
		r->tdr[i].status = 0;
	}
	r->tdr[i-1].status |= BDWrap;
	r->tdrh = 0;
	r->tdri = 0;
	r->ntq = 0;
	return 0;
}
Exemple #7
0
void
main(void)
{
	int machno;

	/* entry to main pushed stuff onto the stack. */

//	memset(edata, 0, (ulong)end-(ulong)edata);

	machno = getpir();
	if (machno > 0)
		startcpu(machno);

//	dcrcompile();
	if (dverify != 0x01020304) {
		uartlputs("data segment not initialised\n");
		panic("data segment not initialised");
	}
	if (bverify != 0) {
		uartlputs("bss segment not zeroed\n");
		panic("bss segment not zeroed");
	}
	mach0init();
	archreset();
	quotefmtinstall();
	optionsinit("/boot/boot boot");
//	archconsole();

	meminit();
	confinit();
	mmuinit();
	xinit();			/* xinit would print if it could */
	trapinit();
	qtminit();
	ioinit();
	uncinit();
	printinit();
	uartliteconsole();

	mainmem->flags |= POOL_ANTAGONISM;
	mainmem->panic = mypanic;
	ethermedium.maxtu = 1512;   /* must be multiple of 4 for temac's dma */

//	print("\n\nPlan 9k H\n");	/* already printed by l.s */
	plan9iniinit();
	timersinit();
	clockinit();

	dma0init();			/* does not start kprocs; see init0 */
	fpuinit();
	procinit0();
	initseg();
	links();

	chandevreset();
	okprint = 1;			/* only now can we print */
	barriers();
	dcflush((uintptr)&okprint, sizeof okprint);

	cpuidprint();

	print("%d Hz clock", HZ);
	print("; memory size %,ud (%#ux)\n", (uint)memsz, (uint)memsz);

	pageinit();
	swapinit();
	userinit();
	active.thunderbirdsarego = 1;
	dcflush((uintptr)&active.thunderbirdsarego,
		sizeof active.thunderbirdsarego);
	schedinit();
	/* no return */
	panic("schedinit returned");
}
Exemple #8
0
static void
interrupt(Ureg*, void *arg)
{
	int len, status, rcvd, xmtd, restart;
	ushort events;
	Ctlr *ctlr;
	BD *dre;
	Block *b, *nb;
	Ether *ether = arg;

	ctlr = ether->ctlr;
	if(!ctlr->active)
		return;	/* not ours */

	/*
	 * Acknowledge all interrupts and whine about those that shouldn't
	 * happen.
	 */
	events = ctlr->fcc->fcce;
	ctlr->fcc->fcce = events;		/* clear events */

#ifdef DBG
	ehisto[events & 0x7f]++;
#endif

	ctlr->interrupts++;

	if(events & BSY)
		ctlr->overrun++;
	if(events & TXE)
		ether->oerrs++;

#ifdef DBG
	rcvd = xmtd = 0;
#endif
	/*
	 * Receiver interrupt: run round the descriptor ring logging
	 * errors and passing valid receive data up to the higher levels
	 * until we encounter a descriptor still owned by the chip.
	 */
	if(events & RXF){
		dre = &ctlr->rdr[ctlr->rdrx];
		dczap(dre, sizeof(BD));
		while(((status = dre->status) & BDEmpty) == 0){
			rcvd++;
			if(status & RxError || (status & (BDFirst|BDLast)) != (BDFirst|BDLast)){
				if(status & (RxeLG|RxeSH))
					ether->buffs++;
				if(status & RxeNO)
					ether->frames++;
				if(status & RxeCR)
					ether->crcs++;
				if(status & RxeOV)
					ether->overflows++;
				print("eth rx: %ux\n", status);
			}else{
				/*
				 * We have a packet. Read it in.
				 */
				len = dre->length-4;
				b = ctlr->rcvbufs[ctlr->rdrx];
				assert(dre->addr == PADDR(b->rp));
				dczap(b->rp, len);
				if(nb = iallocb(Bufsize)){
					b->wp += len;
					etheriq(ether, b, 1);
					b = nb;
					b->rp = (uchar*)(((ulong)b->rp + CACHELINESZ-1) & ~(CACHELINESZ-1));
					b->wp = b->rp;
					ctlr->rcvbufs[ctlr->rdrx] = b;
					ctlr->rdr[ctlr->rdrx].addr = PADDR(b->wp);
				}else
					ether->soverflows++;
			}

			/*
			 * Finished with this descriptor, reinitialise it,
			 * give it back to the chip, then on to the next...
			 */
			dre->length = 0;
			dre->status = (status & BDWrap) | BDEmpty | BDInt;
			dcflush(dre, sizeof(BD));

			ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre);
			dre = &ctlr->rdr[ctlr->rdrx];
			dczap(dre, sizeof(BD));
		}
	}

	/*
	 * Transmitter interrupt: handle anything queued for a free descriptor.
	 */
	if(events & (TXB|TXE)){
		ilock(ctlr);
		restart = 0;
		while(ctlr->ntq){
			dre = &ctlr->tdr[ctlr->tdri];
			dczap(dre, sizeof(BD));
			status = dre->status;
			if(status & BDReady)
				break;
			if(status & TxeDEF)
				ctlr->deferred++;
			if(status & TxeHB)
				ctlr->heartbeat++;
			if(status & TxeLC)
				ctlr->latecoll++;
			if(status & TxeRL)
				ctlr->retrylim++;
			if(status & TxeUN)
				ctlr->underrun++;
			if(status & TxeCSL)
				ctlr->carrierlost++;
			if(status & (TxeLC|TxeRL|TxeUN))
				restart = 1;
			ctlr->retrycount += (status>>2)&0xF;
			b = ctlr->txb[ctlr->tdri];
			if(b == nil)
				panic("fcce/interrupt: bufp");
			ctlr->txb[ctlr->tdri] = nil;
			freeb(b);
			ctlr->ntq--;
			ctlr->tdri = NEXT(ctlr->tdri, Ntdre);
			xmtd++;
		}

		if(restart){
			ctlr->fcc->gfmr &= ~ENT;
			delay(10);
			ctlr->fcc->gfmr |= ENT;
			cpmop(RestartTx, ctlr->fccid, 0xc);
		}
		txstart(ether);
		iunlock(ctlr);
	}