Message ID | 1486704360-27361-10-git-send-email-sjitindarsingh@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Fri, Feb 10, 2017 at 04:25:59PM +1100, Suraj Jitindar Singh wrote: > The cpu has work function is used to mask interrupts used to determine > if there is work for the cpu based on the LPCR. Add a function to do this > for POWER9 and add it to the POWER9 cpu definition. This is similar to that > for POWER8 except using the LPCR bits as defined for POWER9. > > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> > --- > target/ppc/translate_init.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 45 insertions(+) > > diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c > index a3a23d8..cc8ab1f 100644 > --- a/target/ppc/translate_init.c > +++ b/target/ppc/translate_init.c > @@ -8776,10 +8776,54 @@ static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr) > return false; > } > > +static bool cpu_has_work_POWER9(CPUState *cs) > +{ > + PowerPCCPU *cpu = POWERPC_CPU(cs); > + CPUPPCState *env = &cpu->env; > + > + if (cs->halted) { > + if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { > + return false; > + } > + /* External Exception */ > + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && > + (env->spr[SPR_LPCR] & LPCR_EEE)) { > + 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; > + } > + if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { > + return true; > + } > + return false; > + } else { > + return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD); > + } > +} > + > POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) > { > DeviceClass *dc = DEVICE_CLASS(oc); > PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); > + CPUClass *cc = CPU_CLASS(oc); > > dc->fw_name = "PowerPC,POWER9"; > dc->desc = "POWER9"; > @@ -8790,6 +8834,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) > PCR_COMPAT_2_05; > pcc->init_proc = init_proc_POWER9; > pcc->check_pow = check_pow_nocheck; > + cc->has_work = cpu_has_work_POWER9; > pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | > PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | > PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c index a3a23d8..cc8ab1f 100644 --- a/target/ppc/translate_init.c +++ b/target/ppc/translate_init.c @@ -8776,10 +8776,54 @@ static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr) return false; } +static bool cpu_has_work_POWER9(CPUState *cs) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + + if (cs->halted) { + if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { + return false; + } + /* External Exception */ + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && + (env->spr[SPR_LPCR] & LPCR_EEE)) { + 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; + } + if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { + return true; + } + return false; + } else { + return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD); + } +} + POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + CPUClass *cc = CPU_CLASS(oc); dc->fw_name = "PowerPC,POWER9"; dc->desc = "POWER9"; @@ -8790,6 +8834,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER9; pcc->check_pow = check_pow_nocheck; + cc->has_work = cpu_has_work_POWER9; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
The cpu has work function is used to mask interrupts used to determine if there is work for the cpu based on the LPCR. Add a function to do this for POWER9 and add it to the POWER9 cpu definition. This is similar to that for POWER8 except using the LPCR bits as defined for POWER9. Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> --- target/ppc/translate_init.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)