@@ -820,9 +820,9 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
PowerPCCPU *cpu;
CPUState *cs;
qemu_irq *input;
- cpu = cpu_ppc_init(machine->cpu_model);
+ cpu = ppc_cpu_init(machine->cpu_model, NULL);
if (cpu == NULL) {
fprintf(stderr, "Unable to initialize CPU!\n");
exit(1);
}
@@ -192,9 +192,9 @@ static void ppc_core99_init(MachineState *machine)
machine->cpu_model = "G4";
#endif
}
for (i = 0; i < smp_cpus; i++) {
- cpu = cpu_ppc_init(machine->cpu_model);
+ cpu = ppc_cpu_init(machine->cpu_model, NULL);
if (cpu == NULL) {
fprintf(stderr, "Unable to find PowerPC CPU definition\n");
exit(1);
}
@@ -112,9 +112,9 @@ static void ppc_heathrow_init(MachineState *machine)
/* init CPUs */
if (machine->cpu_model == NULL)
machine->cpu_model = "G3";
for (i = 0; i < smp_cpus; i++) {
- cpu = cpu_ppc_init(machine->cpu_model);
+ cpu = ppc_cpu_init(machine->cpu_model, NULL);
if (cpu == NULL) {
fprintf(stderr, "Unable to find PowerPC CPU definition\n");
exit(1);
}
@@ -36,8 +36,9 @@
#include "hw/loader.h"
#include "sysemu/kvm.h"
#include "kvm_ppc.h"
#include "trace.h"
+#include "qapi/error.h"
//#define PPC_DEBUG_IRQ
//#define PPC_DEBUG_TB
@@ -1349,4 +1350,63 @@ PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id)
}
return NULL;
}
+
+void ppc_cpu_compute_dt_id_generic(PowerPCCPU *cpu, Error **errp)
+{
+ CPUState *cs = CPU(cpu);
+ int max_smt = kvm_enabled() ? kvmppc_smt_threads() : 1;
+
+ if (smp_threads > max_smt) {
+ error_setg(errp, "Cannot support more than %d threads on PPC with %s",
+ max_smt, kvm_enabled() ? "KVM" : "TCG");
+ return;
+ }
+ if (!is_power_of_2(smp_threads)) {
+ error_setg(errp, "Cannot support %d threads on PPC with %s, "
+ "threads count must be a power of 2.",
+ smp_threads, kvm_enabled() ? "KVM" : "TCG");
+ return;
+ }
+
+ if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu->cpu_dt_id)) {
+ error_setg(errp, "Can't create CPU with id %d in KVM", cpu->cpu_dt_id);
+ error_append_hint(errp, "Adjust the number of cpus to %d "
+ "or try to raise the number of threads per core\n",
+ cpu->cpu_dt_id * smp_threads / max_smt);
+ return;
+ }
+
+ cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
+ + (cs->cpu_index % smp_threads);
+}
+
+PowerPCCPU *ppc_cpu_init(const char *cpu_model, cpu_compute_dt_id_fn compute_fn)
+{
+ PowerPCCPU *cpu;
+ Error *err = NULL;
+
+ cpu = POWERPC_CPU(cpu_generic_init_no_realize(TYPE_POWERPC_CPU, cpu_model));
+ if (cpu == NULL) {
+ return NULL;
+ }
+
+ if (compute_fn) {
+ compute_fn(cpu, &err);
+ } else {
+ ppc_cpu_compute_dt_id_generic(cpu, &err);
+ }
+ if (err != NULL) {
+ goto out;
+ }
+
+ object_property_set_bool(OBJECT(cpu), true, "realized", &err);
+out:
+ if (err != NULL) {
+ error_report_err(err);
+ object_unref(OBJECT(cpu));
+ return NULL;
+ }
+
+ return cpu;
+}
@@ -185,9 +185,9 @@ static void bamboo_init(MachineState *machine)
/* Setup CPU. */
if (machine->cpu_model == NULL) {
machine->cpu_model = "440EP";
}
- cpu = cpu_ppc_init(machine->cpu_model);
+ cpu = ppc_cpu_init(machine->cpu_model, NULL);
if (cpu == NULL) {
fprintf(stderr, "Unable to initialize CPU!\n");
exit(1);
}
@@ -55,9 +55,9 @@ PowerPCCPU *ppc4xx_init(const char *cpu_model,
PowerPCCPU *cpu;
CPUPPCState *env;
/* init CPUs */
- cpu = cpu_ppc_init(cpu_model);
+ cpu = ppc_cpu_init(cpu_model, NULL);
if (cpu == NULL) {
fprintf(stderr, "Unable to find PowerPC %s CPU definition\n",
cpu_model);
exit(1);
@@ -508,9 +508,9 @@ static void ppc_prep_init(MachineState *machine)
/* init CPUs */
if (machine->cpu_model == NULL)
machine->cpu_model = "602";
for (i = 0; i < smp_cpus; i++) {
- cpu = cpu_ppc_init(machine->cpu_model);
+ cpu = ppc_cpu_init(machine->cpu_model, NULL);
if (cpu == NULL) {
fprintf(stderr, "Unable to find PowerPC CPU definition\n");
exit(1);
}
@@ -1834,9 +1834,9 @@ static void ppc_spapr_init(MachineState *machine)
}
g_free(type);
} else {
for (i = 0; i < smp_cpus; i++) {
- PowerPCCPU *cpu = cpu_ppc_init(machine->cpu_model);
+ PowerPCCPU *cpu = ppc_cpu_init(machine->cpu_model, NULL);
if (cpu == NULL) {
error_report("Unable to find PowerPC CPU definition");
exit(1);
}
@@ -12,8 +12,9 @@
#include "hw/ppc/spapr.h"
#include "hw/boards.h"
#include "qapi/error.h"
#include <sysemu/cpus.h>
+#include <sysemu/kvm.h>
#include "target-ppc/kvm_ppc.h"
#include "hw/ppc/ppc.h"
#include "target-ppc/mmu-hash64.h"
#include <sysemu/numa.h>
@@ -265,8 +266,14 @@ static int spapr_cpu_core_realize_child(Object *child, void *opaque)
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
CPUState *cs = CPU(child);
PowerPCCPU *cpu = POWERPC_CPU(cs);
+ ppc_cpu_compute_dt_id_generic(cpu, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return 1;
+ }
+
object_property_set_bool(child, true, "realized", &local_err);
if (local_err) {
error_propagate(errp, local_err);
return 1;
@@ -95,9 +95,9 @@ static PowerPCCPU *ppc440_init_xilinx(ram_addr_t *ram_size,
PowerPCCPU *cpu;
CPUPPCState *env;
qemu_irq *irqs;
- cpu = cpu_ppc_init(cpu_model);
+ cpu = ppc_cpu_init(cpu_model, NULL);
if (cpu == NULL) {
fprintf(stderr, "Unable to initialize CPU!\n");
exit(1);
}
@@ -105,5 +105,9 @@ enum {
/* ppc_booke.c */
void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags);
+typedef void (*cpu_compute_dt_id_fn)(PowerPCCPU *cpu, Error **errp);
+PowerPCCPU *ppc_cpu_init(const char *cpu_model,
+ cpu_compute_dt_id_fn compute_fn);
+void ppc_cpu_compute_dt_id_generic(PowerPCCPU *cpu, Error **errp);
#endif
@@ -9522,45 +9522,15 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
CPUState *cs = CPU(dev);
PowerPCCPU *cpu = POWERPC_CPU(dev);
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
Error *local_err = NULL;
-#if !defined(CONFIG_USER_ONLY)
- int max_smt = kvm_enabled() ? kvmppc_smt_threads() : 1;
-#endif
-
-#if !defined(CONFIG_USER_ONLY)
- if (smp_threads > max_smt) {
- error_setg(errp, "Cannot support more than %d threads on PPC with %s",
- max_smt, kvm_enabled() ? "KVM" : "TCG");
- return;
- }
- if (!is_power_of_2(smp_threads)) {
- error_setg(errp, "Cannot support %d threads on PPC with %s, "
- "threads count must be a power of 2.",
- smp_threads, kvm_enabled() ? "KVM" : "TCG");
- return;
- }
-#endif
cpu_exec_realize(cs, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
return;
}
-#if !defined(CONFIG_USER_ONLY)
- cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
- + (cs->cpu_index % smp_threads);
-
- if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu->cpu_dt_id)) {
- error_setg(errp, "Can't create CPU with id %d in KVM", cpu->cpu_dt_id);
- error_append_hint(errp, "Adjust the number of cpus to %d "
- "or try to raise the number of threads per core\n",
- cpu->cpu_dt_id * smp_threads / max_smt);
- return;
- }
-#endif
-
if (tcg_enabled()) {
if (ppc_fixup_cpu(cpu) != 0) {
error_setg(errp, "Unable to emulate selected CPU with TCG");
return;
Now that cpu_index is computed at cpu initialization time, we can compute cpu_dt_id in the machine code. All the logic moves from ppc_cpu_realizefn() to a generic function in the machine code, that serves as the default for all machine types. A new ppc_cpu_init() helper is also added to be used instead of the current cpu_ppc_init() from the target code. It allows each machine type to use the default numbering logic or to provide its own one, which will be called just before realizing the cpu. This has no impact on user mode since all of this is for system mode only. Signed-off-by: Greg Kurz <groug@kaod.org> --- hw/ppc/e500.c | 2 + hw/ppc/mac_newworld.c | 2 + hw/ppc/mac_oldworld.c | 2 + hw/ppc/ppc.c | 60 +++++++++++++++++++++++++++++++++++++++++++ hw/ppc/ppc440_bamboo.c | 2 + hw/ppc/ppc4xx_devs.c | 2 + hw/ppc/prep.c | 2 + hw/ppc/spapr.c | 2 + hw/ppc/spapr_cpu_core.c | 7 +++++ hw/ppc/virtex_ml507.c | 2 + include/hw/ppc/ppc.h | 4 +++ target-ppc/translate_init.c | 30 ---------------------- 12 files changed, 79 insertions(+), 38 deletions(-)