diff mbox

[8/8] hw/ppc: move DT cpu id generation to machine code

Message ID 146723351048.9665.9665959488204905423.stgit@bahia.lan (mailing list archive)
State New, archived
Headers show

Commit Message

Greg Kurz June 29, 2016, 8:51 p.m. UTC
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(-)
diff mbox

Patch

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 0cd534df55f8..a8153448c4d4 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -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);
         }
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 32e88b378687..5d4c28cdb5b2 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -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);
         }
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 447948746b1a..3ebabd7f203b 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -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);
         }
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index e4252528a69d..c234b7adfd43 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -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;
+}
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 5c535b18a20d..c5ea15b1f732 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -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);
     }
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index e7f413e49d08..b28bca1b797b 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -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);
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 054af1e8b481..1bd3ede62114 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -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);
         }
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 0771c93f6550..040c9158cce4 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -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);
             }
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index a15dc010626d..56f360cb6c7f 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -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;
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index b97d96685cf1..cf3e71b9f2cc 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -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);
     }
diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
index 5617dc4a2c04..3e6aa7e7720f 100644
--- a/include/hw/ppc/ppc.h
+++ b/include/hw/ppc/ppc.h
@@ -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
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index f7571f34d6ac..f9d1ee8b12f9 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -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;