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 | } |