diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-07-25 09:01:44 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-07-25 09:01:44 +0200 |
commit | 10b456ff446704f32aa2ee237c149244fbabd81d (patch) | |
tree | 4e79763ab8a5aa8689b96637be60e5dc17f4e694 | |
parent | 811b80cae120168762e5825784a135ee4a5558e2 (diff) |
bcm64: add gisb arbiter driver to catch bus timeouts
-rw-r--r-- | sys/src/9/bcm64/gisb.c | 63 | ||||
-rw-r--r-- | sys/src/9/bcm64/trap.c | 4 |
2 files changed, 67 insertions, 0 deletions
diff --git a/sys/src/9/bcm64/gisb.c b/sys/src/9/bcm64/gisb.c new file mode 100644 index 000000000..589ce0f82 --- /dev/null +++ b/sys/src/9/bcm64/gisb.c @@ -0,0 +1,63 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "../port/error.h" +#include "ureg.h" + +/* + * GISB arbiter registers + */ +static u32int *regs = (u32int*)(VIRTIO2 + 0x400000); + +enum { + ArbTimer = 0x008/4, + ArbErrCapClear = 0x7e4/4, + ArbErrCapAddrHi = 0x7e8/4, + ArbErrCapAddr = 0x7ec/4, + ArbErrCapStatus = 0x7f4/4, + CapStatusTimeout = 1<<12, + CapStatusAbort = 1<<11, + CapStatusWrite = 1<<1, + CapStatusValid = 1<<0, + ArbErrCapMaster = 0x7f8/4, +}; + +static int +arbinterrupt(Ureg *) +{ + u32int status = regs[ArbErrCapStatus]; + u32int master; + uvlong addr; + + if((status & CapStatusValid) == 0) + return 0; + + master = regs[ArbErrCapMaster]; + + addr = regs[ArbErrCapAddr]; + addr |= (uvlong)regs[ArbErrCapAddrHi]<<32; + + regs[ArbErrCapClear] = CapStatusValid; + + iprint("cpu%d: GISB arbiter error: %s%s %s bus addr %llux, master %.8ux\n", + m->machno, + (status & CapStatusTimeout) ? "timeout" : "", + (status & CapStatusAbort) ? "abort" : "", + (status & CapStatusWrite) ? "writing" : "reading", + addr, + master); + + return 1; +} + +void +gisblink(void) +{ + extern int (*buserror)(Ureg*); // trap.c + + regs[ArbErrCapClear] = CapStatusValid; + + buserror = arbinterrupt; +} diff --git a/sys/src/9/bcm64/trap.c b/sys/src/9/bcm64/trap.c index 61b53b155..e64e41e77 100644 --- a/sys/src/9/bcm64/trap.c +++ b/sys/src/9/bcm64/trap.c @@ -10,6 +10,8 @@ #include "ureg.h" #include "sysreg.h" +int (*buserror)(Ureg*); + /* SPSR bits user can modify */ #define USPSRMASK (0xFULL<<28) @@ -141,6 +143,8 @@ trap(Ureg *ureg) } if(intr == 3){ case 0x2F: // SError interrupt + if(buserror != nil && (*buserror)(ureg)) + break; dumpregs(ureg); panic("SError interrupt"); break; |