Revision 952a328f target-sparc/op_helper.c
b/target-sparc/op_helper.c | ||
---|---|---|
2 | 2 |
|
3 | 3 |
//#define DEBUG_PCALL |
4 | 4 |
//#define DEBUG_MMU |
5 |
//#define DEBUG_MXCC |
|
5 | 6 |
//#define DEBUG_UNALIGNED |
6 | 7 |
//#define DEBUG_UNASSIGNED |
7 | 8 |
|
9 |
#ifdef DEBUG_MMU |
|
10 |
#define DPRINTF_MMU(fmt, args...) \ |
|
11 |
do { printf("MMU: " fmt , ##args); } while (0) |
|
12 |
#else |
|
13 |
#define DPRINTF_MMU(fmt, args...) |
|
14 |
#endif |
|
15 |
|
|
16 |
#ifdef DEBUG_MXCC |
|
17 |
#define DPRINTF_MXCC(fmt, args...) \ |
|
18 |
do { printf("MXCC: " fmt , ##args); } while (0) |
|
19 |
#else |
|
20 |
#define DPRINTF_MXCC(fmt, args...) |
|
21 |
#endif |
|
22 |
|
|
8 | 23 |
void raise_exception(int tt) |
9 | 24 |
{ |
10 | 25 |
env->exception_index = tt; |
... | ... | |
139 | 154 |
|
140 | 155 |
#ifndef TARGET_SPARC64 |
141 | 156 |
#ifndef CONFIG_USER_ONLY |
157 |
|
|
158 |
#ifdef DEBUG_MXCC |
|
159 |
static void dump_mxcc(CPUState *env) |
|
160 |
{ |
|
161 |
printf("mxccdata: %016llx %016llx %016llx %016llx\n", |
|
162 |
env->mxccdata[0], env->mxccdata[1], env->mxccdata[2], env->mxccdata[3]); |
|
163 |
printf("mxccregs: %016llx %016llx %016llx %016llx\n" |
|
164 |
" %016llx %016llx %016llx %016llx\n", |
|
165 |
env->mxccregs[0], env->mxccregs[1], env->mxccregs[2], env->mxccregs[3], |
|
166 |
env->mxccregs[4], env->mxccregs[5], env->mxccregs[6], env->mxccregs[7]); |
|
167 |
} |
|
168 |
#endif |
|
169 |
|
|
142 | 170 |
void helper_ld_asi(int asi, int size, int sign) |
143 | 171 |
{ |
144 | 172 |
uint32_t ret = 0; |
173 |
#ifdef DEBUG_MXCC |
|
174 |
uint32_t last_T0 = T0; |
|
175 |
#endif |
|
145 | 176 |
|
146 | 177 |
switch (asi) { |
147 | 178 |
case 2: /* SuperSparc MXCC registers */ |
179 |
switch (T0) { |
|
180 |
case 0x01c00a00: /* MXCC control register */ |
|
181 |
if (size == 8) { |
|
182 |
ret = env->mxccregs[3]; |
|
183 |
T0 = env->mxccregs[3] >> 32; |
|
184 |
} else |
|
185 |
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size); |
|
186 |
break; |
|
187 |
case 0x01c00a04: /* MXCC control register */ |
|
188 |
if (size == 4) |
|
189 |
ret = env->mxccregs[3]; |
|
190 |
else |
|
191 |
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size); |
|
192 |
break; |
|
193 |
case 0x01c00f00: /* MBus port address register */ |
|
194 |
if (size == 8) { |
|
195 |
ret = env->mxccregs[7]; |
|
196 |
T0 = env->mxccregs[7] >> 32; |
|
197 |
} else |
|
198 |
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size); |
|
199 |
break; |
|
200 |
default: |
|
201 |
DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", T0, size); |
|
202 |
break; |
|
203 |
} |
|
204 |
DPRINTF_MXCC("asi = %d, size = %d, sign = %d, T0 = %08x -> ret = %08x," |
|
205 |
"T0 = %08x\n", asi, size, sign, last_T0, ret, T0); |
|
206 |
#ifdef DEBUG_MXCC |
|
207 |
dump_mxcc(env); |
|
208 |
#endif |
|
148 | 209 |
break; |
149 | 210 |
case 3: /* MMU probe */ |
150 | 211 |
{ |
... | ... | |
157 | 218 |
ret = mmu_probe(env, T0, mmulev); |
158 | 219 |
//bswap32s(&ret); |
159 | 220 |
} |
160 |
#ifdef DEBUG_MMU |
|
161 |
printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret); |
|
162 |
#endif |
|
221 |
DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret); |
|
163 | 222 |
} |
164 | 223 |
break; |
165 | 224 |
case 4: /* read MMU regs */ |
... | ... | |
169 | 228 |
ret = env->mmuregs[reg]; |
170 | 229 |
if (reg == 3) /* Fault status cleared on read */ |
171 | 230 |
env->mmuregs[reg] = 0; |
172 |
#ifdef DEBUG_MMU |
|
173 |
printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret); |
|
174 |
#endif |
|
231 |
DPRINTF_MMU("mmu_read: reg[%d] = 0x%08x\n", reg, ret); |
|
175 | 232 |
} |
176 | 233 |
break; |
177 | 234 |
case 9: /* Supervisor code access */ |
... | ... | |
302 | 359 |
{ |
303 | 360 |
switch(asi) { |
304 | 361 |
case 2: /* SuperSparc MXCC registers */ |
362 |
switch (T0) { |
|
363 |
case 0x01c00000: /* MXCC stream data register 0 */ |
|
364 |
if (size == 8) |
|
365 |
env->mxccdata[0] = ((uint64_t)T1 << 32) | T2; |
|
366 |
else |
|
367 |
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size); |
|
368 |
break; |
|
369 |
case 0x01c00008: /* MXCC stream data register 1 */ |
|
370 |
if (size == 8) |
|
371 |
env->mxccdata[1] = ((uint64_t)T1 << 32) | T2; |
|
372 |
else |
|
373 |
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size); |
|
374 |
break; |
|
375 |
case 0x01c00010: /* MXCC stream data register 2 */ |
|
376 |
if (size == 8) |
|
377 |
env->mxccdata[2] = ((uint64_t)T1 << 32) | T2; |
|
378 |
else |
|
379 |
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size); |
|
380 |
break; |
|
381 |
case 0x01c00018: /* MXCC stream data register 3 */ |
|
382 |
if (size == 8) |
|
383 |
env->mxccdata[3] = ((uint64_t)T1 << 32) | T2; |
|
384 |
else |
|
385 |
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size); |
|
386 |
break; |
|
387 |
case 0x01c00100: /* MXCC stream source */ |
|
388 |
if (size == 8) |
|
389 |
env->mxccregs[0] = ((uint64_t)T1 << 32) | T2; |
|
390 |
else |
|
391 |
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size); |
|
392 |
env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 0); |
|
393 |
env->mxccdata[1] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 8); |
|
394 |
env->mxccdata[2] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 16); |
|
395 |
env->mxccdata[3] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 24); |
|
396 |
break; |
|
397 |
case 0x01c00200: /* MXCC stream destination */ |
|
398 |
if (size == 8) |
|
399 |
env->mxccregs[1] = ((uint64_t)T1 << 32) | T2; |
|
400 |
else |
|
401 |
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size); |
|
402 |
stq_phys((env->mxccregs[1] & 0xffffffffULL) + 0, env->mxccdata[0]); |
|
403 |
stq_phys((env->mxccregs[1] & 0xffffffffULL) + 8, env->mxccdata[1]); |
|
404 |
stq_phys((env->mxccregs[1] & 0xffffffffULL) + 16, env->mxccdata[2]); |
|
405 |
stq_phys((env->mxccregs[1] & 0xffffffffULL) + 24, env->mxccdata[3]); |
|
406 |
break; |
|
407 |
case 0x01c00a00: /* MXCC control register */ |
|
408 |
if (size == 8) |
|
409 |
env->mxccregs[3] = ((uint64_t)T1 << 32) | T2; |
|
410 |
else |
|
411 |
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size); |
|
412 |
break; |
|
413 |
case 0x01c00a04: /* MXCC control register */ |
|
414 |
if (size == 4) |
|
415 |
env->mxccregs[3] = (env->mxccregs[0xa] & 0xffffffff00000000) | T1; |
|
416 |
else |
|
417 |
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size); |
|
418 |
break; |
|
419 |
case 0x01c00e00: /* MXCC error register */ |
|
420 |
if (size == 8) |
|
421 |
env->mxccregs[6] = ((uint64_t)T1 << 32) | T2; |
|
422 |
else |
|
423 |
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size); |
|
424 |
if (env->mxccregs[6] == 0xffffffffffffffffULL) { |
|
425 |
// this is probably a reset |
|
426 |
} |
|
427 |
break; |
|
428 |
case 0x01c00f00: /* MBus port address register */ |
|
429 |
if (size == 8) |
|
430 |
env->mxccregs[7] = ((uint64_t)T1 << 32) | T2; |
|
431 |
else |
|
432 |
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size); |
|
433 |
break; |
|
434 |
default: |
|
435 |
DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", T0, size); |
|
436 |
break; |
|
437 |
} |
|
438 |
DPRINTF_MXCC("asi = %d, size = %d, T0 = %08x, T1 = %08x\n", asi, size, T0, T1); |
|
439 |
#ifdef DEBUG_MXCC |
|
440 |
dump_mxcc(env); |
|
441 |
#endif |
|
305 | 442 |
break; |
306 | 443 |
case 3: /* MMU flush */ |
307 | 444 |
{ |
308 | 445 |
int mmulev; |
309 | 446 |
|
310 | 447 |
mmulev = (T0 >> 8) & 15; |
311 |
#ifdef DEBUG_MMU |
|
312 |
printf("mmu flush level %d\n", mmulev); |
|
313 |
#endif |
|
448 |
DPRINTF_MMU("mmu flush level %d\n", mmulev); |
|
314 | 449 |
switch (mmulev) { |
315 | 450 |
case 0: // flush page |
316 | 451 |
tlb_flush_page(env, T0 & 0xfffff000); |
... | ... | |
359 | 494 |
env->mmuregs[reg] = T1; |
360 | 495 |
break; |
361 | 496 |
} |
362 |
#ifdef DEBUG_MMU |
|
363 | 497 |
if (oldreg != env->mmuregs[reg]) { |
364 |
printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]);
|
|
498 |
DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]);
|
|
365 | 499 |
} |
500 |
#ifdef DEBUG_MMU |
|
366 | 501 |
dump_mmu(env); |
367 | 502 |
#endif |
368 | 503 |
return; |
... | ... | |
962 | 1097 |
// Mappings generated during D/I MMU disabled mode are |
963 | 1098 |
// invalid in normal mode |
964 | 1099 |
if (oldreg != env->lsu) { |
1100 |
DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu); |
|
965 | 1101 |
#ifdef DEBUG_MMU |
966 |
printf("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu); |
|
967 | 1102 |
dump_mmu(env); |
968 | 1103 |
#endif |
969 | 1104 |
tlb_flush(env, 1); |
... | ... | |
995 | 1130 |
break; |
996 | 1131 |
} |
997 | 1132 |
env->immuregs[reg] = T1; |
998 |
#ifdef DEBUG_MMU |
|
999 | 1133 |
if (oldreg != env->immuregs[reg]) { |
1000 |
printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
|
|
1134 |
DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
|
|
1001 | 1135 |
} |
1136 |
#ifdef DEBUG_MMU |
|
1002 | 1137 |
dump_mmu(env); |
1003 | 1138 |
#endif |
1004 | 1139 |
return; |
... | ... | |
1064 | 1199 |
break; |
1065 | 1200 |
} |
1066 | 1201 |
env->dmmuregs[reg] = T1; |
1067 |
#ifdef DEBUG_MMU |
|
1068 | 1202 |
if (oldreg != env->dmmuregs[reg]) { |
1069 |
printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
|
|
1203 |
DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
|
|
1070 | 1204 |
} |
1205 |
#ifdef DEBUG_MMU |
|
1071 | 1206 |
dump_mmu(env); |
1072 | 1207 |
#endif |
1073 | 1208 |
return; |
Also available in: Unified diff