PPC: Add support for MSR_CM

The BookE variant of MSR_SF is MSR_CM. Implement everything it takes in TCG to
support running 64bit code with MSR_CM set.

Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
Alexander Graf 2012-06-20 21:20:29 +02:00
parent 84755ed51e
commit e42a61f185
4 changed files with 16 additions and 6 deletions

View File

@ -2212,6 +2212,15 @@ static inline uint32_t booke206_tlbnps(CPUPPCState *env, const int tlbn)
#endif #endif
static inline bool msr_is_64bit(CPUPPCState *env, target_ulong msr)
{
if (env->mmu_model == POWERPC_MMU_BOOKE206) {
return msr & (1ULL << MSR_CM);
}
return msr & (1ULL << MSR_SF);
}
extern void (*cpu_ppc_hypercall)(CPUPPCState *); extern void (*cpu_ppc_hypercall)(CPUPPCState *);
static inline bool cpu_has_work(CPUPPCState *env) static inline bool cpu_has_work(CPUPPCState *env)

View File

@ -608,10 +608,11 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
vector |= env->excp_prefix; vector |= env->excp_prefix;
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
if (excp_model == POWERPC_EXCP_BOOKE) { if (excp_model == POWERPC_EXCP_BOOKE) {
if (!msr_icm) { if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
vector = (uint32_t)vector; /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */
} else {
new_msr |= (target_ulong)1 << MSR_CM; new_msr |= (target_ulong)1 << MSR_CM;
} else {
vector = (uint32_t)vector;
} }
} else { } else {
if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) { if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) {
@ -803,7 +804,7 @@ static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
target_ulong msrm, int keep_msrh) target_ulong msrm, int keep_msrh)
{ {
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
if (msr & (1ULL << MSR_SF)) { if (msr_is_64bit(env, msr)) {
nip = (uint64_t)nip; nip = (uint64_t)nip;
msr &= (uint64_t)msrm; msr &= (uint64_t)msrm;
} else { } else {

View File

@ -35,7 +35,7 @@ static inline target_ulong addr_add(CPUPPCState *env, target_ulong addr,
target_long arg) target_long arg)
{ {
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
if (!msr_sf) { if (!msr_is_64bit(env, env->msr)) {
return (uint32_t)(addr + arg); return (uint32_t)(addr + arg);
} else } else
#endif #endif

View File

@ -9626,7 +9626,7 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
ctx.access_type = -1; ctx.access_type = -1;
ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0; ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
ctx.sf_mode = msr_sf; ctx.sf_mode = msr_is_64bit(env, env->msr);
ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR); ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
#endif #endif
ctx.fpu_enabled = msr_fp; ctx.fpu_enabled = msr_fp;