diff options
Diffstat (limited to 'target/ppc')
-rw-r--r-- | target/ppc/excp_helper.c | 58 |
1 files changed, 43 insertions, 15 deletions
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 94adcb7..add4d54 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -2902,29 +2902,57 @@ static uint64_t hash_digest(uint64_t ra, uint64_t rb, uint64_t key) return stage1_h ^ stage1_l; } +static void do_hash(CPUPPCState *env, target_ulong ea, target_ulong ra, + target_ulong rb, uint64_t key, bool store) +{ + uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash; + + if (store) { + cpu_stq_data_ra(env, ea, calculated_hash, GETPC()); + } else { + loaded_hash = cpu_ldq_data_ra(env, ea, GETPC()); + if (loaded_hash != calculated_hash) { + raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, + POWERPC_EXCP_TRAP, GETPC()); + } + } +} + #include "qemu/guest-random.h" -#define HELPER_HASH(op, key, store) \ +#ifdef TARGET_PPC64 +#define HELPER_HASH(op, key, store, dexcr_aspect) \ void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \ target_ulong rb) \ { \ - uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash; \ - \ - if (store) { \ - cpu_stq_data_ra(env, ea, calculated_hash, GETPC()); \ - } else { \ - loaded_hash = cpu_ldq_data_ra(env, ea, GETPC()); \ - if (loaded_hash != calculated_hash) { \ - raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, \ - POWERPC_EXCP_TRAP, GETPC()); \ - } \ + if (env->msr & R_MSR_PR_MASK) { \ + if (!(env->spr[SPR_DEXCR] & R_DEXCR_PRO_##dexcr_aspect##_MASK || \ + env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \ + return; \ + } else if (!(env->msr & R_MSR_HV_MASK)) { \ + if (!(env->spr[SPR_DEXCR] & R_DEXCR_PNH_##dexcr_aspect##_MASK || \ + env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \ + return; \ + } else if (!(env->msr & R_MSR_S_MASK)) { \ + if (!(env->spr[SPR_HDEXCR] & R_HDEXCR_HNU_##dexcr_aspect##_MASK)) \ + return; \ } \ + \ + do_hash(env, ea, ra, rb, key, store); \ +} +#else +#define HELPER_HASH(op, key, store, dexcr_aspect) \ +void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \ + target_ulong rb) \ +{ \ + do_hash(env, ea, ra, rb, key, store); \ } +#endif /* TARGET_PPC64 */ -HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true) -HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false) -HELPER_HASH(HASHSTP, env->spr[SPR_HASHPKEYR], true) -HELPER_HASH(HASHCHKP, env->spr[SPR_HASHPKEYR], false) +HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true, NPHIE) +HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false, NPHIE) +HELPER_HASH(HASHSTP, env->spr[SPR_HASHPKEYR], true, PHIE) +HELPER_HASH(HASHCHKP, env->spr[SPR_HASHPKEYR], false, PHIE) #endif /* CONFIG_TCG */ #if !defined(CONFIG_USER_ONLY) |