Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
qemu-linux-user.7445
0073-target-ppc-Add-compat-CPU-option.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0073-target-ppc-Add-compat-CPU-option.patch of Package qemu-linux-user.7445
From e71f956e1da111de0ff5ea568a329761adb92d70 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy <aik@ozlabs.ru> Date: Fri, 23 May 2014 12:26:50 +1000 Subject: [PATCH] target-ppc: Add "compat" CPU option PowerISA defines a compatibility mode for server POWERPC CPUs which is supported by the PCR special register which is hypervisor privileged. To support this mode for guests, SPAPR defines a set of virtual PVRs, one per PowerISA spec version. When a hypervisor needs a guest to work in a compatibility mode, it puts a virtual PVR value into @cpu-version property of a CPU node. This introduces a "compat" CPU option which defines maximal compatibility mode enabled. The supported modes are power6/power7/power8. This does not change the existing behaviour, new property will be used by next patches. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Alexander Graf <agraf@suse.de> (cherry picked from commit 8dfa3a5e85eca94a93b1495136f49c5776fd5ada) --- target-ppc/cpu-models.h | 10 ++++++ target-ppc/cpu-qom.h | 2 ++ target-ppc/translate_init.c | 75 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h index 644a126459..bbe25d6140 100644 --- a/target-ppc/cpu-models.h +++ b/target-ppc/cpu-models.h @@ -597,6 +597,16 @@ enum { CPU_POWERPC_PA6T = 0x00900000, }; +/* Logical PVR definitions for sPAPR */ +enum { + CPU_POWERPC_LOGICAL_2_04 = 0x0F000001, + CPU_POWERPC_LOGICAL_2_05 = 0x0F000002, + CPU_POWERPC_LOGICAL_2_06 = 0x0F000003, + CPU_POWERPC_LOGICAL_2_06_PLUS = 0x0F100003, + CPU_POWERPC_LOGICAL_2_07 = 0x0F000004, + CPU_POWERPC_LOGICAL_2_08 = 0x0F000005, +}; + /* System version register (used on MPC 8xxx) */ enum { POWERPC_SVR_NONE = 0x00000000, diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h index 046ea0effa..533de8fbd7 100644 --- a/target-ppc/cpu-qom.h +++ b/target-ppc/cpu-qom.h @@ -83,6 +83,7 @@ typedef struct PowerPCCPUClass { * PowerPCCPU: * @env: #CPUPPCState * @cpu_dt_id: CPU index used in the device tree. KVM uses this index too + * @max_compat: Maximal supported logical PVR from the command line * * A PowerPC CPU. */ @@ -93,6 +94,7 @@ struct PowerPCCPU { CPUPPCState env; int cpu_dt_id; + uint32_t max_compat; }; static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index f44b5bc479..23b927baca 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -28,6 +28,8 @@ #include "mmu-hash32.h" #include "mmu-hash64.h" #include "qemu/error-report.h" +#include "qapi/visitor.h" +#include "hw/qdev-properties.h" //#define PPC_DUMP_CPU //#define PPC_DEBUG_SPR @@ -6989,6 +6991,76 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data) pcc->l1_icache_size = 0x10000; } +static void powerpc_get_compat(Object *obj, Visitor *v, + void *opaque, const char *name, Error **errp) +{ + char *value = (char *)""; + Property *prop = opaque; + uint32_t *max_compat = qdev_get_prop_ptr(DEVICE(obj), prop); + + switch (*max_compat) { + case CPU_POWERPC_LOGICAL_2_05: + value = (char *)"power6"; + break; + case CPU_POWERPC_LOGICAL_2_06: + value = (char *)"power7"; + break; + case CPU_POWERPC_LOGICAL_2_07: + value = (char *)"power8"; + break; + case 0: + break; + default: + error_setg(errp, "Internal error: compat is set to %x", + max_compat ? *max_compat : -1); + break; + } + + visit_type_str(v, &value, name, errp); +} + +static void powerpc_set_compat(Object *obj, Visitor *v, + void *opaque, const char *name, Error **errp) +{ + Error *error = NULL; + char *value = NULL; + Property *prop = opaque; + uint32_t *max_compat = qdev_get_prop_ptr(DEVICE(obj), prop); + + visit_type_str(v, &value, name, &error); + if (error) { + error_propagate(errp, error); + return; + } + + if (strcmp(value, "power6") == 0) { + *max_compat = CPU_POWERPC_LOGICAL_2_05; + } else if (strcmp(value, "power7") == 0) { + *max_compat = CPU_POWERPC_LOGICAL_2_06; + } else if (strcmp(value, "power8") == 0) { + *max_compat = CPU_POWERPC_LOGICAL_2_07; + } else { + error_setg(errp, "Invalid compatibility mode \"%s\"", value); + } + + g_free(value); +} + +static PropertyInfo powerpc_compat_propinfo = { + .name = "str", + .legacy_name = "powerpc-server-compat", + .get = powerpc_get_compat, + .set = powerpc_set_compat, +}; + +#define DEFINE_PROP_POWERPC_COMPAT(_n, _s, _f) \ + DEFINE_PROP(_n, _s, _f, powerpc_compat_propinfo, uint32_t) + +static Property powerpc_servercpu_properties[] = { + DEFINE_PROP_POWERPC_COMPAT("compat", PowerPCCPU, max_compat), + DEFINE_PROP_END_OF_LIST(), +}; + static void init_proc_POWER7 (CPUPPCState *env) { gen_spr_ne_601(env); @@ -7075,6 +7147,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->init_proc = init_proc_POWER7; @@ -7119,6 +7192,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->init_proc = init_proc_POWER7; @@ -7175,6 +7249,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) dc->fw_name = "PowerPC,POWER8"; dc->desc = "POWER8"; + dc->props = powerpc_servercpu_properties; pcc->pvr = CPU_POWERPC_POWER8_BASE; pcc->pvr_mask = CPU_POWERPC_POWER8_MASK; pcc->init_proc = init_proc_POWER8;
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