[PATCH v5 05/18] hw/hexagon: group the CPUs in a cluster
Brian Cain <[email protected]> Wed, 5 Aug 2026 21:27:10 -0700
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
The CPUs are now grouped in a TYPE_CPU_CLUSTER. Reviewed-by: Pierrick Bouvier <[email protected]> Signed-off-by: Brian Cain <[email protected]> --- include/hw/hexagon/hex-subsys.h | 12 +++++++++++- include/hw/hexagon/hexagon.h | 1 + hw/hexagon/hex-subsys.c | 30 +++++++++++++++++++++++++++++- hw/hexagon/hexagon_dsp.c | 11 ++++++++++- hw/hexagon/virt.c | 11 ++++++++++- hw/hexagon/Kconfig | 1 + 6 files changed, 62 insertions(+), 4 deletions(-) diff --git a/include/hw/hexagon/hex-subsys.h b/include/hw/hexagon/hex-subsys.h index 087c105cfa4..6d0d5e1da86 100644 --- a/include/hw/hexagon/hex-subsys.h +++ b/include/hw/hexagon/hex-subsys.h @@ -15,7 +15,17 @@ void hex_subsys_create(HexagonCommonMachineState *hms, const struct hexagon_machine_config *m_cfg, Rev_t rev); -/* Realize a CPU into the subsystem. */ +/* + * Parent a CPU into the subsystem's cluster and wire its links. Call for + * every CPU before hex_subsys_realize_cluster(), then realize each CPU with + * hex_subsys_realize_cpu(). + */ +void hex_subsys_add_cpu(HexagonCommonMachineState *hms, DeviceState *cpu); + +/* Realize the CPU cluster, once all CPUs have been parented into it. */ +void hex_subsys_realize_cluster(HexagonCommonMachineState *hms); + +/* Realize a CPU previously parented via hex_subsys_add_cpu(). */ 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 6edd93f478a..31669a829f8 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 *cluster; DeviceState *glob_regs; DeviceState *tlb; }; diff --git a/hw/hexagon/hex-subsys.c b/hw/hexagon/hex-subsys.c index ac7e29604eb..6fad6fe0a4d 100644 --- a/hw/hexagon/hex-subsys.c +++ b/hw/hexagon/hex-subsys.c @@ -10,6 +10,7 @@ #include "hw/hexagon/hex-subsys.h" #include "hw/hexagon/hexagon_globalreg.h" #include "hw/hexagon/hexagon_tlb.h" +#include "hw/cpu/cluster.h" #include "hw/core/loader.h" #include "hw/core/qdev-properties.h" #include "hw/core/qdev.h" @@ -42,6 +43,16 @@ static DeviceState *tlb_create(HexagonCommonMachineState *hms, return tlb; } +static DeviceState *cluster_create(HexagonCommonMachineState *hms) +{ + DeviceState *cluster = qdev_new(TYPE_CPU_CLUSTER); + + object_property_add_child(OBJECT(hms), "cluster", OBJECT(cluster)); + qdev_prop_set_uint32(cluster, "cluster-id", 0); + + return cluster; +} + void hex_subsys_create(HexagonCommonMachineState *hms, const struct hexagon_machine_config *m_cfg, Rev_t rev) { @@ -69,15 +80,32 @@ void hex_subsys_create(HexagonCommonMachineState *hms, &hms->vtcm); } + hms->cluster = cluster_create(hms); hms->glob_regs = globalreg_create(hms, m_cfg, rev); hms->tlb = tlb_create(hms, m_cfg); } -void hex_subsys_realize_cpu(HexagonCommonMachineState *hms, DeviceState *cpu) +void hex_subsys_add_cpu(HexagonCommonMachineState *hms, DeviceState *cpu) { + object_property_add_child(OBJECT(hms->cluster), "cpu[*]", OBJECT(cpu)); object_property_set_link(OBJECT(cpu), "global-regs", OBJECT(hms->glob_regs), &error_fatal); object_property_set_link(OBJECT(cpu), "tlb", OBJECT(hms->tlb), &error_fatal); +} + +void hex_subsys_realize_cluster(HexagonCommonMachineState *hms) +{ + /* + * The cluster must be realized after its CPUs have been parented into it + * (see hex_subsys_add_cpu()) but before any CPU is itself realized, since + * qdev_realize_and_unref() on a CPU latches cluster_index into the TCG + * cflags at that point. + */ + qdev_realize_and_unref(hms->cluster, NULL, &error_fatal); +} + +void hex_subsys_realize_cpu(HexagonCommonMachineState *hms, DeviceState *cpu) +{ qdev_realize_and_unref(cpu, NULL, &error_fatal); } diff --git a/hw/hexagon/hexagon_dsp.c b/hw/hexagon/hexagon_dsp.c index 25e8550fba2..1db5d681665 100644 --- a/hw/hexagon/hexagon_dsp.c +++ b/hw/hexagon/hexagon_dsp.c @@ -118,6 +118,8 @@ static void hexagon_common_init(MachineState *machine, Rev_t rev, hex_subsys_create(hms, m_cfg, rev); + g_autofree HexagonCPU **cpus = g_new(HexagonCPU *, machine->smp.cpus); + for (int i = 0; i < machine->smp.cpus; i++) { HexagonCPU *cpu = HEXAGON_CPU(object_new(machine->cpu_type)); qemu_register_reset(do_cpu_reset, cpu); @@ -130,7 +132,14 @@ static void hexagon_common_init(MachineState *machine, Rev_t rev, if (i == 0) { hexagon_init_bootstrap(dms, cpu); } - hex_subsys_realize_cpu(hms, DEVICE(cpu)); + hex_subsys_add_cpu(hms, DEVICE(cpu)); + cpus[i] = cpu; + } + + hex_subsys_realize_cluster(hms); + + for (int i = 0; i < machine->smp.cpus; i++) { + hex_subsys_realize_cpu(hms, DEVICE(cpus[i])); } } diff --git a/hw/hexagon/virt.c b/hw/hexagon/virt.c index b9e0bbb704c..dc1d5b6aa24 100644 --- a/hw/hexagon/virt.c +++ b/hw/hexagon/virt.c @@ -246,6 +246,8 @@ static void virt_init(MachineState *ms) fdt_add_hvx(vms, m_cfg); + g_autofree HexagonCPU **cpus = g_new(HexagonCPU *, ms->smp.cpus); + 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); @@ -261,7 +263,14 @@ static void virt_init(MachineState *ms) } qdev_prop_set_uint32(DEVICE(cpu), "htid", i); qdev_prop_set_bit(DEVICE(cpu), "start-powered-off", (i != 0)); - hex_subsys_realize_cpu(&vms->parent_obj, DEVICE(cpu)); + hex_subsys_add_cpu(&vms->parent_obj, DEVICE(cpu)); + cpus[i] = cpu; + } + + hex_subsys_realize_cluster(&vms->parent_obj); + + for (int i = 0; i < ms->smp.cpus; i++) { + hex_subsys_realize_cpu(&vms->parent_obj, DEVICE(cpus[i])); } fdt_add_cpu_nodes(vms); diff --git a/hw/hexagon/Kconfig b/hw/hexagon/Kconfig index 52065ab3b22..121c548bbb9 100644 --- a/hw/hexagon/Kconfig +++ b/hw/hexagon/Kconfig @@ -2,6 +2,7 @@ config HEX_DSP bool default y depends on HEXAGON + select CPU_CLUSTER config HEX_VIRT bool -- 2.34.1