aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--target-ppc/cpu.h2
-rw-r--r--target-ppc/translate_init.c15
2 files changed, 13 insertions, 4 deletions
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 9087a08..93c2dd5 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1187,7 +1187,9 @@ void ppc_store_msr (CPUPPCState *env, target_ulong value);
void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf);
int ppc_get_compat_smt_threads(PowerPCCPU *cpu);
+#if defined(TARGET_PPC64)
void ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version, Error **errp);
+#endif
/* Time-base and decrementer management */
#ifndef NO_CPU_IO_DEFS
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index fa09183..274009a 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -9515,28 +9515,34 @@ int ppc_get_compat_smt_threads(PowerPCCPU *cpu)
return ret;
}
+#ifdef TARGET_PPC64
void ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version, Error **errp)
{
int ret = 0;
CPUPPCState *env = &cpu->env;
+ PowerPCCPUClass *host_pcc;
cpu->cpu_version = cpu_version;
switch (cpu_version) {
case CPU_POWERPC_LOGICAL_2_05:
- env->spr[SPR_PCR] = PCR_COMPAT_2_05;
+ env->spr[SPR_PCR] = PCR_TM_DIS | PCR_VSX_DIS | PCR_COMPAT_2_07 |
+ PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
break;
case CPU_POWERPC_LOGICAL_2_06:
- env->spr[SPR_PCR] = PCR_COMPAT_2_06;
- break;
case CPU_POWERPC_LOGICAL_2_06_PLUS:
- env->spr[SPR_PCR] = PCR_COMPAT_2_06;
+ env->spr[SPR_PCR] = PCR_TM_DIS | PCR_COMPAT_2_07 | PCR_COMPAT_2_06;
break;
default:
env->spr[SPR_PCR] = 0;
break;
}
+ host_pcc = kvm_ppc_get_host_cpu_class();
+ if (host_pcc) {
+ env->spr[SPR_PCR] &= host_pcc->pcr_mask;
+ }
+
if (kvm_enabled()) {
ret = kvmppc_set_compat(cpu, cpu->cpu_version);
if (ret < 0) {
@@ -9545,6 +9551,7 @@ void ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version, Error **errp)
}
}
}
+#endif
static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
{