The virt and DSP machine models build the same core subsystem, let's abstract out that part.
The CPUs are now grouped in a TYPE_CPU_CLUSTER. Signed-off-by: Brian Cain <[email protected]> --- include/hw/hexagon/hex-subsys.h | 24 ++++++++ include/hw/hexagon/hexagon.h | 4 ++ include/hw/hexagon/virt.h | 1 - hw/hexagon/hex-subsys.c | 105 ++++++++++++++++++++++++++++++++ hw/hexagon/hexagon_dsp.c | 40 ++---------- hw/hexagon/virt.c | 52 +++------------- hw/hexagon/Kconfig | 1 + hw/hexagon/meson.build | 1 + 8 files changed, 147 insertions(+), 81 deletions(-) create mode 100644 include/hw/hexagon/hex-subsys.h create mode 100644 hw/hexagon/hex-subsys.c diff --git a/include/hw/hexagon/hex-subsys.h b/include/hw/hexagon/hex-subsys.h new file mode 100644 index 00000000000..73403e8951c --- /dev/null +++ b/include/hw/hexagon/hex-subsys.h @@ -0,0 +1,24 @@ +/* + * Hexagon subsystem helpers shared between the machine models. + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_HEXAGON_HEX_SUBSYS_H +#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, Rev_t rev); + +/* Realize a CPU into the subsystem, then hex_subsys_realize_cluster(). */ +void hex_subsys_realize_cpu(HexagonCommonMachineState *hms, DeviceState *cpu); + +/* Realize the CPU cluster, once all CPUs have been parented into it. */ +void hex_subsys_realize_cluster(HexagonCommonMachineState *hms); + +#endif /* HW_HEXAGON_HEX_SUBSYS_H */ diff --git a/include/hw/hexagon/hexagon.h b/include/hw/hexagon/hexagon.h index 1034b09c2ac..31669a829f8 100644 --- a/include/hw/hexagon/hexagon.h +++ b/include/hw/hexagon/hexagon.h @@ -156,6 +156,10 @@ struct HexagonCommonMachineState { MemoryRegion ram; MemoryRegion cfgtable_rom; + MemoryRegion vtcm; + DeviceState *cluster; + DeviceState *glob_regs; + DeviceState *tlb; }; #endif diff --git a/include/hw/hexagon/virt.h b/include/hw/hexagon/virt.h index fcb47762194..cf0cd2f8f22 100644 --- a/include/hw/hexagon/virt.h +++ b/include/hw/hexagon/virt.h @@ -17,7 +17,6 @@ struct HexagonVirtMachineState { int fdt_size; MemoryRegion *sys; MemoryRegion tcm; - MemoryRegion vtcm; MemoryRegion bios; Clock *apb_clk; }; diff --git a/hw/hexagon/hex-subsys.c b/hw/hexagon/hex-subsys.c new file mode 100644 index 00000000000..638b6429100 --- /dev/null +++ b/hw/hexagon/hex-subsys.c @@ -0,0 +1,105 @@ +/* + * Hexagon subsystem helpers shared between the machine models. + * + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#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" +#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; +} + +static DeviceState *tlb_create(HexagonCommonMachineState *hms, + const struct hexagon_machine_config *m_cfg) +{ + DeviceState *tlb = qdev_new(TYPE_HEXAGON_TLB); + + object_property_add_child(OBJECT(hms), "tlb", OBJECT(tlb)); + qdev_prop_set_uint32(tlb, "num-entries", m_cfg->cfgtable.jtlb_size_entries); + sysbus_realize_and_unref(SYS_BUS_DEVICE(tlb), &error_fatal); + + 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) +{ + MachineState *machine = MACHINE(hms); + MemoryRegion *sysmem = get_system_memory(); + + /* Main DDR at the reset vector. */ + memory_region_init_ram(&hms->ram, NULL, "ddr.ram", machine->ram_size, + &error_fatal); + memory_region_add_subregion(sysmem, 0x0, &hms->ram); + + /* Config-table ROM and the blob that backs it. */ + memory_region_init_rom(&hms->cfgtable_rom, NULL, "config_table.rom", + sizeof(m_cfg->cfgtable), &error_fatal); + memory_region_add_subregion(sysmem, m_cfg->cfgbase, &hms->cfgtable_rom); + rom_add_blob_fixed_as("config_table.rom", &m_cfg->cfgtable, + sizeof(m_cfg->cfgtable), m_cfg->cfgbase, + &address_space_memory); + + if (m_cfg->cfgtable.vtcm_size_kb > 0) { + memory_region_init_ram(&hms->vtcm, NULL, "vtcm.ram", + m_cfg->cfgtable.vtcm_size_kb * 1024, + &error_fatal); + memory_region_add_subregion(sysmem, m_cfg->cfgtable.vtcm_base << 16, + &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) +{ + 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); + qdev_realize_and_unref(cpu, NULL, &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_realize_cpu()), so this is called once the CPUs exist. + */ + qdev_realize_and_unref(hms->cluster, NULL, &error_fatal); +} diff --git a/hw/hexagon/hexagon_dsp.c b/hw/hexagon/hexagon_dsp.c index aa493993229..5275ab92386 100644 --- a/hw/hexagon/hexagon_dsp.c +++ b/hw/hexagon/hexagon_dsp.c @@ -14,8 +14,7 @@ #include "hw/core/boards.h" #include "hw/core/qdev-properties.h" #include "hw/hexagon/hexagon.h" -#include "hw/hexagon/hexagon_globalreg.h" -#include "hw/hexagon/hexagon_tlb.h" +#include "hw/hexagon/hex-subsys.h" #include "hw/core/loader.h" #include "qapi/error.h" #include "qemu/error-report.h" @@ -108,9 +107,6 @@ static void hexagon_common_init(MachineState *machine, Rev_t rev, { HexagonCommonMachineState *hms = HEXAGON_COMMON_MACHINE(machine); HexagonDspMachineState *dms = HEXAGON_DSP_MACHINE(machine); - MemoryRegion *address_space; - DeviceState *glob_regs_dev; - DeviceState *tlb_dev; memset(&hexagon_binfo, 0, sizeof(hexagon_binfo)); if (machine->kernel_filename) { @@ -120,29 +116,7 @@ static void hexagon_common_init(MachineState *machine, Rev_t rev, machine->enable_graphics = 0; - address_space = get_system_memory(); - - memory_region_init_rom(&hms->cfgtable_rom, NULL, "config_table.rom", - sizeof(m_cfg->cfgtable), &error_fatal); - memory_region_add_subregion(address_space, m_cfg->cfgbase, - &hms->cfgtable_rom); - - memory_region_init_ram(&hms->ram, NULL, "ddr.ram", - machine->ram_size, &error_fatal); - memory_region_add_subregion(address_space, 0x0, &hms->ram); - - 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); - - tlb_dev = qdev_new(TYPE_HEXAGON_TLB); - object_property_add_child(OBJECT(machine), "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); + hex_subsys_create(hms, m_cfg, rev); for (int i = 0; i < machine->smp.cpus; i++) { HexagonCPU *cpu = HEXAGON_CPU(object_new(machine->cpu_type)); @@ -156,16 +130,10 @@ 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)); } - rom_add_blob_fixed_as("config_table.rom", &m_cfg->cfgtable, - sizeof(m_cfg->cfgtable), m_cfg->cfgbase, - &address_space_memory); + hex_subsys_realize_cluster(hms); } static void init_mc(MachineClass *mc) diff --git a/hw/hexagon/virt.c b/hw/hexagon/virt.c index a3638998b87..ac2b6605dbd 100644 --- a/hw/hexagon/virt.c +++ b/hw/hexagon/virt.c @@ -13,8 +13,7 @@ #include "hw/core/clock.h" #include "hw/core/sysbus-fdt.h" #include "hw/hexagon/hexagon.h" -#include "hw/hexagon/hexagon_globalreg.h" -#include "hw/hexagon/hexagon_tlb.h" +#include "hw/hexagon/hex-subsys.h" #include "hw/core/loader.h" #include "hw/core/qdev-properties.h" #include "hw/core/qdev-clock.h" @@ -74,11 +73,6 @@ static void fdt_add_hvx(HexagonVirtMachineState *vms, const MachineState *ms = MACHINE(vms); uint32_t vtcm_size_bytes = m_cfg->cfgtable.vtcm_size_kb * 1024; if (vtcm_size_bytes > 0) { - memory_region_init_ram(&vms->vtcm, NULL, "vtcm.ram", vtcm_size_bytes, - &error_fatal); - memory_region_add_subregion(vms->sys, m_cfg->cfgtable.vtcm_base << 16, - &vms->vtcm); - qemu_fdt_add_subnode(ms->fdt, "/soc/vtcm"); qemu_fdt_setprop_string(ms->fdt, "/soc/vtcm", "compatible", "qcom,hexagon_vtcm"); @@ -237,9 +231,6 @@ 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; qemu_fdt_setprop_string(ms->fdt, "/chosen", "bootargs", ms->kernel_cmdline); @@ -250,9 +241,7 @@ static void virt_init(MachineState *ms) vms->apb_clk = clock_new(OBJECT(ms), "apb-pclk"); clock_set_hz(vms->apb_clk, 24000000); - memory_region_init_ram(&vms->parent_obj.ram, NULL, "ddr.ram", - ms->ram_size, &error_fatal); - memory_region_add_subregion(vms->sys, 0x0, &vms->parent_obj.ram); + 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, @@ -261,57 +250,32 @@ static void virt_init(MachineState *ms) &vms->tcm); } - memory_region_init_rom(&vms->parent_obj.cfgtable_rom, NULL, - "config_table.rom", sizeof(m_cfg->cfgtable), - &error_fatal); - memory_region_add_subregion(vms->sys, m_cfg->cfgbase, - &vms->parent_obj.cfgtable_rom); 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)); } + + hex_subsys_realize_cluster(&vms->parent_obj); + fdt_add_cpu_nodes(vms); clk_phandle = fdt_add_clocks(vms); fdt_add_uart(vms, VIRT_UART0, clk_phandle); - rom_add_blob_fixed_as("config_table.rom", &m_cfg->cfgtable, - sizeof(m_cfg->cfgtable), m_cfg->cfgbase, - &address_space_memory); - hexagon_load_fdt(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 diff --git a/hw/hexagon/meson.build b/hw/hexagon/meson.build index bade3a32921..720a5d54dcc 100644 --- a/hw/hexagon/meson.build +++ b/hw/hexagon/meson.build @@ -1,6 +1,7 @@ hexagon_ss = ss.source_set() hexagon_ss.add(files('hexagon_tlb.c')) hexagon_ss.add(files('hexagon_globalreg.c')) +hexagon_ss.add(when: 'CONFIG_HEX_DSP', if_true: files('hex-subsys.c')) hexagon_ss.add(when: 'CONFIG_HEX_DSP', if_true: files('hexagon_dsp.c')) hexagon_ss.add(when: 'CONFIG_HEX_VIRT', if_true: files('virt.c')) -- 2.34.1
