hw/hexagon: move global registers to hex-subsys
Both machines create the global register device the same way, so let hex-subsys own it and link it to each CPU as it is realized. Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Link: https://lore.kernel.org/qemu-devel/20260806042723.3785369-4-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
26088c1e7b39e05a724618518594383665b74069
5 files changed
+41
-33
hw/hexagon/hex-subsys.c
+28
-1
@@ -8,11 +8,29 @@
8
#include "qemu/osdep.h"
9
#include "qapi/error.h"
10
#include "hw/hexagon/hex-subsys.h"
11
+#include "hw/hexagon/hexagon_globalreg.h"
12
#include "hw/core/loader.h"
13
+#include "hw/core/qdev-properties.h"
14
+#include "hw/core/qdev.h"
15
+#include "hw/core/sysbus.h"
16
#include "system/address-spaces.h"
17
18
+static DeviceState *globalreg_create(HexagonCommonMachineState *hms,
19
+ const struct hexagon_machine_config *m_cfg,
20
+ Rev_t rev)
21
+{
22
+ DeviceState *glob_regs = qdev_new(TYPE_HEXAGON_GLOBALREG);
23
+
24
+ object_property_add_child(OBJECT(hms), "global-regs", OBJECT(glob_regs));
25
+ qdev_prop_set_uint64(glob_regs, "config-table-addr", m_cfg->cfgbase);
26
+ qdev_prop_set_uint32(glob_regs, "dsp-rev", rev);
27
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(glob_regs), &error_fatal);
28
+
29
+ return glob_regs;
30
+}
31
+
32
void hex_subsys_create(HexagonCommonMachineState *hms,
15
- const struct hexagon_machine_config *m_cfg)
33
+ const struct hexagon_machine_config *m_cfg, Rev_t rev)
34
{
35
MachineState *machine = MACHINE(hms);
36
MemoryRegion *sysmem = get_system_memory();
@@ -37,4 +55,13 @@ void hex_subsys_create(HexagonCommonMachineState *hms,
55
memory_region_add_subregion(sysmem, m_cfg->cfgtable.vtcm_base << 16,
56
&hms->vtcm);
57
}
58
+
59
+ hms->glob_regs = globalreg_create(hms, m_cfg, rev);
60
+}
61
+
62
+void hex_subsys_realize_cpu(HexagonCommonMachineState *hms, DeviceState *cpu)
63
+{
64
+ object_property_set_link(OBJECT(cpu), "global-regs",
65
+ OBJECT(hms->glob_regs), &error_fatal);
66
+ qdev_realize_and_unref(cpu, NULL, &error_fatal);
67
}
hw/hexagon/hexagon_dsp.c
+2
-13
@@ -15,7 +15,6 @@
15
#include "hw/core/qdev-properties.h"
16
#include "hw/hexagon/hexagon.h"
17
#include "hw/hexagon/hex-subsys.h"
18
-#include "hw/hexagon/hexagon_globalreg.h"
18
#include "hw/hexagon/hexagon_tlb.h"
19
#include "hw/core/loader.h"
20
#include "qapi/error.h"
@@ -109,7 +108,6 @@ static void hexagon_common_init(MachineState *machine, Rev_t rev,
108
{
109
HexagonCommonMachineState *hms = HEXAGON_COMMON_MACHINE(machine);
110
HexagonDspMachineState *dms = HEXAGON_DSP_MACHINE(machine);
112
- DeviceState *glob_regs_dev;
111
DeviceState *tlb_dev;
112
113
memset(&hexagon_binfo, 0, sizeof(hexagon_binfo));
@@ -120,14 +118,7 @@ static void hexagon_common_init(MachineState *machine, Rev_t rev,
118
119
machine->enable_graphics = 0;
120
123
- hex_subsys_create(hms, m_cfg);
124
-
125
- glob_regs_dev = qdev_new(TYPE_HEXAGON_GLOBALREG);
126
- object_property_add_child(OBJECT(machine), "global-regs",
127
- OBJECT(glob_regs_dev));
128
- qdev_prop_set_uint64(glob_regs_dev, "config-table-addr", m_cfg->cfgbase);
129
- qdev_prop_set_uint32(glob_regs_dev, "dsp-rev", rev);
130
- sysbus_realize_and_unref(SYS_BUS_DEVICE(glob_regs_dev), &error_fatal);
121
+ hex_subsys_create(hms, m_cfg, rev);
122
123
tlb_dev = qdev_new(TYPE_HEXAGON_TLB);
124
object_property_add_child(OBJECT(machine), "tlb", OBJECT(tlb_dev));
@@ -147,11 +138,9 @@ static void hexagon_common_init(MachineState *machine, Rev_t rev,
138
if (i == 0) {
139
hexagon_init_bootstrap(dms, cpu);
140
}
150
- object_property_set_link(OBJECT(cpu), "global-regs",
151
- OBJECT(glob_regs_dev), &error_fatal);
141
object_property_set_link(OBJECT(cpu), "tlb",
142
OBJECT(tlb_dev), &error_fatal);
154
- qdev_realize_and_unref(DEVICE(cpu), NULL, &error_fatal);
143
+ hex_subsys_realize_cpu(hms, DEVICE(cpu));
144
}
145
}
146
hw/hexagon/virt.c
+5
-18
@@ -14,7 +14,6 @@
14
#include "hw/core/sysbus-fdt.h"
15
#include "hw/hexagon/hexagon.h"
16
#include "hw/hexagon/hex-subsys.h"
17
-#include "hw/hexagon/hexagon_globalreg.h"
17
#include "hw/hexagon/hexagon_tlb.h"
18
#include "hw/core/loader.h"
19
#include "hw/core/qdev-properties.h"
@@ -226,9 +225,7 @@ static void virt_init(MachineState *ms)
225
{
226
HexagonVirtMachineState *vms = HEXAGON_VIRT_MACHINE(ms);
227
const struct hexagon_machine_config *m_cfg = &v68n_1024;
229
- DeviceState *gsregs_dev;
228
DeviceState *tlb_dev;
231
- DeviceState *cpu0;
229
int32_t clk_phandle;
230
231
create_fdt(vms);
@@ -240,7 +237,7 @@ static void virt_init(MachineState *ms)
237
vms->apb_clk = clock_new(OBJECT(ms), "apb-pclk");
238
clock_set_hz(vms->apb_clk, 24000000);
239
243
- hex_subsys_create(&vms->parent_obj, m_cfg);
240
+ hex_subsys_create(&vms->parent_obj, m_cfg, v68_rev);
241
242
if (m_cfg->l2tcm_size) {
243
memory_region_init_ram(&vms->tcm, NULL, "tcm.ram", m_cfg->l2tcm_size,
@@ -251,42 +248,32 @@ static void virt_init(MachineState *ms)
248
249
fdt_add_hvx(vms, m_cfg);
250
254
- gsregs_dev = qdev_new(TYPE_HEXAGON_GLOBALREG);
255
- object_property_add_child(OBJECT(ms), "global-regs", OBJECT(gsregs_dev));
256
- qdev_prop_set_uint64(gsregs_dev, "config-table-addr", m_cfg->cfgbase);
257
- qdev_prop_set_uint32(gsregs_dev, "dsp-rev", v68_rev);
258
- sysbus_realize_and_unref(SYS_BUS_DEVICE(gsregs_dev), &error_fatal);
259
-
251
tlb_dev = qdev_new(TYPE_HEXAGON_TLB);
252
object_property_add_child(OBJECT(ms), "tlb", OBJECT(tlb_dev));
253
qdev_prop_set_uint32(tlb_dev, "num-entries",
254
m_cfg->cfgtable.jtlb_size_entries);
255
sysbus_realize_and_unref(SYS_BUS_DEVICE(tlb_dev), &error_fatal);
256
266
- cpu0 = NULL;
257
for (int i = 0; i < ms->smp.cpus; i++) {
258
HexagonCPU *cpu = HEXAGON_CPU(object_new(ms->cpu_type));
259
qemu_register_reset(do_cpu_reset, cpu);
260
261
if (i == 0) {
272
- cpu0 = DEVICE(cpu);
262
if (ms->kernel_filename) {
263
uint64_t entry = load_kernel(vms);
275
- qdev_prop_set_uint32(cpu0, "exec-start-addr", entry);
264
+ qdev_prop_set_uint32(DEVICE(cpu), "exec-start-addr", entry);
265
} else if (ms->firmware) {
266
uint64_t entry = load_bios(vms);
278
- qdev_prop_set_uint32(cpu0, "exec-start-addr", entry);
267
+ qdev_prop_set_uint32(DEVICE(cpu), "exec-start-addr", entry);
268
}
269
}
270
qdev_prop_set_uint32(DEVICE(cpu), "htid", i);
271
qdev_prop_set_bit(DEVICE(cpu), "start-powered-off", (i != 0));
283
- object_property_set_link(OBJECT(cpu), "global-regs",
284
- OBJECT(gsregs_dev), &error_fatal);
272
object_property_set_link(OBJECT(cpu), "tlb",
273
OBJECT(tlb_dev), &error_fatal);
287
-
288
- qdev_realize_and_unref(DEVICE(cpu), NULL, &error_fatal);
274
+ hex_subsys_realize_cpu(&vms->parent_obj, DEVICE(cpu));
275
}
276
+
277
fdt_add_cpu_nodes(vms);
278
clk_phandle = fdt_add_clocks(vms);
279
fdt_add_uart(vms, VIRT_UART0, clk_phandle);
include/hw/hexagon/hex-subsys.h
+5
-1
@@ -9,9 +9,13 @@
9
#define HW_HEXAGON_HEX_SUBSYS_H
10
11
#include "hw/hexagon/hexagon.h"
12
+#include "hw/core/qdev.h"
13
14
/* Create the subsystem shared by every Hexagon machine. */
15
void hex_subsys_create(HexagonCommonMachineState *hms,
15
- const struct hexagon_machine_config *m_cfg);
16
+ const struct hexagon_machine_config *m_cfg, Rev_t rev);
17
+
18
+/* Realize a CPU into the subsystem. */
19
+void hex_subsys_realize_cpu(HexagonCommonMachineState *hms, DeviceState *cpu);
20
21
#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 *glob_regs;
161
};
162
163
#endif