diff --git a/sys/src/9/cycv/cycv b/sys/src/9/cycv/cycv index 61aa7eabb..7883a6575 100644 --- a/sys/src/9/cycv/cycv +++ b/sys/src/9/cycv/cycv @@ -2,7 +2,7 @@ dev root cons swap -# arch + arch uart mnt srv @@ -24,6 +24,7 @@ dev segment link + dma ethercycv ethermedium loopbackmedium diff --git a/sys/src/9/cycv/dat.h b/sys/src/9/cycv/dat.h index ca1dff54c..ce4417856 100644 --- a/sys/src/9/cycv/dat.h +++ b/sys/src/9/cycv/dat.h @@ -13,6 +13,7 @@ typedef struct Proc Proc; typedef struct PMMU PMMU; typedef struct Ureg Ureg; typedef struct ISAConf ISAConf; +typedef struct DMAC DMAC; typedef uvlong Tval; #pragma incomplete Ureg @@ -202,3 +203,7 @@ struct DevConf #define mpcore ((ulong*)MPCORE_BASE) #define resetmgr ((ulong*)RESETMGR_BASE) #define sysmgr ((ulong*)SYSMGR_BASE) + +/*dmacopy*/ +#define SRC_INC (1<<0) +#define DST_INC (1<<14) diff --git a/sys/src/9/cycv/devarch.c b/sys/src/9/cycv/devarch.c index 00a368fd6..32b832d64 100644 --- a/sys/src/9/cycv/devarch.c +++ b/sys/src/9/cycv/devarch.c @@ -7,11 +7,44 @@ #include "ureg.h" #include "../port/error.h" +#define fpga ((ulong*) FPGAMGR_BASE) + +enum { Timeout = 3000 }; + +enum { + FPGASTAT, + FPGACTRL, + FPGAINTEN = 0x830/4, + FPGAINTTYPE = 0x838/4, + FPGAINTPOL = 0x83C/4, + FPGAINTSTATUS = 0x840/4, + FPGAEOI = 0x84C/4, + FPGAPINS = 0x850/4, +}; + +enum { + /*FPGACTRL*/ + HPSCONFIG = 1<<0, + NCONFIGPULL = 1<<2, + AXICFGEN = 1<<8, + /*FPGAPINS*/ + NSTATUS = 1<<0, + CONF_DONE = 1<<1, + INIT_DONE = 1<<2, + CRC_ERROR = 1<<3, + CVP_CONF_DONE = 1<<4, + PR_READY = 1<<5, + PR_ERROR = 1<<6, + PR_DONE = 1<<7, + NCONFIG_PIN = 1<<8, + NSTATUS_PIN = 1<<9, + CONF_DONE_PIN = 1<<10, + FPGA_POWER_ON = 1<<11 +}; + enum { Qdir = 0, - Qtemp, - Qpl, - Qfbctl, + Qfpga, Qbase, Qmax = 16, @@ -19,288 +52,149 @@ enum { static Dirtab archdir[Qmax] = { ".", { Qdir, 0, QTDIR }, 0, 0555, - "temp", { Qtemp, 0}, 0, 0440, - "pl", { Qpl, 0 }, 0, 0660, - "fbctl", { Qfbctl, 0 }, 0, 0660, + "fpga", { Qfpga, 0 }, 0, 0660, }; static int narchdir = Qbase; -static int temp = -128; -static ulong *devc; -static int dmadone; -enum { PLBUFSIZ = 8192 }; -static uchar *plbuf; -static Rendez plinitr, pldoner, pldmar; -static QLock plrlock, plwlock; -static Ref plwopen; -static Physseg *axi; - -enum { - DEVCTRL = 0, - DEVISTS = 0xc/4, - DEVMASK, - DEVSTS, - DMASRC = 0x18/4, - DMADST, - DMASRCL, - DMADSTL, - XADCCFG = 0x100/4, - XADCSTS, - XADCMASK, - XADCMSTS, - XADCCMD, - XADCREAD, - XADCMCTL, - - FPGA0_CLK_CTRL = 0x170/4, -}; - -enum { - PROG = 1<<30, - DONE = 1<<2, - INITPE = 1<<1, - INIT = 1<<4, - DMADONE = 1<<13, -}; - -static void -scram(void) -{ - splhi(); - slcr[0x100/4] |= 1<<4; - slcr[0x104/4] |= 1<<4; - slcr[0x108/4] |= 1<<4; - slcr[DEVCTRL] &= ~PROG; - slcr[0x244/4] = 1<<4|1<<5; -} - -static void -xadcirq(Ureg *, void *) -{ - int v; - static int al, notfirst; - - while((devc[XADCMSTS] & 1<<8) == 0){ - v = ((u16int)devc[XADCREAD]) >> 4; - if(v == 0){ - if(notfirst) - print("temperature sensor reads 0, shouldn't happen\n"); - break; - } - notfirst = 1; - temp = v * 5040 / 4096 - 2732; - if(temp >= 800){ - if(al == 0) - print("temperature exceeds 80 deg C\n"); - al = 1; - } - if(temp <= 750) - al = 0; - if(temp >= 900){ - print("chip temperature exceeds 90 deg C, shutting down"); - scram(); - } - } - devc[XADCSTS] = -1; -} - -static void -xadctimer(void) -{ - devc[XADCCMD] = 1<<26 | 0<<16; -} - -static void -xadcinit(void) -{ - int i; - int x; - - devc = vmap(DEVC_BASE, 0x11C); - devc[XADCMCTL] |= 1<<4; - devc[XADCMCTL] &= ~(1<<4); - devc[XADCCMD] = 0x08030000; - for(i = 0; i < 15; i++) - devc[XADCCMD] = 0; - while((devc[XADCMSTS] & 1<<10) == 0) - ; - while((devc[XADCMSTS] & 1<<8) == 0){ - x = devc[XADCREAD]; - USED(x); - } - devc[XADCCFG] = 0x80001114; - devc[XADCMASK] = ~(1<<8); - devc[XADCSTS] = -1; - intrenable(XADCIRQ, xadcirq, nil, LEVEL, "xadc"); - addclock0link(xadctimer, XADCINTERVAL); -} +static Ref fpgawopen; +enum { FPGABUFSIZ = 65536 }; +static uchar *fpgabuf; +static int fpgabufp; +static int fpgaok; +static Rendez fpgarend; +static u32int fpgawaitset, fpgawaitclr; static int -isplinit(void *) +donewaiting(void *) { - return devc[DEVSTS] & INIT; + u32int s; + + s = fpga[FPGAPINS]; + return (s & fpgawaitset | ~s & fpgawaitclr) != 0; + +} +static void +fpgairq(Ureg *, void *) +{ + fpga[FPGAEOI] = -1; + if(donewaiting(nil)) + wakeup(&fpgarend); } - static int -ispldone(void *) +fpgawait(u32int set, u32int clr, int timeout) { - return devc[DEVISTS] & DONE; -} + int s; -static int -isdmadone(void *) -{ - return dmadone; + fpgawaitset = set; + fpgawaitclr = clr; + if(donewaiting(nil)) return 0; + s = spllo(); + fpga[FPGAINTEN] = 0; + fpga[FPGAEOI] = -1; + fpga[FPGAINTPOL] = set; + fpga[FPGAINTEN] = set | clr; + tsleep(&fpgarend, donewaiting, nil, timeout); + fpga[FPGAINTEN] = 0; + fpga[FPGAEOI] = -1; + splx(s); + return donewaiting(nil) ? 0 : -1; } static void -plirq(Ureg *, void *) +fpgaconf(void) { - ulong fl; + int msel; + enum { PORFAST = 1, AES = 2, AESMAYBE = 4, COMP = 8, FPP32 = 16 }; + static uchar mseltab[16][3] = { + [0] {0, 1, PORFAST}, + [4] {0, 1, 0}, + [1] {0, 2, PORFAST|AES}, + [5] {0, 2, AES}, + [2] {0, 3, COMP|AESMAYBE|PORFAST}, + [6] {0, 3, COMP|AESMAYBE}, + [8] {1, 1, PORFAST|FPP32}, + [12] {1, 1, FPP32}, + [9] {1, 2, AES|FPP32|PORFAST}, + [13] {1, 2, AES|FPP32}, + [10] {1, 4, COMP|AESMAYBE|PORFAST|FPP32}, + [14] {1, 4, COMP|AESMAYBE|FPP32} + }; - fl = devc[DEVISTS]; - if((fl & INITPE) != 0) - wakeup(&plinitr); - if((fl & DONE) != 0){ - slcr[0x900/4] = 0xf; - slcr[0x240/4] = 0; - devc[DEVMASK] |= DONE; - axi->attr &= ~SG_FAULT; - wakeup(&pldoner); + if((fpga[FPGAPINS] & FPGA_POWER_ON) == 0) + error("FPGA powered off"); + msel = fpga[FPGASTAT] >> 3 & 0x1f; + if(msel >= 16 || mseltab[msel][1] == 0){ + print("MSEL set to invalid setting %#.2x\n", msel); + error("MSEL set to invalid setting"); } - if((fl & DMADONE) != 0){ - dmadone++; - wakeup(&pldmar); - } - devc[DEVISTS] = fl; + fpga[FPGACTRL] = fpga[FPGACTRL] & ~0x3ff + | mseltab[msel][0] << 9 /* cfgwdth */ + | mseltab[msel][1]-1 << 6 /* cdratio */ + | NCONFIGPULL | HPSCONFIG; + if(fpgawait(0, NSTATUS, Timeout) < 0 || fpgawait(0, CONF_DONE, Timeout) < 0) + error("FPGA won't enter reset phase"); + fpga[FPGACTRL] &= ~NCONFIGPULL; + if(fpgawait(NSTATUS, 0, Timeout) < 0) + error("FPGA won't enter configuration phase"); + fpga[FPGACTRL] |= AXICFGEN; } static void -plinit(void) +fpgawrite(uchar *a, int n) { - Physseg seg; + int m; - memset(&seg, 0, sizeof seg); - seg.attr = SG_PHYSICAL | SG_DEVICE | SG_NOEXEC | SG_FAULT; - seg.name = "axi"; - seg.pa = 0x40000000; - seg.size = 0x8000000; - axi = addphysseg(&seg); - - devc[DEVCTRL] &= ~(PROG|1<<25); - devc[DEVCTRL] |= 3<<26|PROG; - devc[DEVISTS] = -1; - devc[DEVMASK] = ~(DONE|INITPE|DMADONE); - intrenable(DEVCIRQ, plirq, nil, LEVEL, "pl"); - - slcr[FPGA0_CLK_CTRL] = 1<<20 | 10<<8; -} - -static void -plconf(void) -{ - axi->attr |= SG_FAULT; - procflushpseg(axi); - flushmmu(); - - slcr[0x240/4] = 0xf; - slcr[0x900/4] = 0xa; - devc[DEVISTS] = DONE|INITPE|DMADONE; - devc[DEVCTRL] |= PROG; - devc[DEVCTRL] &= ~PROG; - devc[DEVMASK] &= ~DONE; - devc[DEVCTRL] |= PROG; - - while(waserror()) - ; - sleep(&plinitr, isplinit, nil); - poperror(); -} - -static long -plwrite(uintptr pa, long n) -{ - dmadone = 0; - coherence(); - devc[DMASRC] = pa; - devc[DMADST] = -1; - devc[DMASRCL] = n>>2; - devc[DMADSTL] = 0; - - while(waserror()) - ; - sleep(&pldmar, isdmadone, nil); - poperror(); - - return n; -} - -static long -plcopy(uchar *d, long n) -{ - long ret; - ulong nn; - uintptr pa; - - if((n & 3) != 0 || n <= 0) - error(Eshort); - - eqlock(&plwlock); if(waserror()){ - qunlock(&plwlock); + fpgaok = 0; nexterror(); } - - ret = n; - pa = PADDR(plbuf); - while(n > 0){ - if(n > PLBUFSIZ) - nn = PLBUFSIZ; - else - nn = n; - memmove(plbuf, d, nn); - cleandse(plbuf, plbuf + nn); - clean2pa(pa, pa + nn); - n -= plwrite(pa, nn); + if((fpga[FPGAPINS] & NSTATUS) == 0) + error("FPGA reports configuration error"); + fpgaok = 1; + while(fpgabufp + n >= FPGABUFSIZ){ + m = FPGABUFSIZ - fpgabufp; + memmove(&fpgabuf[fpgabufp], a, m); + cleandse(fpgabuf, fpgabuf + FPGABUFSIZ); + dmacopy((void *) FPGAMGRDATA, fpgabuf, FPGABUFSIZ, SRC_INC); + a += m; + n -= m; + fpgabufp = 0; } - - qunlock(&plwlock); + memmove(&fpgabuf[fpgabufp], a, n); + fpgabufp += n; poperror(); - - return ret; } -void -archinit(void) +static void +fpgafinish(void) { - slcr[2] = 0xDF0D; - xadcinit(); - plinit(); + if(!fpgaok) return; + while((fpgabufp & 3) != 0) + fpgabuf[fpgabufp++] = 0; + cleandse(fpgabuf, fpgabuf + fpgabufp); + dmacopy((void *) FPGAMGRDATA, fpgabuf, fpgabufp, SRC_INC); + fpga[FPGACTRL] &= ~AXICFGEN; + if(fpgawait(CONF_DONE, NSTATUS, Timeout) < 0){ + print("FPGA stuck in configuration phase -- truncated file?\n"); + return; + } + if((fpga[FPGAPINS] & NSTATUS) == 0){ + print("FPGA reports configuration error\n"); + return; + } + if(fpgawait(INIT_DONE, 0, Timeout) < 0){ + print("FPGA stuck in initialization phase\n"); + return; + } + fpga[FPGACTRL] &= ~HPSCONFIG; } static long -archread(Chan *c, void *a, long n, vlong offset) +archread(Chan *c, void *a, long n, vlong) { - char buf[64]; - switch((ulong)c->qid.path){ case Qdir: return devdirread(c, a, n, archdir, narchdir, devgen); - case Qtemp: - snprint(buf, sizeof(buf), "%d.%d\n", temp/10, temp%10); - return readstr(offset, a, n, buf); - case Qpl: - eqlock(&plrlock); - if(waserror()){ - qunlock(&plrlock); - nexterror(); - } - sleep(&pldoner, ispldone, nil); - qunlock(&plrlock); - poperror(); - return 0; - case Qfbctl: - return fbctlread(c, a, n, offset); default: error(Egreg); return -1; @@ -308,13 +202,12 @@ archread(Chan *c, void *a, long n, vlong offset) } static long -archwrite(Chan *c, void *a, long n, vlong offset) +archwrite(Chan *c, void *a, long n, vlong) { switch((ulong)c->qid.path){ - case Qpl: - return plcopy(a, n); - case Qfbctl: - return fbctlwrite(c, a, n, offset); + case Qfpga: + fpgawrite(a, n); + return n; default: error(Egreg); return -1; @@ -337,14 +230,16 @@ static Chan* archopen(Chan* c, int omode) { devopen(c, omode, archdir, narchdir, devgen); - if((ulong)c->qid.path == Qpl && (c->mode == OWRITE || c->mode == ORDWR)){ - if(incref(&plwopen) != 1){ + if((ulong)c->qid.path == Qfpga && (c->mode == OWRITE || c->mode == ORDWR)){ + if(incref(&fpgawopen) != 1){ c->flag &= ~COPEN; - decref(&plwopen); + decref(&fpgawopen); error(Einuse); } - plbuf = smalloc(PLBUFSIZ); - plconf(); + fpgaok = 0; + fpgaconf(); + fpgabuf = xspanalloc(FPGABUFSIZ, 64, 0); + fpgabufp = 0; } return c; } @@ -353,13 +248,23 @@ static void archclose(Chan* c) { if((c->flag & COPEN) != 0) - if((ulong)c->qid.path == Qpl && (c->mode == OWRITE || c->mode == ORDWR)){ - free(plbuf); - plbuf = nil; - decref(&plwopen); + if((ulong)c->qid.path == Qfpga && (c->mode == OWRITE || c->mode == ORDWR)){ + fpgafinish(); + //xfree(fpgabuf); + fpgabuf = nil; + decref(&fpgawopen); } } +static void +archreset(void) +{ + fpga[FPGAINTEN] = 0; + fpga[FPGAEOI] = -1; + fpga[FPGAINTTYPE] = -1; + intrenable(FPGAMGRIRQ, fpgairq, nil, LEVEL, "fpgamgr"); +} + static Chan* archattach(char* spec) { @@ -370,7 +275,7 @@ Dev archdevtab = { 'P', "arch", - devreset, + archreset, devinit, devshutdown, archattach, diff --git a/sys/src/9/cycv/dma.c b/sys/src/9/cycv/dma.c new file mode 100644 index 000000000..211e71ec2 --- /dev/null +++ b/sys/src/9/cycv/dma.c @@ -0,0 +1,265 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "ureg.h" +#include "../port/error.h" + +#define dmar ((ulong*)DMAS_BASE) + +enum { + DSR = 0x000, + DPC = 0x004/4, + INTEN = 0x20 / 4, + INT_EVENT_RIS = 0x024 / 4, + INTMIS = 0x028 / 4, + INTCLR = 0x02C / 4, + FSRD = 0x030 / 4, + FSRC = 0x034 / 4, + FTRD = 0x038 / 4, + DBGSTATUS = 0xD00 / 4, + DBGCMD = 0xD04 / 4, + DBGINST0 = 0xD08 / 4, + DBGINST1 = 0xD0C / 4, + CR0 = 0xE00 / 4, + CR1, CR2, CR3, CR4, CRD, + WD = 0xE80 / 4, +}; +enum { + DMAStopped, + DMAExecuting, + DMACacheMiss, + DMAUpdatingPC, + DMAWaitingForEvent, + DMAAtBarrier, + DMAWaitingForPeripheral = 7, + DMAKilling, + DMACompleting, + DMAFaultingCompleting=14, + DMAFaulting, +}; +#define FTR(n) dmar[(0x40/4 + (n))] +#define CSR(n) dmar[(0x100/4 + (n)*2)] +#define CPC(n) dmar[(0x104/4 + (n)*2)] +#define SAR(n) dmar[(0x400/4 + (n)*8)] +#define DAR(n) dmar[(0x404/4 + (n)*8)] +#define CCR(n) dmar[(0x408/4 + (n)*8)] +#define LC0(n) dmar[(0x40C/4 + (n)*8)] +#define LC1(n) dmar[(0x410/4 + (n)*8)] + +#define DST_BURST(n) (((n)-1&0xf)<<18) +#define DST_BEAT_1 (0) +#define DST_BEAT_2 (1<<15) +#define DST_BEAT_4 (2<<15) +#define DST_BEAT_8 (3<<15) +#define DST_BEAT_16 (4<<15) +#define SRC_BURST(n) (((n)-1&0xf)<<4) +#define SRC_BEAT_1 (0) +#define SRC_BEAT_2 (1<<1) +#define SRC_BEAT_4 (2<<1) +#define SRC_BEAT_8 (3<<1) +#define SRC_BEAT_16 (4<<1) + +#define dmaMOV_SARn 0x00bc +#define dmaMOV_CCRn 0x01bc +#define dmaMOV_DARn 0x02bc +#define dmaLP0(n) (((n)-1&0xff)<<8|0x20) +#define dmaLP1(n) (((n)-1&0xff)<<8|0x22) +#define dmaLPEND0(n) (((n)&0xff)<<8|0x38) +#define dmaLPEND1(n) (((n)&0xff)<<8|0x3c) +#define dmaLD 0x04 +#define dmaST 0x08 +#define dmaSEV(n) (((n)&31)<<11|0x34) +#define dmaEND 0x00 +#define dmaWMB 0x13 + +static QLock dmalock; +static Rendez dmarend; +static int finished; +static ulong code[64]; + +static int +isfinished(void *) +{ + return finished; +} +static void +dmairq(Ureg *, void *) +{ + dmar[INTCLR] = -1; + finished = 1; + wakeup(&dmarend); +} + +static void +compactify(ulong *lp) +{ + uchar *p, *q; + + q = p = (uchar *) lp; + for(;;){ + switch(*p){ + case 0xbc: + q[0] = p[0]; + q[1] = p[1]; + q[2] = p[4]; + q[3] = p[5]; + q[4] = p[6]; + q[5] = p[7]; + q += 6; p += 8; + break; + case 0x20: case 0x22: case 0x38: case 0x3c: case 0x34: + q[0] = p[0]; + q[1] = p[1]; + q += 2; p += 4; + break; + case 0x04: case 0x08: case 0x13: + q[0] = p[0]; + q++; p += 4; + break; + case 0x00: + q[0] = 0; + return; + default: + panic("DMA: unknown opcode %.2x", *p); + } + } +} + +#define BURST(n) *p++ = dmaMOV_CCRn, *p++ = DST_BEAT_4 | SRC_BEAT_4 | SRC_BURST(n) | DST_BURST(n) | attr + +void +dmacopy(void *dst, void *src, ulong n, int attr) +{ + ulong *p; + + assert((n & 3) == 0 && ((uintptr)src & 3) == 0 && ((uintptr)dst & 3) == 0); + while(n > (1<<22)){ + dmacopy(dst, src, 1<<22, attr); + if((attr & SRC_INC) != 0) src = (uchar*)src + (1<<22); + if((attr & DST_INC) != 0) dst = (uchar*)dst + (1<<22); + } + if(n == 0) return; + qlock(&dmalock); + p = code; + *p++ = dmaMOV_SARn; *p++ = PADDR(src); + *p++ = dmaMOV_DARn; *p++ = PADDR(dst); + if((n >> 6) >= 1){ + BURST(16); + if((n>>14) >= 1){ + if((n>>14) > 1) *p++ = dmaLP0(n >> 14); + *p++ = dmaLP1(256); + *p++ = dmaLD; + *p++ = dmaST; + *p++ = dmaLPEND1(2); + if((n>>14) > 1) *p++ = dmaLPEND0(6); + n &= (1<<14)-1; + } + if((n >> 6) >= 1){ + if((n>>6) > 1) *p++ = dmaLP0(n >> 6); + *p++ = dmaLD; + *p++ = dmaST; + if((n>>6) > 1) *p++ = dmaLPEND0(2); + n &= 63; + } + } + if(n >= 4){ + BURST(n>>2); + *p++ = dmaLD; + *p++ = dmaST; + } + *p++ = dmaWMB; + *p++ = dmaSEV(0); + *p = dmaEND; + compactify(code); + if((CSR(0) & 0xf) != DMAStopped){ + while((dmar[DBGSTATUS] & 1) != 0) + tsleep(&up->sleep, return0, nil, 1); + dmar[DBGINST0] = 0x1 << 16 | 1; + dmar[DBGCMD] = 0; + while((dmar[DBGSTATUS] & 1) != 0) + tsleep(&up->sleep, return0, nil, 1); + while((CSR(0) & 0xf) != DMAStopped) + tsleep(&up->sleep, return0, nil, 1); + } + cleandse(code, code + nelem(code)); + while((dmar[DBGSTATUS] & 1) != 0) + tsleep(&up->sleep, return0, nil, 1); + dmar[DBGINST0] = 0xa0 << 16; + dmar[DBGINST1] = PADDR(code); + finished = 0; + dmar[DBGCMD] = 0; + while(!finished) + sleep(&dmarend, isfinished, nil); + qunlock(&dmalock); +} + + +static void +dmaabort(Ureg *, void *) +{ + int i; + + if((dmar[FSRD] & 1) != 0){ + iprint("dma: manager fault: "); + if((dmar[FTRD] & 1<<30) != 0) + iprint("debug instruction, "); + if((dmar[FTRD] & 1<<16) != 0) + iprint("instruction fetch error, "); + if((dmar[FTRD] & 1<<5) != 0) + iprint("event security violation, "); + if((dmar[FTRD] & 1<<4) != 0) + iprint("DMAGO security violation, "); + if((dmar[FTRD] & 1<<1) != 0) + iprint("operand invalid, "); + if((dmar[FTRD] & 1<<0) != 0) + iprint("undefined instruction, "); + iprint("\n"); + } + for(i = 0; i < 8; i++){ + if((dmar[FSRC] & 1<rxr[4 * c->rxconsi]; if((r[0] >> 31) != 0) break; - if((r[0] & 1<<15) != 0) - iprint("eth: error frame\n"); if((r[0] & (3<<8)) != (3<<8)) iprint("eth: lilu dallas multidescriptor\n"); bp = c->rxs[c->rxconsi]; @@ -404,6 +402,38 @@ ethmcast(void *arg, uchar *ea, int on) } } +static long +ethifstat(Ether *edev, void *a, long n, ulong offset) +{ + static char *names[] = { + "txoctetcount_gb", "txframecount_gb", "txbroadcastframes_g", "txmulticastframes_g", + "tx64octets_gb", "tx65to127octets_gb", "tx128to255octets_gb", "tx256to511octets_gb", + "tx512to1023octets_gb", "tx1024tomaxoctets_gb", "txunicastframes_gb", "txmulticastframes_gb", + "txbroadcastframes_gb", "txunderflowerror", "txsinglecol_g", "txmulticol_g", + "txdeferred", "txlatecol", "txexesscol", "txcarriererr", + "txoctetcnt", "txframecount_g", "txexcessdef", "txpauseframes", + "txvlanframes_g", "txoversize_g", "rxframecount_gb", "rxoctetcount_gb", + "rxoctetcount_g", "rxbroadcastframes_g", "rxmulticastframes_g", "rxcrcerror", + "rxalignmenterror", "rxrunterror", "rxjabbererror", "rxundersize_g", + "rxoversize_g", "rx64octets_gb", "rx65to127octets_gb", "rx128to255octets_gb", + "rx256to511octets_gb", "rx512to1023octets_gb", "rx1024tomaxoctets_gb", "rxunicastframes_g", + "rxlengtherror", "rxoutofrangetype", "rxpauseframes", "rxfifooverflow", + "rxvlanframes_gb", "rxwatchdogerror", "rxrcverror", "rxctrlframes_g", + }; + int i; + char *buf, *p, *e; + Ctlr *c; + + p = buf = smalloc(READSTR); + e = p + READSTR; + c = edev->ctlr; + for(i = 0; i < nelem(names); i++) + p = seprint(p, e, "%s: %lud\n", names[i], c->r[0x114/4 + i]); + n = readstr(offset, a, n, buf); + free(buf); + return n; +} + static int etherpnp(Ether *edev) { @@ -425,6 +455,7 @@ etherpnp(Ether *edev) edev->mbps = 1000; edev->promiscuous = ethprom; edev->multicast = ethmcast; + edev->ifstat = ethifstat; if(ethinit(edev) < 0){ edev->ctlr = nil; diff --git a/sys/src/9/cycv/fns.h b/sys/src/9/cycv/fns.h index 6606c4ee4..0e8ef57c0 100644 --- a/sys/src/9/cycv/fns.h +++ b/sys/src/9/cycv/fns.h @@ -76,3 +76,4 @@ uintptr palookur(void *); void screeninit(void); int isaconfig(char*, int, ISAConf*); void cputhex(u32int); +void dmacopy(void *, void *, ulong, int); diff --git a/sys/src/9/cycv/io.h b/sys/src/9/cycv/io.h index 88be84978..318fca8c8 100644 --- a/sys/src/9/cycv/io.h +++ b/sys/src/9/cycv/io.h @@ -5,7 +5,10 @@ #define EMAC1_BASE 0xFF702000 #define RESETMGR_BASE 0xFFD05000 #define SYSMGR_BASE 0xFFD08000 +#define FPGAMGR_BASE 0xFF706000 +#define FPGAMGRDATA 0xFFB90000 #define OCRAM 0xFFFF0000 +#define DMAS_BASE 0xFFE01000 /*RESETMGR*/ #define PERMODRST (0x14/4) @@ -17,6 +20,9 @@ #define TIMERIRQ 29 #define UART0IRQ 194 #define EMAC1IRQ 152 +#define FPGAMGRIRQ 207 +#define DMAIRQ0 136 +#define DMAABORTIRQ 144 #define LEVEL 0 #define EDGE 1 diff --git a/sys/src/9/cycv/l.s b/sys/src/9/cycv/l.s index a2a1f48d0..b1e898faa 100644 --- a/sys/src/9/cycv/l.s +++ b/sys/src/9/cycv/l.s @@ -37,7 +37,7 @@ TEXT _start0(SB), $-4 _clrstart: MOVW.P R0, 4(R1) CMP.S R1, R2 - BGE _clrstart + BGT _clrstart /* clean BSS */ MOVW $edata-KZERO(SB), R1 @@ -45,7 +45,7 @@ _clrstart: _clrbss: MOVW.P R0, 4(R1) CMP.S R1, R2 - BGE _clrbss + BGT _clrbss PUTC('a')