Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
qemu.3557
0128-target-ppc-Add-pvr_match-callback.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0128-target-ppc-Add-pvr_match-callback.patch of Package qemu.3557
From b3d87dd88a9497f9c778be14880ab389e640da56 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy <aik@ozlabs.ru> Date: Fri, 4 Jul 2014 00:48:55 +1000 Subject: [PATCH] target-ppc: Add pvr_match() callback So far it was enough to have a base PVR value and mask per CPU family such as POWER7 or POWER8. However there CPUs which are completely architecturally compatible but have different PVRs such as POWER7/POWER7+ and POWER8/POWER8E. For these CPUs, top 16 bits are CPU family and low 16 bits are the version. The families have PVR base values different enough so defining a mask which would cover both (or potentially more) CPUs within the family is not possible. This adds a pvr_match() callback to PowerPCCPUClass. The default handler simply compares PVR defined in the class. This implements ppc_pvr_match_power7/ppc_pvr_match_power8 callbacks for POWER7/8 families. These check for POWER7/POWER7+ and POWER8/POWER8E. This changes ppc_cpu_compare_class_pvr_mask() not to check masks but use the pvr_match() callback. Since all server CPUs use the same mask, this defines one mask value - CPU_POWERPC_POWER_SERVER_MASK - which is used everywhere now. This removes other mask definitions. This removes pvr_mask from PowerPCCPUClass as it is not used anymore. This removes pvr initialization for POWER7/8 families as it is not used to find the class, the pvr_match() callback is used instead. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Alexander Graf <agraf@suse.de> (cherry picked from commit 22168903f3e108528d19afa3d1f227c06d2ee5ec) Signed-off-by: Alexander Graf <agraf@suse.de> --- target-ppc/cpu-models.c | 1 - target-ppc/cpu-models.h | 6 +----- target-ppc/cpu-qom.h | 2 +- target-ppc/translate_init.c | 49 ++++++++++++++++++++++++++++++++------------- 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c index 05d088a..24ee80a 100644 --- a/target-ppc/cpu-models.c +++ b/target-ppc/cpu-models.c @@ -44,7 +44,6 @@ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); \ \ pcc->pvr = _pvr; \ - pcc->pvr_mask = CPU_POWERPC_DEFAULT_MASK; \ pcc->svr = _svr; \ dc->desc = _desc; \ } \ diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h index c39d03a..290a759 100644 --- a/target-ppc/cpu-models.h +++ b/target-ppc/cpu-models.h @@ -39,7 +39,6 @@ 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 @@ -553,17 +552,14 @@ enum { CPU_POWERPC_POWER6 = 0x003E0000, CPU_POWERPC_POWER6_5 = 0x0F000001, /* POWER6 in POWER5 mode */ CPU_POWERPC_POWER6A = 0x0F000002, + CPU_POWERPC_POWER_SERVER_MASK = 0xFFFF0000, CPU_POWERPC_POWER7_BASE = 0x003F0000, - CPU_POWERPC_POWER7_MASK = 0xFFFF0000, CPU_POWERPC_POWER7_v23 = 0x003F0203, CPU_POWERPC_POWER7P_BASE = 0x004A0000, - CPU_POWERPC_POWER7P_MASK = 0xFFFF0000, CPU_POWERPC_POWER7P_v21 = 0x004A0201, CPU_POWERPC_POWER8E_BASE = 0x004B0000, - CPU_POWERPC_POWER8E_MASK = 0xFFFF0000, CPU_POWERPC_POWER8E_v10 = 0x004B0100, CPU_POWERPC_POWER8_BASE = 0x004D0000, - CPU_POWERPC_POWER8_MASK = 0xFFFF0000, CPU_POWERPC_POWER8_v10 = 0x004D0100, CPU_POWERPC_970 = 0x00390202, CPU_POWERPC_970FX_v10 = 0x00391100, diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h index 13c7031..4ae3a5e 100644 --- a/target-ppc/cpu-qom.h +++ b/target-ppc/cpu-qom.h @@ -56,7 +56,7 @@ typedef struct PowerPCCPUClass { void (*parent_reset)(CPUState *cpu); uint32_t pvr; - uint32_t pvr_mask; + bool (*pvr_match)(struct PowerPCCPUClass *pcc, uint32_t pvr); uint64_t pcr_mask; uint32_t svr; uint64_t insns_flags; diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 86ce3d3..ce63e60 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7149,6 +7149,17 @@ static void init_proc_POWER7 (CPUPPCState *env) 0x00000000); } +static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr) +{ + if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7P_BASE) { + return true; + } + if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7_BASE) { + return true; + } + return false; +} + POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -7157,8 +7168,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) dc->fw_name = "PowerPC,POWER7"; dc->desc = "POWER7"; dc->props = powerpc_servercpu_properties; - pcc->pvr = CPU_POWERPC_POWER7_BASE; - pcc->pvr_mask = CPU_POWERPC_POWER7_MASK; + pcc->pvr_match = ppc_pvr_match_power7; pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06; pcc->init_proc = init_proc_POWER7; pcc->check_pow = check_pow_nocheck; @@ -7203,8 +7213,7 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data) dc->fw_name = "PowerPC,POWER7+"; dc->desc = "POWER7+"; dc->props = powerpc_servercpu_properties; - pcc->pvr = CPU_POWERPC_POWER7P_BASE; - pcc->pvr_mask = CPU_POWERPC_POWER7P_MASK; + pcc->pvr_match = ppc_pvr_match_power7; pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06; pcc->init_proc = init_proc_POWER7; pcc->check_pow = check_pow_nocheck; @@ -7253,6 +7262,17 @@ static void init_proc_POWER8(CPUPPCState *env) 0x00000000); } +static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr) +{ + if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8E_BASE) { + return true; + } + if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8_BASE) { + return true; + } + return false; +} + POWERPC_FAMILY(POWER8E)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -7261,8 +7281,7 @@ POWERPC_FAMILY(POWER8E)(ObjectClass *oc, void *data) dc->fw_name = "PowerPC,POWER8"; dc->desc = "POWER8E"; dc->props = powerpc_servercpu_properties; - pcc->pvr = CPU_POWERPC_POWER8E_BASE; - pcc->pvr_mask = CPU_POWERPC_POWER8E_MASK; + pcc->pvr_match = ppc_pvr_match_power8; pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06; pcc->init_proc = init_proc_POWER8; pcc->check_pow = check_pow_nocheck; @@ -7304,13 +7323,10 @@ POWERPC_FAMILY(POWER8E)(ObjectClass *oc, void *data) POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); ppc_POWER8E_cpu_family_class_init(oc, data); dc->desc = "POWER8"; - pcc->pvr = CPU_POWERPC_POWER8_BASE; - pcc->pvr_mask = CPU_POWERPC_POWER8_MASK; } #endif /* defined (TARGET_PPC64) */ @@ -8293,7 +8309,6 @@ static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b) ObjectClass *oc = (ObjectClass *)a; uint32_t pvr = *(uint32_t *)b; PowerPCCPUClass *pcc = (PowerPCCPUClass *)a; - gint ret; /* -cpu host does a PVR lookup during construction */ if (unlikely(strcmp(object_class_get_name(oc), @@ -8305,9 +8320,11 @@ static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b) return -1; } - ret = (((pcc->pvr & pcc->pvr_mask) == (pvr & pcc->pvr_mask)) ? 0 : -1); + if (pcc->pvr_match(pcc, pvr)) { + return 0; + } - return ret; + return -1; } PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr) @@ -8697,6 +8714,11 @@ static void ppc_cpu_initfn(Object *obj) } } +static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr) +{ + return pcc->pvr == pvr; +} + static void ppc_cpu_class_init(ObjectClass *oc, void *data) { PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); @@ -8704,8 +8726,7 @@ 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 = CPU_POWERPC_DEFAULT_MASK; + pcc->pvr_match = ppc_pvr_match_default; pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always; dc->realize = ppc_cpu_realizefn; dc->unrealize = ppc_cpu_unrealizefn;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor