[PATCH v4 05/18] hw/hexagon: group the CPUs in a cluster

Brian Cain <[email protected]>
Newsgroups gmane.comp.emulators.qemu
Message-ID <[email protected]>
The CPUs are now grouped in a TYPE_CPU_CLUSTER.

Signed-off-by: Brian Cain <[email protected]>
---
 include/hw/hexagon/hex-subsys.h | 12 +++++++++++-
 include/hw/hexagon/hexagon.h    |  1 +
 hw/hexagon/hex-subsys.c         | 30 +++++++++++++++++++++++++++++-
 hw/hexagon/hexagon_dsp.c        | 11 ++++++++++-
 hw/hexagon/virt.c               | 11 ++++++++++-
 hw/hexagon/Kconfig              |  1 +
 6 files changed, 62 insertions(+), 4 deletions(-)

diff --git a/include/hw/hexagon/hex-subsys.h b/include/hw/hexagon/hex-subsys.h
index 087c105cfa4..6d0d5e1da86 100644
--- a/include/hw/hexagon/hex-subsys.h
+++ b/include/hw/hexagon/hex-subsys.h
@@ -15,7 +15,17 @@
 void hex_subsys_create(HexagonCommonMachineState *hms,
                        const struct hexagon_machine_config *m_cfg, Rev_t rev);
 
-/* Realize a CPU into the subsystem. */
+/*
+ * Parent a CPU into the subsystem's cluster and wire its links.  Call for
+ * every CPU before hex_subsys_realize_cluster(), then realize each CPU with
+ * hex_subsys_realize_cpu().
+ */
+void hex_subsys_add_cpu(HexagonCommonMachineState *hms, DeviceState *cpu);
+
+/* Realize the CPU cluster, once all CPUs have been parented into it. */
+void hex_subsys_realize_cluster(HexagonCommonMachineState *hms);
+
+/* Realize a CPU previously parented via hex_subsys_add_cpu(). */
 void hex_subsys_realize_cpu(HexagonCommonMachineState *hms, DeviceState *cpu);
 
 #endif /* HW_HEXAGON_HEX_SUBSYS_H */
diff --git a/include/hw/hexagon/hexagon.h b/include/hw/hexagon/hexagon.h
index 6edd93f478a..31669a829f8 100644
--- a/include/hw/hexagon/hexagon.h
+++ b/include/hw/hexagon/hexagon.h
@@ -157,6 +157,7 @@ struct HexagonCommonMachineState {
     MemoryRegion ram;
     MemoryRegion cfgtable_rom;
     MemoryRegion vtcm;
+    DeviceState *cluster;
     DeviceState *glob_regs;
     DeviceState *tlb;
 };
diff --git a/hw/hexagon/hex-subsys.c b/hw/hexagon/hex-subsys.c
index ac7e29604eb..6fad6fe0a4d 100644
--- a/hw/hexagon/hex-subsys.c
+++ b/hw/hexagon/hex-subsys.c
@@ -10,6 +10,7 @@
 #include "hw/hexagon/hex-subsys.h"
 #include "hw/hexagon/hexagon_globalreg.h"
 #include "hw/hexagon/hexagon_tlb.h"
+#include "hw/cpu/cluster.h"
 #include "hw/core/loader.h"
 #include "hw/core/qdev-properties.h"
 #include "hw/core/qdev.h"
@@ -42,6 +43,16 @@ static DeviceState *tlb_create(HexagonCommonMachineState *hms,
     return tlb;
 }
 
+static DeviceState *cluster_create(HexagonCommonMachineState *hms)
+{
+    DeviceState *cluster = qdev_new(TYPE_CPU_CLUSTER);
+
+    object_property_add_child(OBJECT(hms), "cluster", OBJECT(cluster));
+    qdev_prop_set_uint32(cluster, "cluster-id", 0);
+
+    return cluster;
+}
+
 void hex_subsys_create(HexagonCommonMachineState *hms,
                        const struct hexagon_machine_config *m_cfg, Rev_t rev)
 {
@@ -69,15 +80,32 @@ void hex_subsys_create(HexagonCommonMachineState *hms,
                                     &hms->vtcm);
     }
 
+    hms->cluster = cluster_create(hms);
     hms->glob_regs = globalreg_create(hms, m_cfg, rev);
     hms->tlb = tlb_create(hms, m_cfg);
 }
 
-void hex_subsys_realize_cpu(HexagonCommonMachineState *hms, DeviceState *cpu)
+void hex_subsys_add_cpu(HexagonCommonMachineState *hms, DeviceState *cpu)
 {
+    object_property_add_child(OBJECT(hms->cluster), "cpu[*]", OBJECT(cpu));
     object_property_set_link(OBJECT(cpu), "global-regs",
                              OBJECT(hms->glob_regs), &error_fatal);
     object_property_set_link(OBJECT(cpu), "tlb", OBJECT(hms->tlb),
                              &error_fatal);
+}
+
+void hex_subsys_realize_cluster(HexagonCommonMachineState *hms)
+{
+    /*
+     * The cluster must be realized after its CPUs have been parented into it
+     * (see hex_subsys_add_cpu()) but before any CPU is itself realized, since
+     * qdev_realize_and_unref() on a CPU latches cluster_index into the TCG
+     * cflags at that point.
+     */
+    qdev_realize_and_unref(hms->cluster, NULL, &error_fatal);
+}
+
+void hex_subsys_realize_cpu(HexagonCommonMachineState *hms, DeviceState *cpu)
+{
     qdev_realize_and_unref(cpu, NULL, &error_fatal);
 }
diff --git a/hw/hexagon/hexagon_dsp.c b/hw/hexagon/hexagon_dsp.c
index 25e8550fba2..1db5d681665 100644
--- a/hw/hexagon/hexagon_dsp.c
+++ b/hw/hexagon/hexagon_dsp.c
@@ -118,6 +118,8 @@ static void hexagon_common_init(MachineState *machine, Rev_t rev,
 
     hex_subsys_create(hms, m_cfg, rev);
 
+    g_autofree HexagonCPU **cpus = g_new(HexagonCPU *, machine->smp.cpus);
+
     for (int i = 0; i < machine->smp.cpus; i++) {
         HexagonCPU *cpu = HEXAGON_CPU(object_new(machine->cpu_type));
         qemu_register_reset(do_cpu_reset, cpu);
@@ -130,7 +132,14 @@ static void hexagon_common_init(MachineState *machine, Rev_t rev,
         if (i == 0) {
             hexagon_init_bootstrap(dms, cpu);
         }
-        hex_subsys_realize_cpu(hms, DEVICE(cpu));
+        hex_subsys_add_cpu(hms, DEVICE(cpu));
+        cpus[i] = cpu;
+    }
+
+    hex_subsys_realize_cluster(hms);
+
+    for (int i = 0; i < machine->smp.cpus; i++) {
+        hex_subsys_realize_cpu(hms, DEVICE(cpus[i]));
     }
 }
 
diff --git a/hw/hexagon/virt.c b/hw/hexagon/virt.c
index b9e0bbb704c..dc1d5b6aa24 100644
--- a/hw/hexagon/virt.c
+++ b/hw/hexagon/virt.c
@@ -246,6 +246,8 @@ static void virt_init(MachineState *ms)
 
     fdt_add_hvx(vms, m_cfg);
 
+    g_autofree HexagonCPU **cpus = g_new(HexagonCPU *, ms->smp.cpus);
+
     for (int i = 0; i < ms->smp.cpus; i++) {
         HexagonCPU *cpu = HEXAGON_CPU(object_new(ms->cpu_type));
         qemu_register_reset(do_cpu_reset, cpu);
@@ -261,7 +263,14 @@ static void virt_init(MachineState *ms)
         }
         qdev_prop_set_uint32(DEVICE(cpu), "htid", i);
         qdev_prop_set_bit(DEVICE(cpu), "start-powered-off", (i != 0));
-        hex_subsys_realize_cpu(&vms->parent_obj, DEVICE(cpu));
+        hex_subsys_add_cpu(&vms->parent_obj, DEVICE(cpu));
+        cpus[i] = cpu;
+    }
+
+    hex_subsys_realize_cluster(&vms->parent_obj);
+
+    for (int i = 0; i < ms->smp.cpus; i++) {
+        hex_subsys_realize_cpu(&vms->parent_obj, DEVICE(cpus[i]));
     }
 
     fdt_add_cpu_nodes(vms);
diff --git a/hw/hexagon/Kconfig b/hw/hexagon/Kconfig
index 52065ab3b22..121c548bbb9 100644
--- a/hw/hexagon/Kconfig
+++ b/hw/hexagon/Kconfig
@@ -2,6 +2,7 @@ config HEX_DSP
     bool
     default y
     depends on HEXAGON
+    select CPU_CLUSTER
 
 config HEX_VIRT
     bool
-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.