Implement multiple physical core support by creating
CPU devices accorading to the new topology and passing
pcore/vp information to CPC and CMGCR sub-devices.
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
hw/mips/cps.c | 66 +++++++++++++++++++++++++++++++--------------------
include/hw/mips/cps.h | 1 +
2 files changed, 41 insertions(+), 26 deletions(-)
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 07b73b0a1f..6cf02379a9 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -73,31 +73,43 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
return;
}
- for (int i = 0; i < s->num_vp; i++) {
- MIPSCPU *cpu = MIPS_CPU(object_new(s->cpu_type));
- CPUMIPSState *env = &cpu->env;
+ object_initialize_child(OBJECT(dev), "gcr", &s->gcr, TYPE_MIPS_GCR);
- /* All VPs are halted on reset. Leave powering up to CPC. */
- object_property_set_bool(OBJECT(cpu), "start-powered-off", true,
- &error_abort);
+ for (int corenum = 0; corenum < s->num_pcore; corenum++) {
+ for (int vpid = 0; vpid < s->num_vp; vpid++) {
+ int vpnum = corenum * s->num_vp + vpid;
+ int32_t globalnumber = (corenum << CP0GN_CoreNum) | vpid;
- /* All cores use the same clock tree */
- qdev_connect_clock_in(DEVICE(cpu), "clk-in", s->clock);
+ MIPSCPU *cpu = MIPS_CPU(object_new(s->cpu_type));
+ CPUMIPSState *env = &cpu->env;
- if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
- return;
- }
+ /* All VPs are halted on reset. Leave powering up to CPC. */
+ object_property_set_bool(OBJECT(cpu), "start-powered-off", true,
+ &error_abort);
+
+ object_property_set_int(OBJECT(cpu), "globalnumber", globalnumber,
+ &error_abort);
+
+ /* All cores use the same clock tree */
+ qdev_connect_clock_in(DEVICE(cpu), "clk-in", s->clock);
+
+ if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
+ return;
+ }
+
+ g_assert(vpnum == CPU(cpu)->cpu_index);
- /* Init internal devices */
- cpu_mips_irq_init_cpu(cpu);
- cpu_mips_clock_init(cpu);
+ /* Init internal devices */
+ cpu_mips_irq_init_cpu(cpu);
+ cpu_mips_clock_init(cpu);
- if (cpu_mips_itu_supported(env)) {
- itu_present = true;
- /* Attach ITC Tag to the VP */
- env->itc_tag = mips_itu_get_tag_region(&s->itu);
+ if (cpu_mips_itu_supported(env)) {
+ itu_present = true;
+ /* Attach ITC Tag to the VP */
+ env->itc_tag = mips_itu_get_tag_region(&s->itu);
+ }
+ qemu_register_reset(main_cpu_reset, cpu);
}
- qemu_register_reset(main_cpu_reset, cpu);
}
/* Inter-Thread Communication Unit */
@@ -119,8 +131,12 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
object_initialize_child(OBJECT(dev), "cpc", &s->cpc, TYPE_MIPS_CPC);
object_property_set_uint(OBJECT(&s->cpc), "num-vp", s->num_vp,
&error_abort);
+ object_property_set_uint(OBJECT(&s->cpc), "num-pcore", s->num_pcore,
+ &error_abort);
object_property_set_int(OBJECT(&s->cpc), "vp-start-running", 1,
&error_abort);
+ object_property_set_link(OBJECT(&s->cpc), "gcr", OBJECT(&s->gcr),
+ &error_abort);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpc), errp)) {
return;
}
@@ -130,7 +146,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
/* Global Interrupt Controller */
object_initialize_child(OBJECT(dev), "gic", &s->gic, TYPE_MIPS_GIC);
- object_property_set_uint(OBJECT(&s->gic), "num-vp", s->num_vp,
+ object_property_set_uint(OBJECT(&s->gic), "num-vp", s->num_vp * s->num_pcore,
&error_abort);
object_property_set_uint(OBJECT(&s->gic), "num-irq", 128,
&error_abort);
@@ -141,16 +157,13 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion(&s->container, 0,
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gic), 0));
- /* Global Configuration Registers */
- gcr_base = MIPS_CPU(first_cpu)->env.CP0_CMGCRBase << 4;
-
- object_initialize_child(OBJECT(dev), "gcr", &s->gcr, TYPE_MIPS_GCR);
+ gcr_base = GCR_BASE_ADDR;
+ object_property_set_uint(OBJECT(&s->gcr), "num-pcores", s->num_pcore,
+ &error_abort);
object_property_set_uint(OBJECT(&s->gcr), "num-vp", s->num_vp,
&error_abort);
object_property_set_int(OBJECT(&s->gcr), "gcr-rev", 0x800,
&error_abort);
- object_property_set_int(OBJECT(&s->gcr), "gcr-base", gcr_base,
- &error_abort);
object_property_set_link(OBJECT(&s->gcr), "gic", OBJECT(&s->gic.mr),
&error_abort);
object_property_set_link(OBJECT(&s->gcr), "cpc", OBJECT(&s->cpc.mr),
@@ -164,6 +177,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
}
static Property mips_cps_properties[] = {
+ DEFINE_PROP_UINT32("num-pcore", MIPSCPSState, num_pcore, 1),
DEFINE_PROP_UINT32("num-vp", MIPSCPSState, num_vp, 1),
DEFINE_PROP_UINT32("num-irq", MIPSCPSState, num_irq, 256),
DEFINE_PROP_STRING("cpu-type", MIPSCPSState, cpu_type),
diff --git a/include/hw/mips/cps.h b/include/hw/mips/cps.h
index 04d636246a..ea184b46a9 100644
--- a/include/hw/mips/cps.h
+++ b/include/hw/mips/cps.h
@@ -35,6 +35,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(MIPSCPSState, MIPS_CPS)
struct MIPSCPSState {
SysBusDevice parent_obj;
+ uint32_t num_pcore;
uint32_t num_vp;
uint32_t num_irq;
char *cpu_type;
--
2.34.1
© 2016 - 2024 Red Hat, Inc.