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