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 <[email protected]>
Link: 
https://lore.kernel.org/qemu-devel/[email protected]
Signed-off-by: Brian Cain <[email protected]>
---
 include/hw/hexagon/hex-subsys.h |  6 +++++-
 include/hw/hexagon/hexagon.h    |  1 +
 hw/hexagon/hex-subsys.c         | 29 ++++++++++++++++++++++++++++-
 hw/hexagon/hexagon_dsp.c        | 15 ++-------------
 hw/hexagon/virt.c               | 23 +++++------------------
 5 files changed, 41 insertions(+), 33 deletions(-)

diff --git a/include/hw/hexagon/hex-subsys.h b/include/hw/hexagon/hex-subsys.h
index 6bcde303f2e..087c105cfa4 100644
--- a/include/hw/hexagon/hex-subsys.h
+++ b/include/hw/hexagon/hex-subsys.h
@@ -9,9 +9,13 @@
 #define HW_HEXAGON_HEX_SUBSYS_H
 
 #include "hw/hexagon/hexagon.h"
+#include "hw/core/qdev.h"
 
 /* Create the subsystem shared by every Hexagon machine. */
 void hex_subsys_create(HexagonCommonMachineState *hms,
-                       const struct hexagon_machine_config *m_cfg);
+                       const struct hexagon_machine_config *m_cfg, Rev_t rev);
+
+/* Realize a CPU into the subsystem. */
+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 9c73cadb16d..ef5700082cc 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 *glob_regs;
 };
 
 #endif
diff --git a/hw/hexagon/hex-subsys.c b/hw/hexagon/hex-subsys.c
index 0c20cf02e7d..6789b6bb23d 100644
--- a/hw/hexagon/hex-subsys.c
+++ b/hw/hexagon/hex-subsys.c
@@ -8,11 +8,29 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/hexagon/hex-subsys.h"
+#include "hw/hexagon/hexagon_globalreg.h"
 #include "hw/core/loader.h"
+#include "hw/core/qdev-properties.h"
+#include "hw/core/qdev.h"
+#include "hw/core/sysbus.h"
 #include "system/address-spaces.h"
 
+static DeviceState *globalreg_create(HexagonCommonMachineState *hms,
+                                     const struct hexagon_machine_config 
*m_cfg,
+                                     Rev_t rev)
+{
+    DeviceState *glob_regs = qdev_new(TYPE_HEXAGON_GLOBALREG);
+
+    object_property_add_child(OBJECT(hms), "global-regs", OBJECT(glob_regs));
+    qdev_prop_set_uint64(glob_regs, "config-table-addr", m_cfg->cfgbase);
+    qdev_prop_set_uint32(glob_regs, "dsp-rev", rev);
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(glob_regs), &error_fatal);
+
+    return glob_regs;
+}
+
 void hex_subsys_create(HexagonCommonMachineState *hms,
-                       const struct hexagon_machine_config *m_cfg)
+                       const struct hexagon_machine_config *m_cfg, Rev_t rev)
 {
     MachineState *machine = MACHINE(hms);
     MemoryRegion *sysmem = get_system_memory();
@@ -37,4 +55,13 @@ void hex_subsys_create(HexagonCommonMachineState *hms,
         memory_region_add_subregion(sysmem, m_cfg->cfgtable.vtcm_base << 16,
                                     &hms->vtcm);
     }
+
+    hms->glob_regs = globalreg_create(hms, m_cfg, rev);
+}
+
+void hex_subsys_realize_cpu(HexagonCommonMachineState *hms, DeviceState *cpu)
+{
+    object_property_set_link(OBJECT(cpu), "global-regs",
+                             OBJECT(hms->glob_regs), &error_fatal);
+    qdev_realize_and_unref(cpu, NULL, &error_fatal);
 }
diff --git a/hw/hexagon/hexagon_dsp.c b/hw/hexagon/hexagon_dsp.c
index f94f7fd4e11..8599f5883bf 100644
--- a/hw/hexagon/hexagon_dsp.c
+++ b/hw/hexagon/hexagon_dsp.c
@@ -15,7 +15,6 @@
 #include "hw/core/qdev-properties.h"
 #include "hw/hexagon/hexagon.h"
 #include "hw/hexagon/hex-subsys.h"
-#include "hw/hexagon/hexagon_globalreg.h"
 #include "hw/hexagon/hexagon_tlb.h"
 #include "hw/core/loader.h"
 #include "qapi/error.h"
@@ -109,7 +108,6 @@ static void hexagon_common_init(MachineState *machine, 
Rev_t rev,
 {
     HexagonCommonMachineState *hms = HEXAGON_COMMON_MACHINE(machine);
     HexagonDspMachineState *dms = HEXAGON_DSP_MACHINE(machine);
-    DeviceState *glob_regs_dev;
     DeviceState *tlb_dev;
 
     memset(&hexagon_binfo, 0, sizeof(hexagon_binfo));
@@ -120,14 +118,7 @@ static void hexagon_common_init(MachineState *machine, 
Rev_t rev,
 
     machine->enable_graphics = 0;
 
-    hex_subsys_create(hms, m_cfg);
-
-    glob_regs_dev = qdev_new(TYPE_HEXAGON_GLOBALREG);
-    object_property_add_child(OBJECT(machine), "global-regs",
-                              OBJECT(glob_regs_dev));
-    qdev_prop_set_uint64(glob_regs_dev, "config-table-addr", m_cfg->cfgbase);
-    qdev_prop_set_uint32(glob_regs_dev, "dsp-rev", rev);
-    sysbus_realize_and_unref(SYS_BUS_DEVICE(glob_regs_dev), &error_fatal);
+    hex_subsys_create(hms, m_cfg, rev);
 
     tlb_dev = qdev_new(TYPE_HEXAGON_TLB);
     object_property_add_child(OBJECT(machine), "tlb", OBJECT(tlb_dev));
@@ -147,11 +138,9 @@ static void hexagon_common_init(MachineState *machine, 
Rev_t rev,
         if (i == 0) {
             hexagon_init_bootstrap(dms, cpu);
         }
-        object_property_set_link(OBJECT(cpu), "global-regs",
-                                 OBJECT(glob_regs_dev), &error_fatal);
         object_property_set_link(OBJECT(cpu), "tlb",
                                  OBJECT(tlb_dev), &error_fatal);
-        qdev_realize_and_unref(DEVICE(cpu), NULL, &error_fatal);
+        hex_subsys_realize_cpu(hms, DEVICE(cpu));
     }
 }
 
diff --git a/hw/hexagon/virt.c b/hw/hexagon/virt.c
index 53eaafaf85a..290783d511f 100644
--- a/hw/hexagon/virt.c
+++ b/hw/hexagon/virt.c
@@ -14,7 +14,6 @@
 #include "hw/core/sysbus-fdt.h"
 #include "hw/hexagon/hexagon.h"
 #include "hw/hexagon/hex-subsys.h"
-#include "hw/hexagon/hexagon_globalreg.h"
 #include "hw/hexagon/hexagon_tlb.h"
 #include "hw/core/loader.h"
 #include "hw/core/qdev-properties.h"
@@ -226,9 +225,7 @@ static void virt_init(MachineState *ms)
 {
     HexagonVirtMachineState *vms = HEXAGON_VIRT_MACHINE(ms);
     const struct hexagon_machine_config *m_cfg = &v68n_1024;
-    DeviceState *gsregs_dev;
     DeviceState *tlb_dev;
-    DeviceState *cpu0;
     int32_t clk_phandle;
 
     create_fdt(vms);
@@ -240,7 +237,7 @@ static void virt_init(MachineState *ms)
     vms->apb_clk = clock_new(OBJECT(ms), "apb-pclk");
     clock_set_hz(vms->apb_clk, 24000000);
 
-    hex_subsys_create(&vms->parent_obj, m_cfg);
+    hex_subsys_create(&vms->parent_obj, m_cfg, v68_rev);
 
     if (m_cfg->l2tcm_size) {
         memory_region_init_ram(&vms->tcm, NULL, "tcm.ram", m_cfg->l2tcm_size,
@@ -251,42 +248,32 @@ static void virt_init(MachineState *ms)
 
     fdt_add_hvx(vms, m_cfg);
 
-    gsregs_dev = qdev_new(TYPE_HEXAGON_GLOBALREG);
-    object_property_add_child(OBJECT(ms), "global-regs", OBJECT(gsregs_dev));
-    qdev_prop_set_uint64(gsregs_dev, "config-table-addr", m_cfg->cfgbase);
-    qdev_prop_set_uint32(gsregs_dev, "dsp-rev", v68_rev);
-    sysbus_realize_and_unref(SYS_BUS_DEVICE(gsregs_dev), &error_fatal);
-
     tlb_dev = qdev_new(TYPE_HEXAGON_TLB);
     object_property_add_child(OBJECT(ms), "tlb", OBJECT(tlb_dev));
     qdev_prop_set_uint32(tlb_dev, "num-entries",
                          m_cfg->cfgtable.jtlb_size_entries);
     sysbus_realize_and_unref(SYS_BUS_DEVICE(tlb_dev), &error_fatal);
 
-    cpu0 = NULL;
     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);
 
         if (i == 0) {
-            cpu0 = DEVICE(cpu);
             if (ms->kernel_filename) {
                 uint64_t entry = load_kernel(vms);
-                qdev_prop_set_uint32(cpu0, "exec-start-addr", entry);
+                qdev_prop_set_uint32(DEVICE(cpu), "exec-start-addr", entry);
             } else if (ms->firmware) {
                 uint64_t entry = load_bios(vms);
-                qdev_prop_set_uint32(cpu0, "exec-start-addr", entry);
+                qdev_prop_set_uint32(DEVICE(cpu), "exec-start-addr", entry);
             }
         }
         qdev_prop_set_uint32(DEVICE(cpu), "htid", i);
         qdev_prop_set_bit(DEVICE(cpu), "start-powered-off", (i != 0));
-        object_property_set_link(OBJECT(cpu), "global-regs",
-                                 OBJECT(gsregs_dev), &error_fatal);
         object_property_set_link(OBJECT(cpu), "tlb",
                                  OBJECT(tlb_dev), &error_fatal);
-
-        qdev_realize_and_unref(DEVICE(cpu), NULL, &error_fatal);
+        hex_subsys_realize_cpu(&vms->parent_obj, DEVICE(cpu));
     }
+
     fdt_add_cpu_nodes(vms);
     clk_phandle = fdt_add_clocks(vms);
     fdt_add_uart(vms, VIRT_UART0, clk_phandle);
-- 
2.34.1

Reply via email to