1 #include "u.h" 2 #include "../port/lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 #include "ureg.h" 7 #include "io.h" 8 9 enum 10 { 11 MC_IFETCH = (1<<30), 12 MC_STORE = (1<<11), /* bit 23 if X-form, bit 3 if D-form => write */ 13 DSI_STORE = (1<<25), 14 DSI_PROT = (1<<27), 15 }; 16 17 void 18 faultpower(Ureg *ur) 19 { 20 ulong addr; 21 char buf[ERRMAX]; 22 int read, i; 23 24 addr = ur->pc; /* assume instr. exception */ 25 read = 1; 26 i = ur->cause >> 8; 27 if(i == CDSI || i == CDTLBE || i == CMCHECK && (ur->status&MC_IFETCH) == 0) { /* data access error including machine check load/store */ 28 addr = getdar(); 29 if(getdsisr() & (DSI_STORE|MC_STORE)) 30 read = 0; 31 } else if(i == CDMISS) /* DTLB miss */ 32 addr = getdepn() & ~0x3FF; /* can't distinguish read/write, but Inferno doesn't care */ 33 /* 34 print("fault %lux %lux %lux %d\n", ur->pc, ur->cause, addr, read); 35 print("imiss %lux dmiss %lux hash1 %lux dcmp %lux hash2 %lux\n", 36 getimiss(), getdmiss(), gethash1(), getdcmp(), gethash2()); 37 print("up %lux %lux %lux\n", m->upage, m->upage->virt, m->upage->phys); 38 */ 39 40 up->dbgreg = ur; /* For remote ACID */ 41 42 spllo(); 43 sprint(buf, "trap: fault %s pc=0x%lux addr=0x%lux", 44 read ? "read" : "write", ur->pc, addr); 45 if(up->type == Interp) 46 disfault(ur, buf); 47 dumpregs(ur); 48 panic("fault: %s\n", buf); 49 } 50