|
|
1.1 ! root 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 "../port/error.h" ! 8: ! 9: #define FORMAT(ur) ((((ur)->vo)>>12)&0xF) ! 10: #define OFFSET(ur) (((ur)->vo)&0xFFF) ! 11: ! 12: struct FFrame ! 13: { ! 14: ulong ea; /* effective address */ ! 15: ushort ssw; /* special status word */ ! 16: ushort wb3s; /* write back 3 status */ ! 17: ushort wb2s; /* write back 2 status */ ! 18: ushort wb1s; /* write back 1 status */ ! 19: ulong fa; /* fault address */ ! 20: ulong wb3a; /* write back 3 address */ ! 21: ulong wb3d; /* write back 3 data */ ! 22: ulong wb2a; /* write back 2 address */ ! 23: ulong wb2d; /* write back 2 data */ ! 24: ulong wb1a; /* write back 1 address */ ! 25: ulong wb1d; /* write back 3 data */ ! 26: ulong pd1; /* push data lw1 */ ! 27: ulong pd2; /* push data lw2 */ ! 28: ulong pd3; /* push data lw3 */ ! 29: }; ! 30: ! 31: static uchar tsz[4] = { 4, 1, 2, 0 }; ! 32: ! 33: /* ! 34: * SSW bits ! 35: */ ! 36: #define READ 0x0100 ! 37: #define TM 0x0007 ! 38: ! 39: /* ! 40: * Writeback bits ! 41: */ ! 42: #define WBVALID (1<<7) ! 43: #define WBSIZE (3<<5) ! 44: #define WBSZSH 5 ! 45: #define WBTT (3<<3) ! 46: #define WBTM (7<<0) ! 47: ! 48: int wbfault(ulong, int, ushort, int, ulong); ! 49: ulong normalize(ulong, ulong, ulong); ! 50: ! 51: extern struct{ ! 52: ulong addr; ! 53: ulong baddr; ! 54: Lock; ! 55: }kmapalloc; ! 56: ! 57: void ! 58: fault68040(Ureg *ur, FFrame *f) ! 59: { ! 60: ulong addr, badvaddr; ! 61: int user, read, insyscall; ! 62: char buf[ERRLEN]; ! 63: flushatc(); ! 64: if(u == 0){ ! 65: dumpregs(ur); ! 66: print("ssw=%ux ea=%lux fa=%lux\n", f->ssw, f->ea, f->fa); ! 67: panic("fault u==0 pc=%lux fa=%lux ssw=%lux", ur->pc, f->fa, f->ssw); ! 68: } ! 69: ! 70: insyscall = u->p->insyscall; ! 71: u->p->insyscall = 1; ! 72: addr = f->fa; ! 73: addr &= VAMASK; ! 74: badvaddr = addr; ! 75: addr &= ~(BY2PG-1); ! 76: read = 0; ! 77: if(f->ssw & READ) ! 78: read = 1; ! 79: user = !(ur->sr&SUPER); ! 80: if(user) ! 81: u->dbgreg = ur; ! 82: if((f->ssw&TM) == 0) ! 83: panic("cache push pc %lux addr %lux ssw %lux\n", ur->pc, f->fa, f->ssw); ! 84: /* print("fault pc=%lux addr=%lux read %d\n", ur->pc, badvaddr, read); /**/ ! 85: ! 86: /* ! 87: * original fault plus 3 writeback buffers ! 88: */ ! 89: if(fault(addr, read) < 0 ! 90: || wbfault(f->wb1a, user, f->wb1s, 1, normalize(f->wb1s, f->wb1a, f->wb1d)) < 0 ! 91: || wbfault(f->wb2a, user, f->wb2s, 2, f->wb2d) < 0 ! 92: || wbfault(f->wb3a, user, f->wb3s, 3, f->wb3d) < 0){ ! 93: if(user){ ! 94: sprint(buf, "sys: trap: fault %s addr=0x%lux", ! 95: read? "read" : "write", badvaddr); ! 96: postnote(u->p, 1, buf, NDebug); ! 97: notify(ur); ! 98: return; ! 99: } ! 100: dumpregs(ur); ! 101: print("wb1a %lux wb1s %lux wb1d %lux\n", f->wb1a, f->wb1s, f->wb1d); ! 102: print("wb2a %lux wb2s %lux wb2d %lux\n", f->wb2a, f->wb2s, f->wb2d); ! 103: print("wb3a %lux wb3s %lux wb3d %lux\n", f->wb3a, f->wb3s, f->wb3d); ! 104: panic("fault: 0x%lux 0x%lux", badvaddr, addr); ! 105: } ! 106: u->p->insyscall = insyscall; ! 107: if(user) ! 108: notify(ur); ! 109: } ! 110: ! 111: /* ! 112: * get relevant data into the right hand side of the long ! 113: */ ! 114: ulong ! 115: normalize(ulong stat, ulong addr, ulong val) ! 116: { ! 117: int thecase, size; ! 118: ! 119: size = (stat&WBSIZE) >> WBSZSH; ! 120: thecase = (size<<2) | (addr&3); ! 121: switch(thecase){ ! 122: /* long write */ ! 123: case 0: return val; ! 124: case 1: return (val<<8) | ((val>>24)&0xff); ! 125: case 2: return (val<<16) | ((val>>16)&0xffff); ! 126: case 3: return (val<<24) | ((val>>8)&0xffffff); ! 127: /* byte write */ ! 128: case 4: return val>>24; ! 129: case 5: return val>>16; ! 130: case 6: return val>>8; ! 131: case 7: return val; ! 132: /* short write */ ! 133: case 8: return val>>16; ! 134: case 9: return val>>8; ! 135: case 10: return val; ! 136: case 11: return (val<<8) | ((val>>24)&0xff); ! 137: } ! 138: } ! 139: ! 140: /* ! 141: * Check fault status before doing writeback ! 142: */ ! 143: int ! 144: wbfault(ulong fa, int user, ushort wbs, int wbn, ulong d) ! 145: { ! 146: int s; ! 147: ulong addr; ! 148: ! 149: if(!(wbs & WBVALID)) ! 150: return 0; ! 151: if(wbs & WBTT) ! 152: panic("writeback%d status %ux", wbn, wbs); ! 153: addr = fa & ~(BY2PG-1); ! 154: s = tsz[(wbs&WBSIZE) >> WBSZSH]; ! 155: if(user || !kernaddr(addr)){ ! 156: if(fault(fa, 0) < 0){ ! 157: print("wbfault: %lux, 0\n", fa); ! 158: return -1; ! 159: } ! 160: if(addr != ((fa+s-1)&~(BY2PG-1))) ! 161: if(fault(fa+s-1, 0) < 0){ ! 162: print("wbfault: %lux, %lux\n", fa, fa+s-1); ! 163: return -1; ! 164: } ! 165: } ! 166: ! 167: switch(s){ ! 168: case 4: ! 169: *(ulong*)fa = d; ! 170: break; ! 171: case 1: ! 172: *(uchar*)fa = d; ! 173: break; ! 174: case 2: ! 175: *(ushort*)fa = d; ! 176: break; ! 177: default: ! 178: panic("writeback%d %d\n", wbn, s); ! 179: } ! 180: return 0; ! 181: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.