| plan 9 kernel history: overview | file list | diff list |
1992/0806/ss/faultsparc.c (diff list | history)
| 1992/0806/sys/src/9/ss/faultsparc.c:1,88 – 1992/0812/sys/src/9/ss/faultsparc.c:1,87 (short | long | prev | next) | ||
| 1990/1223 | #include "u.h" | |
| 1992/0321 | #include "../port/lib.h" | |
| 1990/1223 | #include "mem.h" #include "dat.h" #include "fns.h" #include "ureg.h" | |
| 1992/0111 | #include "../port/error.h" | |
| 1990/1223 | ||
| 1992/0704 | enum { SE_WRITE = 0x8000, SE_INV = 0x0080, SE_PROT = 0x0040, }; | |
| 1990/1223 | void | |
| 1990/1226 | faultsparc(Ureg *ur) | |
| 1990/1223 | { ulong addr, badvaddr; | |
| 1991/0717 | char buf[ERRLEN]; | |
| 1991/01151 | int user, read; | |
| 1992/0704 | ulong tbr, ser; | |
| 1990/1223 | ||
| 1990/1227 | tbr = (ur->tbr&0xFFF)>>4; | |
| 1990/1226 | addr = ur->pc; /* assume instr. exception */ | |
| 1990/1231 | read = 1; if(tbr == 9){ /* data access exception */ /* * According to the book, this isn't good enough. We'll see. */ | |
| 1992/0806 | addr = getsysspace(SEVAR); ser = getsysspace(SER); | |
| 1992/0704 | if(ser&(SE_WRITE|SE_PROT)) | |
| 1990/1231 | read = 0; | |
| 1990/1226 | } spllo(); | |
| 1990/1223 | if(u == 0){ dumpregs(ur); | |
| 1991/01151 | panic("fault u==0 pc=%lux addr=%lux", ur->pc, addr); | |
| 1990/1223 | } | |
| 1990/1226 | /* addr &= VAMASK; /**/ | |
| 1990/1223 | badvaddr = addr; addr &= ~(BY2PG-1); | |
| 1990/1231 | user = !(ur->psr&PSRPSUPER); | |
| 1990/1223 | if(fault(addr, read) < 0){ if(user){ | |
| 1991/1218 | sprint(buf, "sys: trap: fault %s addr=0x%lux", read? "read" : "write", badvaddr); | |
| 1991/0717 | postnote(u->p, 1, buf, NDebug); return; | |
| 1990/1223 | } dumpregs(ur); panic("fault: 0x%lux", badvaddr); | |
| 1991/01151 | splhi(); | |
| 1991/0110 | } void faultasync(Ureg *ur) { int user; | |
| 1992/0806 | print("interrupt 15 ASER %lux ASEVAR %lux SER %lux\n", getsysspace(ASER), getsysspace(ASEVAR), getsysspace(SER)); | |
| 1991/0110 | dumpregs(ur); /* * Clear interrupt by toggling low bit of interrupt register */ *intrreg &= ~1; *intrreg |= 1; user = !(ur->psr&PSRPSUPER); if(user) pexit("Suicide", 0); panic("interrupt 15"); | |
| 1990/1226 | } /* * called in sysfile.c */ void evenaddr(ulong addr) { if(addr & 3){ postnote(u->p, 1, "sys: odd address", NDebug); error(Ebadarg); } | |
| 1990/1223 | } | |