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.y...@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