new file mode 100644
@@ -0,0 +1,45 @@
+/*
+ * ARM CPUs
+ *
+ * Copyright (c) 2022 Greensocs
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_ARM_CPUS_H
+#define HW_ARM_CPUS_H
+
+#include "hw/cpu/cpus.h"
+#include "target/arm/cpu.h"
+
+#define TYPE_ARM_CPUS "arm-cpus"
+OBJECT_DECLARE_SIMPLE_TYPE(ArmCpusState, ARM_CPUS)
+
+/**
+ * ArmCpusState:
+ * @reset_hivecs: use to initialize cpu's reset-hivecs
+ * @has_el3: use to initialize cpu's has_el3
+ * @has_el2: use to initialize cpu's has_el2
+ * @reset_cbar: use to initialize cpu's reset-cbar
+ */
+struct ArmCpusState {
+ CpusState parent_obj;
+
+ bool reset_hivecs;
+ bool has_el3;
+ bool has_el2;
+ uint64_t reset_cbar;
+};
+
+/*
+ * arm_cpus_get_cpu:
+ * Helper to get an ArmCpu from the container.
+ */
+static inline ARMCPU *arm_cpus_get_cpu(ArmCpusState *s, unsigned i)
+{
+ return ARM_CPU(CPUS(s)->cpus[i]);
+}
+
+#endif /* HW_ARM_CPUS_H */
new file mode 100644
@@ -0,0 +1,63 @@
+/*
+ * ARM CPUs
+ *
+ * Copyright (c) 2022 Greensocs
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/arm/arm_cpus.h"
+#include "hw/cpu/cpus.h"
+#include "hw/qdev-properties.h"
+#include "cpu.h"
+
+static Property arm_cpus_props[] = {
+ /* FIXME: get the default values from the arm cpu object */
+ DEFINE_PROP_BOOL("reset-hivecs", ArmCpusState, reset_hivecs, false),
+ DEFINE_PROP_BOOL("has_el3", ArmCpusState, has_el3, false),
+ DEFINE_PROP_BOOL("has_el2", ArmCpusState, has_el2, false),
+ DEFINE_PROP_UINT64("reset-cbar", ArmCpusState, reset_cbar, 0),
+ DEFINE_PROP_END_OF_LIST()
+};
+
+static void arm_cpus_configure_cpu(CpusState *base, CPUState *cpu,
+ unsigned i)
+{
+ ArmCpusState *s = ARM_CPUS(base);
+ DeviceState *cpudev = DEVICE(cpu);
+
+ qdev_prop_set_uint32(cpudev, "core-count", base->topology.cpus);
+ qdev_prop_set_bit(cpudev, "reset-hivecs", s->reset_hivecs);
+ qdev_prop_set_bit(cpudev, "has_el3", s->has_el3);
+ qdev_prop_set_bit(cpudev, "has_el2", s->has_el2);
+ qdev_prop_set_uint64(cpudev, "reset-cbar", s->reset_cbar);
+}
+
+static void arm_cpus_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ CpusClass *cc = CPUS_CLASS(klass);
+
+ device_class_set_props(dc, arm_cpus_props);
+
+ cc->configure_cpu = arm_cpus_configure_cpu;
+ cc->base_cpu_type = TYPE_ARM_CPU;
+}
+
+static const TypeInfo arm_cpus_info = {
+ .name = TYPE_ARM_CPUS,
+ .parent = TYPE_CPUS,
+ .instance_size = sizeof(ArmCpusState),
+ .class_init = arm_cpus_class_init,
+};
+
+static void arm_cpus_register_types(void)
+{
+ type_register_static(&arm_cpus_info);
+}
+
+type_init(arm_cpus_register_types)
@@ -58,5 +58,6 @@ arm_ss.add(when: 'CONFIG_FSL_IMX7', if_true: files('fsl-imx7.c', 'mcimx7d-sabre.
arm_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c', 'smmuv3.c'))
arm_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 'mcimx6ul-evk.c'))
arm_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c'))
+arm_ss.add(files('arm_cpus.c'))
hw_arch += {'arm': arm_ss}
This object can be used to create a group of homogeneous arm cpus. Signed-off-by: Damien Hedde <damien.hedde@greensocs.com> --- include/hw/arm/arm_cpus.h | 45 ++++++++++++++++++++++++++++ hw/arm/arm_cpus.c | 63 +++++++++++++++++++++++++++++++++++++++ hw/arm/meson.build | 1 + 3 files changed, 109 insertions(+) create mode 100644 include/hw/arm/arm_cpus.h create mode 100644 hw/arm/arm_cpus.c