The CPUs are now grouped in a TYPE_CPU_CLUSTER.
Reviewed-by: Pierrick Bouvier <[email protected]>
Link:
https://lore.kernel.org/qemu-devel/[email protected]
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