hw/hexagon: group the CPUs in a cluster
The CPUs are now grouped in a TYPE_CPU_CLUSTER. Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Link: https://lore.kernel.org/qemu-devel/20260806042723.3785369-6-brian.cain@oss.qualcomm.com Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Brian Cain committed
Aug 5, 2026 at 21:27 UTC
d33ec047c30d28c883cac0eaa4a7c9168cd81a5f
6 files changed
+62
-4
hw/hexagon/Kconfig
+1
@@ -2,6 +2,7 @@ config HEX_DSP
2
bool
3
default y
4
depends on HEXAGON
5
+ select CPU_CLUSTER
6
7
config HEX_VIRT
8
bool
hw/hexagon/hex-subsys.c
+29
-1
@@ -10,6 +10,7 @@
10
#include "hw/hexagon/hex-subsys.h"
11
#include "hw/hexagon/hexagon_globalreg.h"
12
#include "hw/hexagon/hexagon_tlb.h"
13
+#include "hw/cpu/cluster.h"
14
#include "hw/core/loader.h"
15
#include "hw/core/qdev-properties.h"
16
#include "hw/core/qdev.h"
@@ -42,6 +43,16 @@ static DeviceState *tlb_create(HexagonCommonMachineState *hms,
43
return tlb;
44
}
45
46
+static DeviceState *cluster_create(HexagonCommonMachineState *hms)
47
+{
48
+ DeviceState *cluster = qdev_new(TYPE_CPU_CLUSTER);
49
+
50
+ object_property_add_child(OBJECT(hms), "cluster", OBJECT(cluster));
51
+ qdev_prop_set_uint32(cluster, "cluster-id", 0);
52
+
53
+ return cluster;
54
+}
55
+
56
void hex_subsys_create(HexagonCommonMachineState *hms,
57
const struct hexagon_machine_config *m_cfg, Rev_t rev)
58
{
@@ -69,15 +80,32 @@ void hex_subsys_create(HexagonCommonMachineState *hms,
80
&hms->vtcm);
81
}
82
83
+ hms->cluster = cluster_create(hms);
84
hms->glob_regs = globalreg_create(hms, m_cfg, rev);
85
hms->tlb = tlb_create(hms, m_cfg);
86
}
87
76
-void hex_subsys_realize_cpu(HexagonCommonMachineState *hms, DeviceState *cpu)
88
+void hex_subsys_add_cpu(HexagonCommonMachineState *hms, DeviceState *cpu)
89
{
90
+ object_property_add_child(OBJECT(hms->cluster), "cpu[*]", OBJECT(cpu));
91
object_property_set_link(OBJECT(cpu), "global-regs",
92
OBJECT(hms->glob_regs), &error_fatal);
93
object_property_set_link(OBJECT(cpu), "tlb", OBJECT(hms->tlb),
94
&error_fatal);
95
+}
96
+
97
+void hex_subsys_realize_cluster(HexagonCommonMachineState *hms)
98
+{
99
+ /*
100
+ * The cluster must be realized after its CPUs have been parented into it
101
+ * (see hex_subsys_add_cpu()) but before any CPU is itself realized, since
102
+ * qdev_realize_and_unref() on a CPU latches cluster_index into the TCG
103
+ * cflags at that point.
104
+ */
105
+ qdev_realize_and_unref(hms->cluster, NULL, &error_fatal);
106
+}
107
+
108
+void hex_subsys_realize_cpu(HexagonCommonMachineState *hms, DeviceState *cpu)
109
+{
110
qdev_realize_and_unref(cpu, NULL, &error_fatal);
111
}
hw/hexagon/hexagon_dsp.c
+10
-1
@@ -118,6 +118,8 @@ static void hexagon_common_init(MachineState *machine, Rev_t rev,
118
119
hex_subsys_create(hms, m_cfg, rev);
120
121
+ g_autofree HexagonCPU **cpus = g_new(HexagonCPU *, machine->smp.cpus);
122
+
123
for (int i = 0; i < machine->smp.cpus; i++) {
124
HexagonCPU *cpu = HEXAGON_CPU(object_new(machine->cpu_type));
125
qemu_register_reset(do_cpu_reset, cpu);
@@ -130,7 +132,14 @@ static void hexagon_common_init(MachineState *machine, Rev_t rev,
132
if (i == 0) {
133
hexagon_init_bootstrap(dms, cpu);
134
}
133
- hex_subsys_realize_cpu(hms, DEVICE(cpu));
135
+ hex_subsys_add_cpu(hms, DEVICE(cpu));
136
+ cpus[i] = cpu;
137
+ }
138
+
139
+ hex_subsys_realize_cluster(hms);
140
+
141
+ for (int i = 0; i < machine->smp.cpus; i++) {
142
+ hex_subsys_realize_cpu(hms, DEVICE(cpus[i]));
143
}
144
}
145
hw/hexagon/virt.c
+10
-1
@@ -246,6 +246,8 @@ static void virt_init(MachineState *ms)
246
247
fdt_add_hvx(vms, m_cfg);
248
249
+ g_autofree HexagonCPU **cpus = g_new(HexagonCPU *, ms->smp.cpus);
250
+
251
for (int i = 0; i < ms->smp.cpus; i++) {
252
HexagonCPU *cpu = HEXAGON_CPU(object_new(ms->cpu_type));
253
qemu_register_reset(do_cpu_reset, cpu);
@@ -261,7 +263,14 @@ static void virt_init(MachineState *ms)
263
}
264
qdev_prop_set_uint32(DEVICE(cpu), "htid", i);
265
qdev_prop_set_bit(DEVICE(cpu), "start-powered-off", (i != 0));
264
- hex_subsys_realize_cpu(&vms->parent_obj, DEVICE(cpu));
266
+ hex_subsys_add_cpu(&vms->parent_obj, DEVICE(cpu));
267
+ cpus[i] = cpu;
268
+ }
269
+
270
+ hex_subsys_realize_cluster(&vms->parent_obj);
271
+
272
+ for (int i = 0; i < ms->smp.cpus; i++) {
273
+ hex_subsys_realize_cpu(&vms->parent_obj, DEVICE(cpus[i]));
274
}
275
276
fdt_add_cpu_nodes(vms);
include/hw/hexagon/hex-subsys.h
+11
-1
@@ -15,7 +15,17 @@
15
void hex_subsys_create(HexagonCommonMachineState *hms,
16
const struct hexagon_machine_config *m_cfg, Rev_t rev);
17
18
-/* Realize a CPU into the subsystem. */
18
+/*
19
+ * Parent a CPU into the subsystem's cluster and wire its links. Call for
20
+ * every CPU before hex_subsys_realize_cluster(), then realize each CPU with
21
+ * hex_subsys_realize_cpu().
22
+ */
23
+void hex_subsys_add_cpu(HexagonCommonMachineState *hms, DeviceState *cpu);
24
+
25
+/* Realize the CPU cluster, once all CPUs have been parented into it. */
26
+void hex_subsys_realize_cluster(HexagonCommonMachineState *hms);
27
+
28
+/* Realize a CPU previously parented via hex_subsys_add_cpu(). */
29
void hex_subsys_realize_cpu(HexagonCommonMachineState *hms, DeviceState *cpu);
30
31
#endif /* HW_HEXAGON_HEX_SUBSYS_H */
include/hw/hexagon/hexagon.h
+1
@@ -157,6 +157,7 @@ struct HexagonCommonMachineState {
157
MemoryRegion ram;
158
MemoryRegion cfgtable_rom;
159
MemoryRegion vtcm;
160
+ DeviceState *cluster;
161
DeviceState *glob_regs;
162
DeviceState *tlb;
163
};