qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v5] powerpc: add PVR mask support


From: Andreas Färber
Subject: Re: [Qemu-devel] [PATCH v5] powerpc: add PVR mask support
Date: Wed, 28 Aug 2013 12:49:27 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130801 Thunderbird/17.0.8

Am 28.08.2013 12:37, schrieb Alexey Kardashevskiy:
> IBM POWERPC processors encode PVR as a CPU family in higher 16 bits and
> a CPU version in lower 16 bits. Since there is no significant change
> in behavior between versions, there is no point to add every single CPU
> version in QEMU's CPU list. Also, new CPU versions of already supported
> CPU won't break the existing code.
> 
> This does the following:
> 1. add a PVR mask support for a CPU family;
> 2. make CPU family not abstract;
> 3. hide family CPU classes from "-cpu ?" list.
> 
> As CPU family class name for POWER7 is "POWER7-family", there is no need
> to touch aliases.
> 
> Cc: Andreas Färber <address@hidden>
> Signed-off-by: Alexey Kardashevskiy <address@hidden>
> 
> ---
> 
> I would really love to avoid adding masks to other classes as long as 
> possible -
> I do not know them well, they do not know me, I am scared of breaking them :)
> 
> 
> ---
> Changes:
> v5:
> * removed pvr_default
> * added hiding of family CPU classes (should not appear in -cpu ?)
> * separated POWER7+ into a class (it used to be POWER7) and added a mask for 
> it
> * added mask for POWER8
> * added _BASE suffix to PVR mask constants and moved them before actual CPUs
> 
> v4:
> * removed bogus layer from hierarchy
> 
> v3:
> * renamed macros to describe the functionality better
> * added default PVR value for the powerpc cpu family (what alias used to do)
> 
> v2:
> * aliases are replaced with another level in class hierarchy
> ---
>  target-ppc/cpu-models.c     |  3 ++-
>  target-ppc/cpu-models.h     |  7 ++++++
>  target-ppc/cpu-qom.h        |  1 +
>  target-ppc/kvm.c            |  1 +
>  target-ppc/translate_init.c | 53 
> +++++++++++++++++++++++++++++++++++++++++++--
>  5 files changed, 62 insertions(+), 3 deletions(-)
> 
> diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c
> index 8dea560..7c9466f 100644
> --- a/target-ppc/cpu-models.c
> +++ b/target-ppc/cpu-models.c
> @@ -44,6 +44,7 @@
>          PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);                       \
>                                                                              \
>          pcc->pvr          = _pvr;                                           \
> +        pcc->pvr_mask     = CPU_POWERPC_DEFAULT_MASK;                       \
>          pcc->svr          = _svr;                                           \
>          dc->desc          = _desc;                                          \
>      }                                                                       \
> @@ -1139,7 +1140,7 @@
>                  "POWER7 v2.1")
>      POWERPC_DEF("POWER7_v2.3",   CPU_POWERPC_POWER7_v23,             POWER7,
>                  "POWER7 v2.3")
> -    POWERPC_DEF("POWER7+_v2.1",  CPU_POWERPC_POWER7P_v21,            POWER7,
> +    POWERPC_DEF("POWER7+_v2.1",  CPU_POWERPC_POWER7P_v21,            POWER7P,
>                  "POWER7+ v2.1")
>      POWERPC_DEF("POWER8_v1.0",   CPU_POWERPC_POWER8_v10,             POWER8,
>                  "POWER8 v1.0")

As always, please put independent changes like this POWER7P introduction
in its own patch.

> diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h
> index d9145d1..49ba4a4 100644
> --- a/target-ppc/cpu-models.h
> +++ b/target-ppc/cpu-models.h
> @@ -39,6 +39,7 @@ extern PowerPCCPUAlias ppc_cpu_aliases[];
>  
> /*****************************************************************************/
>  /* PVR definitions for most known PowerPC                                    
> */
>  enum {
> +    CPU_POWERPC_DEFAULT_MASK       = 0xFFFFFFFF,
>      /* PowerPC 401 family */
>      /* Generic PowerPC 401 */
>  #define CPU_POWERPC_401              CPU_POWERPC_401G2
> @@ -552,10 +553,16 @@ enum {
>      CPU_POWERPC_POWER6             = 0x003E0000,
>      CPU_POWERPC_POWER6_5           = 0x0F000001, /* POWER6 in POWER5 mode */
>      CPU_POWERPC_POWER6A            = 0x0F000002,
> +    CPU_POWERPC_POWER7_BASE        = 0x003F0000,
> +    CPU_POWERPC_POWER7_MASK        = 0xFFFF0000,
>      CPU_POWERPC_POWER7_v20         = 0x003F0200,
>      CPU_POWERPC_POWER7_v21         = 0x003F0201,
>      CPU_POWERPC_POWER7_v23         = 0x003F0203,
> +    CPU_POWERPC_POWER7P_BASE       = 0x004A0000,
> +    CPU_POWERPC_POWER7P_MASK       = 0xFFFF0000,
>      CPU_POWERPC_POWER7P_v21        = 0x004A0201,
> +    CPU_POWERPC_POWER8_BASE        = 0x004B0000,
> +    CPU_POWERPC_POWER8_MASK        = 0xFFFF0000,
>      CPU_POWERPC_POWER8_v10         = 0x004B0100,
>      CPU_POWERPC_970                = 0x00390202,
>      CPU_POWERPC_970FX_v10          = 0x00391100,
> diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
> index f3c710a..0ae8b09 100644
> --- a/target-ppc/cpu-qom.h
> +++ b/target-ppc/cpu-qom.h
> @@ -54,6 +54,7 @@ typedef struct PowerPCCPUClass {
>      void (*parent_reset)(CPUState *cpu);
>  
>      uint32_t pvr;
> +    uint32_t pvr_mask;
>      uint32_t svr;
>      uint64_t insns_flags;
>      uint64_t insns_flags2;
> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
> index 30a870e..d7d9865 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -1732,6 +1732,7 @@ static void kvmppc_host_cpu_class_init(ObjectClass *oc, 
> void *data)
>      uint32_t icache_size = kvmppc_read_int_cpu_dt("i-cache-size");
>  
>      /* Now fix up the class with information we can query from the host */
> +    pcc->pvr = mfpvr();
>  
>      if (vmx != -1) {
>          /* Only override when we know what the host supports */
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index 761b2e5..39cb69b 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -3105,7 +3105,6 @@ static int check_pow_hid0_74xx (CPUPPCState *env)
>      glue(glue(ppc_, _name), _cpu_family_type_info) = {                      \
>          .name = stringify(_name) "-family-" TYPE_POWERPC_CPU,               \
>          .parent = TYPE_POWERPC_CPU,                                         \
> -        .abstract = true,                                                   \
>          .class_init = glue(glue(ppc_, _name), _cpu_family_class_init),      \
>      };                                                                      \
>                                                                              \

Comment not yet incorporated.

> @@ -7216,6 +7215,45 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
>  
>      dc->fw_name = "PowerPC,POWER7";
>      dc->desc = "POWER7";
> +    pcc->pvr = CPU_POWERPC_POWER7_BASE;
> +    pcc->pvr_mask = CPU_POWERPC_POWER7_MASK;
> +    pcc->init_proc = init_proc_POWER7;
> +    pcc->check_pow = check_pow_nocheck;
> +    pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
> +                       PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
> +                       PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
> +                       PPC_FLOAT_STFIWX |
> +                       PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
> +                       PPC_MEM_SYNC | PPC_MEM_EIEIO |
> +                       PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
> +                       PPC_64B | PPC_ALTIVEC |
> +                       PPC_SEGMENT_64B | PPC_SLBI |
> +                       PPC_POPCNTB | PPC_POPCNTWD;
> +    pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205;
> +    pcc->msr_mask = 0x800000000204FF37ULL;
> +    pcc->mmu_model = POWERPC_MMU_2_06;
> +#if defined(CONFIG_SOFTMMU)
> +    pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
> +#endif
> +    pcc->excp_model = POWERPC_EXCP_POWER7;
> +    pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
> +    pcc->bfd_mach = bfd_mach_ppc64;
> +    pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
> +                 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
> +                 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR;
> +    pcc->l1_dcache_size = 0x8000;
> +    pcc->l1_icache_size = 0x8000;
> +}
> +
> +POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(oc);
> +    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
> +
> +    dc->fw_name = "PowerPC,POWER7+";

According to the only reply I received, it's "POWER7", not "POWER7+" -
see my patch description. If that information was wrong, we'll need to
move POWER7P introduction before my fw_name patch and update it accordingly.

> +    dc->desc = "POWER7+";
> +    pcc->pvr = CPU_POWERPC_POWER7P_BASE;
> +    pcc->pvr_mask = CPU_POWERPC_POWER7P_MASK;
>      pcc->init_proc = init_proc_POWER7;
>      pcc->check_pow = check_pow_nocheck;
>      pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
> @@ -7251,6 +7289,8 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
>  
>      dc->fw_name = "PowerPC,POWER8";
>      dc->desc = "POWER8";
> +    pcc->pvr = CPU_POWERPC_POWER8_BASE;
> +    pcc->pvr_mask = CPU_POWERPC_POWER8_MASK;
>      pcc->init_proc = init_proc_POWER7;
>      pcc->check_pow = check_pow_nocheck;
>      pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
> @@ -8165,7 +8205,7 @@ static gint ppc_cpu_compare_class_pvr(gconstpointer a, 
> gconstpointer b)
>      }
>  #endif
>  
> -    return pcc->pvr == pvr ? 0 : -1;
> +    return ((pcc->pvr == (pvr & pcc->pvr_mask)) ? 0 : -1);

As discussed in lengths this is the wrong place IMO. Also, the
comparison should be:
(pcc->pvr & pcc->pvr_mask) == (pvr & pcc->pvr_mask)
to match specific models where available. Note that pvr_mask gets
inherited from the family like any other class field.

>  }
>  
>  PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
> @@ -8326,6 +8366,8 @@ static void ppc_cpu_list_entry(gpointer data, gpointer 
> user_data)
>      CPUListState *s = user_data;
>      PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
>      const char *typename = object_class_get_name(oc);
> +    ObjectClass *oc_parent = object_class_get_parent(oc);
> +    const char *typename_parent = object_class_get_name(oc_parent);
>      char *name;
>      int i;
>  
> @@ -8338,6 +8380,11 @@ static void ppc_cpu_list_entry(gpointer data, gpointer 
> user_data)
>          return;
>      }
>  
> +    /* Do not show non-abstract family CPU classes */
> +    if (unlikely(strcmp(typename_parent, TYPE_POWERPC_CPU) == 0)) {
> +        return;
> +    }
> +
>      name = g_strndup(typename,
>                       strlen(typename) - strlen("-" TYPE_POWERPC_CPU));
>      (*s->cpu_fprintf)(s->file, "PowerPC %-16s PVR %08x\n",

Becomes unnecessary when dropping the abstractness change.

> @@ -8557,6 +8604,8 @@ static void ppc_cpu_class_init(ObjectClass *oc, void 
> *data)
>      DeviceClass *dc = DEVICE_CLASS(oc);
>  
>      pcc->parent_realize = dc->realize;
> +    pcc->pvr = CPU_POWERPC_DEFAULT_MASK;
> +    pcc->pvr_mask = 0;
>      dc->realize = ppc_cpu_realizefn;
>      dc->unrealize = ppc_cpu_unrealizefn;
>  

Regards,
Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg



reply via email to

[Prev in Thread] Current Thread [Next in Thread]