bcm64: poll gisb arbiter for asynchronous bus errors
This commit is contained in:
parent
54becb8466
commit
031f5756ab
1 changed files with 33 additions and 10 deletions
|
@ -12,52 +12,75 @@
|
||||||
static u32int *regs = (u32int*)(VIRTIO2 + 0x400000);
|
static u32int *regs = (u32int*)(VIRTIO2 + 0x400000);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
ArbMasterMask = 0x004/4,
|
||||||
ArbTimer = 0x008/4,
|
ArbTimer = 0x008/4,
|
||||||
|
TimerFreq = 216000000, // 216MHz
|
||||||
|
|
||||||
ArbErrCapClear = 0x7e4/4,
|
ArbErrCapClear = 0x7e4/4,
|
||||||
ArbErrCapAddrHi = 0x7e8/4,
|
ArbErrCapAddrHi = 0x7e8/4,
|
||||||
ArbErrCapAddr = 0x7ec/4,
|
ArbErrCapAddr = 0x7ec/4,
|
||||||
|
ArbErrCapData = 0x7f0/4,
|
||||||
ArbErrCapStatus = 0x7f4/4,
|
ArbErrCapStatus = 0x7f4/4,
|
||||||
CapStatusTimeout = 1<<12,
|
CapStatusTimeout = 1<<12,
|
||||||
CapStatusAbort = 1<<11,
|
CapStatusAbort = 1<<11,
|
||||||
|
CapStatusStrobe = 15<<2,
|
||||||
CapStatusWrite = 1<<1,
|
CapStatusWrite = 1<<1,
|
||||||
CapStatusValid = 1<<0,
|
CapStatusValid = 1<<0,
|
||||||
ArbErrCapMaster = 0x7f8/4,
|
ArbErrCapMaster = 0x7f8/4,
|
||||||
|
|
||||||
|
ArbIntrSts = 0x3000/4,
|
||||||
|
ArbIntrSet = 0x3004/4,
|
||||||
|
ArbIntrClr = 0x3008/4,
|
||||||
|
|
||||||
|
ArbCpuMaskSet = 0x3010/4,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
arbinterrupt(Ureg *)
|
arberror(Ureg*)
|
||||||
{
|
{
|
||||||
u32int status = regs[ArbErrCapStatus];
|
u32int status, intr;
|
||||||
u32int master;
|
u32int master, data;
|
||||||
uvlong addr;
|
uvlong addr;
|
||||||
|
|
||||||
|
status = regs[ArbErrCapStatus];
|
||||||
if((status & CapStatusValid) == 0)
|
if((status & CapStatusValid) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
intr = regs[ArbIntrSts];
|
||||||
master = regs[ArbErrCapMaster];
|
master = regs[ArbErrCapMaster];
|
||||||
|
|
||||||
addr = regs[ArbErrCapAddr];
|
addr = regs[ArbErrCapAddr];
|
||||||
addr |= (uvlong)regs[ArbErrCapAddrHi]<<32;
|
addr |= (uvlong)regs[ArbErrCapAddrHi]<<32;
|
||||||
|
data = regs[ArbErrCapData];
|
||||||
|
if(intr)
|
||||||
|
regs[ArbIntrClr] = intr;
|
||||||
regs[ArbErrCapClear] = CapStatusValid;
|
regs[ArbErrCapClear] = CapStatusValid;
|
||||||
|
|
||||||
iprint("cpu%d: GISB arbiter error: %s%s %s bus addr %llux, master %.8ux\n",
|
iprint("cpu%d: GISB arbiter error: %s%s %s bus addr %llux data %.8ux, "
|
||||||
|
"master %.8ux, status %.8ux, intr %.8ux\n",
|
||||||
m->machno,
|
m->machno,
|
||||||
(status & CapStatusTimeout) ? "timeout" : "",
|
(status & CapStatusTimeout) ? "timeout" : "",
|
||||||
(status & CapStatusAbort) ? "abort" : "",
|
(status & CapStatusAbort) ? "abort" : "",
|
||||||
(status & CapStatusWrite) ? "writing" : "reading",
|
(status & CapStatusWrite) ? "writing" : "reading",
|
||||||
addr,
|
addr, data,
|
||||||
master);
|
master, status, intr);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
arbclock(void)
|
||||||
|
{
|
||||||
|
arberror(nil);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gisblink(void)
|
gisblink(void)
|
||||||
{
|
{
|
||||||
extern int (*buserror)(Ureg*); // trap.c
|
extern int (*buserror)(Ureg*); // trap.c
|
||||||
|
|
||||||
regs[ArbErrCapClear] = CapStatusValid;
|
regs[ArbErrCapClear] = CapStatusValid;
|
||||||
|
regs[ArbIntrClr] = -1;
|
||||||
|
|
||||||
buserror = arbinterrupt;
|
addclock0link(arbclock, 100);
|
||||||
|
|
||||||
|
buserror = arberror;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue