cyclone v kernel: fpga support, fix CONFADDR

This commit is contained in:
aiju 2020-01-12 03:40:42 +00:00
parent 7cf8369411
commit 561346d07f
8 changed files with 483 additions and 269 deletions

View file

@ -2,7 +2,7 @@ dev
root
cons
swap
# arch
arch
uart
mnt
srv
@ -24,6 +24,7 @@ dev
segment
link
dma
ethercycv
ethermedium
loopbackmedium

View file

@ -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)

View file

@ -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,

265
sys/src/9/cycv/dma.c Normal file
View file

@ -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<<i) == 0)
continue;
iprint("dma: channel %d fault\n", i);
iprint("code = %.8p, PC = %.8ulx\n", code, CPC(i));
iprint("CCRn = %.8ulx, CSRn = %.8ulx\n", CCR(i), CSR(i));
iprint("LC0 = %.2ulx, LC1 = %.2ulx\n", LC0(i), LC1(i));
if((FTR(i) & 1<<31) != 0)
iprint("insufficient resources, ");
if((FTR(i) & 1<<30) != 0)
iprint("debug instruction, ");
if((FTR(i) & 1<<18) != 0)
iprint("read error, ");
if((FTR(i) & 1<<17) != 0)
iprint("write error, ");
if((FTR(i) & 1<<16) != 0)
iprint("instruction fetch error, ");
if((FTR(i) & 1<<13) != 0)
iprint("FIFO underflow, ");
if((FTR(i) & 1<<12) != 0)
iprint("FIFO error, ");
if((FTR(i) & 1<<7) != 0)
iprint("CCRn security violation, ");
if((FTR(i) & 1<<6) != 0)
iprint("peripheral security violation, ");
if((FTR(i) & 1<<5) != 0)
iprint("event security violation, ");
if((FTR(i) & 1<<4) != 0)
iprint("DMAGO security violation, ");
if((FTR(i) & 1<<1) != 0)
iprint("operand invalid, ");
if((FTR(i) & 1<<0) != 0)
iprint("undefined instruction, ");
iprint("\n");
}
panic("DMA fault");
}
void
dmalink(void)
{
dmar[INTEN] = 1;
intrenable(DMAIRQ0, dmairq, nil, LEVEL, "dma");
intrenable(DMAABORTIRQ, dmaabort, nil, LEVEL, "dma_abort");
}

View file

@ -199,8 +199,6 @@ ethrx(Ether *edev)
r = &c->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;

View file

@ -76,3 +76,4 @@ uintptr palookur(void *);
void screeninit(void);
int isaconfig(char*, int, ISAConf*);
void cputhex(u32int);
void dmacopy(void *, void *, ulong, int);

View file

@ -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

View file

@ -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')