On Fri, Nov 04, 2016 at 01:57:45PM +1100, Alexey Kardashevskiy wrote: > On 30/10/16 22:11, David Gibson wrote: > > This rewrites the ppc_set_compat() function so that instead of open coding > > the various compatibility modes, it reads the relevant data from a table. > > This is a first step in consolidating the information on compatibility > > modes scattered across the code into a single place. > > > > It also makes one change to the logic. The old code masked the bits to be > > set in the PCR (Processor Compatibility Register) by which bits are valid > > on the host CPU. This made no sense, since it was done regardless of > > whether our guest CPU was the same as the host CPU or not. Futhermore, > > s/Futhermore/Furthermore/ > > > > the actual PCR bits are only relevant for TCG[1] - KVM instead uses the > > compatibility mode we tell it in kvmppc_set_compat(). When using TCG > > host cpu information usually isn't even present. > > > > While we're at it, we put the new implementation in a new file to make the > > enormouse translate_init.c a little smaller. > > s/enormouse/enormous/
Thanks, spelling corrections applied. > > > > > > [1] Actually it doesn't even do anything in TCG, but it will if / when we > > get to implementing compatibility mode logic at that level. > > > > Signed-off-by: David Gibson <da...@gibson.dropbear.id.au> > > Reviewed-by: Alexey Kardashevskiy <a...@ozlabs.ru> > > > --- > > target-ppc/Makefile.objs | 1 + > > target-ppc/compat.c | 91 > > +++++++++++++++++++++++++++++++++++++++++++++ > > target-ppc/cpu.h | 6 ++- > > target-ppc/translate_init.c | 41 -------------------- > > 4 files changed, 97 insertions(+), 42 deletions(-) > > create mode 100644 target-ppc/compat.c > > > > diff --git a/target-ppc/Makefile.objs b/target-ppc/Makefile.objs > > index e667e69..feb5c30 100644 > > --- a/target-ppc/Makefile.objs > > +++ b/target-ppc/Makefile.objs > > @@ -15,3 +15,4 @@ obj-y += misc_helper.o > > obj-y += mem_helper.o > > obj-$(CONFIG_USER_ONLY) += user_only_helper.o > > obj-y += gdbstub.o > > +obj-$(TARGET_PPC64) += compat.o > > diff --git a/target-ppc/compat.c b/target-ppc/compat.c > > new file mode 100644 > > index 0000000..f3fd9c6 > > --- /dev/null > > +++ b/target-ppc/compat.c > > @@ -0,0 +1,91 @@ > > +/* > > + * PowerPC CPU initialization for qemu. > > + * > > + * Copyright 2016, David Gibson, Red Hat Inc. <dgib...@redhat.com> > > + * > > + * This library is free software; you can redistribute it and/or > > + * modify it under the terms of the GNU Lesser General Public > > + * License as published by the Free Software Foundation; either > > + * version 2 of the License, or (at your option) any later version. > > + * > > + * This library is distributed in the hope that it will be useful, > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > > + * Lesser General Public License for more details. > > + * > > + * You should have received a copy of the GNU Lesser General Public > > + * License along with this library; if not, see > > <http://www.gnu.org/licenses/>. > > + */ > > + > > +#include "qemu/osdep.h" > > +#include "sysemu/kvm.h" > > +#include "kvm_ppc.h" > > +#include "sysemu/cpus.h" > > +#include "qemu/error-report.h" > > +#include "qapi/error.h" > > +#include "cpu-models.h" > > + > > +typedef struct { > > + uint32_t pvr; > > + uint64_t pcr; > > +} CompatInfo; > > + > > +static const CompatInfo compat_table[] = { > > + { /* POWER6, ISA2.05 */ > > + .pvr = CPU_POWERPC_LOGICAL_2_05, > > + .pcr = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05 > > + | PCR_TM_DIS | PCR_VSX_DIS, > > + }, > > + { /* POWER7, ISA2.06 */ > > + .pvr = CPU_POWERPC_LOGICAL_2_06, > > + .pcr = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_TM_DIS, > > + }, > > + { > > + .pvr = CPU_POWERPC_LOGICAL_2_06_PLUS, > > + .pcr = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_TM_DIS, > > + }, > > + { /* POWER8, ISA2.07 */ > > + .pvr = CPU_POWERPC_LOGICAL_2_07, > > + .pcr = PCR_COMPAT_2_07, > > + }, > > +}; > > + > > +static const CompatInfo *compat_by_pvr(uint32_t pvr) > > +{ > > + int i; > > + > > + for (i = 0; i < ARRAY_SIZE(compat_table); i++) { > > + if (compat_table[i].pvr == pvr) { > > + return &compat_table[i]; > > + } > > + } > > + return NULL; > > +} > > + > > +void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr, Error **errp) > > +{ > > + const CompatInfo *compat = compat_by_pvr(compat_pvr); > > + CPUPPCState *env = &cpu->env; > > + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); > > + uint64_t pcr; > > + > > + if (!compat_pvr) { > > + pcr = 0; > > + } else if (!compat) { > > + error_setg(errp, "Unknown compatibility PVR 0x%08"PRIx32, > > compat_pvr); > > + return; > > + } else { > > + pcr = compat->pcr; > > + } > > + > > + cpu->compat_pvr = compat_pvr; > > + env->spr[SPR_PCR] = pcr & pcc->pcr_mask; > > + > > + if (kvm_enabled()) { > > + int ret = kvmppc_set_compat(cpu, cpu->compat_pvr); > > + if (ret < 0) { > > + error_setg_errno(errp, -ret, > > + "Unable to set CPU compatibility mode in > > KVM"); > > + } > > + } > > +} > > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h > > index f7656cb..15d5e4b 100644 > > --- a/target-ppc/cpu.h > > +++ b/target-ppc/cpu.h > > @@ -1243,7 +1243,6 @@ 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 compat_pvr, Error **errp); > > #endif > > > > /* Time-base and decrementer management */ > > @@ -1314,6 +1313,11 @@ static inline int cpu_mmu_index (CPUPPCState *env, > > bool ifetch) > > return ifetch ? env->immu_idx : env->dmmu_idx; > > } > > > > +/* Compatibility modes */ > > +#if defined(TARGET_PPC64) > > +void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr, Error **errp); > > +#endif /* defined(TARGET_PPC64) */ > > + > > #include "exec/cpu-all.h" > > > > > > /*****************************************************************************/ > > diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c > > index c35065d..a70eafb 100644 > > --- a/target-ppc/translate_init.c > > +++ b/target-ppc/translate_init.c > > @@ -9972,47 +9972,6 @@ int ppc_get_compat_smt_threads(PowerPCCPU *cpu) > > return ret; > > } > > > > -#ifdef TARGET_PPC64 > > -void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr, Error **errp) > > -{ > > - int ret = 0; > > - CPUPPCState *env = &cpu->env; > > - PowerPCCPUClass *host_pcc; > > - > > - cpu->compat_pvr = compat_pvr; > > - > > - switch (compat_pvr) { > > - case CPU_POWERPC_LOGICAL_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: > > - case CPU_POWERPC_LOGICAL_2_06_PLUS: > > - env->spr[SPR_PCR] = PCR_TM_DIS | PCR_COMPAT_2_07 | PCR_COMPAT_2_06; > > - break; > > - case CPU_POWERPC_LOGICAL_2_07: > > - env->spr[SPR_PCR] = PCR_COMPAT_2_07; > > - 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->compat_pvr); > > - if (ret < 0) { > > - error_setg_errno(errp, -ret, > > - "Unable to set CPU compatibility mode in > > KVM"); > > - } > > - } > > -} > > -#endif > > - > > static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b) > > { > > ObjectClass *oc = (ObjectClass *)a; > > > > -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
signature.asc
Description: PGP signature