Commit 4b3686faeefab6279f6d395fcf56ea5405d040da
1 parent
85c4adf6
PowerPC merge
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@861 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
6 changed files
with
274 additions
and
150 deletions
target-ppc/exec.h
@@ -135,6 +135,8 @@ void do_sraw(void); | @@ -135,6 +135,8 @@ void do_sraw(void); | ||
135 | 135 | ||
136 | void do_fctiw (void); | 136 | void do_fctiw (void); |
137 | void do_fctiwz (void); | 137 | void do_fctiwz (void); |
138 | +void do_fnmadd (void); | ||
139 | +void do_fnmsub (void); | ||
138 | void do_fnmadds (void); | 140 | void do_fnmadds (void); |
139 | void do_fnmsubs (void); | 141 | void do_fnmsubs (void); |
140 | void do_fsqrt (void); | 142 | void do_fsqrt (void); |
@@ -147,7 +149,11 @@ void do_fcmpo (void); | @@ -147,7 +149,11 @@ void do_fcmpo (void); | ||
147 | void do_fabs (void); | 149 | void do_fabs (void); |
148 | void do_fnabs (void); | 150 | void do_fnabs (void); |
149 | 151 | ||
152 | +void do_check_reservation (void); | ||
150 | void do_icbi (void); | 153 | void do_icbi (void); |
154 | +void do_store_sr (uint32_t srnum); | ||
155 | +void do_store_ibat (int ul, int nr); | ||
156 | +void do_store_dbat (int ul, int nr); | ||
151 | void do_tlbia (void); | 157 | void do_tlbia (void); |
152 | void do_tlbie (void); | 158 | void do_tlbie (void); |
153 | 159 |
target-ppc/helper.c
@@ -28,9 +28,6 @@ | @@ -28,9 +28,6 @@ | ||
28 | //#define DEBUG_EXCEPTIONS | 28 | //#define DEBUG_EXCEPTIONS |
29 | 29 | ||
30 | extern FILE *stdout, *stderr; | 30 | extern FILE *stdout, *stderr; |
31 | -void abort (void); | ||
32 | - | ||
33 | -/*****************************************************************************/ | ||
34 | 31 | ||
35 | /*****************************************************************************/ | 32 | /*****************************************************************************/ |
36 | /* PPC MMU emulation */ | 33 | /* PPC MMU emulation */ |
@@ -365,7 +362,8 @@ int get_physical_address (CPUState *env, uint32_t *physical, int *prot, | @@ -365,7 +362,8 @@ int get_physical_address (CPUState *env, uint32_t *physical, int *prot, | ||
365 | fprintf(logfile, "%s\n", __func__); | 362 | fprintf(logfile, "%s\n", __func__); |
366 | } | 363 | } |
367 | 364 | ||
368 | - if ((access_type == ACCESS_CODE && msr_ir == 0) || msr_dr == 0) { | 365 | + if ((access_type == ACCESS_CODE && msr_ir == 0) || |
366 | + (access_type != ACCESS_CODE && msr_dr == 0)) { | ||
369 | /* No address translation */ | 367 | /* No address translation */ |
370 | *physical = address & ~0xFFF; | 368 | *physical = address & ~0xFFF; |
371 | *prot = PAGE_READ | PAGE_WRITE; | 369 | *prot = PAGE_READ | PAGE_WRITE; |
@@ -441,12 +439,15 @@ void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr) | @@ -441,12 +439,15 @@ void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr) | ||
441 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | 439 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
442 | tlb_addrr = env->tlb_read[is_user][index].address; | 440 | tlb_addrr = env->tlb_read[is_user][index].address; |
443 | tlb_addrw = env->tlb_write[is_user][index].address; | 441 | tlb_addrw = env->tlb_write[is_user][index].address; |
444 | -#if 0 | ||
445 | - printf("%s 1 %p %p idx=%d addr=0x%08lx tbl_addr=0x%08lx 0x%08lx " | 442 | +#if 1 |
443 | + if (loglevel) { | ||
444 | + fprintf(logfile, | ||
445 | + "%s 1 %p %p idx=%d addr=0x%08lx tbl_addr=0x%08lx 0x%08lx " | ||
446 | "(0x%08lx 0x%08lx)\n", __func__, env, | 446 | "(0x%08lx 0x%08lx)\n", __func__, env, |
447 | &env->tlb_read[is_user][index], index, addr, | 447 | &env->tlb_read[is_user][index], index, addr, |
448 | tlb_addrr, tlb_addrw, addr & TARGET_PAGE_MASK, | 448 | tlb_addrr, tlb_addrw, addr & TARGET_PAGE_MASK, |
449 | tlb_addrr & (TARGET_PAGE_MASK | TLB_INVALID_MASK)); | 449 | tlb_addrr & (TARGET_PAGE_MASK | TLB_INVALID_MASK)); |
450 | + } | ||
450 | #endif | 451 | #endif |
451 | } | 452 | } |
452 | ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, is_user, 1); | 453 | ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, is_user, 1); |
@@ -631,11 +632,14 @@ uint32_t _load_msr (CPUState *env) | @@ -631,11 +632,14 @@ uint32_t _load_msr (CPUState *env) | ||
631 | 632 | ||
632 | void _store_msr (CPUState *env, uint32_t value) | 633 | void _store_msr (CPUState *env, uint32_t value) |
633 | { | 634 | { |
635 | +#if 0 // TRY | ||
634 | if (((value >> MSR_IR) & 0x01) != msr_ir || | 636 | if (((value >> MSR_IR) & 0x01) != msr_ir || |
635 | - ((value >> MSR_DR) & 0x01) != msr_dr) { | 637 | + ((value >> MSR_DR) & 0x01) != msr_dr) |
638 | + { | ||
636 | /* Flush all tlb when changing translation mode or privilege level */ | 639 | /* Flush all tlb when changing translation mode or privilege level */ |
637 | tlb_flush(env, 1); | 640 | tlb_flush(env, 1); |
638 | } | 641 | } |
642 | +#endif | ||
639 | msr_pow = (value >> MSR_POW) & 0x03; | 643 | msr_pow = (value >> MSR_POW) & 0x03; |
640 | msr_ile = (value >> MSR_ILE) & 0x01; | 644 | msr_ile = (value >> MSR_ILE) & 0x01; |
641 | msr_ee = (value >> MSR_EE) & 0x01; | 645 | msr_ee = (value >> MSR_EE) & 0x01; |
@@ -699,13 +703,8 @@ void do_interrupt (CPUState *env) | @@ -699,13 +703,8 @@ void do_interrupt (CPUState *env) | ||
699 | goto store_next; | 703 | goto store_next; |
700 | case EXCP_MACHINE_CHECK: | 704 | case EXCP_MACHINE_CHECK: |
701 | if (msr_me == 0) { | 705 | if (msr_me == 0) { |
702 | - printf("Machine check exception while not allowed !\n"); | ||
703 | - if (loglevel) { | ||
704 | - fprintf(logfile, | ||
705 | - "Machine check exception while not allowed !\n"); | 706 | + cpu_abort(env, "Machine check exception while not allowed\n"); |
706 | } | 707 | } |
707 | - abort(); | ||
708 | - } | ||
709 | msr_me = 0; | 708 | msr_me = 0; |
710 | break; | 709 | break; |
711 | case EXCP_DSI: | 710 | case EXCP_DSI: |
@@ -801,7 +800,7 @@ void do_interrupt (CPUState *env) | @@ -801,7 +800,7 @@ void do_interrupt (CPUState *env) | ||
801 | env->fpscr[7] |= 0x4; | 800 | env->fpscr[7] |= 0x4; |
802 | break; | 801 | break; |
803 | case EXCP_INVAL: | 802 | case EXCP_INVAL: |
804 | - printf("Invalid instruction at 0x%08x\n", env->nip); | 803 | + // printf("Invalid instruction at 0x%08x\n", env->nip); |
805 | msr |= 0x00080000; | 804 | msr |= 0x00080000; |
806 | break; | 805 | break; |
807 | case EXCP_PRIV: | 806 | case EXCP_PRIV: |
target-ppc/op.c
@@ -242,10 +242,7 @@ PPC_OP(load_srin) | @@ -242,10 +242,7 @@ PPC_OP(load_srin) | ||
242 | 242 | ||
243 | PPC_OP(store_srin) | 243 | PPC_OP(store_srin) |
244 | { | 244 | { |
245 | -#if defined (DEBUG_OP) | ||
246 | - dump_store_sr(T1 >> 28); | ||
247 | -#endif | ||
248 | - regs->sr[T1 >> 28] = T0; | 245 | + do_store_sr(T1 >> 28); |
249 | RETURN(); | 246 | RETURN(); |
250 | } | 247 | } |
251 | 248 | ||
@@ -402,10 +399,7 @@ PPC_OP(load_ibat) | @@ -402,10 +399,7 @@ PPC_OP(load_ibat) | ||
402 | 399 | ||
403 | PPC_OP(store_ibat) | 400 | PPC_OP(store_ibat) |
404 | { | 401 | { |
405 | -#if defined (DEBUG_OP) | ||
406 | - dump_store_ibat(PARAM(1), PARAM(2)); | ||
407 | -#endif | ||
408 | - regs->IBAT[PARAM(1)][PARAM(2)] = T0; | 402 | + do_store_ibat(PARAM(1), PARAM(2)); |
409 | } | 403 | } |
410 | 404 | ||
411 | PPC_OP(load_dbat) | 405 | PPC_OP(load_dbat) |
@@ -415,10 +409,7 @@ PPC_OP(load_dbat) | @@ -415,10 +409,7 @@ PPC_OP(load_dbat) | ||
415 | 409 | ||
416 | PPC_OP(store_dbat) | 410 | PPC_OP(store_dbat) |
417 | { | 411 | { |
418 | -#if defined (DEBUG_OP) | ||
419 | - dump_store_dbat(PARAM(1), PARAM(2)); | ||
420 | -#endif | ||
421 | - regs->DBAT[PARAM(1)][PARAM(2)] = T0; | 412 | + do_store_dbat(PARAM(1), PARAM(2)); |
422 | } | 413 | } |
423 | 414 | ||
424 | /* FPSCR */ | 415 | /* FPSCR */ |
@@ -1344,9 +1335,7 @@ PPC_OP(fmsubs) | @@ -1344,9 +1335,7 @@ PPC_OP(fmsubs) | ||
1344 | /* fnmadd - fnmadd. - fnmadds - fnmadds. */ | 1335 | /* fnmadd - fnmadd. - fnmadds - fnmadds. */ |
1345 | PPC_OP(fnmadd) | 1336 | PPC_OP(fnmadd) |
1346 | { | 1337 | { |
1347 | - FT0 *= FT1; | ||
1348 | - FT0 += FT2; | ||
1349 | - FT0 = -FT0; | 1338 | + do_fnmadd(); |
1350 | RETURN(); | 1339 | RETURN(); |
1351 | } | 1340 | } |
1352 | 1341 | ||
@@ -1360,9 +1349,7 @@ PPC_OP(fnmadds) | @@ -1360,9 +1349,7 @@ PPC_OP(fnmadds) | ||
1360 | /* fnmsub - fnmsub. */ | 1349 | /* fnmsub - fnmsub. */ |
1361 | PPC_OP(fnmsub) | 1350 | PPC_OP(fnmsub) |
1362 | { | 1351 | { |
1363 | - FT0 *= FT1; | ||
1364 | - FT0 -= FT2; | ||
1365 | - FT0 = -FT0; | 1352 | + do_fnmsub(); |
1366 | RETURN(); | 1353 | RETURN(); |
1367 | } | 1354 | } |
1368 | 1355 | ||
@@ -1444,11 +1431,22 @@ PPC_OP(fneg) | @@ -1444,11 +1431,22 @@ PPC_OP(fneg) | ||
1444 | #include "op_mem.h" | 1431 | #include "op_mem.h" |
1445 | #endif | 1432 | #endif |
1446 | 1433 | ||
1434 | +/* Special op to check and maybe clear reservation */ | ||
1435 | +PPC_OP(check_reservation) | ||
1436 | +{ | ||
1437 | + do_check_reservation(); | ||
1438 | + RETURN(); | ||
1439 | +} | ||
1440 | + | ||
1447 | /* Return from interrupt */ | 1441 | /* Return from interrupt */ |
1448 | PPC_OP(rfi) | 1442 | PPC_OP(rfi) |
1449 | { | 1443 | { |
1450 | regs->nip = regs->spr[SRR0] & ~0x00000003; | 1444 | regs->nip = regs->spr[SRR0] & ~0x00000003; |
1445 | +#if 1 // TRY | ||
1446 | + T0 = regs->spr[SRR1] & ~0xFFF00000; | ||
1447 | +#else | ||
1451 | T0 = regs->spr[SRR1] & ~0xFFFF0000; | 1448 | T0 = regs->spr[SRR1] & ~0xFFFF0000; |
1449 | +#endif | ||
1452 | do_store_msr(); | 1450 | do_store_msr(); |
1453 | #if defined (DEBUG_OP) | 1451 | #if defined (DEBUG_OP) |
1454 | dump_rfi(); | 1452 | dump_rfi(); |
target-ppc/op_helper.c
@@ -127,11 +127,14 @@ void do_load_msr (void) | @@ -127,11 +127,14 @@ void do_load_msr (void) | ||
127 | 127 | ||
128 | void do_store_msr (void) | 128 | void do_store_msr (void) |
129 | { | 129 | { |
130 | +#if 1 // TRY | ||
130 | if (((T0 >> MSR_IR) & 0x01) != msr_ir || | 131 | if (((T0 >> MSR_IR) & 0x01) != msr_ir || |
131 | - ((T0 >> MSR_DR) & 0x01) != msr_dr) { | ||
132 | - /* Flush all tlb when changing translation mode or privilege level */ | 132 | + ((T0 >> MSR_DR) & 0x01) != msr_dr || |
133 | + ((T0 >> MSR_PR) & 0x01) != msr_pr) | ||
134 | + { | ||
133 | do_tlbia(); | 135 | do_tlbia(); |
134 | } | 136 | } |
137 | +#endif | ||
135 | msr_pow = (T0 >> MSR_POW) & 0x03; | 138 | msr_pow = (T0 >> MSR_POW) & 0x03; |
136 | msr_ile = (T0 >> MSR_ILE) & 0x01; | 139 | msr_ile = (T0 >> MSR_ILE) & 0x01; |
137 | msr_ee = (T0 >> MSR_EE) & 0x01; | 140 | msr_ee = (T0 >> MSR_EE) & 0x01; |
@@ -157,14 +160,18 @@ void do_sraw (void) | @@ -157,14 +160,18 @@ void do_sraw (void) | ||
157 | xer_ca = 0; | 160 | xer_ca = 0; |
158 | if (T1 & 0x20) { | 161 | if (T1 & 0x20) { |
159 | ret = (-1) * (T0 >> 31); | 162 | ret = (-1) * (T0 >> 31); |
160 | - if (ret < 0) | 163 | + if (ret < 0 && (T0 & ~0x80000000) != 0) |
161 | xer_ca = 1; | 164 | xer_ca = 1; |
165 | +#if 1 // TRY | ||
166 | + } else if (T1 == 0) { | ||
167 | + ret = T0; | ||
168 | +#endif | ||
162 | } else { | 169 | } else { |
163 | ret = (int32_t)T0 >> (T1 & 0x1f); | 170 | ret = (int32_t)T0 >> (T1 & 0x1f); |
164 | if (ret < 0 && ((int32_t)T0 & ((1 << T1) - 1)) != 0) | 171 | if (ret < 0 && ((int32_t)T0 & ((1 << T1) - 1)) != 0) |
165 | xer_ca = 1; | 172 | xer_ca = 1; |
166 | } | 173 | } |
167 | - (int32_t)T0 = ret; | 174 | + T0 = ret; |
168 | } | 175 | } |
169 | 176 | ||
170 | /* Floating point operations helpers */ | 177 | /* Floating point operations helpers */ |
@@ -267,14 +274,24 @@ void do_fctiwz (void) | @@ -267,14 +274,24 @@ void do_fctiwz (void) | ||
267 | fesetround(cround); | 274 | fesetround(cround); |
268 | } | 275 | } |
269 | 276 | ||
277 | +void do_fnmadd (void) | ||
278 | +{ | ||
279 | + FT0 = -((FT0 * FT1) + FT2); | ||
280 | +} | ||
281 | + | ||
282 | +void do_fnmsub (void) | ||
283 | +{ | ||
284 | + FT0 = -((FT0 * FT1) - FT2); | ||
285 | +} | ||
286 | + | ||
270 | void do_fnmadds (void) | 287 | void do_fnmadds (void) |
271 | { | 288 | { |
272 | - FTS0 = -((FTS0 * FTS1) + FTS2); | 289 | + FT0 = -((FTS0 * FTS1) + FTS2); |
273 | } | 290 | } |
274 | 291 | ||
275 | void do_fnmsubs (void) | 292 | void do_fnmsubs (void) |
276 | { | 293 | { |
277 | - FTS0 = -((FTS0 * FTS1) - FTS2); | 294 | + FT0 = -((FTS0 * FTS1) - FTS2); |
278 | } | 295 | } |
279 | 296 | ||
280 | void do_fsqrt (void) | 297 | void do_fsqrt (void) |
@@ -307,7 +324,6 @@ void do_fsel (void) | @@ -307,7 +324,6 @@ void do_fsel (void) | ||
307 | 324 | ||
308 | void do_fcmpu (void) | 325 | void do_fcmpu (void) |
309 | { | 326 | { |
310 | - env->fpscr[4] &= ~0x1; | ||
311 | if (isnan(FT0) || isnan(FT1)) { | 327 | if (isnan(FT0) || isnan(FT1)) { |
312 | T0 = 0x01; | 328 | T0 = 0x01; |
313 | env->fpscr[4] |= 0x1; | 329 | env->fpscr[4] |= 0x1; |
@@ -319,7 +335,7 @@ void do_fcmpu (void) | @@ -319,7 +335,7 @@ void do_fcmpu (void) | ||
319 | } else { | 335 | } else { |
320 | T0 = 0x02; | 336 | T0 = 0x02; |
321 | } | 337 | } |
322 | - env->fpscr[3] |= T0; | 338 | + env->fpscr[3] = T0; |
323 | } | 339 | } |
324 | 340 | ||
325 | void do_fcmpo (void) | 341 | void do_fcmpo (void) |
@@ -343,7 +359,7 @@ void do_fcmpo (void) | @@ -343,7 +359,7 @@ void do_fcmpo (void) | ||
343 | } else { | 359 | } else { |
344 | T0 = 0x02; | 360 | T0 = 0x02; |
345 | } | 361 | } |
346 | - env->fpscr[3] |= T0; | 362 | + env->fpscr[3] = T0; |
347 | } | 363 | } |
348 | 364 | ||
349 | void do_fabs (void) | 365 | void do_fabs (void) |
@@ -359,6 +375,12 @@ void do_fnabs (void) | @@ -359,6 +375,12 @@ void do_fnabs (void) | ||
359 | /* Instruction cache invalidation helper */ | 375 | /* Instruction cache invalidation helper */ |
360 | #define ICACHE_LINE_SIZE 32 | 376 | #define ICACHE_LINE_SIZE 32 |
361 | 377 | ||
378 | +void do_check_reservation (void) | ||
379 | +{ | ||
380 | + if ((env->reserve & ~(ICACHE_LINE_SIZE - 1)) == T0) | ||
381 | + env->reserve = -1; | ||
382 | +} | ||
383 | + | ||
362 | void do_icbi (void) | 384 | void do_icbi (void) |
363 | { | 385 | { |
364 | /* Invalidate one cache line */ | 386 | /* Invalidate one cache line */ |
@@ -377,6 +399,69 @@ void do_tlbie (void) | @@ -377,6 +399,69 @@ void do_tlbie (void) | ||
377 | tlb_flush_page(env, T0); | 399 | tlb_flush_page(env, T0); |
378 | } | 400 | } |
379 | 401 | ||
402 | +void do_store_sr (uint32_t srnum) | ||
403 | +{ | ||
404 | +#if defined (DEBUG_OP) | ||
405 | + dump_store_sr(srnum); | ||
406 | +#endif | ||
407 | +#if 0 // TRY | ||
408 | + { | ||
409 | + uint32_t base, page; | ||
410 | + | ||
411 | + base = srnum << 28; | ||
412 | + for (page = base; page != base + 0x100000000; page += 0x1000) | ||
413 | + tlb_flush_page(env, page); | ||
414 | + } | ||
415 | +#else | ||
416 | + tlb_flush(env, 1); | ||
417 | +#endif | ||
418 | + env->sr[srnum] = T0; | ||
419 | +} | ||
420 | + | ||
421 | +/* For BATs, we may not invalidate any TLBs if the change is only on | ||
422 | + * protection bits for user mode. | ||
423 | + */ | ||
424 | +void do_store_ibat (int ul, int nr) | ||
425 | +{ | ||
426 | +#if defined (DEBUG_OP) | ||
427 | + dump_store_ibat(ul, nr); | ||
428 | +#endif | ||
429 | +#if 0 // TRY | ||
430 | + { | ||
431 | + uint32_t base, length, page; | ||
432 | + | ||
433 | + base = env->IBAT[0][nr]; | ||
434 | + length = (((base >> 2) & 0x000007FF) + 1) << 17; | ||
435 | + base &= 0xFFFC0000; | ||
436 | + for (page = base; page != base + length; page += 0x1000) | ||
437 | + tlb_flush_page(env, page); | ||
438 | + } | ||
439 | +#else | ||
440 | + tlb_flush(env, 1); | ||
441 | +#endif | ||
442 | + env->IBAT[ul][nr] = T0; | ||
443 | +} | ||
444 | + | ||
445 | +void do_store_dbat (int ul, int nr) | ||
446 | +{ | ||
447 | +#if defined (DEBUG_OP) | ||
448 | + dump_store_dbat(ul, nr); | ||
449 | +#endif | ||
450 | +#if 0 // TRY | ||
451 | + { | ||
452 | + uint32_t base, length, page; | ||
453 | + base = env->DBAT[0][nr]; | ||
454 | + length = (((base >> 2) & 0x000007FF) + 1) << 17; | ||
455 | + base &= 0xFFFC0000; | ||
456 | + for (page = base; page != base + length; page += 0x1000) | ||
457 | + tlb_flush_page(env, page); | ||
458 | + } | ||
459 | +#else | ||
460 | + tlb_flush(env, 1); | ||
461 | +#endif | ||
462 | + env->DBAT[ul][nr] = T0; | ||
463 | +} | ||
464 | + | ||
380 | /*****************************************************************************/ | 465 | /*****************************************************************************/ |
381 | /* Special helpers for debug */ | 466 | /* Special helpers for debug */ |
382 | extern FILE *stdout; | 467 | extern FILE *stdout; |
@@ -389,7 +474,7 @@ void dump_state (void) | @@ -389,7 +474,7 @@ void dump_state (void) | ||
389 | void dump_rfi (void) | 474 | void dump_rfi (void) |
390 | { | 475 | { |
391 | #if 0 | 476 | #if 0 |
392 | - printf("Return from interrupt %d => 0x%08x\n", pos, env->nip); | 477 | + printf("Return from interrupt => 0x%08x\n", env->nip); |
393 | // cpu_ppc_dump_state(env, stdout, 0); | 478 | // cpu_ppc_dump_state(env, stdout, 0); |
394 | #endif | 479 | #endif |
395 | } | 480 | } |
target-ppc/op_template.h
@@ -175,10 +175,7 @@ void OPPROTO glue(op_load_sr, REG)(void) | @@ -175,10 +175,7 @@ void OPPROTO glue(op_load_sr, REG)(void) | ||
175 | 175 | ||
176 | void OPPROTO glue(op_store_sr, REG)(void) | 176 | void OPPROTO glue(op_store_sr, REG)(void) |
177 | { | 177 | { |
178 | -#if defined (DEBUG_OP) | ||
179 | - dump_store_sr(REG); | ||
180 | -#endif | ||
181 | - env->sr[REG] = T0; | 178 | + do_store_sr(REG); |
182 | RETURN(); | 179 | RETURN(); |
183 | } | 180 | } |
184 | #endif | 181 | #endif |
target-ppc/translate.c
@@ -28,8 +28,6 @@ | @@ -28,8 +28,6 @@ | ||
28 | #include "disas.h" | 28 | #include "disas.h" |
29 | 29 | ||
30 | //#define DO_SINGLE_STEP | 30 | //#define DO_SINGLE_STEP |
31 | -//#define DO_STEP_FLUSH | ||
32 | -//#define DEBUG_DISAS | ||
33 | //#define PPC_DEBUG_DISAS | 31 | //#define PPC_DEBUG_DISAS |
34 | 32 | ||
35 | enum { | 33 | enum { |
@@ -639,7 +637,7 @@ GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) | @@ -639,7 +637,7 @@ GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) | ||
639 | } | 637 | } |
640 | gen_op_load_gpr_T0(rS(ctx->opcode)); | 638 | gen_op_load_gpr_T0(rS(ctx->opcode)); |
641 | if (uimm != 0) | 639 | if (uimm != 0) |
642 | - gen_op_xori(UIMM(ctx->opcode)); | 640 | + gen_op_xori(uimm); |
643 | gen_op_store_T0_gpr(rA(ctx->opcode)); | 641 | gen_op_store_T0_gpr(rA(ctx->opcode)); |
644 | } | 642 | } |
645 | 643 | ||
@@ -654,7 +652,7 @@ GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) | @@ -654,7 +652,7 @@ GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) | ||
654 | } | 652 | } |
655 | gen_op_load_gpr_T0(rS(ctx->opcode)); | 653 | gen_op_load_gpr_T0(rS(ctx->opcode)); |
656 | if (uimm != 0) | 654 | if (uimm != 0) |
657 | - gen_op_xori(UIMM(ctx->opcode) << 16); | 655 | + gen_op_xori(uimm << 16); |
658 | gen_op_store_T0_gpr(rA(ctx->opcode)); | 656 | gen_op_store_T0_gpr(rA(ctx->opcode)); |
659 | } | 657 | } |
660 | 658 | ||
@@ -682,25 +680,29 @@ GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) | @@ -682,25 +680,29 @@ GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) | ||
682 | mb = MB(ctx->opcode); | 680 | mb = MB(ctx->opcode); |
683 | me = ME(ctx->opcode); | 681 | me = ME(ctx->opcode); |
684 | gen_op_load_gpr_T0(rS(ctx->opcode)); | 682 | gen_op_load_gpr_T0(rS(ctx->opcode)); |
683 | +#if 1 // TRY | ||
684 | + if (sh == 0) { | ||
685 | + gen_op_andi_(MASK(mb, me)); | ||
686 | + goto store; | ||
687 | + } | ||
688 | +#endif | ||
685 | if (mb == 0) { | 689 | if (mb == 0) { |
686 | if (me == 31) { | 690 | if (me == 31) { |
687 | gen_op_rotlwi(sh); | 691 | gen_op_rotlwi(sh); |
688 | goto store; | 692 | goto store; |
693 | +#if 0 | ||
689 | } else if (me == (31 - sh)) { | 694 | } else if (me == (31 - sh)) { |
690 | gen_op_slwi(sh); | 695 | gen_op_slwi(sh); |
691 | goto store; | 696 | goto store; |
692 | - } else if (sh == 0) { | ||
693 | - gen_op_andi_(MASK(0, me)); | ||
694 | - goto store; | 697 | +#endif |
695 | } | 698 | } |
696 | } else if (me == 31) { | 699 | } else if (me == 31) { |
700 | +#if 0 | ||
697 | if (sh == (32 - mb)) { | 701 | if (sh == (32 - mb)) { |
698 | gen_op_srwi(mb); | 702 | gen_op_srwi(mb); |
699 | goto store; | 703 | goto store; |
700 | - } else if (sh == 0) { | ||
701 | - gen_op_andi_(MASK(mb, 31)); | ||
702 | - goto store; | ||
703 | } | 704 | } |
705 | +#endif | ||
704 | } | 706 | } |
705 | gen_op_rlwinm(sh, MASK(mb, me)); | 707 | gen_op_rlwinm(sh, MASK(mb, me)); |
706 | store: | 708 | store: |
@@ -1268,12 +1270,16 @@ GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER) | @@ -1268,12 +1270,16 @@ GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER) | ||
1268 | /* stswi */ | 1270 | /* stswi */ |
1269 | GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER) | 1271 | GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER) |
1270 | { | 1272 | { |
1273 | + int nb = NB(ctx->opcode); | ||
1274 | + | ||
1271 | if (rA(ctx->opcode) == 0) { | 1275 | if (rA(ctx->opcode) == 0) { |
1272 | gen_op_set_T0(0); | 1276 | gen_op_set_T0(0); |
1273 | } else { | 1277 | } else { |
1274 | gen_op_load_gpr_T0(rA(ctx->opcode)); | 1278 | gen_op_load_gpr_T0(rA(ctx->opcode)); |
1275 | } | 1279 | } |
1276 | - gen_op_set_T1(NB(ctx->opcode)); | 1280 | + if (nb == 0) |
1281 | + nb = 32; | ||
1282 | + gen_op_set_T1(nb); | ||
1277 | op_ldsts(stsw, rS(ctx->opcode)); | 1283 | op_ldsts(stsw, rS(ctx->opcode)); |
1278 | } | 1284 | } |
1279 | 1285 | ||
@@ -1931,7 +1937,6 @@ GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MISC) | @@ -1931,7 +1937,6 @@ GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MISC) | ||
1931 | /* We need to update the time base before reading it */ | 1937 | /* We need to update the time base before reading it */ |
1932 | switch (sprn) { | 1938 | switch (sprn) { |
1933 | case V_TBL: | 1939 | case V_TBL: |
1934 | - /* TBL is still in T0 */ | ||
1935 | gen_op_load_tbl(); | 1940 | gen_op_load_tbl(); |
1936 | break; | 1941 | break; |
1937 | case V_TBU: | 1942 | case V_TBU: |
@@ -2007,135 +2012,135 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC) | @@ -2007,135 +2012,135 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC) | ||
2007 | break; | 2012 | break; |
2008 | case IBAT0U: | 2013 | case IBAT0U: |
2009 | gen_op_store_ibat(0, 0); | 2014 | gen_op_store_ibat(0, 0); |
2010 | - gen_op_tlbia(); | 2015 | + RET_MTMSR(ctx); |
2011 | break; | 2016 | break; |
2012 | case IBAT1U: | 2017 | case IBAT1U: |
2013 | gen_op_store_ibat(0, 1); | 2018 | gen_op_store_ibat(0, 1); |
2014 | - gen_op_tlbia(); | 2019 | + RET_MTMSR(ctx); |
2015 | break; | 2020 | break; |
2016 | case IBAT2U: | 2021 | case IBAT2U: |
2017 | gen_op_store_ibat(0, 2); | 2022 | gen_op_store_ibat(0, 2); |
2018 | - gen_op_tlbia(); | 2023 | + RET_MTMSR(ctx); |
2019 | break; | 2024 | break; |
2020 | case IBAT3U: | 2025 | case IBAT3U: |
2021 | gen_op_store_ibat(0, 3); | 2026 | gen_op_store_ibat(0, 3); |
2022 | - gen_op_tlbia(); | 2027 | + RET_MTMSR(ctx); |
2023 | break; | 2028 | break; |
2024 | case IBAT4U: | 2029 | case IBAT4U: |
2025 | gen_op_store_ibat(0, 4); | 2030 | gen_op_store_ibat(0, 4); |
2026 | - gen_op_tlbia(); | 2031 | + RET_MTMSR(ctx); |
2027 | break; | 2032 | break; |
2028 | case IBAT5U: | 2033 | case IBAT5U: |
2029 | gen_op_store_ibat(0, 5); | 2034 | gen_op_store_ibat(0, 5); |
2030 | - gen_op_tlbia(); | 2035 | + RET_MTMSR(ctx); |
2031 | break; | 2036 | break; |
2032 | case IBAT6U: | 2037 | case IBAT6U: |
2033 | gen_op_store_ibat(0, 6); | 2038 | gen_op_store_ibat(0, 6); |
2034 | - gen_op_tlbia(); | 2039 | + RET_MTMSR(ctx); |
2035 | break; | 2040 | break; |
2036 | case IBAT7U: | 2041 | case IBAT7U: |
2037 | gen_op_store_ibat(0, 7); | 2042 | gen_op_store_ibat(0, 7); |
2038 | - gen_op_tlbia(); | 2043 | + RET_MTMSR(ctx); |
2039 | break; | 2044 | break; |
2040 | case IBAT0L: | 2045 | case IBAT0L: |
2041 | gen_op_store_ibat(1, 0); | 2046 | gen_op_store_ibat(1, 0); |
2042 | - gen_op_tlbia(); | 2047 | + RET_MTMSR(ctx); |
2043 | break; | 2048 | break; |
2044 | case IBAT1L: | 2049 | case IBAT1L: |
2045 | gen_op_store_ibat(1, 1); | 2050 | gen_op_store_ibat(1, 1); |
2046 | - gen_op_tlbia(); | 2051 | + RET_MTMSR(ctx); |
2047 | break; | 2052 | break; |
2048 | case IBAT2L: | 2053 | case IBAT2L: |
2049 | gen_op_store_ibat(1, 2); | 2054 | gen_op_store_ibat(1, 2); |
2050 | - gen_op_tlbia(); | 2055 | + RET_MTMSR(ctx); |
2051 | break; | 2056 | break; |
2052 | case IBAT3L: | 2057 | case IBAT3L: |
2053 | gen_op_store_ibat(1, 3); | 2058 | gen_op_store_ibat(1, 3); |
2054 | - gen_op_tlbia(); | 2059 | + RET_MTMSR(ctx); |
2055 | break; | 2060 | break; |
2056 | case IBAT4L: | 2061 | case IBAT4L: |
2057 | gen_op_store_ibat(1, 4); | 2062 | gen_op_store_ibat(1, 4); |
2058 | - gen_op_tlbia(); | 2063 | + RET_MTMSR(ctx); |
2059 | break; | 2064 | break; |
2060 | case IBAT5L: | 2065 | case IBAT5L: |
2061 | gen_op_store_ibat(1, 5); | 2066 | gen_op_store_ibat(1, 5); |
2062 | - gen_op_tlbia(); | 2067 | + RET_MTMSR(ctx); |
2063 | break; | 2068 | break; |
2064 | case IBAT6L: | 2069 | case IBAT6L: |
2065 | gen_op_store_ibat(1, 6); | 2070 | gen_op_store_ibat(1, 6); |
2066 | - gen_op_tlbia(); | 2071 | + RET_MTMSR(ctx); |
2067 | break; | 2072 | break; |
2068 | case IBAT7L: | 2073 | case IBAT7L: |
2069 | gen_op_store_ibat(1, 7); | 2074 | gen_op_store_ibat(1, 7); |
2070 | - gen_op_tlbia(); | 2075 | + RET_MTMSR(ctx); |
2071 | break; | 2076 | break; |
2072 | case DBAT0U: | 2077 | case DBAT0U: |
2073 | gen_op_store_dbat(0, 0); | 2078 | gen_op_store_dbat(0, 0); |
2074 | - gen_op_tlbia(); | 2079 | + RET_MTMSR(ctx); |
2075 | break; | 2080 | break; |
2076 | case DBAT1U: | 2081 | case DBAT1U: |
2077 | gen_op_store_dbat(0, 1); | 2082 | gen_op_store_dbat(0, 1); |
2078 | - gen_op_tlbia(); | 2083 | + RET_MTMSR(ctx); |
2079 | break; | 2084 | break; |
2080 | case DBAT2U: | 2085 | case DBAT2U: |
2081 | gen_op_store_dbat(0, 2); | 2086 | gen_op_store_dbat(0, 2); |
2082 | - gen_op_tlbia(); | 2087 | + RET_MTMSR(ctx); |
2083 | break; | 2088 | break; |
2084 | case DBAT3U: | 2089 | case DBAT3U: |
2085 | gen_op_store_dbat(0, 3); | 2090 | gen_op_store_dbat(0, 3); |
2086 | - gen_op_tlbia(); | 2091 | + RET_MTMSR(ctx); |
2087 | break; | 2092 | break; |
2088 | case DBAT4U: | 2093 | case DBAT4U: |
2089 | gen_op_store_dbat(0, 4); | 2094 | gen_op_store_dbat(0, 4); |
2090 | - gen_op_tlbia(); | 2095 | + RET_MTMSR(ctx); |
2091 | break; | 2096 | break; |
2092 | case DBAT5U: | 2097 | case DBAT5U: |
2093 | gen_op_store_dbat(0, 5); | 2098 | gen_op_store_dbat(0, 5); |
2094 | - gen_op_tlbia(); | 2099 | + RET_MTMSR(ctx); |
2095 | break; | 2100 | break; |
2096 | case DBAT6U: | 2101 | case DBAT6U: |
2097 | gen_op_store_dbat(0, 6); | 2102 | gen_op_store_dbat(0, 6); |
2098 | - gen_op_tlbia(); | 2103 | + RET_MTMSR(ctx); |
2099 | break; | 2104 | break; |
2100 | case DBAT7U: | 2105 | case DBAT7U: |
2101 | gen_op_store_dbat(0, 7); | 2106 | gen_op_store_dbat(0, 7); |
2102 | - gen_op_tlbia(); | 2107 | + RET_MTMSR(ctx); |
2103 | break; | 2108 | break; |
2104 | case DBAT0L: | 2109 | case DBAT0L: |
2105 | gen_op_store_dbat(1, 0); | 2110 | gen_op_store_dbat(1, 0); |
2106 | - gen_op_tlbia(); | 2111 | + RET_MTMSR(ctx); |
2107 | break; | 2112 | break; |
2108 | case DBAT1L: | 2113 | case DBAT1L: |
2109 | gen_op_store_dbat(1, 1); | 2114 | gen_op_store_dbat(1, 1); |
2110 | - gen_op_tlbia(); | 2115 | + RET_MTMSR(ctx); |
2111 | break; | 2116 | break; |
2112 | case DBAT2L: | 2117 | case DBAT2L: |
2113 | gen_op_store_dbat(1, 2); | 2118 | gen_op_store_dbat(1, 2); |
2114 | - gen_op_tlbia(); | 2119 | + RET_MTMSR(ctx); |
2115 | break; | 2120 | break; |
2116 | case DBAT3L: | 2121 | case DBAT3L: |
2117 | gen_op_store_dbat(1, 3); | 2122 | gen_op_store_dbat(1, 3); |
2118 | - gen_op_tlbia(); | 2123 | + RET_MTMSR(ctx); |
2119 | break; | 2124 | break; |
2120 | case DBAT4L: | 2125 | case DBAT4L: |
2121 | gen_op_store_dbat(1, 4); | 2126 | gen_op_store_dbat(1, 4); |
2122 | - gen_op_tlbia(); | 2127 | + RET_MTMSR(ctx); |
2123 | break; | 2128 | break; |
2124 | case DBAT5L: | 2129 | case DBAT5L: |
2125 | gen_op_store_dbat(1, 5); | 2130 | gen_op_store_dbat(1, 5); |
2126 | - gen_op_tlbia(); | 2131 | + RET_MTMSR(ctx); |
2127 | break; | 2132 | break; |
2128 | case DBAT6L: | 2133 | case DBAT6L: |
2129 | gen_op_store_dbat(1, 6); | 2134 | gen_op_store_dbat(1, 6); |
2130 | - gen_op_tlbia(); | 2135 | + RET_MTMSR(ctx); |
2131 | break; | 2136 | break; |
2132 | case DBAT7L: | 2137 | case DBAT7L: |
2133 | gen_op_store_dbat(1, 7); | 2138 | gen_op_store_dbat(1, 7); |
2134 | - gen_op_tlbia(); | 2139 | + RET_MTMSR(ctx); |
2135 | break; | 2140 | break; |
2136 | case SDR1: | 2141 | case SDR1: |
2137 | gen_op_store_sdr1(); | 2142 | gen_op_store_sdr1(); |
2138 | - gen_op_tlbia(); | 2143 | + RET_MTMSR(ctx); |
2139 | break; | 2144 | break; |
2140 | case O_TBL: | 2145 | case O_TBL: |
2141 | gen_op_store_tbl(); | 2146 | gen_op_store_tbl(); |
@@ -2146,6 +2151,11 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC) | @@ -2146,6 +2151,11 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC) | ||
2146 | case DECR: | 2151 | case DECR: |
2147 | gen_op_store_decr(); | 2152 | gen_op_store_decr(); |
2148 | break; | 2153 | break; |
2154 | +#if 0 | ||
2155 | + case HID0: | ||
2156 | + gen_op_store_hid0(); | ||
2157 | + break; | ||
2158 | +#endif | ||
2149 | default: | 2159 | default: |
2150 | gen_op_store_spr(sprn); | 2160 | gen_op_store_spr(sprn); |
2151 | break; | 2161 | break; |
@@ -2236,6 +2246,7 @@ GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE) | @@ -2236,6 +2246,7 @@ GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE) | ||
2236 | gen_op_add(); | 2246 | gen_op_add(); |
2237 | } | 2247 | } |
2238 | op_dcbz(); | 2248 | op_dcbz(); |
2249 | + gen_op_check_reservation(); | ||
2239 | } | 2250 | } |
2240 | 2251 | ||
2241 | /* icbi */ | 2252 | /* icbi */ |
@@ -2302,10 +2313,6 @@ GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT) | @@ -2302,10 +2313,6 @@ GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT) | ||
2302 | } | 2313 | } |
2303 | gen_op_load_gpr_T0(rS(ctx->opcode)); | 2314 | gen_op_load_gpr_T0(rS(ctx->opcode)); |
2304 | gen_op_store_sr(SR(ctx->opcode)); | 2315 | gen_op_store_sr(SR(ctx->opcode)); |
2305 | -#if 0 | ||
2306 | - gen_op_tlbia(); | ||
2307 | - RET_MTMSR(ctx); | ||
2308 | -#endif | ||
2309 | #endif | 2316 | #endif |
2310 | } | 2317 | } |
2311 | 2318 | ||
@@ -2322,7 +2329,6 @@ GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT) | @@ -2322,7 +2329,6 @@ GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT) | ||
2322 | gen_op_load_gpr_T0(rS(ctx->opcode)); | 2329 | gen_op_load_gpr_T0(rS(ctx->opcode)); |
2323 | gen_op_load_gpr_T1(rB(ctx->opcode)); | 2330 | gen_op_load_gpr_T1(rB(ctx->opcode)); |
2324 | gen_op_store_srin(); | 2331 | gen_op_store_srin(); |
2325 | - gen_op_tlbia(); | ||
2326 | #endif | 2332 | #endif |
2327 | } | 2333 | } |
2328 | 2334 | ||
@@ -2341,6 +2347,7 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_OPT) | @@ -2341,6 +2347,7 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_OPT) | ||
2341 | return; | 2347 | return; |
2342 | } | 2348 | } |
2343 | gen_op_tlbia(); | 2349 | gen_op_tlbia(); |
2350 | + RET_MTMSR(ctx); | ||
2344 | #endif | 2351 | #endif |
2345 | } | 2352 | } |
2346 | 2353 | ||
@@ -2356,6 +2363,7 @@ GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM) | @@ -2356,6 +2363,7 @@ GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM) | ||
2356 | } | 2363 | } |
2357 | gen_op_load_gpr_T0(rB(ctx->opcode)); | 2364 | gen_op_load_gpr_T0(rB(ctx->opcode)); |
2358 | gen_op_tlbie(); | 2365 | gen_op_tlbie(); |
2366 | + RET_MTMSR(ctx); | ||
2359 | #endif | 2367 | #endif |
2360 | } | 2368 | } |
2361 | 2369 | ||
@@ -2372,6 +2380,7 @@ GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM) | @@ -2372,6 +2380,7 @@ GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM) | ||
2372 | /* This has no effect: it should ensure that all previous | 2380 | /* This has no effect: it should ensure that all previous |
2373 | * tlbie have completed | 2381 | * tlbie have completed |
2374 | */ | 2382 | */ |
2383 | + RET_MTMSR(ctx); | ||
2375 | #endif | 2384 | #endif |
2376 | } | 2385 | } |
2377 | 2386 | ||
@@ -2692,59 +2701,78 @@ static void init_spr_rights (uint32_t pvr) | @@ -2692,59 +2701,78 @@ static void init_spr_rights (uint32_t pvr) | ||
2692 | spr_set_rights(DBAT3U, SPR_SR | SPR_SW); | 2701 | spr_set_rights(DBAT3U, SPR_SR | SPR_SW); |
2693 | /* DBAT3L (SPR 543) */ | 2702 | /* DBAT3L (SPR 543) */ |
2694 | spr_set_rights(DBAT3L, SPR_SR | SPR_SW); | 2703 | spr_set_rights(DBAT3L, SPR_SR | SPR_SW); |
2695 | - /* DABR (SPR 1013) */ | ||
2696 | - spr_set_rights(DABR, SPR_SR | SPR_SW); | ||
2697 | /* FPECR (SPR 1022) */ | 2704 | /* FPECR (SPR 1022) */ |
2698 | spr_set_rights(FPECR, SPR_SR | SPR_SW); | 2705 | spr_set_rights(FPECR, SPR_SR | SPR_SW); |
2699 | - /* PIR (SPR 1023) */ | 2706 | + /* Special registers for PPC 604 */ |
2707 | + if ((pvr & 0xFFFF0000) == 0x00040000) { | ||
2708 | + /* IABR */ | ||
2709 | + spr_set_rights(IABR , SPR_SR | SPR_SW); | ||
2710 | + /* DABR (SPR 1013) */ | ||
2711 | + spr_set_rights(DABR, SPR_SR | SPR_SW); | ||
2712 | + /* HID0 */ | ||
2713 | + spr_set_rights(HID0, SPR_SR | SPR_SW); | ||
2714 | + /* PIR */ | ||
2700 | spr_set_rights(PIR, SPR_SR | SPR_SW); | 2715 | spr_set_rights(PIR, SPR_SR | SPR_SW); |
2716 | + /* PMC1 */ | ||
2717 | + spr_set_rights(PMC1, SPR_SR | SPR_SW); | ||
2718 | + /* PMC2 */ | ||
2719 | + spr_set_rights(PMC2, SPR_SR | SPR_SW); | ||
2720 | + /* MMCR0 */ | ||
2721 | + spr_set_rights(MMCR0, SPR_SR | SPR_SW); | ||
2722 | + /* SIA */ | ||
2723 | + spr_set_rights(SIA, SPR_SR | SPR_SW); | ||
2724 | + /* SDA */ | ||
2725 | + spr_set_rights(SDA, SPR_SR | SPR_SW); | ||
2726 | + } | ||
2701 | /* Special registers for MPC740/745/750/755 (aka G3) & IBM 750 */ | 2727 | /* Special registers for MPC740/745/750/755 (aka G3) & IBM 750 */ |
2702 | if ((pvr & 0xFFFF0000) == 0x00080000 || | 2728 | if ((pvr & 0xFFFF0000) == 0x00080000 || |
2703 | (pvr & 0xFFFF0000) == 0x70000000) { | 2729 | (pvr & 0xFFFF0000) == 0x70000000) { |
2704 | /* HID0 */ | 2730 | /* HID0 */ |
2705 | - spr_set_rights(SPR_ENCODE(1008), SPR_SR | SPR_SW); | 2731 | + spr_set_rights(HID0, SPR_SR | SPR_SW); |
2706 | /* HID1 */ | 2732 | /* HID1 */ |
2707 | - spr_set_rights(SPR_ENCODE(1009), SPR_SR | SPR_SW); | 2733 | + spr_set_rights(HID1, SPR_SR | SPR_SW); |
2708 | /* IABR */ | 2734 | /* IABR */ |
2709 | - spr_set_rights(SPR_ENCODE(1010), SPR_SR | SPR_SW); | 2735 | + spr_set_rights(IABR, SPR_SR | SPR_SW); |
2710 | /* ICTC */ | 2736 | /* ICTC */ |
2711 | - spr_set_rights(SPR_ENCODE(1019), SPR_SR | SPR_SW); | 2737 | + spr_set_rights(ICTC, SPR_SR | SPR_SW); |
2712 | /* L2CR */ | 2738 | /* L2CR */ |
2713 | - spr_set_rights(SPR_ENCODE(1017), SPR_SR | SPR_SW); | 2739 | + spr_set_rights(L2CR, SPR_SR | SPR_SW); |
2714 | /* MMCR0 */ | 2740 | /* MMCR0 */ |
2715 | - spr_set_rights(SPR_ENCODE(952), SPR_SR | SPR_SW); | 2741 | + spr_set_rights(MMCR0, SPR_SR | SPR_SW); |
2716 | /* MMCR1 */ | 2742 | /* MMCR1 */ |
2717 | - spr_set_rights(SPR_ENCODE(956), SPR_SR | SPR_SW); | 2743 | + spr_set_rights(MMCR1, SPR_SR | SPR_SW); |
2718 | /* PMC1 */ | 2744 | /* PMC1 */ |
2719 | - spr_set_rights(SPR_ENCODE(953), SPR_SR | SPR_SW); | 2745 | + spr_set_rights(PMC1, SPR_SR | SPR_SW); |
2720 | /* PMC2 */ | 2746 | /* PMC2 */ |
2721 | - spr_set_rights(SPR_ENCODE(954), SPR_SR | SPR_SW); | 2747 | + spr_set_rights(PMC2, SPR_SR | SPR_SW); |
2722 | /* PMC3 */ | 2748 | /* PMC3 */ |
2723 | - spr_set_rights(SPR_ENCODE(957), SPR_SR | SPR_SW); | 2749 | + spr_set_rights(PMC3, SPR_SR | SPR_SW); |
2724 | /* PMC4 */ | 2750 | /* PMC4 */ |
2725 | - spr_set_rights(SPR_ENCODE(958), SPR_SR | SPR_SW); | 2751 | + spr_set_rights(PMC4, SPR_SR | SPR_SW); |
2726 | /* SIA */ | 2752 | /* SIA */ |
2727 | - spr_set_rights(SPR_ENCODE(955), SPR_SR | SPR_SW); | 2753 | + spr_set_rights(SIA, SPR_SR | SPR_SW); |
2754 | + /* SDA */ | ||
2755 | + spr_set_rights(SDA, SPR_SR | SPR_SW); | ||
2728 | /* THRM1 */ | 2756 | /* THRM1 */ |
2729 | - spr_set_rights(SPR_ENCODE(1020), SPR_SR | SPR_SW); | 2757 | + spr_set_rights(THRM1, SPR_SR | SPR_SW); |
2730 | /* THRM2 */ | 2758 | /* THRM2 */ |
2731 | - spr_set_rights(SPR_ENCODE(1021), SPR_SR | SPR_SW); | 2759 | + spr_set_rights(THRM2, SPR_SR | SPR_SW); |
2732 | /* THRM3 */ | 2760 | /* THRM3 */ |
2733 | - spr_set_rights(SPR_ENCODE(1022), SPR_SR | SPR_SW); | 2761 | + spr_set_rights(THRM3, SPR_SR | SPR_SW); |
2734 | /* UMMCR0 */ | 2762 | /* UMMCR0 */ |
2735 | - spr_set_rights(SPR_ENCODE(936), SPR_UR | SPR_UW); | 2763 | + spr_set_rights(UMMCR0, SPR_UR | SPR_UW); |
2736 | /* UMMCR1 */ | 2764 | /* UMMCR1 */ |
2737 | - spr_set_rights(SPR_ENCODE(940), SPR_UR | SPR_UW); | 2765 | + spr_set_rights(UMMCR1, SPR_UR | SPR_UW); |
2738 | /* UPMC1 */ | 2766 | /* UPMC1 */ |
2739 | - spr_set_rights(SPR_ENCODE(937), SPR_UR | SPR_UW); | 2767 | + spr_set_rights(UPMC1, SPR_UR | SPR_UW); |
2740 | /* UPMC2 */ | 2768 | /* UPMC2 */ |
2741 | - spr_set_rights(SPR_ENCODE(938), SPR_UR | SPR_UW); | 2769 | + spr_set_rights(UPMC2, SPR_UR | SPR_UW); |
2742 | /* UPMC3 */ | 2770 | /* UPMC3 */ |
2743 | - spr_set_rights(SPR_ENCODE(941), SPR_UR | SPR_UW); | 2771 | + spr_set_rights(UPMC3, SPR_UR | SPR_UW); |
2744 | /* UPMC4 */ | 2772 | /* UPMC4 */ |
2745 | - spr_set_rights(SPR_ENCODE(942), SPR_UR | SPR_UW); | 2773 | + spr_set_rights(UPMC4, SPR_UR | SPR_UW); |
2746 | /* USIA */ | 2774 | /* USIA */ |
2747 | - spr_set_rights(SPR_ENCODE(939), SPR_UR | SPR_UW); | 2775 | + spr_set_rights(USIA, SPR_UR | SPR_UW); |
2748 | } | 2776 | } |
2749 | /* MPC755 has special registers */ | 2777 | /* MPC755 has special registers */ |
2750 | if (pvr == 0x00083100) { | 2778 | if (pvr == 0x00083100) { |
@@ -2789,23 +2817,23 @@ static void init_spr_rights (uint32_t pvr) | @@ -2789,23 +2817,23 @@ static void init_spr_rights (uint32_t pvr) | ||
2789 | /* DBAT7L */ | 2817 | /* DBAT7L */ |
2790 | spr_set_rights(DBAT7L, SPR_SR | SPR_SW); | 2818 | spr_set_rights(DBAT7L, SPR_SR | SPR_SW); |
2791 | /* DMISS */ | 2819 | /* DMISS */ |
2792 | - spr_set_rights(SPR_ENCODE(976), SPR_SR | SPR_SW); | 2820 | + spr_set_rights(DMISS, SPR_SR | SPR_SW); |
2793 | /* DCMP */ | 2821 | /* DCMP */ |
2794 | - spr_set_rights(SPR_ENCODE(977), SPR_SR | SPR_SW); | 2822 | + spr_set_rights(DCMP, SPR_SR | SPR_SW); |
2795 | /* DHASH1 */ | 2823 | /* DHASH1 */ |
2796 | - spr_set_rights(SPR_ENCODE(978), SPR_SR | SPR_SW); | 2824 | + spr_set_rights(DHASH1, SPR_SR | SPR_SW); |
2797 | /* DHASH2 */ | 2825 | /* DHASH2 */ |
2798 | - spr_set_rights(SPR_ENCODE(979), SPR_SR | SPR_SW); | 2826 | + spr_set_rights(DHASH2, SPR_SR | SPR_SW); |
2799 | /* IMISS */ | 2827 | /* IMISS */ |
2800 | - spr_set_rights(SPR_ENCODE(980), SPR_SR | SPR_SW); | 2828 | + spr_set_rights(IMISS, SPR_SR | SPR_SW); |
2801 | /* ICMP */ | 2829 | /* ICMP */ |
2802 | - spr_set_rights(SPR_ENCODE(981), SPR_SR | SPR_SW); | 2830 | + spr_set_rights(ICMP, SPR_SR | SPR_SW); |
2803 | /* RPA */ | 2831 | /* RPA */ |
2804 | - spr_set_rights(SPR_ENCODE(982), SPR_SR | SPR_SW); | 2832 | + spr_set_rights(RPA, SPR_SR | SPR_SW); |
2805 | /* HID2 */ | 2833 | /* HID2 */ |
2806 | - spr_set_rights(SPR_ENCODE(1011), SPR_SR | SPR_SW); | 2834 | + spr_set_rights(HID2, SPR_SR | SPR_SW); |
2807 | /* L2PM */ | 2835 | /* L2PM */ |
2808 | - spr_set_rights(SPR_ENCODE(1016), SPR_SR | SPR_SW); | 2836 | + spr_set_rights(L2PM, SPR_SR | SPR_SW); |
2809 | } | 2837 | } |
2810 | } | 2838 | } |
2811 | 2839 | ||
@@ -2941,10 +2969,9 @@ CPUPPCState *cpu_ppc_init(void) | @@ -2941,10 +2969,9 @@ CPUPPCState *cpu_ppc_init(void) | ||
2941 | 2969 | ||
2942 | cpu_exec_init(); | 2970 | cpu_exec_init(); |
2943 | 2971 | ||
2944 | - env = malloc(sizeof(CPUPPCState)); | 2972 | + env = qemu_mallocz(sizeof(CPUPPCState)); |
2945 | if (!env) | 2973 | if (!env) |
2946 | return NULL; | 2974 | return NULL; |
2947 | - memset(env, 0, sizeof(CPUPPCState)); | ||
2948 | #if !defined(CONFIG_USER_ONLY) && defined (USE_OPEN_FIRMWARE) | 2975 | #if !defined(CONFIG_USER_ONLY) && defined (USE_OPEN_FIRMWARE) |
2949 | setup_machine(env, 0); | 2976 | setup_machine(env, 0); |
2950 | #else | 2977 | #else |
@@ -2953,22 +2980,34 @@ CPUPPCState *cpu_ppc_init(void) | @@ -2953,22 +2980,34 @@ CPUPPCState *cpu_ppc_init(void) | ||
2953 | // env->spr[PVR] = 0x00083100; /* MPC755 (G3 embedded) */ | 2980 | // env->spr[PVR] = 0x00083100; /* MPC755 (G3 embedded) */ |
2954 | // env->spr[PVR] = 0x00070100; /* IBM 750FX */ | 2981 | // env->spr[PVR] = 0x00070100; /* IBM 750FX */ |
2955 | #endif | 2982 | #endif |
2956 | - if (create_ppc_proc(ppc_opcodes, env->spr[PVR]) < 0) | ||
2957 | - return NULL; | ||
2958 | - init_spr_rights(env->spr[PVR]); | ||
2959 | tlb_flush(env, 1); | 2983 | tlb_flush(env, 1); |
2960 | #if defined (DO_SINGLE_STEP) | 2984 | #if defined (DO_SINGLE_STEP) |
2961 | /* Single step trace mode */ | 2985 | /* Single step trace mode */ |
2962 | msr_se = 1; | 2986 | msr_se = 1; |
2963 | #endif | 2987 | #endif |
2988 | + msr_fp = 1; /* Allow floating point exceptions */ | ||
2989 | + msr_me = 1; /* Allow machine check exceptions */ | ||
2964 | #if defined(CONFIG_USER_ONLY) | 2990 | #if defined(CONFIG_USER_ONLY) |
2965 | msr_pr = 1; | 2991 | msr_pr = 1; |
2992 | + cpu_ppc_register(env, 0x00080000); | ||
2993 | +#else | ||
2994 | + env->nip = 0xFFFFFFFC; | ||
2966 | #endif | 2995 | #endif |
2967 | env->access_type = ACCESS_INT; | 2996 | env->access_type = ACCESS_INT; |
2968 | 2997 | ||
2969 | return env; | 2998 | return env; |
2970 | } | 2999 | } |
2971 | 3000 | ||
3001 | +int cpu_ppc_register (CPUPPCState *env, uint32_t pvr) | ||
3002 | +{ | ||
3003 | + env->spr[PVR] = pvr; | ||
3004 | + if (create_ppc_proc(ppc_opcodes, env->spr[PVR]) < 0) | ||
3005 | + return -1; | ||
3006 | + init_spr_rights(env->spr[PVR]); | ||
3007 | + | ||
3008 | + return 0; | ||
3009 | +} | ||
3010 | + | ||
2972 | void cpu_ppc_close(CPUPPCState *env) | 3011 | void cpu_ppc_close(CPUPPCState *env) |
2973 | { | 3012 | { |
2974 | /* Should also remove all opcode tables... */ | 3013 | /* Should also remove all opcode tables... */ |
@@ -3047,26 +3086,26 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | @@ -3047,26 +3086,26 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | ||
3047 | } | 3086 | } |
3048 | } | 3087 | } |
3049 | /* Is opcode *REALLY* valid ? */ | 3088 | /* Is opcode *REALLY* valid ? */ |
3050 | - if ((ctx.opcode & handler->inval) != 0) { | ||
3051 | - if (loglevel > 0) { | ||
3052 | if (handler->handler == &gen_invalid) { | 3089 | if (handler->handler == &gen_invalid) { |
3090 | + if (loglevel > 0) { | ||
3053 | fprintf(logfile, "invalid/unsupported opcode: " | 3091 | fprintf(logfile, "invalid/unsupported opcode: " |
3054 | - "%02x -%02x - %02x (%08x) 0x%08x\n", | 3092 | + "%02x - %02x - %02x (%08x) 0x%08x %d\n", |
3055 | opc1(ctx.opcode), opc2(ctx.opcode), | 3093 | opc1(ctx.opcode), opc2(ctx.opcode), |
3056 | - opc3(ctx.opcode), ctx.opcode, ctx.nip - 4); | 3094 | + opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir); |
3095 | + } else { | ||
3096 | + printf("invalid/unsupported opcode: " | ||
3097 | + "%02x - %02x - %02x (%08x) 0x%08x %d\n", | ||
3098 | + opc1(ctx.opcode), opc2(ctx.opcode), | ||
3099 | + opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir); | ||
3100 | + } | ||
3057 | } else { | 3101 | } else { |
3102 | + if ((ctx.opcode & handler->inval) != 0) { | ||
3103 | + if (loglevel > 0) { | ||
3058 | fprintf(logfile, "invalid bits: %08x for opcode: " | 3104 | fprintf(logfile, "invalid bits: %08x for opcode: " |
3059 | "%02x -%02x - %02x (0x%08x) (0x%08x)\n", | 3105 | "%02x -%02x - %02x (0x%08x) (0x%08x)\n", |
3060 | ctx.opcode & handler->inval, opc1(ctx.opcode), | 3106 | ctx.opcode & handler->inval, opc1(ctx.opcode), |
3061 | opc2(ctx.opcode), opc3(ctx.opcode), | 3107 | opc2(ctx.opcode), opc3(ctx.opcode), |
3062 | ctx.opcode, ctx.nip - 4); | 3108 | ctx.opcode, ctx.nip - 4); |
3063 | - } | ||
3064 | - } else { | ||
3065 | - if (handler->handler == &gen_invalid) { | ||
3066 | - printf("invalid/unsupported opcode: " | ||
3067 | - "%02x -%02x - %02x (%08x) 0x%08x\n", | ||
3068 | - opc1(ctx.opcode), opc2(ctx.opcode), | ||
3069 | - opc3(ctx.opcode), ctx.opcode, ctx.nip - 4); | ||
3070 | } else { | 3109 | } else { |
3071 | printf("invalid bits: %08x for opcode: " | 3110 | printf("invalid bits: %08x for opcode: " |
3072 | "%02x -%02x - %02x (0x%08x) (0x%08x)\n", | 3111 | "%02x -%02x - %02x (0x%08x) (0x%08x)\n", |
@@ -3074,11 +3113,11 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | @@ -3074,11 +3113,11 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | ||
3074 | opc2(ctx.opcode), opc3(ctx.opcode), | 3113 | opc2(ctx.opcode), opc3(ctx.opcode), |
3075 | ctx.opcode, ctx.nip - 4); | 3114 | ctx.opcode, ctx.nip - 4); |
3076 | } | 3115 | } |
3116 | + RET_INVAL(ctxp); | ||
3117 | + break; | ||
3077 | } | 3118 | } |
3078 | - (*gen_invalid)(&ctx); | ||
3079 | - } else { | ||
3080 | - (*(handler->handler))(&ctx); | ||
3081 | } | 3119 | } |
3120 | + (*(handler->handler))(&ctx); | ||
3082 | /* Check trace mode exceptions */ | 3121 | /* Check trace mode exceptions */ |
3083 | if ((msr_be && ctx.exception == EXCP_BRANCH) || | 3122 | if ((msr_be && ctx.exception == EXCP_BRANCH) || |
3084 | /* Check in single step trace mode | 3123 | /* Check in single step trace mode |
@@ -3126,7 +3165,6 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | @@ -3126,7 +3165,6 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | ||
3126 | } else { | 3165 | } else { |
3127 | tb->size = ctx.nip - pc_start; | 3166 | tb->size = ctx.nip - pc_start; |
3128 | } | 3167 | } |
3129 | - env->access_type = ACCESS_INT; | ||
3130 | #ifdef DEBUG_DISAS | 3168 | #ifdef DEBUG_DISAS |
3131 | if (loglevel & CPU_LOG_TB_CPU) { | 3169 | if (loglevel & CPU_LOG_TB_CPU) { |
3132 | fprintf(logfile, "---------------- excp: %04x\n", ctx.exception); | 3170 | fprintf(logfile, "---------------- excp: %04x\n", ctx.exception); |
@@ -3143,6 +3181,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | @@ -3143,6 +3181,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | ||
3143 | fprintf(logfile, "\n"); | 3181 | fprintf(logfile, "\n"); |
3144 | } | 3182 | } |
3145 | #endif | 3183 | #endif |
3184 | + env->access_type = ACCESS_INT; | ||
3146 | 3185 | ||
3147 | return 0; | 3186 | return 0; |
3148 | } | 3187 | } |