diff options
Diffstat (limited to 'target-ppc')
-rw-r--r-- | target-ppc/cpu.h | 6 | ||||
-rw-r--r-- | target-ppc/excp_helper.c | 40 | ||||
-rw-r--r-- | target-ppc/kvm.c | 12 |
3 files changed, 34 insertions, 24 deletions
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 380a8d2926..c3cbad7371 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -2222,10 +2222,12 @@ static inline bool msr_is_64bit(CPUPPCState *env, target_ulong msr) return msr & (1ULL << MSR_SF); } -extern void (*cpu_ppc_hypercall)(CPUPPCState *); +extern void (*cpu_ppc_hypercall)(PowerPCCPU *); -static inline bool cpu_has_work(CPUPPCState *env) +static inline bool cpu_has_work(CPUState *cpu) { + CPUPPCState *env = &POWERPC_CPU(cpu)->env; + return msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD); } diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c index 1a593f6f3f..5e34ad08a8 100644 --- a/target-ppc/excp_helper.c +++ b/target-ppc/excp_helper.c @@ -33,7 +33,7 @@ /*****************************************************************************/ /* PowerPC Hypercall emulation */ -void (*cpu_ppc_hypercall)(CPUPPCState *); +void (*cpu_ppc_hypercall)(PowerPCCPU *); /*****************************************************************************/ /* Exception processing */ @@ -63,8 +63,9 @@ static inline void dump_syscall(CPUPPCState *env) /* Note that this function should be greatly optimized * when called with a constant excp, from ppc_hw_interrupt */ -static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp) +static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) { + CPUPPCState *env = &cpu->env; target_ulong msr, new_msr, vector; int srr0, srr1, asrr0, asrr1; int lpes0, lpes1, lev; @@ -238,7 +239,7 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp) dump_syscall(env); lev = env->error_code; if ((lev == 1) && cpu_ppc_hypercall) { - cpu_ppc_hypercall(env); + cpu_ppc_hypercall(cpu); return; } if (lev == 1 || (lpes0 == 0 && lpes1 == 0)) { @@ -643,11 +644,14 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp) void do_interrupt(CPUPPCState *env) { - powerpc_excp(env, env->excp_model, env->exception_index); + PowerPCCPU *cpu = ppc_env_get_cpu(env); + + powerpc_excp(cpu, env->excp_model, env->exception_index); } void ppc_hw_interrupt(CPUPPCState *env) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); int hdice; #if 0 @@ -658,20 +662,20 @@ void ppc_hw_interrupt(CPUPPCState *env) /* External reset */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET); - powerpc_excp(env, env->excp_model, POWERPC_EXCP_RESET); + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET); return; } /* Machine check exception */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK); - powerpc_excp(env, env->excp_model, POWERPC_EXCP_MCHECK); + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_MCHECK); return; } #if 0 /* TODO */ /* External debug exception */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG); - powerpc_excp(env, env->excp_model, POWERPC_EXCP_DEBUG); + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DEBUG); return; } #endif @@ -685,7 +689,7 @@ void ppc_hw_interrupt(CPUPPCState *env) /* Hypervisor decrementer exception */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR); - powerpc_excp(env, env->excp_model, POWERPC_EXCP_HDECR); + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HDECR); return; } } @@ -698,7 +702,7 @@ void ppc_hw_interrupt(CPUPPCState *env) #if 0 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CEXT); #endif - powerpc_excp(env, env->excp_model, POWERPC_EXCP_CRITICAL); + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_CRITICAL); return; } } @@ -706,30 +710,30 @@ void ppc_hw_interrupt(CPUPPCState *env) /* Watchdog timer on embedded PowerPC */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT); - powerpc_excp(env, env->excp_model, POWERPC_EXCP_WDT); + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_WDT); return; } if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL); - powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORCI); + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORCI); return; } /* Fixed interval timer on embedded PowerPC */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT); - powerpc_excp(env, env->excp_model, POWERPC_EXCP_FIT); + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_FIT); return; } /* Programmable interval timer on embedded PowerPC */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT); - powerpc_excp(env, env->excp_model, POWERPC_EXCP_PIT); + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PIT); return; } /* Decrementer exception */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR); - powerpc_excp(env, env->excp_model, POWERPC_EXCP_DECR); + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DECR); return; } /* External interrupt */ @@ -740,23 +744,23 @@ void ppc_hw_interrupt(CPUPPCState *env) #if 0 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT); #endif - powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL); + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL); return; } if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); - powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORI); + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI); return; } if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM); - powerpc_excp(env, env->excp_model, POWERPC_EXCP_PERFM); + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PERFM); return; } /* Thermal interrupt */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM); - powerpc_excp(env, env->excp_model, POWERPC_EXCP_THERM); + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_THERM); return; } } diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 5cbe98a164..3f5df5772f 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -73,9 +73,11 @@ static int cap_hior; */ static QEMUTimer *idle_timer; -static void kvm_kick_env(void *env) +static void kvm_kick_cpu(void *opaque) { - qemu_cpu_kick(env); + PowerPCCPU *cpu = opaque; + + qemu_cpu_kick(CPU(cpu)); } int kvm_arch_init(KVMState *s) @@ -375,6 +377,7 @@ static inline void kvm_fixup_page_sizes(CPUPPCState *env) int kvm_arch_init_vcpu(CPUPPCState *cenv) { + PowerPCCPU *cpu = ppc_env_get_cpu(cenv); int ret; /* Gather server mmu info from KVM and update the CPU state */ @@ -386,7 +389,7 @@ int kvm_arch_init_vcpu(CPUPPCState *cenv) return ret; } - idle_timer = qemu_new_timer_ns(vm_clock, kvm_kick_env, cenv); + idle_timer = qemu_new_timer_ns(vm_clock, kvm_kick_cpu, cpu); /* Some targets support access to KVM's guest TLB. */ switch (cenv->mmu_model) { @@ -814,7 +817,8 @@ int kvm_arch_handle_exit(CPUPPCState *env, struct kvm_run *run) #ifdef CONFIG_PSERIES case KVM_EXIT_PAPR_HCALL: dprintf("handle PAPR hypercall\n"); - run->papr_hcall.ret = spapr_hypercall(env, run->papr_hcall.nr, + run->papr_hcall.ret = spapr_hypercall(ppc_env_get_cpu(env), + run->papr_hcall.nr, run->papr_hcall.args); ret = 0; break; |