1*7dd7cddfSDavid du Colombier #include <u.h> 2*7dd7cddfSDavid du Colombier #include <libc.h> 3*7dd7cddfSDavid du Colombier #include <bio.h> 4*7dd7cddfSDavid du Colombier #include <mach.h> 5*7dd7cddfSDavid du Colombier #define Extern extern 6*7dd7cddfSDavid du Colombier #include "arm.h" 7*7dd7cddfSDavid du Colombier 8*7dd7cddfSDavid du Colombier extern ulong textbase; 9*7dd7cddfSDavid du Colombier 10*7dd7cddfSDavid du Colombier ulong 11*7dd7cddfSDavid du Colombier ifetch(ulong addr) 12*7dd7cddfSDavid du Colombier { 13*7dd7cddfSDavid du Colombier uchar *va; 14*7dd7cddfSDavid du Colombier 15*7dd7cddfSDavid du Colombier if(addr&3) { 16*7dd7cddfSDavid du Colombier Bprint(bioout, "Address error (I-fetch) vaddr %.8lux\n", addr); 17*7dd7cddfSDavid du Colombier longjmp(errjmp, 0); 18*7dd7cddfSDavid du Colombier } 19*7dd7cddfSDavid du Colombier 20*7dd7cddfSDavid du Colombier if(icache.on) 21*7dd7cddfSDavid du Colombier updateicache(addr); 22*7dd7cddfSDavid du Colombier iprof[(addr-textbase)/PROFGRAN]++; 23*7dd7cddfSDavid du Colombier 24*7dd7cddfSDavid du Colombier va = vaddr(addr); 25*7dd7cddfSDavid du Colombier va += addr&(BY2PG-1); 26*7dd7cddfSDavid du Colombier 27*7dd7cddfSDavid du Colombier return va[3]<<24 | va[2]<<16 | va[1]<<8 | va[0]; 28*7dd7cddfSDavid du Colombier } 29*7dd7cddfSDavid du Colombier 30*7dd7cddfSDavid du Colombier ulong 31*7dd7cddfSDavid du Colombier getmem_4(ulong addr) 32*7dd7cddfSDavid du Colombier { 33*7dd7cddfSDavid du Colombier ulong val; 34*7dd7cddfSDavid du Colombier int i; 35*7dd7cddfSDavid du Colombier 36*7dd7cddfSDavid du Colombier val = 0; 37*7dd7cddfSDavid du Colombier for(i = 0; i < 4; i++) 38*7dd7cddfSDavid du Colombier val = (val>>8) | (getmem_b(addr++)<<24); 39*7dd7cddfSDavid du Colombier return val; 40*7dd7cddfSDavid du Colombier } 41*7dd7cddfSDavid du Colombier 42*7dd7cddfSDavid du Colombier ulong 43*7dd7cddfSDavid du Colombier getmem_2(ulong addr) 44*7dd7cddfSDavid du Colombier { 45*7dd7cddfSDavid du Colombier ulong val; 46*7dd7cddfSDavid du Colombier int i; 47*7dd7cddfSDavid du Colombier 48*7dd7cddfSDavid du Colombier val = 0; 49*7dd7cddfSDavid du Colombier for(i = 0; i < 2; i++) 50*7dd7cddfSDavid du Colombier val = (val>>8) | (getmem_b(addr++)<<16); 51*7dd7cddfSDavid du Colombier return val; 52*7dd7cddfSDavid du Colombier } 53*7dd7cddfSDavid du Colombier 54*7dd7cddfSDavid du Colombier ulong 55*7dd7cddfSDavid du Colombier getmem_w(ulong addr) 56*7dd7cddfSDavid du Colombier { 57*7dd7cddfSDavid du Colombier uchar *va; 58*7dd7cddfSDavid du Colombier ulong w; 59*7dd7cddfSDavid du Colombier 60*7dd7cddfSDavid du Colombier if(addr&3) { 61*7dd7cddfSDavid du Colombier w = getmem_w(addr & ~3); 62*7dd7cddfSDavid du Colombier while(addr & 3) { 63*7dd7cddfSDavid du Colombier w = (w>>8) | (w<<24); 64*7dd7cddfSDavid du Colombier addr--; 65*7dd7cddfSDavid du Colombier } 66*7dd7cddfSDavid du Colombier return w; 67*7dd7cddfSDavid du Colombier } 68*7dd7cddfSDavid du Colombier if(membpt) 69*7dd7cddfSDavid du Colombier brkchk(addr, Read); 70*7dd7cddfSDavid du Colombier 71*7dd7cddfSDavid du Colombier va = vaddr(addr); 72*7dd7cddfSDavid du Colombier va += addr&(BY2PG-1); 73*7dd7cddfSDavid du Colombier 74*7dd7cddfSDavid du Colombier return va[3]<<24 | va[2]<<16 | va[1]<<8 | va[0]; 75*7dd7cddfSDavid du Colombier } 76*7dd7cddfSDavid du Colombier 77*7dd7cddfSDavid du Colombier uchar 78*7dd7cddfSDavid du Colombier getmem_b(ulong addr) 79*7dd7cddfSDavid du Colombier { 80*7dd7cddfSDavid du Colombier uchar *va; 81*7dd7cddfSDavid du Colombier 82*7dd7cddfSDavid du Colombier if(membpt) 83*7dd7cddfSDavid du Colombier brkchk(addr, Read); 84*7dd7cddfSDavid du Colombier 85*7dd7cddfSDavid du Colombier va = vaddr(addr); 86*7dd7cddfSDavid du Colombier va += addr&(BY2PG-1); 87*7dd7cddfSDavid du Colombier return va[0]; 88*7dd7cddfSDavid du Colombier } 89*7dd7cddfSDavid du Colombier 90*7dd7cddfSDavid du Colombier void 91*7dd7cddfSDavid du Colombier putmem_w(ulong addr, ulong data) 92*7dd7cddfSDavid du Colombier { 93*7dd7cddfSDavid du Colombier uchar *va; 94*7dd7cddfSDavid du Colombier 95*7dd7cddfSDavid du Colombier if(addr&3) { 96*7dd7cddfSDavid du Colombier Bprint(bioout, "Address error (Store) vaddr %.8lux\n", addr); 97*7dd7cddfSDavid du Colombier longjmp(errjmp, 0); 98*7dd7cddfSDavid du Colombier } 99*7dd7cddfSDavid du Colombier 100*7dd7cddfSDavid du Colombier va = vaddr(addr); 101*7dd7cddfSDavid du Colombier va += addr&(BY2PG-1); 102*7dd7cddfSDavid du Colombier 103*7dd7cddfSDavid du Colombier va[3] = data>>24; 104*7dd7cddfSDavid du Colombier va[2] = data>>16; 105*7dd7cddfSDavid du Colombier va[1] = data>>8; 106*7dd7cddfSDavid du Colombier va[0] = data; 107*7dd7cddfSDavid du Colombier if(membpt) 108*7dd7cddfSDavid du Colombier brkchk(addr, Write); 109*7dd7cddfSDavid du Colombier } 110*7dd7cddfSDavid du Colombier void 111*7dd7cddfSDavid du Colombier putmem_b(ulong addr, uchar data) 112*7dd7cddfSDavid du Colombier { 113*7dd7cddfSDavid du Colombier uchar *va; 114*7dd7cddfSDavid du Colombier 115*7dd7cddfSDavid du Colombier va = vaddr(addr); 116*7dd7cddfSDavid du Colombier va += addr&(BY2PG-1); 117*7dd7cddfSDavid du Colombier va[0] = data; 118*7dd7cddfSDavid du Colombier if(membpt) 119*7dd7cddfSDavid du Colombier brkchk(addr, Write); 120*7dd7cddfSDavid du Colombier } 121*7dd7cddfSDavid du Colombier 122*7dd7cddfSDavid du Colombier char * 123*7dd7cddfSDavid du Colombier memio(char *mb, ulong mem, int size, int dir) 124*7dd7cddfSDavid du Colombier { 125*7dd7cddfSDavid du Colombier int i; 126*7dd7cddfSDavid du Colombier char *buf, c; 127*7dd7cddfSDavid du Colombier 128*7dd7cddfSDavid du Colombier if(mb == 0) 129*7dd7cddfSDavid du Colombier mb = emalloc(size); 130*7dd7cddfSDavid du Colombier 131*7dd7cddfSDavid du Colombier buf = mb; 132*7dd7cddfSDavid du Colombier switch(dir) { 133*7dd7cddfSDavid du Colombier default: 134*7dd7cddfSDavid du Colombier fatal(0, "memio"); 135*7dd7cddfSDavid du Colombier case MemRead: 136*7dd7cddfSDavid du Colombier while(size--) 137*7dd7cddfSDavid du Colombier *mb++ = getmem_b(mem++); 138*7dd7cddfSDavid du Colombier break; 139*7dd7cddfSDavid du Colombier case MemReadstring: 140*7dd7cddfSDavid du Colombier for(;;) { 141*7dd7cddfSDavid du Colombier if(size-- == 0) { 142*7dd7cddfSDavid du Colombier Bprint(bioout, "memio: user/kernel copy too long for arm\n"); 143*7dd7cddfSDavid du Colombier longjmp(errjmp, 0); 144*7dd7cddfSDavid du Colombier } 145*7dd7cddfSDavid du Colombier c = getmem_b(mem++); 146*7dd7cddfSDavid du Colombier *mb++ = c; 147*7dd7cddfSDavid du Colombier if(c == '\0') 148*7dd7cddfSDavid du Colombier break; 149*7dd7cddfSDavid du Colombier } 150*7dd7cddfSDavid du Colombier break; 151*7dd7cddfSDavid du Colombier case MemWrite: 152*7dd7cddfSDavid du Colombier for(i = 0; i < size; i++) 153*7dd7cddfSDavid du Colombier putmem_b(mem++, *mb++); 154*7dd7cddfSDavid du Colombier break; 155*7dd7cddfSDavid du Colombier } 156*7dd7cddfSDavid du Colombier return buf; 157*7dd7cddfSDavid du Colombier } 158*7dd7cddfSDavid du Colombier 159*7dd7cddfSDavid du Colombier void 160*7dd7cddfSDavid du Colombier dotlb(ulong vaddr) 161*7dd7cddfSDavid du Colombier { 162*7dd7cddfSDavid du Colombier ulong *l, *e; 163*7dd7cddfSDavid du Colombier 164*7dd7cddfSDavid du Colombier vaddr &= ~(BY2PG-1); 165*7dd7cddfSDavid du Colombier 166*7dd7cddfSDavid du Colombier e = &tlb.tlbent[tlb.tlbsize]; 167*7dd7cddfSDavid du Colombier for(l = tlb.tlbent; l < e; l++) 168*7dd7cddfSDavid du Colombier if(*l == vaddr) { 169*7dd7cddfSDavid du Colombier tlb.hit++; 170*7dd7cddfSDavid du Colombier return; 171*7dd7cddfSDavid du Colombier } 172*7dd7cddfSDavid du Colombier 173*7dd7cddfSDavid du Colombier tlb.miss++; 174*7dd7cddfSDavid du Colombier tlb.tlbent[lnrand(tlb.tlbsize)] = vaddr; 175*7dd7cddfSDavid du Colombier } 176*7dd7cddfSDavid du Colombier 177*7dd7cddfSDavid du Colombier void * 178*7dd7cddfSDavid du Colombier vaddr(ulong addr) 179*7dd7cddfSDavid du Colombier { 180*7dd7cddfSDavid du Colombier Segment *s, *es; 181*7dd7cddfSDavid du Colombier int off, foff, l, n; 182*7dd7cddfSDavid du Colombier uchar **p, *a; 183*7dd7cddfSDavid du Colombier 184*7dd7cddfSDavid du Colombier if(tlb.on) 185*7dd7cddfSDavid du Colombier dotlb(addr); 186*7dd7cddfSDavid du Colombier 187*7dd7cddfSDavid du Colombier es = &memory.seg[Nseg]; 188*7dd7cddfSDavid du Colombier for(s = memory.seg; s < es; s++) { 189*7dd7cddfSDavid du Colombier if(addr >= s->base && addr < s->end) { 190*7dd7cddfSDavid du Colombier s->refs++; 191*7dd7cddfSDavid du Colombier off = (addr-s->base)/BY2PG; 192*7dd7cddfSDavid du Colombier p = &s->table[off]; 193*7dd7cddfSDavid du Colombier if(*p) 194*7dd7cddfSDavid du Colombier return *p; 195*7dd7cddfSDavid du Colombier s->rss++; 196*7dd7cddfSDavid du Colombier switch(s->type) { 197*7dd7cddfSDavid du Colombier default: 198*7dd7cddfSDavid du Colombier fatal(0, "vaddr"); 199*7dd7cddfSDavid du Colombier case Text: 200*7dd7cddfSDavid du Colombier *p = emalloc(BY2PG); 201*7dd7cddfSDavid du Colombier if(seek(text, s->fileoff+(off*BY2PG), 0) < 0) 202*7dd7cddfSDavid du Colombier fatal(1, "vaddr text seek"); 203*7dd7cddfSDavid du Colombier if(read(text, *p, BY2PG) < 0) 204*7dd7cddfSDavid du Colombier fatal(1, "vaddr text read"); 205*7dd7cddfSDavid du Colombier return *p; 206*7dd7cddfSDavid du Colombier case Data: 207*7dd7cddfSDavid du Colombier *p = emalloc(BY2PG); 208*7dd7cddfSDavid du Colombier foff = s->fileoff+(off*BY2PG); 209*7dd7cddfSDavid du Colombier if(seek(text, foff, 0) < 0) 210*7dd7cddfSDavid du Colombier fatal(1, "vaddr text seek"); 211*7dd7cddfSDavid du Colombier n = read(text, *p, BY2PG); 212*7dd7cddfSDavid du Colombier if(n < 0) 213*7dd7cddfSDavid du Colombier fatal(1, "vaddr text read"); 214*7dd7cddfSDavid du Colombier if(foff + n > s->fileend) { 215*7dd7cddfSDavid du Colombier l = BY2PG - (s->fileend-foff); 216*7dd7cddfSDavid du Colombier a = *p+(s->fileend-foff); 217*7dd7cddfSDavid du Colombier memset(a, 0, l); 218*7dd7cddfSDavid du Colombier } 219*7dd7cddfSDavid du Colombier return *p; 220*7dd7cddfSDavid du Colombier case Bss: 221*7dd7cddfSDavid du Colombier case Stack: 222*7dd7cddfSDavid du Colombier *p = emalloc(BY2PG); 223*7dd7cddfSDavid du Colombier return *p; 224*7dd7cddfSDavid du Colombier } 225*7dd7cddfSDavid du Colombier } 226*7dd7cddfSDavid du Colombier } 227*7dd7cddfSDavid du Colombier Bprint(bioout, "User TLB miss vaddr 0x%.8lux\n", addr); 228*7dd7cddfSDavid du Colombier longjmp(errjmp, 0); 229*7dd7cddfSDavid du Colombier return 0; /*to stop compiler whining*/ 230*7dd7cddfSDavid du Colombier } 231