diff options
-rw-r--r-- | hw/ppc/spapr.c | 2 | ||||
-rw-r--r-- | target-ppc/cpu.h | 1 | ||||
-rw-r--r-- | target-ppc/translate_init.c | 27 |
3 files changed, 29 insertions, 1 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index f5baa33fc9..15adeed8e2 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -293,7 +293,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr) } ret = spapr_fixup_cpu_smt_dt(fdt, offset, cpu, - smp_threads); + ppc_get_compat_smt_threads(cpu)); if (ret < 0) { return ret; } diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 0d2253b53c..406a406ebb 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1122,6 +1122,7 @@ void ppc_store_sdr1 (CPUPPCState *env, target_ulong value); 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); int ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version); /* Time-base and decrementer management */ diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index faac74a33c..56d3b97368 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -8921,6 +8921,33 @@ static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp) } } +int ppc_get_compat_smt_threads(PowerPCCPU *cpu) +{ + int ret = smp_threads; + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); + + switch (cpu->cpu_version) { + case CPU_POWERPC_LOGICAL_2_05: + ret = 2; + break; + case CPU_POWERPC_LOGICAL_2_06: + ret = 4; + break; + case CPU_POWERPC_LOGICAL_2_07: + ret = 8; + break; + default: + if (pcc->pcr_mask & PCR_COMPAT_2_06) { + ret = 4; + } else if (pcc->pcr_mask & PCR_COMPAT_2_05) { + ret = 2; + } + break; + } + + return MIN(ret, smp_threads); +} + int ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version) { int ret = 0; |