Commit 497ad68cd499bf2b6cc3bfde49fdb5aa05934ec4
1 parent
185f0762
Fix TB chaining for exceptions.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3721 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
17 additions
and
35 deletions
cpu-exec.c
| @@ -232,6 +232,11 @@ static inline TranslationBlock *tb_find_fast(void) | @@ -232,6 +232,11 @@ static inline TranslationBlock *tb_find_fast(void) | ||
| 232 | return tb; | 232 | return tb; |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | +#if defined(__sparc__) && !defined(HOST_SOLARIS) | ||
| 236 | +#define BREAK_CHAIN tmp_T0 = 0 | ||
| 237 | +#else | ||
| 238 | +#define BREAK_CHAIN T0 = 0 | ||
| 239 | +#endif | ||
| 235 | 240 | ||
| 236 | /* main execution loop */ | 241 | /* main execution loop */ |
| 237 | 242 | ||
| @@ -405,11 +410,7 @@ int cpu_exec(CPUState *env1) | @@ -405,11 +410,7 @@ int cpu_exec(CPUState *env1) | ||
| 405 | svm_check_intercept(SVM_EXIT_SMI); | 410 | svm_check_intercept(SVM_EXIT_SMI); |
| 406 | env->interrupt_request &= ~CPU_INTERRUPT_SMI; | 411 | env->interrupt_request &= ~CPU_INTERRUPT_SMI; |
| 407 | do_smm_enter(); | 412 | do_smm_enter(); |
| 408 | -#if defined(__sparc__) && !defined(HOST_SOLARIS) | ||
| 409 | - tmp_T0 = 0; | ||
| 410 | -#else | ||
| 411 | - T0 = 0; | ||
| 412 | -#endif | 413 | + BREAK_CHAIN; |
| 413 | } else if ((interrupt_request & CPU_INTERRUPT_HARD) && | 414 | } else if ((interrupt_request & CPU_INTERRUPT_HARD) && |
| 414 | (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) && | 415 | (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) && |
| 415 | !(env->hflags & HF_INHIBIT_IRQ_MASK)) { | 416 | !(env->hflags & HF_INHIBIT_IRQ_MASK)) { |
| @@ -423,11 +424,7 @@ int cpu_exec(CPUState *env1) | @@ -423,11 +424,7 @@ int cpu_exec(CPUState *env1) | ||
| 423 | do_interrupt(intno, 0, 0, 0, 1); | 424 | do_interrupt(intno, 0, 0, 0, 1); |
| 424 | /* ensure that no TB jump will be modified as | 425 | /* ensure that no TB jump will be modified as |
| 425 | the program flow was changed */ | 426 | the program flow was changed */ |
| 426 | -#if defined(__sparc__) && !defined(HOST_SOLARIS) | ||
| 427 | - tmp_T0 = 0; | ||
| 428 | -#else | ||
| 429 | - T0 = 0; | ||
| 430 | -#endif | 427 | + BREAK_CHAIN; |
| 431 | #if !defined(CONFIG_USER_ONLY) | 428 | #if !defined(CONFIG_USER_ONLY) |
| 432 | } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && | 429 | } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && |
| 433 | (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) { | 430 | (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) { |
| @@ -441,11 +438,7 @@ int cpu_exec(CPUState *env1) | @@ -441,11 +438,7 @@ int cpu_exec(CPUState *env1) | ||
| 441 | do_interrupt(intno, 0, 0, -1, 1); | 438 | do_interrupt(intno, 0, 0, -1, 1); |
| 442 | stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), | 439 | stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), |
| 443 | ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK); | 440 | ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK); |
| 444 | -#if defined(__sparc__) && !defined(HOST_SOLARIS) | ||
| 445 | - tmp_T0 = 0; | ||
| 446 | -#else | ||
| 447 | - T0 = 0; | ||
| 448 | -#endif | 441 | + BREAK_CHAIN; |
| 449 | #endif | 442 | #endif |
| 450 | } | 443 | } |
| 451 | #elif defined(TARGET_PPC) | 444 | #elif defined(TARGET_PPC) |
| @@ -458,11 +451,7 @@ int cpu_exec(CPUState *env1) | @@ -458,11 +451,7 @@ int cpu_exec(CPUState *env1) | ||
| 458 | ppc_hw_interrupt(env); | 451 | ppc_hw_interrupt(env); |
| 459 | if (env->pending_interrupts == 0) | 452 | if (env->pending_interrupts == 0) |
| 460 | env->interrupt_request &= ~CPU_INTERRUPT_HARD; | 453 | env->interrupt_request &= ~CPU_INTERRUPT_HARD; |
| 461 | -#if defined(__sparc__) && !defined(HOST_SOLARIS) | ||
| 462 | - tmp_T0 = 0; | ||
| 463 | -#else | ||
| 464 | - T0 = 0; | ||
| 465 | -#endif | 454 | + BREAK_CHAIN; |
| 466 | } | 455 | } |
| 467 | #elif defined(TARGET_MIPS) | 456 | #elif defined(TARGET_MIPS) |
| 468 | if ((interrupt_request & CPU_INTERRUPT_HARD) && | 457 | if ((interrupt_request & CPU_INTERRUPT_HARD) && |
| @@ -475,11 +464,7 @@ int cpu_exec(CPUState *env1) | @@ -475,11 +464,7 @@ int cpu_exec(CPUState *env1) | ||
| 475 | env->exception_index = EXCP_EXT_INTERRUPT; | 464 | env->exception_index = EXCP_EXT_INTERRUPT; |
| 476 | env->error_code = 0; | 465 | env->error_code = 0; |
| 477 | do_interrupt(env); | 466 | do_interrupt(env); |
| 478 | -#if defined(__sparc__) && !defined(HOST_SOLARIS) | ||
| 479 | - tmp_T0 = 0; | ||
| 480 | -#else | ||
| 481 | - T0 = 0; | ||
| 482 | -#endif | 467 | + BREAK_CHAIN; |
| 483 | } | 468 | } |
| 484 | #elif defined(TARGET_SPARC) | 469 | #elif defined(TARGET_SPARC) |
| 485 | if ((interrupt_request & CPU_INTERRUPT_HARD) && | 470 | if ((interrupt_request & CPU_INTERRUPT_HARD) && |
| @@ -496,11 +481,7 @@ int cpu_exec(CPUState *env1) | @@ -496,11 +481,7 @@ int cpu_exec(CPUState *env1) | ||
| 496 | #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) | 481 | #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) |
| 497 | cpu_check_irqs(env); | 482 | cpu_check_irqs(env); |
| 498 | #endif | 483 | #endif |
| 499 | -#if defined(__sparc__) && !defined(HOST_SOLARIS) | ||
| 500 | - tmp_T0 = 0; | ||
| 501 | -#else | ||
| 502 | - T0 = 0; | ||
| 503 | -#endif | 484 | + BREAK_CHAIN; |
| 504 | } | 485 | } |
| 505 | } else if (interrupt_request & CPU_INTERRUPT_TIMER) { | 486 | } else if (interrupt_request & CPU_INTERRUPT_TIMER) { |
| 506 | //do_interrupt(0, 0, 0, 0, 0); | 487 | //do_interrupt(0, 0, 0, 0, 0); |
| @@ -511,6 +492,7 @@ int cpu_exec(CPUState *env1) | @@ -511,6 +492,7 @@ int cpu_exec(CPUState *env1) | ||
| 511 | && !(env->uncached_cpsr & CPSR_F)) { | 492 | && !(env->uncached_cpsr & CPSR_F)) { |
| 512 | env->exception_index = EXCP_FIQ; | 493 | env->exception_index = EXCP_FIQ; |
| 513 | do_interrupt(env); | 494 | do_interrupt(env); |
| 495 | + BREAK_CHAIN; | ||
| 514 | } | 496 | } |
| 515 | /* ARMv7-M interrupt return works by loading a magic value | 497 | /* ARMv7-M interrupt return works by loading a magic value |
| 516 | into the PC. On real hardware the load causes the | 498 | into the PC. On real hardware the load causes the |
| @@ -526,17 +508,20 @@ int cpu_exec(CPUState *env1) | @@ -526,17 +508,20 @@ int cpu_exec(CPUState *env1) | ||
| 526 | || !(env->uncached_cpsr & CPSR_I))) { | 508 | || !(env->uncached_cpsr & CPSR_I))) { |
| 527 | env->exception_index = EXCP_IRQ; | 509 | env->exception_index = EXCP_IRQ; |
| 528 | do_interrupt(env); | 510 | do_interrupt(env); |
| 511 | + BREAK_CHAIN; | ||
| 529 | } | 512 | } |
| 530 | #elif defined(TARGET_SH4) | 513 | #elif defined(TARGET_SH4) |
| 531 | /* XXXXX */ | 514 | /* XXXXX */ |
| 532 | #elif defined(TARGET_ALPHA) | 515 | #elif defined(TARGET_ALPHA) |
| 533 | if (interrupt_request & CPU_INTERRUPT_HARD) { | 516 | if (interrupt_request & CPU_INTERRUPT_HARD) { |
| 534 | do_interrupt(env); | 517 | do_interrupt(env); |
| 518 | + BREAK_CHAIN; | ||
| 535 | } | 519 | } |
| 536 | #elif defined(TARGET_CRIS) | 520 | #elif defined(TARGET_CRIS) |
| 537 | if (interrupt_request & CPU_INTERRUPT_HARD) { | 521 | if (interrupt_request & CPU_INTERRUPT_HARD) { |
| 538 | do_interrupt(env); | 522 | do_interrupt(env); |
| 539 | env->interrupt_request &= ~CPU_INTERRUPT_HARD; | 523 | env->interrupt_request &= ~CPU_INTERRUPT_HARD; |
| 524 | + BREAK_CHAIN; | ||
| 540 | } | 525 | } |
| 541 | #elif defined(TARGET_M68K) | 526 | #elif defined(TARGET_M68K) |
| 542 | if (interrupt_request & CPU_INTERRUPT_HARD | 527 | if (interrupt_request & CPU_INTERRUPT_HARD |
| @@ -549,6 +534,7 @@ int cpu_exec(CPUState *env1) | @@ -549,6 +534,7 @@ int cpu_exec(CPUState *env1) | ||
| 549 | first signalled. */ | 534 | first signalled. */ |
| 550 | env->exception_index = env->pending_vector; | 535 | env->exception_index = env->pending_vector; |
| 551 | do_interrupt(1); | 536 | do_interrupt(1); |
| 537 | + BREAK_CHAIN; | ||
| 552 | } | 538 | } |
| 553 | #endif | 539 | #endif |
| 554 | /* Don't use the cached interupt_request value, | 540 | /* Don't use the cached interupt_request value, |
| @@ -557,11 +543,7 @@ int cpu_exec(CPUState *env1) | @@ -557,11 +543,7 @@ int cpu_exec(CPUState *env1) | ||
| 557 | env->interrupt_request &= ~CPU_INTERRUPT_EXITTB; | 543 | env->interrupt_request &= ~CPU_INTERRUPT_EXITTB; |
| 558 | /* ensure that no TB jump will be modified as | 544 | /* ensure that no TB jump will be modified as |
| 559 | the program flow was changed */ | 545 | the program flow was changed */ |
| 560 | -#if defined(__sparc__) && !defined(HOST_SOLARIS) | ||
| 561 | - tmp_T0 = 0; | ||
| 562 | -#else | ||
| 563 | - T0 = 0; | ||
| 564 | -#endif | 546 | + BREAK_CHAIN; |
| 565 | } | 547 | } |
| 566 | if (interrupt_request & CPU_INTERRUPT_EXIT) { | 548 | if (interrupt_request & CPU_INTERRUPT_EXIT) { |
| 567 | env->interrupt_request &= ~CPU_INTERRUPT_EXIT; | 549 | env->interrupt_request &= ~CPU_INTERRUPT_EXIT; |