@@ -7589,33 +7589,29 @@ static bool cpu_has_work_POWER7(CPUState *cs)
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *env = &cpu->env;
- if (cs->halted) {
- if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
- return false;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
- (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
- (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
- (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
- (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
- return true;
- }
- if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
- return true;
- }
+ if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
return false;
- } else {
- return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
}
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
+ (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
+ return true;
+ }
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
+ (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
+ return true;
+ }
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
+ (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
+ return true;
+ }
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
+ (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
+ return true;
+ }
+ if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
+ return true;
+ }
+ return false;
}
#endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
@@ -7750,41 +7746,37 @@ static bool cpu_has_work_POWER8(CPUState *cs)
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *env = &cpu->env;
- if (cs->halted) {
- if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
- return false;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
- return true;
- }
- if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
- return true;
- }
+ if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
return false;
- } else {
- return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
}
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
+ (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
+ return true;
+ }
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
+ (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
+ return true;
+ }
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
+ (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
+ return true;
+ }
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
+ (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
+ return true;
+ }
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
+ (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
+ return true;
+ }
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
+ (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
+ return true;
+ }
+ if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
+ return true;
+ }
+ return false;
}
#endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
@@ -7948,58 +7940,53 @@ static bool cpu_has_work_POWER9(CPUState *cs)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *env = &cpu->env;
+ uint64_t psscr = env->spr[SPR_PSSCR];
- if (cs->halted) {
- uint64_t psscr = env->spr[SPR_PSSCR];
-
- if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
- return false;
- }
-
- /* If EC is clear, just return true on any pending interrupt */
- if (!(psscr & PSSCR_EC)) {
- return true;
- }
- /* External Exception */
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
- (env->spr[SPR_LPCR] & LPCR_EEE)) {
- bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
- if (heic == 0 || !msr_hv || msr_pr) {
- return true;
- }
- }
- /* Decrementer Exception */
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
- (env->spr[SPR_LPCR] & LPCR_DEE)) {
- return true;
- }
- /* Machine Check or Hypervisor Maintenance Exception */
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
- 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
- return true;
- }
- /* Privileged Doorbell Exception */
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
- (env->spr[SPR_LPCR] & LPCR_PDEE)) {
- return true;
- }
- /* Hypervisor Doorbell Exception */
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
- (env->spr[SPR_LPCR] & LPCR_HDEE)) {
- return true;
- }
- /* Hypervisor virtualization exception */
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
- (env->spr[SPR_LPCR] & LPCR_HVEE)) {
- return true;
- }
- if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
- return true;
- }
+ if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
return false;
- } else {
- return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
}
+
+ /* If EC is clear, just return true on any pending interrupt */
+ if (!(psscr & PSSCR_EC)) {
+ return true;
+ }
+ /* External Exception */
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
+ (env->spr[SPR_LPCR] & LPCR_EEE)) {
+ bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
+ if (heic == 0 || !msr_hv || msr_pr) {
+ return true;
+ }
+ }
+ /* Decrementer Exception */
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
+ (env->spr[SPR_LPCR] & LPCR_DEE)) {
+ return true;
+ }
+ /* Machine Check or Hypervisor Maintenance Exception */
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
+ 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
+ return true;
+ }
+ /* Privileged Doorbell Exception */
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
+ (env->spr[SPR_LPCR] & LPCR_PDEE)) {
+ return true;
+ }
+ /* Hypervisor Doorbell Exception */
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
+ (env->spr[SPR_LPCR] & LPCR_HDEE)) {
+ return true;
+ }
+ /* Hypervisor virtualization exception */
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
+ (env->spr[SPR_LPCR] & LPCR_HVEE)) {
+ return true;
+ }
+ if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
+ return true;
+ }
+ return false;
}
#endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
@@ -8158,58 +8145,53 @@ static bool cpu_has_work_POWER10(CPUState *cs)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *env = &cpu->env;
+ uint64_t psscr = env->spr[SPR_PSSCR];
- if (cs->halted) {
- uint64_t psscr = env->spr[SPR_PSSCR];
-
- if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
- return false;
- }
-
- /* If EC is clear, just return true on any pending interrupt */
- if (!(psscr & PSSCR_EC)) {
- return true;
- }
- /* External Exception */
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
- (env->spr[SPR_LPCR] & LPCR_EEE)) {
- bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
- if (heic == 0 || !msr_hv || msr_pr) {
- return true;
- }
- }
- /* Decrementer Exception */
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
- (env->spr[SPR_LPCR] & LPCR_DEE)) {
- return true;
- }
- /* Machine Check or Hypervisor Maintenance Exception */
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
- 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
- return true;
- }
- /* Privileged Doorbell Exception */
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
- (env->spr[SPR_LPCR] & LPCR_PDEE)) {
- return true;
- }
- /* Hypervisor Doorbell Exception */
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
- (env->spr[SPR_LPCR] & LPCR_HDEE)) {
- return true;
- }
- /* Hypervisor virtualization exception */
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
- (env->spr[SPR_LPCR] & LPCR_HVEE)) {
- return true;
- }
- if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
- return true;
- }
+ if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
return false;
- } else {
- return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
}
+
+ /* If EC is clear, just return true on any pending interrupt */
+ if (!(psscr & PSSCR_EC)) {
+ return true;
+ }
+ /* External Exception */
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
+ (env->spr[SPR_LPCR] & LPCR_EEE)) {
+ bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
+ if (heic == 0 || !msr_hv || msr_pr) {
+ return true;
+ }
+ }
+ /* Decrementer Exception */
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
+ (env->spr[SPR_LPCR] & LPCR_DEE)) {
+ return true;
+ }
+ /* Machine Check or Hypervisor Maintenance Exception */
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
+ 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
+ return true;
+ }
+ /* Privileged Doorbell Exception */
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
+ (env->spr[SPR_LPCR] & LPCR_PDEE)) {
+ return true;
+ }
+ /* Hypervisor Doorbell Exception */
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
+ (env->spr[SPR_LPCR] & LPCR_HDEE)) {
+ return true;
+ }
+ /* Hypervisor virtualization exception */
+ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
+ (env->spr[SPR_LPCR] & LPCR_HVEE)) {
+ return true;
+ }
+ if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
+ return true;
+ }
+ return false;
}
#endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
The common ppc_cpu_has_work() handler already checks for cs->halted, so we can simplify all callees. Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> --- target/ppc/cpu_init.c | 294 ++++++++++++++++++++---------------------- 1 file changed, 138 insertions(+), 156 deletions(-)