diff options
author | Matheus Ferst <matheus.ferst@eldorado.org.br> | 2022-10-11 17:48:10 -0300 |
---|---|---|
committer | Daniel Henrique Barboza <danielhb413@gmail.com> | 2022-10-28 13:15:22 -0300 |
commit | 0ccd9d67b1ee9289dd96f2d133a618f97f7a89ab (patch) | |
tree | 2ff510de215da75bae5f7ec3bc3618a05d3a7f19 | |
parent | ed3a24c95a9d8d870bf671d5675b8b4b32a0db75 (diff) |
target/ppc: move power-saving interrupt masking out of cpu_has_work_POWER9
Move the interrupt masking logic out of cpu_has_work_POWER9 in a new
method, p9_interrupt_powersave, that only returns an interrupt if it can
wake the processor from power-saving mode.
Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>
Message-Id: <20221011204829.1641124-11-matheus.ferst@eldorado.org.br>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
-rw-r--r-- | target/ppc/cpu_init.c | 126 |
1 files changed, 50 insertions, 76 deletions
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 07171c679c..9ecea10b48 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -6351,6 +6351,52 @@ static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr, bool best) return false; } +static int p9_interrupt_powersave(CPUPPCState *env) +{ + /* External Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && + (env->spr[SPR_LPCR] & LPCR_EEE)) { + bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); + if (!heic || !FIELD_EX64_HV(env->msr) || + FIELD_EX64(env->msr, MSR, PR)) { + return PPC_INTERRUPT_EXT; + } + } + /* Decrementer Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && + (env->spr[SPR_LPCR] & LPCR_DEE)) { + return PPC_INTERRUPT_DECR; + } + /* Machine Check or Hypervisor Maintenance Exception */ + if (env->spr[SPR_LPCR] & LPCR_OEE) { + if (env->pending_interrupts & PPC_INTERRUPT_MCK) { + return PPC_INTERRUPT_MCK; + } + if (env->pending_interrupts & PPC_INTERRUPT_HMI) { + return PPC_INTERRUPT_HMI; + } + } + /* Privileged Doorbell Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && + (env->spr[SPR_LPCR] & LPCR_PDEE)) { + return PPC_INTERRUPT_DOORBELL; + } + /* Hypervisor Doorbell Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && + (env->spr[SPR_LPCR] & LPCR_HDEE)) { + return PPC_INTERRUPT_HDOORBELL; + } + /* Hypervisor virtualization exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) && + (env->spr[SPR_LPCR] & LPCR_HVEE)) { + return PPC_INTERRUPT_HVIRT; + } + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + return PPC_INTERRUPT_RESET; + } + return 0; +} + static bool cpu_has_work_POWER9(CPUState *cs) { PowerPCCPU *cpu = POWERPC_CPU(cs); @@ -6367,44 +6413,8 @@ static bool cpu_has_work_POWER9(CPUState *cs) if (!(psscr & PSSCR_EC)) { return true; } - /* External Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && - (env->spr[SPR_LPCR] & LPCR_EEE)) { - bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); - if (!heic || !FIELD_EX64_HV(env->msr) || - FIELD_EX64(env->msr, MSR, PR)) { - return true; - } - } - /* Decrementer Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && - (env->spr[SPR_LPCR] & LPCR_DEE)) { - return true; - } - /* Machine Check or Hypervisor Maintenance Exception */ - if ((env->pending_interrupts & (PPC_INTERRUPT_MCK | PPC_INTERRUPT_HMI)) - && (env->spr[SPR_LPCR] & LPCR_OEE)) { - return true; - } - /* Privileged Doorbell Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && - (env->spr[SPR_LPCR] & LPCR_PDEE)) { - return true; - } - /* Hypervisor Doorbell Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && - (env->spr[SPR_LPCR] & LPCR_HDEE)) { - return true; - } - /* Hypervisor virtualization exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) && - (env->spr[SPR_LPCR] & LPCR_HVEE)) { - return true; - } - if (env->pending_interrupts & PPC_INTERRUPT_RESET) { - return true; - } - return false; + + return p9_interrupt_powersave(env) != 0; } else { return FIELD_EX64(env->msr, MSR, EE) && (cs->interrupt_request & CPU_INTERRUPT_HARD); @@ -6600,44 +6610,8 @@ static bool cpu_has_work_POWER10(CPUState *cs) if (!(psscr & PSSCR_EC)) { return true; } - /* External Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && - (env->spr[SPR_LPCR] & LPCR_EEE)) { - bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); - if (!heic || !FIELD_EX64_HV(env->msr) || - FIELD_EX64(env->msr, MSR, PR)) { - return true; - } - } - /* Decrementer Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && - (env->spr[SPR_LPCR] & LPCR_DEE)) { - return true; - } - /* Machine Check or Hypervisor Maintenance Exception */ - if ((env->pending_interrupts & (PPC_INTERRUPT_MCK | PPC_INTERRUPT_HMI)) - && (env->spr[SPR_LPCR] & LPCR_OEE)) { - return true; - } - /* Privileged Doorbell Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && - (env->spr[SPR_LPCR] & LPCR_PDEE)) { - return true; - } - /* Hypervisor Doorbell Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && - (env->spr[SPR_LPCR] & LPCR_HDEE)) { - return true; - } - /* Hypervisor virtualization exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) && - (env->spr[SPR_LPCR] & LPCR_HVEE)) { - return true; - } - if (env->pending_interrupts & PPC_INTERRUPT_RESET) { - return true; - } - return false; + + return p9_interrupt_powersave(env) != 0; } else { return FIELD_EX64(env->msr, MSR, EE) && (cs->interrupt_request & CPU_INTERRUPT_HARD); |