@samitouri / QOSamiQemu / commits / d33ec047c3

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 };