qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC PATCH v3 11/24] ppc: Create sockets and cores for CPUs


From: Bharata B Rao
Subject: [Qemu-devel] [RFC PATCH v3 11/24] ppc: Create sockets and cores for CPUs
Date: Fri, 24 Apr 2015 12:17:33 +0530

ppc machine init functions create individual CPU threads. Change this
for sPAPR by switching to socket creation. CPUs are created recursively
by socket and core instance init routines.

TODO: Switching to socket level CPU creation is done only for sPAPR
target now.

Signed-off-by: Bharata B Rao <address@hidden>
---
 hw/ppc/cpu-core.c           | 19 +++++++++++++++++++
 hw/ppc/cpu-socket.c         | 21 +++++++++++++++++++++
 hw/ppc/spapr.c              | 17 ++++++++++-------
 target-ppc/cpu.h            |  1 +
 target-ppc/translate_init.c | 46 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 97 insertions(+), 7 deletions(-)

diff --git a/hw/ppc/cpu-core.c b/hw/ppc/cpu-core.c
index ed0481f..f257495 100644
--- a/hw/ppc/cpu-core.c
+++ b/hw/ppc/cpu-core.c
@@ -7,6 +7,9 @@
 
 #include "hw/qdev.h"
 #include "hw/ppc/cpu-core.h"
+#include "hw/boards.h"
+#include <sysemu/cpus.h>
+#include <sysemu/sysemu.h>
 
 static int ppc_cpu_core_realize_child(Object *child, void *opaque)
 {
@@ -32,10 +35,26 @@ static void ppc_cpu_core_class_init(ObjectClass *oc, void 
*data)
     dc->realize = ppc_cpu_core_realize;
 }
 
+static void ppc_cpu_core_instance_init(Object *obj)
+{
+    int i;
+    PowerPCCPU *cpu = NULL;
+    MachineState *machine = MACHINE(qdev_get_machine());
+    int threads_per_core = (smp_cpus > smp_threads) ? smp_threads : smp_cpus;
+
+    for (i = 0; i < threads_per_core; i++) {
+        cpu = POWERPC_CPU(cpu_ppc_create(TYPE_POWERPC_CPU, 
machine->cpu_model));
+        object_property_add_child(obj, "thread[*]", OBJECT(cpu), &error_abort);
+        object_unref(OBJECT(cpu));
+    }
+}
+
 static const TypeInfo ppc_cpu_core_type_info = {
     .name = TYPE_POWERPC_CPU_CORE,
     .parent = TYPE_DEVICE,
     .class_init = ppc_cpu_core_class_init,
+    .instance_init = ppc_cpu_core_instance_init,
+    .instance_size = sizeof(PowerPCCPUCore),
 };
 
 static void ppc_cpu_core_register_types(void)
diff --git a/hw/ppc/cpu-socket.c b/hw/ppc/cpu-socket.c
index 602a060..af8c35f 100644
--- a/hw/ppc/cpu-socket.c
+++ b/hw/ppc/cpu-socket.c
@@ -8,6 +8,9 @@
 #include "hw/qdev.h"
 #include "hw/ppc/cpu-socket.h"
 #include "sysemu/cpus.h"
+#include "sysemu/sysemu.h"
+#include "qemu/config-file.h"
+#include "cpu.h"
 
 static int ppc_cpu_socket_realize_child(Object *child, void *opaque)
 {
@@ -33,10 +36,28 @@ static void ppc_cpu_socket_class_init(ObjectClass *oc, void 
*data)
     dc->realize = ppc_cpu_socket_realize;
 }
 
+static void ppc_cpu_socket_instance_init(Object *obj)
+{
+    int i;
+    Object *core;
+    QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
+    int sockets = opts ? qemu_opt_get_number(opts, "sockets", 0) : 0;
+    int cores = (smp_cpus/smp_threads) ? smp_cpus/smp_threads : 1;
+
+    sockets = sockets ? sockets : cores;
+    for (i = 0; i < cores/sockets; i++) {
+        core = object_new(TYPE_POWERPC_CPU_CORE);
+        object_property_add_child(obj, "core[*]", core, &error_abort);
+        object_unref(core);
+    }
+}
+
 static const TypeInfo ppc_cpu_socket_type_info = {
     .name = TYPE_POWERPC_CPU_SOCKET,
     .parent = TYPE_CPU_SOCKET,
     .class_init = ppc_cpu_socket_class_init,
+    .instance_init = ppc_cpu_socket_instance_init,
+    .instance_size = sizeof(PowerPCCPUSocket),
 };
 
 static void ppc_cpu_socket_register_types(void)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 8cc55fe..b526b7d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -37,6 +37,7 @@
 #include "mmu-hash64.h"
 #include "qom/cpu.h"
 
+#include "hw/ppc/cpu-socket.h"
 #include "hw/boards.h"
 #include "hw/ppc/ppc.h"
 #include "hw/loader.h"
@@ -1477,7 +1478,6 @@ static void ppc_spapr_init(MachineState *machine)
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
     const char *boot_device = machine->boot_order;
-    PowerPCCPU *cpu;
     PCIHostState *phb;
     int i;
     MemoryRegion *sysmem = get_system_memory();
@@ -1492,7 +1492,12 @@ static void ppc_spapr_init(MachineState *machine)
     bool kernel_le = false;
     char *filename;
     int smt = kvmppc_smt_threads();
+    Object *socket;
+    QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
+    int sockets = opts ? qemu_opt_get_number(opts, "sockets", 0) : 0;
+    int cores = (smp_cpus/smp_threads) ? smp_cpus/smp_threads : 1;
 
+    sockets = sockets ? sockets : cores;
     msi_supported = true;
 
     spapr = g_malloc0(sizeof(*spapr));
@@ -1569,12 +1574,10 @@ static void ppc_spapr_init(MachineState *machine)
     if (machine->cpu_model == NULL) {
         machine->cpu_model = kvm_enabled() ? "host" : "POWER7";
     }
-    for (i = 0; i < smp_cpus; i++) {
-        cpu = cpu_ppc_init(machine->cpu_model);
-        if (cpu == NULL) {
-            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
-            exit(1);
-        }
+
+    for (i = 0; i < sockets; i++) {
+        socket = object_new(TYPE_POWERPC_CPU_SOCKET);
+        object_property_set_bool(socket, true, "realized", &error_abort);
     }
 
     /* allocate RAM */
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index abc3545..f15cc2c 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1162,6 +1162,7 @@ do {                                            \
 
 /*****************************************************************************/
 PowerPCCPU *cpu_ppc_init(const char *cpu_model);
+CPUState *cpu_ppc_create(const char *typename, const char *cpu_model);
 void ppc_translate_init(void);
 void gen_update_current_nip(void *opaque);
 int cpu_ppc_exec (CPUPPCState *s);
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index d74f4f0..a8716cf 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -9365,6 +9365,52 @@ static ObjectClass *ppc_cpu_class_by_name(const char 
*name)
     return NULL;
 }
 
+/*
+ * This is essentially same as cpu_generic_init() but without a set
+ * realize call.
+ */
+CPUState *cpu_ppc_create(const char *typename, const char *cpu_model)
+{
+    char *str, *name, *featurestr;
+    CPUState *cpu;
+    ObjectClass *oc;
+    CPUClass *cc;
+    Error *err = NULL;
+
+    str = g_strdup(cpu_model);
+    name = strtok(str, ",");
+
+    oc = cpu_class_by_name(typename, name);
+    if (oc == NULL) {
+        g_free(str);
+        return NULL;
+    }
+
+    cpu = CPU(object_new(object_class_get_name(oc)));
+    cc = CPU_GET_CLASS(cpu);
+
+    featurestr = strtok(NULL, ",");
+    cc->parse_features(cpu, featurestr, &err);
+    g_free(str);
+    if (err != NULL) {
+        goto out;
+    }
+
+out:
+    if (err != NULL) {
+        error_report("%s", error_get_pretty(err));
+        error_free(err);
+        object_unref(OBJECT(cpu));
+        return NULL;
+    }
+
+    return cpu;
+}
+
+/*
+ * TODO: This can be removed when all powerpc targets are converted to
+ * socket level CPU realization.
+ */
 PowerPCCPU *cpu_ppc_init(const char *cpu_model)
 {
     return POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU, cpu_model));
-- 
2.1.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]