diff --git a/target-ppc/helper.c b/target-ppc/helper.c index bd711b6..69275d8 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -2478,11 +2478,15 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp) qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx " => %08x (%02x)\n", env->nip, excp, env->error_code); - /* new srr1 value excluding must-be-zero bits */ + /* new srr1 value with interrupt-specific bits defaulting to zero */ msr = env->msr & ~0x783f0000ULL; - /* new interrupt handler msr */ - new_msr = env->msr & ((target_ulong)1 << MSR_ME); + /* new interrupt handler msr (as per PowerISA 2.06B p.811 and p.814): + 1) force the following bits to zero + IR, DR, FE0, FE1, EE, BE, FP, PMM, PR, SE + 2) default the following bits to zero (can be overidden later on) + RI, HVB (note HVB is a different bit between PPC32/64) */ + new_msr = env->msr & ~0xed36ULL & ~((target_ulong) MSR_HVB); /* target registers */ srr0 = SPR_SRR0; @@ -2960,7 +2964,7 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp) if (asrr1 != -1) env->spr[asrr1] = env->spr[srr1]; /* If we disactivated any translation, flush TLBs */ - if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR))) + if (msr & ((1 << MSR_IR) | (1 << MSR_DR))) tlb_flush(env, 1); if (msr_ile) {