[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH v2 2/2] target-ppc: add "compat" CPU option
From: |
Alexey Kardashevskiy |
Subject: |
[Qemu-ppc] [PATCH v2 2/2] target-ppc: add "compat" CPU option |
Date: |
Fri, 8 Nov 2013 19:22:43 +1100 |
To be able to boot on newer hardware that the software support,
PowerISA defines a logical PVR, one per every PowerISA specification
version from 2.04.
This adds the "compat" option which takes values 205 or 206 and forces
QEMU to boot the guest with a logical PVR (CPU_POWERPC_LOGICAL_2_05 or
CPU_POWERPC_LOGICAL_2_06).
The guest reads the logical PVR value from "cpu-version" property of
a CPU device node.
Cc: Nikunj A Dadhania <address@hidden>
Cc: Andreas Färber <address@hidden>
Signed-off-by: Alexey Kardashevskiy <address@hidden>
---
hw/ppc/spapr.c | 13 ++++++++-
target-ppc/cpu-models.h | 16 +++++++++++
target-ppc/cpu.h | 4 +++
target-ppc/translate_init.c | 67 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 99 insertions(+), 1 deletion(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 7e53a5f..9fcbd96 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -206,6 +206,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment
*spapr)
CPU_FOREACH(cpu) {
DeviceClass *dc = DEVICE_GET_CLASS(cpu);
+ CPUPPCState *env = &POWERPC_CPU(cpu)->env;
uint32_t associativity[] = {cpu_to_be32(0x5),
cpu_to_be32(0x0),
cpu_to_be32(0x0),
@@ -238,6 +239,14 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment
*spapr)
if (ret < 0) {
return ret;
}
+
+ if (env->compat) {
+ ret = fdt_setprop(fdt, offset, "cpu-version",
+ &env->compat, sizeof(env->compat));
+ if (ret < 0) {
+ return ret;
+ }
+ }
}
return ret;
}
@@ -1101,7 +1110,7 @@ static SaveVMHandlers savevm_htab_handlers = {
static void ppc_spapr_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
- const char *cpu_model = args->cpu_model;
+ const char *cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
@@ -1121,6 +1130,8 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
msi_supported = true;
+ cpu_model = qemu_opt_get(qemu_get_cpu_opts(), "type");
+
spapr = g_malloc0(sizeof(*spapr));
QLIST_INIT(&spapr->phbs);
diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h
index 49ba4a4..38f38d1 100644
--- a/target-ppc/cpu-models.h
+++ b/target-ppc/cpu-models.h
@@ -583,6 +583,16 @@ enum {
CPU_POWERPC_RS64II = 0x00340000,
CPU_POWERPC_RS64III = 0x00360000,
CPU_POWERPC_RS64IV = 0x00370000,
+
+ /* Logical CPUs */
+ CPU_POWERPC_LOGICAL_MASK = 0xFFFFFFFF,
+ 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,
+
#endif /* defined(TARGET_PPC64) */
/* Original POWER */
/* XXX: should be POWER (RIOS), RSC3308, RSC4608,
@@ -745,4 +755,10 @@ enum {
POWERPC_SVR_8641D = 0x80900121,
};
+/* Processor Compatibility Register (PCR) */
+enum {
+ POWERPC_ISA_COMPAT_2_05 = 1ULL << 62,
+ POWERPC_ISA_COMPAT_2_06 = 1ULL << 61,
+};
+
#endif
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index bb84767..8e30518 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1006,6 +1006,9 @@ struct CPUPPCState {
/* Device control registers */
ppc_dcr_t *dcr_env;
+ /* Architecture compatibility mode PVR */
+ uint32_t compat;
+
int dcache_line_size;
int icache_line_size;
@@ -1330,6 +1333,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
#define SPR_BOOKE_DVC1 (0x13E)
#define SPR_BOOKE_DVC2 (0x13F)
#define SPR_BOOKE_TSR (0x150)
+#define SPR_PCR (0x152)
#define SPR_BOOKE_TCR (0x154)
#define SPR_BOOKE_TLB0PS (0x158)
#define SPR_BOOKE_TLB1PS (0x159)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index c030a20..b297fb3 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -28,6 +28,7 @@
#include "mmu-hash32.h"
#include "mmu-hash64.h"
#include "qemu/error-report.h"
+#include "qapi/visitor.h"
//#define PPC_DUMP_CPU
//#define PPC_DEBUG_SPR
@@ -7201,6 +7202,10 @@ static void init_proc_POWER7 (CPUPPCState *env)
&spr_read_generic, &spr_write_generic,
&spr_read_generic, &spr_write_generic,
0x00000000);
+ spr_register(env, SPR_PCR, "PCR",
+ &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
#if !defined(CONFIG_USER_ONLY)
env->slb_nr = 32;
#endif
@@ -7330,6 +7335,57 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
}
#endif /* defined (TARGET_PPC64) */
+static void powerpc_get_compat(Object *obj, Visitor *v,
+ void *opaque, const char *name, Error **errp)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(obj);
+ int64_t value = 0;
+
+ switch (cpu->env.compat) {
+ case CPU_POWERPC_LOGICAL_2_05:
+ value = 205;
+ break;
+ case CPU_POWERPC_LOGICAL_2_06:
+ value = 206;
+ break;
+ case 0:
+ break;
+ default:
+ perror("Unsupported mode, only are 205, 206 supported\n");
+ break;
+ }
+
+ visit_type_int(v, &value, name, errp);
+}
+
+static void powerpc_set_compat(Object *obj, Visitor *v,
+ void *opaque, const char *name, Error **errp)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(obj);
+ Error *error = NULL;
+ int64_t value;
+
+ visit_type_int(v, &value, name, &error);
+ if (error) {
+ error_propagate(errp, error);
+ return;
+ }
+
+ switch (value) {
+ case 0:
+ cpu->env.compat = 0;
+ break;
+ case 205:
+ cpu->env.compat = CPU_POWERPC_LOGICAL_2_05;
+ break;
+ case 206:
+ cpu->env.compat = CPU_POWERPC_LOGICAL_2_06;
+ break;
+ default:
+ perror("Unsupported mode, only are 205, 206 supported\n");
+ return;
+ }
+}
/*****************************************************************************/
/* Generic CPU instantiation routine */
@@ -7497,6 +7553,12 @@ static void init_ppc_proc(PowerPCCPU *cpu)
"registered.\n"
" Attempt QEMU to crash very soon !\n");
}
+
+ if (env->spr_cb[SPR_PCR].oea_read) {
+ object_property_add(OBJECT(cpu), "compat", "int",
+ powerpc_get_compat, powerpc_set_compat,
+ NULL, NULL, NULL);
+ }
}
#if defined(PPC_DUMP_CPU)
@@ -8376,6 +8438,10 @@ PowerPCCPU *cpu_ppc_init(const char *cpu_model)
return NULL;
}
+ if (cpu_parse_options(CPU(cpu))) {
+ return NULL;
+ }
+
return cpu;
}
@@ -8674,6 +8740,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void
*data)
#endif
dc->fw_name = "PowerPC,UNKNOWN";
+ cc->parse_options = cpu_default_parse_options_func;
}
static const TypeInfo ppc_cpu_type_info = {
--
1.8.4.rc4
- Re: [Qemu-ppc] [PATCH] spapr: add "compat" machine option, (continued)
- Re: [Qemu-ppc] [PATCH] spapr: add "compat" machine option, Igor Mammedov, 2013/11/06
- Re: [Qemu-ppc] [PATCH] spapr: add "compat" machine option, Alexey Kardashevskiy, 2013/11/07
- Re: [Qemu-ppc] [PATCH] spapr: add "compat" machine option, Igor Mammedov, 2013/11/07
- Re: [Qemu-ppc] [PATCH] spapr: add "compat" machine option, Alexey Kardashevskiy, 2013/11/08
- Re: [Qemu-ppc] [PATCH] spapr: add "compat" machine option, Andreas Färber, 2013/11/08
- Re: [Qemu-ppc] [PATCH] spapr: add "compat" machine option, Alexey Kardashevskiy, 2013/11/08
- Re: [Qemu-ppc] [PATCH] spapr: add "compat" machine option, Andreas Färber, 2013/11/08
- Re: [Qemu-ppc] [PATCH] spapr: add "compat" machine option, Andreas Färber, 2013/11/07
- [Qemu-ppc] [PATCH v2 0/2] spapr: add "compat" machine option, Alexey Kardashevskiy, 2013/11/08
- [Qemu-ppc] [PATCH v2 1/2] cpu: add suboptions support, Alexey Kardashevskiy, 2013/11/08
- [Qemu-ppc] [PATCH v2 2/2] target-ppc: add "compat" CPU option,
Alexey Kardashevskiy <=
- Re: [Qemu-ppc] [PATCH v2 0/2] spapr: add "compat" machine option, Andreas Färber, 2013/11/08
Re: [Qemu-ppc] [PATCH] spapr: add "compat" machine option, Paul Mackerras, 2013/11/05
Re: [Qemu-ppc] [PATCH] spapr: add "compat" machine option, Paul Mackerras, 2013/11/06