aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc/spapr_cpu_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/ppc/spapr_cpu_core.c')
-rw-r--r--hw/ppc/spapr_cpu_core.c55
1 files changed, 37 insertions, 18 deletions
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 4f316a6f9d..e7c9edd033 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -20,6 +20,7 @@
#include "target/ppc/kvm_ppc.h"
#include "hw/ppc/ppc.h"
#include "target/ppc/mmu-hash64.h"
+#include "target/ppc/power8-pmu.h"
#include "sysemu/numa.h"
#include "sysemu/reset.h"
#include "sysemu/hw_accel.h"
@@ -36,6 +37,15 @@ static void spapr_reset_vcpu(PowerPCCPU *cpu)
cpu_reset(cs);
+ /*
+ * "PowerPC Processor binding to IEEE 1275" defines the initial MSR state
+ * as 32bit (MSR_SF=0) with MSR_ME=1 and MSR_FP=1 in "8.2.1. Initial
+ * Register Values". This can also be found in "LoPAPR 1.1" "C.9.2.1
+ * Initial Register Values".
+ */
+ env->msr &= ~(1ULL << MSR_SF);
+ env->msr |= (1ULL << MSR_ME) | (1ULL << MSR_FP);
+
env->spr[SPR_HIOR] = 0;
lpcr = env->spr[SPR_LPCR];
@@ -68,6 +78,8 @@ static void spapr_reset_vcpu(PowerPCCPU *cpu)
kvm_check_mmu(cpu, &error_fatal);
+ cpu_ppc_tb_reset(env);
+
spapr_irq_cpu_intc_reset(spapr, cpu);
}
@@ -119,7 +131,7 @@ static const VMStateDescription vmstate_spapr_cpu_slb_shadow = {
.version_id = 1,
.minimum_version_id = 1,
.needed = slb_shadow_needed,
- .fields = (VMStateField[]) {
+ .fields = (const VMStateField[]) {
VMSTATE_UINT64(slb_shadow_addr, SpaprCpuState),
VMSTATE_UINT64(slb_shadow_size, SpaprCpuState),
VMSTATE_END_OF_LIST()
@@ -138,7 +150,7 @@ static const VMStateDescription vmstate_spapr_cpu_dtl = {
.version_id = 1,
.minimum_version_id = 1,
.needed = dtl_needed,
- .fields = (VMStateField[]) {
+ .fields = (const VMStateField[]) {
VMSTATE_UINT64(dtl_addr, SpaprCpuState),
VMSTATE_UINT64(dtl_size, SpaprCpuState),
VMSTATE_END_OF_LIST()
@@ -157,11 +169,11 @@ static const VMStateDescription vmstate_spapr_cpu_vpa = {
.version_id = 1,
.minimum_version_id = 1,
.needed = vpa_needed,
- .fields = (VMStateField[]) {
+ .fields = (const VMStateField[]) {
VMSTATE_UINT64(vpa_addr, SpaprCpuState),
VMSTATE_END_OF_LIST()
},
- .subsections = (const VMStateDescription * []) {
+ .subsections = (const VMStateDescription * const []) {
&vmstate_spapr_cpu_slb_shadow,
&vmstate_spapr_cpu_dtl,
NULL
@@ -172,10 +184,10 @@ static const VMStateDescription vmstate_spapr_cpu_state = {
.name = "spapr_cpu",
.version_id = 1,
.minimum_version_id = 1,
- .fields = (VMStateField[]) {
+ .fields = (const VMStateField[]) {
VMSTATE_END_OF_LIST()
},
- .subsections = (const VMStateDescription * []) {
+ .subsections = (const VMStateDescription * const []) {
&vmstate_spapr_cpu_vpa,
NULL
}
@@ -183,10 +195,13 @@ static const VMStateDescription vmstate_spapr_cpu_state = {
static void spapr_unrealize_vcpu(PowerPCCPU *cpu, SpaprCpuCore *sc)
{
+ CPUPPCState *env = &cpu->env;
+
if (!sc->pre_3_0_migration) {
vmstate_unregister(NULL, &vmstate_spapr_cpu_state, cpu->machine_data);
}
spapr_irq_cpu_intc_destroy(SPAPR_MACHINE(qdev_get_machine()), cpu);
+ cpu_ppc_tb_free(env);
qdev_unrealize(DEVICE(cpu));
}
@@ -234,8 +249,7 @@ static void spapr_cpu_core_unrealize(DeviceState *dev)
* spapr_cpu_core_realize(), make sure we only unrealize
* vCPUs that have already been realized.
*/
- if (object_property_get_bool(OBJECT(sc->threads[i]), "realized",
- &error_abort)) {
+ if (qdev_is_realized(DEVICE(sc->threads[i]))) {
spapr_unrealize_vcpu(sc->threads[i], sc);
}
spapr_delete_vcpu(sc->threads[i]);
@@ -246,7 +260,7 @@ static void spapr_cpu_core_unrealize(DeviceState *dev)
}
static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
- SpaprCpuCore *sc, Error **errp)
+ SpaprCpuCore *sc, int thread_index, Error **errp)
{
CPUPPCState *env = &cpu->env;
CPUState *cs = CPU(cpu);
@@ -255,12 +269,17 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
return false;
}
- /* Set time-base frequency to 512 MHz */
- cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
-
cpu_ppc_set_vhyp(cpu, PPC_VIRTUAL_HYPERVISOR(spapr));
kvmppc_set_papr(cpu);
+ env->spr_cb[SPR_PIR].default_value = cs->cpu_index;
+ env->spr_cb[SPR_TIR].default_value = thread_index;
+
+ cpu_ppc_set_1lpar(cpu);
+
+ /* Set time-base frequency to 512 MHz. vhyp must be set first. */
+ cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
+
if (spapr_irq_cpu_intc_create(spapr, cpu, errp) < 0) {
qdev_unrealize(DEVICE(cpu));
return false;
@@ -290,7 +309,7 @@ static PowerPCCPU *spapr_create_vcpu(SpaprCpuCore *sc, int i, Error **errp)
* All CPUs start halted. CPU0 is unhalted from the machine level reset code
* and the rest are explicitly started up by the guest using an RTAS call.
*/
- cs->start_powered_off = true;
+ qdev_prop_set_bit(DEVICE(obj), "start-powered-off", true);
cs->cpu_index = cc->core_id + i;
if (!spapr_set_vcpu_id(cpu, cs->cpu_index, errp)) {
return NULL;
@@ -328,7 +347,7 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
for (i = 0; i < cc->nr_threads; i++) {
sc->threads[i] = spapr_create_vcpu(sc, i, errp);
if (!sc->threads[i] ||
- !spapr_realize_vcpu(sc->threads[i], spapr, sc, errp)) {
+ !spapr_realize_vcpu(sc->threads[i], spapr, sc, i, errp)) {
spapr_cpu_core_unrealize(dev);
return;
}
@@ -373,15 +392,15 @@ static const TypeInfo spapr_cpu_core_type_infos[] = {
DEFINE_SPAPR_CPU_CORE_TYPE("970_v2.2"),
DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.0"),
DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.1"),
- DEFINE_SPAPR_CPU_CORE_TYPE("power5+_v2.1"),
+ DEFINE_SPAPR_CPU_CORE_TYPE("power5p_v2.1"),
DEFINE_SPAPR_CPU_CORE_TYPE("power7_v2.3"),
- DEFINE_SPAPR_CPU_CORE_TYPE("power7+_v2.1"),
+ DEFINE_SPAPR_CPU_CORE_TYPE("power7p_v2.1"),
DEFINE_SPAPR_CPU_CORE_TYPE("power8_v2.0"),
DEFINE_SPAPR_CPU_CORE_TYPE("power8e_v2.1"),
DEFINE_SPAPR_CPU_CORE_TYPE("power8nvl_v1.0"),
- DEFINE_SPAPR_CPU_CORE_TYPE("power9_v1.0"),
DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.0"),
- DEFINE_SPAPR_CPU_CORE_TYPE("power10_v1.0"),
+ DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.2"),
+ DEFINE_SPAPR_CPU_CORE_TYPE("power10_v2.0"),
#ifdef CONFIG_KVM
DEFINE_SPAPR_CPU_CORE_TYPE("host"),
#endif