qemu-ppc
[Top][All Lists]
Advanced

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

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


From: Alexey Kardashevskiy
Subject: [Qemu-ppc] [PATCH v5] powerpc: add PVR mask support
Date: Wed, 28 Aug 2013 20:37:17 +1000

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")
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),      \
     };                                                                      \
                                                                             \
@@ -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+";
+    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);
 }
 
 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",
@@ -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;
 
-- 
1.8.4.rc4




reply via email to

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