aboutsummaryrefslogtreecommitdiff
path: root/target-ppc
diff options
context:
space:
mode:
authorAndreas Färber <afaerber@suse.de>2013-01-17 18:51:17 +0100
committerAndreas Färber <afaerber@suse.de>2013-03-12 10:35:55 +0100
commit259186a7d2f7184efc96ae99bc5658e6159f53ad (patch)
tree7d49386c5725627dccbab0ee342520ee7437fc8d /target-ppc
parent21317bc222ef4cdca594b1856eea62f3dfbbfb6c (diff)
cpu: Move halted and interrupt_request fields to CPUState
Both fields are used in VMState, thus need to be moved together. Explicitly zero them on reset since they were located before breakpoints. Pass PowerPCCPU to kvmppc_handle_halt(). Signed-off-by: Andreas Färber <afaerber@suse.de>
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/cpu.h5
-rw-r--r--target-ppc/excp_helper.c22
-rw-r--r--target-ppc/helper_regs.h11
-rw-r--r--target-ppc/kvm.c16
-rw-r--r--target-ppc/translate.c3
5 files changed, 36 insertions, 21 deletions
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 417abb0dd1..1b31b1d9c9 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -2217,9 +2217,10 @@ extern void (*cpu_ppc_hypercall)(PowerPCCPU *);
static inline bool cpu_has_work(CPUState *cpu)
{
- CPUPPCState *env = &POWERPC_CPU(cpu)->env;
+ PowerPCCPU *ppc_cpu = POWERPC_CPU(cpu);
+ CPUPPCState *env = &ppc_cpu->env;
- return msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD);
+ return msr_ee && (cpu->interrupt_request & CPU_INTERRUPT_HARD);
}
#include "exec/exec-all.h"
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 0a1ac86a42..79ce7bf7c4 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -66,6 +66,7 @@ static inline void dump_syscall(CPUPPCState *env)
static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
{
CPUPPCState *env = &cpu->env;
+ CPUState *cs;
target_ulong msr, new_msr, vector;
int srr0, srr1, asrr0, asrr1;
int lpes0, lpes1, lev;
@@ -131,8 +132,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
fprintf(stderr, "Machine check while not allowed. "
"Entering checkstop state\n");
}
- env->halted = 1;
- env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+ cs = CPU(cpu);
+ cs->halted = 1;
+ cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
}
if (0) {
/* XXX: find a suitable condition to enable the hypervisor mode */
@@ -663,11 +665,12 @@ void ppc_hw_interrupt(CPUPPCState *env)
{
PowerPCCPU *cpu = ppc_env_get_cpu(env);
int hdice;
-
#if 0
+ CPUState *cs = CPU(cpu);
+
qemu_log_mask(CPU_LOG_INT, "%s: %p pending %08x req %08x me %d ee %d\n",
- __func__, env, env->pending_interrupts,
- env->interrupt_request, (int)msr_me, (int)msr_ee);
+ __func__, env, env->pending_interrupts,
+ cs->interrupt_request, (int)msr_me, (int)msr_ee);
#endif
/* External reset */
if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
@@ -807,9 +810,12 @@ void helper_raise_exception(CPUPPCState *env, uint32_t exception)
#if !defined(CONFIG_USER_ONLY)
void helper_store_msr(CPUPPCState *env, target_ulong val)
{
+ CPUState *cs;
+
val = hreg_store_msr(env, val, 0);
if (val != 0) {
- env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+ cs = CPU(ppc_env_get_cpu(env));
+ cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
helper_raise_exception(env, val);
}
}
@@ -817,6 +823,8 @@ void helper_store_msr(CPUPPCState *env, target_ulong val)
static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
target_ulong msrm, int keep_msrh)
{
+ CPUState *cs = CPU(ppc_env_get_cpu(env));
+
#if defined(TARGET_PPC64)
if (msr_is_64bit(env, msr)) {
nip = (uint64_t)nip;
@@ -841,7 +849,7 @@ static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
/* No need to raise an exception here,
* as rfi is always the last insn of a TB
*/
- env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+ cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
}
void helper_rfi(CPUPPCState *env)
diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h
index 3c988502ed..a6d5e2fe2f 100644
--- a/target-ppc/helper_regs.h
+++ b/target-ppc/helper_regs.h
@@ -68,10 +68,13 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
int alter_hv)
{
int excp;
+#if !defined(CONFIG_USER_ONLY)
+ CPUState *cs = CPU(ppc_env_get_cpu(env));
+#endif
excp = 0;
value &= env->msr_mask;
-#if !defined (CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
if (!alter_hv) {
/* mtmsr cannot alter the hypervisor state */
value &= ~MSR_HVB;
@@ -82,7 +85,7 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
/* Flush all tlb when changing translation mode */
tlb_flush(env, 1);
excp = POWERPC_EXCP_NONE;
- env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+ cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
}
if (unlikely((env->flags & POWERPC_FLAG_TGPR) &&
((value ^ env->msr) & (1 << MSR_TGPR)))) {
@@ -96,10 +99,10 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
#endif
env->msr = value;
hreg_compute_hflags(env);
-#if !defined (CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
if (unlikely(msr_pow == 1)) {
if ((*env->check_pow)(env)) {
- env->halted = 1;
+ cs->halted = 1;
excp = EXCP_HALTED;
}
}
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 9dff7607f1..e663ff0acb 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -993,7 +993,7 @@ void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
* interrupt, reset, etc) in PPC-specific env->irq_input_state. */
if (!cap_interrupt_level &&
run->ready_for_interrupt_injection &&
- (env->interrupt_request & CPU_INTERRUPT_HARD) &&
+ (cs->interrupt_request & CPU_INTERRUPT_HARD) &&
(env->irq_input_state & (1<<PPC_INPUT_INT)))
{
/* For now KVM disregards the 'irq' argument. However, in the
@@ -1024,14 +1024,16 @@ void kvm_arch_post_run(CPUState *cpu, struct kvm_run *run)
int kvm_arch_process_async_events(CPUState *cs)
{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- return cpu->env.halted;
+ return cs->halted;
}
-static int kvmppc_handle_halt(CPUPPCState *env)
+static int kvmppc_handle_halt(PowerPCCPU *cpu)
{
- if (!(env->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) {
- env->halted = 1;
+ CPUState *cs = CPU(cpu);
+ CPUPPCState *env = &cpu->env;
+
+ if (!(cs->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) {
+ cs->halted = 1;
env->exception_index = EXCP_HLT;
}
@@ -1073,7 +1075,7 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
break;
case KVM_EXIT_HLT:
dprintf("handle halt\n");
- ret = kvmppc_handle_halt(env);
+ ret = kvmppc_handle_halt(cpu);
break;
#ifdef CONFIG_PSERIES
case KVM_EXIT_PAPR_HCALL:
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index fa9e9e3857..380a884131 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3103,7 +3103,8 @@ static void gen_sync(DisasContext *ctx)
static void gen_wait(DisasContext *ctx)
{
TCGv_i32 t0 = tcg_temp_new_i32();
- tcg_gen_st_i32(t0, cpu_env, offsetof(CPUPPCState, halted));
+ tcg_gen_st_i32(t0, cpu_env,
+ -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
tcg_temp_free_i32(t0);
/* Stop translation, as the CPU is supposed to sleep from now */
gen_exception_err(ctx, EXCP_HLT, 1);