[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH] spapr: add "compat" machine option
From: |
Alexey Kardashevskiy |
Subject: |
[Qemu-ppc] [PATCH] spapr: add "compat" machine option |
Date: |
Fri, 27 Sep 2013 18:06:40 +1000 |
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 | 40 ++++++++++++++++++++++++++++++++++++++++
include/hw/ppc/spapr.h | 2 ++
target-ppc/cpu-models.h | 10 ++++++++++
target-ppc/cpu.h | 3 +++
target-ppc/kvm.c | 2 ++
vl.c | 4 ++++
6 files changed, 61 insertions(+)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index a09a1d9..737452d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -33,6 +33,7 @@
#include "sysemu/kvm.h"
#include "kvm_ppc.h"
#include "mmu-hash64.h"
+#include "cpu-models.h"
#include "hw/boards.h"
#include "hw/ppc/ppc.h"
@@ -196,6 +197,26 @@ static XICSState *xics_system_init(int nr_servers, int
nr_irqs)
return icp;
}
+static void spapr_compat_mode_init(sPAPREnvironment *spapr)
+{
+ QemuOpts *machine_opts = qemu_get_machine_opts();
+ uint64_t compat = qemu_opt_get_number(machine_opts, "compat", 0);
+
+ switch (compat) {
+ case 0:
+ break;
+ case 205:
+ spapr->arch_compat = CPU_POWERPC_LOGICAL_2_05;
+ break;
+ case 206:
+ spapr->arch_compat = CPU_POWERPC_LOGICAL_2_06;
+ break;
+ default:
+ perror("Unsupported mode, only are 205, 206 supported\n");
+ break;
+ }
+}
+
static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
{
int ret = 0, offset;
@@ -206,6 +227,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 +260,14 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment
*spapr)
if (ret < 0) {
return ret;
}
+
+ if (env->arch_compat) {
+ ret = fdt_setprop(fdt, offset, "cpu-version",
+ &env->arch_compat, sizeof(env->arch_compat));
+ if (ret < 0) {
+ return ret;
+ }
+ }
}
return ret;
}
@@ -1145,6 +1175,8 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
spapr = g_malloc0(sizeof(*spapr));
QLIST_INIT(&spapr->phbs);
+ spapr_compat_mode_init(spapr);
+
cpu_ppc_hypercall = emulate_spapr_hypercall;
/* Allocate RMA if necessary */
@@ -1226,6 +1258,14 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
xics_cpu_setup(spapr->icp, cpu);
+ /*
+ * If compat mode is set in the command line, pass it to CPU so KVM
+ * will be able to set it in the host kernel.
+ */
+ if (spapr->arch_compat) {
+ env->arch_compat = spapr->arch_compat;
+ }
+
qemu_register_reset(spapr_cpu_reset, cpu);
}
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index ca175b0..201c578 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -34,6 +34,8 @@ typedef struct sPAPREnvironment {
uint32_t epow_irq;
Notifier epow_notifier;
+ uint32_t arch_compat; /* Compatible PVR from the command line */
+
/* Migration state */
int htab_save_index;
bool htab_first_pass;
diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h
index 49ba4a4..d7c033c 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,
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 422a6bb..fc837c1 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -999,6 +999,9 @@ struct CPUPPCState {
/* Device control registers */
ppc_dcr_t *dcr_env;
+ /* Architecture compatibility mode */
+ uint32_t arch_compat;
+
int dcache_line_size;
int icache_line_size;
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 4bc4496..7b853a3 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -872,6 +872,7 @@ int kvm_arch_put_registers(CPUState *cs, int level)
DPRINTF("Warning: Unable to set VPA information to KVM\n");
}
}
+ kvm_set_one_reg(cs, KVM_REG_PPC_ARCH_COMPAT, &env->arch_compat);
#endif /* TARGET_PPC64 */
}
@@ -1083,6 +1084,7 @@ int kvm_arch_get_registers(CPUState *cs)
DPRINTF("Warning: Unable to get VPA information from KVM\n");
}
}
+ kvm_get_one_reg(cs, KVM_REG_PPC_ARCH_COMPAT, &env->arch_compat);
#endif
}
diff --git a/vl.c b/vl.c
index 4e709d5..90dad7b 100644
--- a/vl.c
+++ b/vl.c
@@ -427,6 +427,10 @@ static QemuOptsList qemu_machine_opts = {
.name = "usb",
.type = QEMU_OPT_BOOL,
.help = "Set on/off to enable/disable usb",
+ }, {
+ .name = "compat",
+ .type = QEMU_OPT_NUMBER,
+ .help = "Selects compatibility mode on CPU",
},
{ /* End of list */ }
},
--
1.8.4.rc4
- [Qemu-ppc] [PATCH] spapr: add "compat" machine option,
Alexey Kardashevskiy <=