diff mbox series

[4/5] hw/mips/cps: Implement multi core support

Message ID 20240506-mips-smp-v1-4-3cc234786910@flygoat.com (mailing list archive)
State New, archived
Headers show
Series hw/mips: Proper multi core support | expand

Commit Message

Jiaxun Yang May 6, 2024, 3:31 p.m. UTC
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 mbox series

Patch

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;