diff mbox

[v4,2/5] ppc: parse cpu features once

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

Commit Message

Greg Kurz July 12, 2016, 12:12 p.m. UTC
Considering that features are converted to global properties and
global properties are automatically applied to every new instance
of created CPU (at object_new() time), there is no point in
parsing cpu_model string every time a CPU created. So move
parsing outside CPU creation loop and do it only once.

Parsing also should be done before any CPU is created so that
features would affect the first CPU a well.

This patch does that for all PowerPC machine types.

It is based on previous work from Bharata:

https://lists.nongnu.org/archive/html/qemu-devel/2016-06/msg07564.html

Signed-off-by: Greg Kurz <groug@kaod.org>
---
 hw/ppc/e500.c          |    2 ++
 hw/ppc/mac_newworld.c  |    1 +
 hw/ppc/mac_oldworld.c  |    1 +
 hw/ppc/ppc.c           |   26 ++++++++++++++++++++++++++
 hw/ppc/ppc440_bamboo.c |    1 +
 hw/ppc/ppc4xx_devs.c   |    1 +
 hw/ppc/prep.c          |    1 +
 hw/ppc/spapr.c         |    2 ++
 hw/ppc/virtex_ml507.c  |    1 +
 include/hw/ppc/ppc.h   |    1 +
 10 files changed, 37 insertions(+)
diff mbox

Patch

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index ff5d92e48dd9..b9221cc2c14a 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -814,6 +814,8 @@  void ppce500_init(MachineState *machine, PPCE500Params *params)
         machine->cpu_model = "e500v2_v30";
     }
 
+    ppc_cpu_parse_features(machine->cpu_model);
+
     irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
     irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
     for (i = 0; i < smp_cpus; i++) {
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index ecd40914be45..366089085844 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -192,6 +192,7 @@  static void ppc_core99_init(MachineState *machine)
         machine->cpu_model = "G4";
 #endif
     }
+    ppc_cpu_parse_features(machine->cpu_model);
     for (i = 0; i < smp_cpus; i++) {
         cpu = ppc_cpu_init(machine->cpu_model);
         if (cpu == NULL) {
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 77fbdfffd4e2..5c2dc53cb584 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -112,6 +112,7 @@  static void ppc_heathrow_init(MachineState *machine)
     /* init CPUs */
     if (machine->cpu_model == NULL)
         machine->cpu_model = "G3";
+    ppc_cpu_parse_features(machine->cpu_model);
     for (i = 0; i < smp_cpus; i++) {
         cpu = ppc_cpu_init(machine->cpu_model);
         if (cpu == NULL) {
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index dc3d214009c5..313b3f0b9a51 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -33,6 +33,7 @@ 
 #include "hw/timer/m48t59.h"
 #include "qemu/log.h"
 #include "qemu/error-report.h"
+#include "qapi/error.h"
 #include "hw/loader.h"
 #include "sysemu/kvm.h"
 #include "kvm_ppc.h"
@@ -1355,3 +1356,28 @@  PowerPCCPU *ppc_cpu_init(const char *cpu_model)
 {
     return POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU, cpu_model));
 }
+
+void ppc_cpu_parse_features(const char *cpu_model)
+{
+    CPUClass *cc;
+    ObjectClass *oc;
+    const char *typename;
+    gchar **model_pieces;
+
+    model_pieces = g_strsplit(cpu_model, ",", 2);
+    if (!model_pieces[0]) {
+        error_report("Invalid/empty CPU model name");
+        exit(1);
+    }
+
+    oc = cpu_class_by_name(TYPE_POWERPC_CPU, model_pieces[0]);
+    if (oc == NULL) {
+        error_report("Unable to find CPU definition: %s", model_pieces[0]);
+        exit(1);
+    }
+
+    typename = object_class_get_name(oc);
+    cc = CPU_CLASS(oc);
+    cc->parse_features(typename, model_pieces[1], &error_fatal);
+    g_strfreev(model_pieces);
+}
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 7f22433c8e91..709a779cba7e 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -186,6 +186,7 @@  static void bamboo_init(MachineState *machine)
     if (machine->cpu_model == NULL) {
         machine->cpu_model = "440EP";
     }
+    ppc_cpu_parse_features(machine->cpu_model);
     cpu = ppc_cpu_init(machine->cpu_model);
     if (cpu == NULL) {
         fprintf(stderr, "Unable to initialize CPU!\n");
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index d48b61f04910..8cbe50361e86 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -56,6 +56,7 @@  PowerPCCPU *ppc4xx_init(const char *cpu_model,
     CPUPPCState *env;
 
     /* init CPUs */
+    ppc_cpu_parse_features(cpu_model);
     cpu = ppc_cpu_init(cpu_model);
     if (cpu == NULL) {
         fprintf(stderr, "Unable to find PowerPC %s CPU definition\n",
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index e62fe643f492..99409a09f0ef 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -508,6 +508,7 @@  static void ppc_prep_init(MachineState *machine)
     /* init CPUs */
     if (machine->cpu_model == NULL)
         machine->cpu_model = "602";
+    ppc_cpu_parse_features(machine->cpu_model);
     for (i = 0; i < smp_cpus; i++) {
         cpu = ppc_cpu_init(machine->cpu_model);
         if (cpu == NULL) {
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index d134eb2f338e..658ccee799c0 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1803,6 +1803,8 @@  static void ppc_spapr_init(MachineState *machine)
         machine->cpu_model = kvm_enabled() ? "host" : "POWER7";
     }
 
+    ppc_cpu_parse_features(machine->cpu_model);
+
     if (smc->dr_cpu_enabled) {
         char *type = spapr_get_cpu_core_type(machine->cpu_model);
 
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 7e4445b6879a..a19dd17addda 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -96,6 +96,7 @@  static PowerPCCPU *ppc440_init_xilinx(ram_addr_t *ram_size,
     CPUPPCState *env;
     qemu_irq *irqs;
 
+    ppc_cpu_parse_features(cpu_model);
     cpu = ppc_cpu_init(cpu_model);
     if (cpu == NULL) {
         fprintf(stderr, "Unable to initialize CPU!\n");
diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
index a4db1db82e1b..2ed063e09bec 100644
--- a/include/hw/ppc/ppc.h
+++ b/include/hw/ppc/ppc.h
@@ -107,4 +107,5 @@  enum {
 void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags);
 
 PowerPCCPU *ppc_cpu_init(const char *cpu_model);
+void ppc_cpu_parse_features(const char *cpu_model);
 #endif