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