@samitouri / QOSamiQemu / commits / 26088c1e7b

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