diff -Nru /sys/src/9/vt4/etherif.h /sys/src/9/vt4/etherif.h --- /sys/src/9/vt4/etherif.h Mon Jul 15 00:00:00 2013 +++ /sys/src/9/vt4/etherif.h Mon Jul 15 00:00:00 2013 @@ -32,8 +32,8 @@ /* statistics */ ulong interrupts; - ulong dmarxintr; - ulong dmatxintr; + ulong rxintr; + ulong txintr; ulong promisc; ulong pktsdropped; ulong pktsmisaligned; diff -Nru /sys/src/9/vt4/etherlltemac.c /sys/src/9/vt4/etherlltemac.c --- /sys/src/9/vt4/etherlltemac.c Mon Jul 15 00:00:00 2013 +++ /sys/src/9/vt4/etherlltemac.c Mon Jul 15 00:00:00 2013 @@ -1,7 +1,6 @@ /* * Xilinx XPS LL Temac Ethernet v1.00b + XPS LL Local Link FIFOs v1.00a driver. * - * It uses the Central DMA controller. * There are two interfaces per Temac controller. * Each Temac interface is connected to a pair of FIFOs (tx and rx). * Half-duplex is not supported by hardware. @@ -187,15 +186,8 @@ Lock; ushort active; - /* tx state, for Block being sent */ - int txdma; - Block *tbp; /* non-nil if dma to fifo in progress */ - /* rx state, for packet being read */ - int rxdma; - long rlf; /* read from frp->rlf iff non-negative */ ulong fifoier; - Block *rbp; /* non-nil if dma from fifo in progress */ }; struct Llfiforegs { @@ -220,7 +212,6 @@ char *msg; } Error; -extern int dmaready; /* flag: ready for general use? */ extern uchar mymac[Eaddrlen]; static Error errs[] = { @@ -237,7 +228,7 @@ int fifointr(ulong bit); static void fiforeset(Ether *ether); -static int dmatxstart(Ether *); +static int txstart(Ether *); static void getready(Temacregs *trp) @@ -296,8 +287,10 @@ while ((sts = trp->is) & (Autoneg | Rxfifoovr)) { forme = 1; if (sts & Rxfifoovr) { - iprint("temac: receive fifo overrun. "); - whackether(ether); +// iprint("temac: receive fifo overrun. "); +// whackether(ether); + trp->is = sts; /* extinguish intr source */ + barriers(); } if (sts & Autoneg) { iprint("temac: autoneg done\n"); @@ -318,10 +311,7 @@ ctlr = ether->ctlr; - delay(20); /* let any dma in progress complete */ - ctlr->active = ctlr->txdma = ctlr->rxdma = 0; - ctlr->rlf = -1; - ctlr->rbp = ctlr->tbp = nil; + ctlr->active = 0; barriers(); } @@ -366,7 +356,7 @@ static void temacshutdown(Ether* ether) { - reset(ether); /* stop dma at the very least */ + reset(ether); } static int promon, multion; @@ -430,7 +420,7 @@ ctlr = ether->ctlr; ilock(ctlr); - dmatxstart(ether); + txstart(ether); iunlock(ctlr); } @@ -464,10 +454,10 @@ p = malloc(READSTR); len = snprint(p, READSTR, "interrupts: %lud\n", ether->interrupts); - len += snprint(p+len, READSTR-len, "dma rx intrs: %lud\n", - ether->dmarxintr); - len += snprint(p+len, READSTR-len, "dma tx intrs: %lud\n", - ether->dmatxintr); + len += snprint(p+len, READSTR-len, "rx intrs: %lud\n", + ether->rxintr); + len += snprint(p+len, READSTR-len, "tx intrs: %lud\n", + ether->txintr); len += snprint(p+len, READSTR-len, "broadcasts rcvd: %lud\n", ether->bcasts); len += snprint(p+len, READSTR-len, "multicasts rcvd: %lud\n", @@ -528,7 +518,7 @@ wrindir(trp, Tc, Tx); ether->promisc = 0; -if (0) { +if (1) { ea = 0; for (i = 0; i < Eaddrlen; i++) ea |= (uvlong)pausemac[i] << (i * 8); @@ -539,6 +529,7 @@ wrindir(trp, Fcc, 0); /* no flow control */ wrindir(trp, Emmc, Defls); +// wrindir(trp, Rcw1, Rx); ctlr->active = 1; barriers(); @@ -674,7 +665,7 @@ return 0; } -static int dmarecv(Ether *); +static int recv(Ether *); static void fifointrset(Temacctlr *ctlr) @@ -711,74 +702,6 @@ } static void -dmarxdone(int) -{ - int whack, multi; - long rdfo; - Block *bp; - Ether *ether; - Etherpkt *pkt; - Temacctlr *ctlr; - - ether = ethers[0]; - ctlr = ether->ctlr; - - ilock(ctlr); - ether->dmarxintr++; - bp = ctlr->rbp; - ctlr->rbp = nil; /* prevent accidents */ - if (ctlr->rxdma == 0 || bp == nil) { - if (bp != nil) - freeb(bp); - if (ctlr->rxdma == 0) - iprint("dmarxdone: no rx dma in progress\n"); - else - iprint("dmarxdone: no block for rx dma just finished!\n"); - lightbitoff(Ledethinwait); - enafifointr(ctlr, Rc); - iunlock(ctlr); - return; - } - ctlr->rxdma = 0; - barriers(); - - /* - * rx Step 2: packet is in Block, pass it upstream. - */ - /* could check for dma errors */ - pkt = (Etherpkt*)bp->rp; - assert(pkt != nil); - multi = pkt->d[0] & 1; - if (multi) - if(memcmp(pkt->d, ether->bcast, sizeof pkt->d) == 0) - ether->bcasts++; - else - ether->mcasts++; - - etheriq(ether, bp, 1); - lightbitoff(Ledethinwait); - - /* - * rx Step 3/0: if there's another packet in the rx fifo, - * start dma into a new Block, else reenable recv intrs. - */ - whack = 0; - rdfo = getrdfo(); - if (rdfo < 0) - whack = 1; /* ether is buggered */ - else if (rdfo > 0) /* more packets in rx fifo? */ - whack = dmarecv(ether); /* if dma starts, disables Rc */ - else { - if (frp->isr & Rc) - wave('|'); /* isr Rc was set when fifo was empty */ - enafifointr(ctlr, Rc); - } - /* if this whacks the ctlr, all the intr enable bits will be set */ - whackiferr(ether, whack, frp->isr); - iunlock(ctlr); -} - -static void discard(Ether *ether, unsigned ruplen) { ulong null; @@ -797,21 +720,21 @@ * interrupts masked. */ static int -dmarecv(Ether *ether) +recv(Ether *ether) { long rdfo; ulong len, ruplen; Block *bp; Temacctlr *ctlr; + Etherpkt *pkt; + int whack, multi; ctlr = ether->ctlr; - if (ctlr->rxdma) - return 0; /* next rx dma interrupt should process this packet*/ /* ignore frp->isr & Rc; just look at rx fifo occupancy */ rdfo = getrdfo(); if (rdfo < 0) { - iprint("dmarecv: negative rdfo\n"); + iprint("recv: negative rdfo\n"); return 1; /* ether is buggered */ } if (rdfo == 0) @@ -820,25 +743,16 @@ if (!(frp->isr & Rc)) wave('@'); /* isr Rc wasn't set when fifo had stuff in it */ - /* - * We have at least one packet in the rx fifo. Read the length - * of the first one, if not already known. - */ - if (ctlr->rlf >= 0) - len = ctlr->rlf; /* from a previous call */ - else { - assert(frp != nil); - /* read length word from rx fifo */ - len = frp->rlf; - if (len & ~Bytecnt) { - iprint("fifo: impossible rlf value\n"); - return 1; - } - if (len == 0) { - iprint("fifo: rdfo %lud > 0 but rlf == 0\n", rdfo); - return 1; - } - ctlr->rlf = len; /* save in case dma is busy below */ + assert(frp != nil); + /* read length word from rx fifo */ + len = frp->rlf; + if (len & ~Bytecnt) { + iprint("fifo: impossible rlf value\n"); + return 1; + } + if (len == 0) { + iprint("fifo: rdfo %lud > 0 but rlf == 0\n", rdfo); + return 1; } ruplen = ROUNDUP(len, BY2WD); @@ -847,9 +761,6 @@ discard(ether, ruplen); return 0; } - - if (!dmaready) /* too early, dma not really set up */ - return 0; bp = clallocb(); if(bp == nil){ iprint("fifo: no buffer for input pkt\n"); @@ -860,28 +771,52 @@ /* * rx Step 1: dma from rx fifo into Block, turn off recv interrupts. - * wait for dmarxdone (interrupt) to pass the Block upstream. */ - if (!dmastart(Chan0, bp->rp, &frp->rdfd, ruplen, Dinc, dmarxdone)) { - /* should never get here */ - iprint("dmarecv: dmastart failed for Chan0\n"); - freeb(bp); - enafifointr(ctlr, Rc); - /* we'll try again next time we're called */ - return 0; - } - ctlr->rlf = -1; /* we're committed now */ + fifocpy(bp->rp, &frp->rdfd, ruplen, Dinc); lightbiton(Ledethinwait); bp->wp = bp->rp + len; - assert(ctlr->rbp == nil); - ctlr->rbp = bp; - ctlr->rxdma = 1; barriers(); /* * we're waiting for dma and can't start dma of another * incoming packet until the current dma is finished. */ disfifointr(ctlr, Rc); + + ether->rxintr++; + + /* + * rx Step 2: packet is in Block, pass it upstream. + */ + pkt = (Etherpkt*)bp->rp; + assert(pkt != nil); + multi = pkt->d[0] & 1; + if (multi) + if(memcmp(pkt->d, ether->bcast, sizeof pkt->d) == 0) + ether->bcasts++; + else + ether->mcasts++; + + etheriq(ether, bp, 1); + lightbitoff(Ledethinwait); + + /* + * rx Step 3: if there's another packet in the rx fifo, + * start dma into a new Block, else reenable recv intrs. + */ + whack = 0; + rdfo = getrdfo(); + if (rdfo < 0) + whack = 1; /* ether is buggered */ + else if (rdfo > 0) /* more packets in rx fifo? */ + whack = recv(ether); /* if dma starts, disables Rc */ + else { + if (frp->isr & Rc) + wave('|'); /* isr Rc was set when fifo was empty */ + enafifointr(ctlr, Rc); + } + /* if this whacks the ctlr, all the intr enable bits will be set */ + whackiferr(ether, whack, frp->isr); + return 0; } @@ -933,7 +868,7 @@ r |= ic; whack = 0; if (sts & Rc) - whack = dmarecv(ether); + whack = recv(ether); else if (getrdfo() != 0) wave('~'); /* isr Rc off, yet fifo !empty */ @@ -965,7 +900,6 @@ Temacctlr *ctlr; barriers(); - dma0init(); /* could be dma in progress, so shut that down */ ctlr = ether->ctlr; ctlr->fifoier = 0; @@ -1010,44 +944,6 @@ } /* - * tx Step 2: write frp->tlr, thus initiating ethernet transmission of - * the Block just copied into the tx fifo, and free that Block. - */ -static void -dmatxdone(int) -{ - Block *bp; - Ether *ether; - Temacctlr *ctlr; - - ether = ethers[0]; - ctlr = ether->ctlr; - - ilock(ctlr); - ether->dmatxintr++; - ctlr->txdma = 0; - - /* - * start transmitting this packet from the output fifo. - * contrary to DS568 Table 5's description of TSE, it seems - * to be legal to write an odd value into tlf (unless the word - * `match' implies ±1), but it may be necessary to provide a - * padding byte in the fifo if you do. - */ - bp = ctlr->tbp; - if (bp != nil) { - ctlr->tbp = nil; - frp->tlf = padpktlen(BLEN(bp)); - barriers(); - freeb(bp); - ether->tbusy = 0; - } - - dmatxstart(ether); /* attempt another dma to tx fifo */ - iunlock(ctlr); -} - -/* * if possible, start dma of the first packet of the output queue into * the tx fifo. * @@ -1058,16 +954,12 @@ * as of v2 of the dma controller. */ static int -dmatxstart(Ether *ether) +txstart(Ether *ether) { unsigned len, ruplen; Block *bp; - Temacctlr *ctlr; - if (ether == nil || ether->oq == nil || ether->tbusy) - return 0; - ctlr = ether->ctlr; - if (ctlr->txdma) + if (ether == nil || ether->oq == nil) return 0; SET(len); while ((bp = qget(ether->oq)) != nil) { @@ -1081,12 +973,6 @@ } if (bp == nil) return 0; - if (!dmaready) { /* too early? */ - iprint("dmatxstart: dma not ready\n"); - freeb(bp); - disfifointr(ctlr, FifoTc); - return 0; - } if (len == 0) print("idiot sending zero-byte packet\n"); @@ -1098,20 +984,19 @@ * interrupt will resume transmission of it. */ if ((frp->tdfv & Wordcnt) < ruplen / BY2WD) { - iprint("dmatxstart: no room in tx fifo\n"); + iprint("txstart: no room in tx fifo\n"); return 0; } - /* tx Step 1: dma to tx fifo, wait for dma tx interrupt */ + /* tx Step 1: to tx fifo */ lightbiton(Ledethoutwait); - if (dmastart(Chan1, &frp->tdfd, bp->rp, ruplen, Sinc, dmatxdone)) { - ether->tbusy = 1; - ctlr->txdma = 1; - barriers(); - /* Rc may be off if we got Rc intrs too early */ -// enafifointr(ctlr, FifoTc | Rc); - ctlr->tbp = bp; /* remember this block */ - } else - iprint("dmatxstart: dmastart failed for Chan1\n"); + fifocpy(&frp->tdfd, bp->rp, ruplen, Sinc); + ether->txintr++; + frp->tlf = padpktlen(BLEN(bp)); + barriers(); + freeb(bp); + + txstart(ether); + return 1; } diff -Nru /sys/src/9/vt4/main.c /sys/src/9/vt4/main.c --- /sys/src/9/vt4/main.c Mon Jul 15 00:00:00 2013 +++ /sys/src/9/vt4/main.c Mon Jul 15 00:00:00 2013 @@ -190,7 +190,7 @@ timersinit(); clockinit(); - dma0init(); /* does not start kprocs; see init0 */ +// dma0init(); /* does not start kprocs; see init0 */ fpuinit(); procinit0(); initseg(); @@ -281,7 +281,7 @@ up->slash->path = newpath("/"); up->dot = cclone(up->slash); - dmainit(); /* starts dma kprocs */ +// dmainit(); /* starts dma kprocs */ devtabinit(); if(!waserror()){ diff -Nru /sys/src/9/vt4/physmem.h /sys/src/9/vt4/physmem.h --- /sys/src/9/vt4/physmem.h Mon Jul 15 00:00:00 2013 +++ /sys/src/9/vt4/physmem.h Mon Jul 15 00:00:00 2013 @@ -14,19 +14,9 @@ #define PHYSMMIO Io -#define Io 0xf0000000 /* ~512K of IO registers */ -#define Uartlite 0xf0000000 -#define Gpio 0xf0010000 -#define Intctlr 0xf0020000 -#define Temac 0xf0030000 -#define Llfifo 0xf0040000 -#define Dmactlr 0xf0050000 -#define Dmactlr2 0xf0060000 -/* - * if these devices exist in a given hardware configuration, - * they will be at these addresses. - */ -#define Qtm 0xf0070000 /* encrypted memory control */ -#define Mpmc 0xf0080000 /* multi-port memory controller */ -/* setting low bit interrupts cpu0; don't set Hie */ -#define Intctlr2 0xf0090000 /* sw interrupt controller */ +#define Io 0xf0000000 /* ~1MB of IO registers */ +#define Uartlite 0xf0000000 /* 64 KB */ +#define Gpio 0xf0010000 /* 64 KB */ +#define Intctlr 0xf0020000 /* 64 KB */ +#define Llfifo 0xf0070000 /* 64 KB */ +#define Temac 0xf0080000 /* 512 KB */ diff -Nru /sys/src/9/vt4/tlb.s /sys/src/9/vt4/tlb.s --- /sys/src/9/vt4/tlb.s Mon Jul 15 00:00:00 2013 +++ /sys/src/9/vt4/tlb.s Mon Jul 15 00:00:00 2013 @@ -44,11 +44,9 @@ /* MACs are stored in 113.78—128 MB in the secure-memory design */ TLBED16MB(7) - /* memory-mapped IO, 512KB */ - TLBE(PHYSMMIO | TLB256K | TLBVALID, + /* memory-mapped IO, 1MB */ + TLBE(PHYSMMIO | TLB1MB | TLBVALID, PHYSMMIO | TLBZONE(0) | TLBWR | TLBI | TLBG) - TLBE(PHYSMMIO+256*1024 | TLB256K | TLBVALID, - PHYSMMIO+256*1024 | TLBZONE(0) | TLBWR | TLBI | TLBG) /* SRAM, 128K. put vectors here. */ TLBE(PHYSSRAM | TLB64K | TLBVALID, diff -Nru /sys/src/9/vt4/vt4cpu /sys/src/9/vt4/vt4cpu --- /sys/src/9/vt4/vt4cpu Mon Jul 15 00:00:00 2013 +++ /sys/src/9/vt4/vt4cpu Mon Jul 15 00:00:00 2013 @@ -38,7 +38,7 @@ ipmux misc - dma +# dma rdb # sdaoe sdscsi softfpu diff -Nru /sys/src/boot/vt4/load.c /sys/src/boot/vt4/load.c --- /sys/src/boot/vt4/load.c Mon Jul 15 00:00:00 2013 +++ /sys/src/boot/vt4/load.c Mon Jul 15 00:00:00 2013 @@ -483,12 +483,12 @@ */ trapinit(); PROG(' ') - securemem = (probeaddr(Qtm) >= 0); - if (securemem) - PROG('q') - else - PROG('n') -PROG(' ') +// securemem = (probeaddr(Qtm) >= 0); +// if (securemem) +// PROG('q') +// else +// PROG('n') +//PROG(' ') /* * the stack is now at top of sram, and entry to main just pushed diff -Nru /sys/src/boot/vt4/physmem.h /sys/src/boot/vt4/physmem.h --- /sys/src/boot/vt4/physmem.h Mon Jul 15 00:00:00 2013 +++ /sys/src/boot/vt4/physmem.h Mon Jul 15 00:00:00 2013 @@ -15,19 +15,9 @@ #define PHYSDRAM 0 #define PHYSSRAM 0xfffe0000 /* 128K long, in top 128M */ -#define Io 0xf0000000 /* ~512K of IO registers */ -#define Uartlite 0xf0000000 -#define Gpio 0xf0010000 -#define Intctlr 0xf0020000 -#define Temac 0xf0030000 -#define Llfifo 0xf0040000 -#define Dmactlr 0xf0050000 -#define Dmactlr2 0xf0060000 -/* - * if these devices exist in a given hardware configuration, - * they will be at these addresses. - */ -#define Qtm 0xf0070000 /* encrypted memory control */ -#define Mpmc 0xf0080000 /* multi-port memory controller */ -/* setting low bit interrupts cpu0; don't set Hie */ -#define Intctlr2 0xf0090000 /* sw interrupt controller */ +#define Io 0xf0000000 /* ~1MB of IO registers */ +#define Uartlite 0xf0000000 /* 64 KB */ +#define Gpio 0xf0010000 /* 64 KB */ +#define Intctlr 0xf0020000 /* 64 KB */ +#define Llfifo 0xf0070000 /* 64 KB */ +#define Temac 0xf0080000 /* 512 KB */