qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] hw/mips: Proper multi core support
@ 2024-05-06 15:31 Jiaxun Yang
  2024-05-06 15:31 ` [PATCH 1/5] target/mips: Make globalnumber a CPU property Jiaxun Yang
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Jiaxun Yang @ 2024-05-06 15:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Jiaxun Yang

Hi all,

This series implemented propper multiple core support for MIPS
CPS systsm.

Previously all CPUs are being implemented as a smt thread in a
single core. Now it respects topology supplied in QEMU args.

To test:
Build a latest kernel with 64r6el_defconfig (tested on 6.6,
next-20240506).

Then run:
```
qemu-system-mips64el -M boston -cpu I6500 -kernel ~/linux-next/vmlinux -smp 4,cores=2,threads=2 -append "console=ttyS0,115200" -nographic
```
In dmesg of guest kernel:
```
[    0.000000] VP topology {2,2} total 4
...
[    0.085190] smp: Bringing up secondary CPUs ...
[    0.090219] Primary instruction cache 64kB, VIPT, 4-way, linesize 64 bytes.
[    0.095461] Primary data cache 64kB, 4-way, PIPT, no aliases, linesize 64 bytes
[    0.096658] CPU1 revision is: 0001b000 (MIPS I6500)
[    0.096718] FPU revision is: 20f30300
[    0.124711] Synchronize counters for CPU 1: done.
[    0.940979] Primary instruction cache 64kB, VIPT, 4-way, linesize 64 bytes.
[    0.941041] Primary data cache 64kB, 4-way, PIPT, no aliases, linesize 64 bytes
[    0.941256] CPU2 revision is: 0001b000 (MIPS I6500)
[    0.941289] FPU revision is: 20f30300
[    0.965322] Synchronize counters for CPU 2: done.
[    1.260937] Primary instruction cache 64kB, VIPT, 4-way, linesize 64 bytes.
[    1.261001] Primary data cache 64kB, 4-way, PIPT, no aliases, linesize 64 bytes
[    1.261172] CPU3 revision is: 0001b000 (MIPS I6500)
[    1.261209] FPU revision is: 20f30300
[    1.285390] Synchronize counters for CPU 3: done.
[    1.346985] smp: Brought up 1 node, 4 CPUs
```

Please review.

Thanks

To: qemu-devel@nongnu.org
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
Jiaxun Yang (5):
      target/mips: Make globalnumber a CPU property
      hw/msic/mips_cmgcr: Implement multicore functions
      hw/msic/mips_cpc: Implement multi core support
      hw/mips/cps: Implement multi core support
      hw/mips/boston: Implement multi core support

 hw/mips/boston.c             |  37 +++++++++-
 hw/mips/cps.c                |  66 ++++++++++-------
 hw/misc/mips_cmgcr.c         | 168 +++++++++++++++++++++++++++++++++++--------
 hw/misc/mips_cpc.c           |  97 ++++++++++++++++++-------
 include/hw/mips/cps.h        |   1 +
 include/hw/misc/mips_cmgcr.h |  87 +++++++++++++++++++---
 include/hw/misc/mips_cpc.h   |  15 +++-
 target/mips/cpu.c            |  16 ++++-
 target/mips/cpu.h            |  10 ++-
 target/mips/sysemu/machine.c |   5 +-
 10 files changed, 403 insertions(+), 99 deletions(-)
---
base-commit: 248f6f62df073a3b4158fd0093863ab885feabb5
change-id: 20240506-mips-smp-9af9e71ad8c2

Best regards,
-- 
Jiaxun Yang <jiaxun.yang@flygoat.com>



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/5] target/mips: Make globalnumber a CPU property
  2024-05-06 15:31 [PATCH 0/5] hw/mips: Proper multi core support Jiaxun Yang
@ 2024-05-06 15:31 ` Jiaxun Yang
  2024-05-06 15:31 ` [PATCH 2/5] hw/msic/mips_cmgcr: Implement multicore functions Jiaxun Yang
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2024-05-06 15:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Jiaxun Yang

GlobalNumber marks topology information of a CPU instance.

Make it a CPU property to allow CPS to override topology information.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 target/mips/cpu.c            | 16 +++++++++++++++-
 target/mips/cpu.h            | 10 +++++++++-
 target/mips/sysemu/machine.c |  5 ++---
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index bbe01d07dd..762000d09b 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -296,7 +296,6 @@ static void mips_cpu_reset_hold(Object *obj, ResetType type)
     env->CP0_Random = env->tlb->nb_tlb - 1;
     env->tlb->tlb_in_use = env->tlb->nb_tlb;
     env->CP0_Wired = 0;
-    env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
     env->CP0_EBase = KSEG0_BASE | (cs->cpu_index & 0x3FF);
     if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
         env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
@@ -484,6 +483,12 @@ static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
 
     env->exception_base = (int32_t)0xBFC00000;
 
+#if !defined(CONFIG_USER_ONLY)
+    if (env->CP0_GlobalNumber == -1) {
+        env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
+    }
+#endif
+
 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
     mmu_init(env, env->cpu_model);
 #endif
@@ -563,6 +568,13 @@ static const TCGCPUOps mips_tcg_ops = {
 };
 #endif /* CONFIG_TCG */
 
+static Property mips_cpu_properties[] = {
+#if !defined(CONFIG_USER_ONLY)
+    DEFINE_PROP_INT32("globalnumber", MIPSCPU, env.CP0_GlobalNumber, -1),
+#endif
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void mips_cpu_class_init(ObjectClass *c, void *data)
 {
     MIPSCPUClass *mcc = MIPS_CPU_CLASS(c);
@@ -592,6 +604,8 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
 #ifdef CONFIG_TCG
     cc->tcg_ops = &mips_tcg_ops;
 #endif /* CONFIG_TCG */
+
+    device_class_set_props(dc, mips_cpu_properties);
 }
 
 static const TypeInfo mips_cpu_type_info = {
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 3e906a175a..7499608678 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -612,8 +612,13 @@ typedef struct CPUArchState {
 # define CP0EnLo_RI 31
 # define CP0EnLo_XI 30
 #endif
-    int32_t CP0_GlobalNumber;
+    /* CP0_GlobalNumber is preserved across CPU reset. */
 #define CP0GN_VPId 0
+#define CP0GN_VPId_MASK (0xFFUL << CP0GN_VPId)
+#define CP0GN_CoreNum 8
+#define CP0GN_CoreNum_MASK (0xFUL << CP0GN_CoreNum)
+#define CP0GN_ClusterNum 16
+#define CP0GN_ClusterNum_MASK (0xFUL << CP0GN_ClusterNum)
 /*
  * CP0 Register 4
  */
@@ -1175,6 +1180,9 @@ typedef struct CPUArchState {
     struct {} end_reset_fields;
 
     /* Fields from here on are preserved across CPU reset. */
+#if !defined(CONFIG_USER_ONLY)
+    int32_t CP0_GlobalNumber;
+#endif
     CPUMIPSMVPContext *mvp;
 #if !defined(CONFIG_USER_ONLY)
     CPUMIPSTLBContext *tlb;
diff --git a/target/mips/sysemu/machine.c b/target/mips/sysemu/machine.c
index 213fd637fc..235d640862 100644
--- a/target/mips/sysemu/machine.c
+++ b/target/mips/sysemu/machine.c
@@ -218,8 +218,8 @@ static const VMStateDescription vmstate_tlb = {
 
 const VMStateDescription vmstate_mips_cpu = {
     .name = "cpu",
-    .version_id = 21,
-    .minimum_version_id = 21,
+    .version_id = 22,
+    .minimum_version_id = 22,
     .post_load = cpu_post_load,
     .fields = (const VMStateField[]) {
         /* Active TC */
@@ -257,7 +257,6 @@ const VMStateDescription vmstate_mips_cpu = {
         VMSTATE_INT32(env.CP0_VPEOpt, MIPSCPU),
         VMSTATE_UINT64(env.CP0_EntryLo0, MIPSCPU),
         VMSTATE_UINT64(env.CP0_EntryLo1, MIPSCPU),
-        VMSTATE_INT32(env.CP0_GlobalNumber, MIPSCPU),
         VMSTATE_UINTTL(env.CP0_Context, MIPSCPU),
         VMSTATE_INT32(env.CP0_MemoryMapID, MIPSCPU),
         VMSTATE_INT32(env.CP0_PageMask, MIPSCPU),

-- 
2.34.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/5] hw/msic/mips_cmgcr: Implement multicore functions
  2024-05-06 15:31 [PATCH 0/5] hw/mips: Proper multi core support Jiaxun Yang
  2024-05-06 15:31 ` [PATCH 1/5] target/mips: Make globalnumber a CPU property Jiaxun Yang
@ 2024-05-06 15:31 ` Jiaxun Yang
  2024-05-06 15:31 ` [PATCH 3/5] hw/msic/mips_cpc: Implement multi core support Jiaxun Yang
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2024-05-06 15:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Jiaxun Yang

We implemented following functions to allow software
to probe and control VPs on secondary core

- Reading out pcore count and coherence state
- Two scratch GCRs for firmware
- Semaphore GCR for register locking
- Redirect block to other cores

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 hw/misc/mips_cmgcr.c         | 168 +++++++++++++++++++++++++++++++++++--------
 include/hw/misc/mips_cmgcr.h |  87 +++++++++++++++++++---
 2 files changed, 215 insertions(+), 40 deletions(-)

diff --git a/hw/misc/mips_cmgcr.c b/hw/misc/mips_cmgcr.c
index 2703040f45..8c2d184f2c 100644
--- a/hw/misc/mips_cmgcr.c
+++ b/hw/misc/mips_cmgcr.c
@@ -73,14 +73,19 @@ static inline void update_gic_base(MIPSGCRState *gcr, uint64_t val)
 static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
 {
     MIPSGCRState *gcr = (MIPSGCRState *) opaque;
-    MIPSGCRVPState *current_vps = &gcr->vps[current_cpu->cpu_index];
-    MIPSGCRVPState *other_vps = &gcr->vps[current_vps->other];
+    int redirect_corenum = mips_gcr_get_redirect_corenum(gcr);
+    int redirect_vpid = mips_gcr_get_redirect_vpid(gcr);
+    int current_corenum = mips_gcr_get_current_corenum(gcr);
+    int current_vpid = mips_gcr_get_current_vpid(gcr);
+    MIPSGCRPCoreState *current_pcore = &gcr->pcs[current_corenum];
+    MIPSGCRVPState *current_vps = &current_pcore->vps[current_vpid];
+    MIPSGCRPCoreState *other_pcore = &gcr->pcs[redirect_corenum];
+    MIPSGCRVPState *other_vps = &other_pcore->vps[redirect_vpid];
 
     switch (addr) {
     /* Global Control Block Register */
     case GCR_CONFIG_OFS:
-        /* Set PCORES to 0 */
-        return 0;
+        return gcr->num_pcores - 1;
     case GCR_BASE_OFS:
         return gcr->gcr_base;
     case GCR_REV_OFS:
@@ -96,7 +101,19 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
     case GCR_L2_CONFIG_OFS:
         /* L2 BYPASS */
         return GCR_L2_CONFIG_BYPASS_MSK;
+    case GCR_SYS_CONFIG2_OFS:
+        return gcr->num_vps << GCR_SYS_CONFIG2_MAXVP_SHF;
+    case GCR_SCRATCH0_OFS:
+        return gcr->scratch[0];
+    case GCR_SCRATCH1_OFS:
+        return gcr->scratch[1];
+    case GCR_SEM_OFS:
+        return gcr->sem;
         /* Core-Local and Core-Other Control Blocks */
+    case MIPS_CLCB_OFS + GCR_CL_COH_EN_OFS:
+        return current_pcore->coh_en;
+    case MIPS_COCB_OFS + GCR_CL_COH_EN_OFS:
+        return other_pcore->coh_en;
     case MIPS_CLCB_OFS + GCR_CL_CONFIG_OFS:
     case MIPS_COCB_OFS + GCR_CL_CONFIG_OFS:
         /* Set PVP to # of VPs - 1 */
@@ -105,10 +122,18 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
         return current_vps->reset_base;
     case MIPS_COCB_OFS + GCR_CL_RESETBASE_OFS:
         return other_vps->reset_base;
-    case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS:
-        return current_vps->other;
-    case MIPS_COCB_OFS + GCR_CL_OTHER_OFS:
-        return other_vps->other;
+    case MIPS_CLCB_OFS + GCR_CL_REDIRECT_OFS:
+        return current_vps->redirect;
+    case MIPS_COCB_OFS + GCR_CL_REDIRECT_OFS:
+        return other_vps->redirect;
+    case MIPS_CLCB_OFS + GCR_CL_ID_OFS:
+        return current_corenum;
+    case MIPS_COCB_OFS + GCR_CL_ID_OFS:
+        return redirect_corenum;
+    case MIPS_CLCB_OFS + GCR_CL_SCRATCH_OFS:
+        return current_vps->scratch;
+    case MIPS_COCB_OFS + GCR_CL_SCRATCH_OFS:
+        return other_vps->scratch;
     default:
         qemu_log_mask(LOG_UNIMP, "Read %d bytes at GCR offset 0x%" HWADDR_PRIx
                       "\n", size, addr);
@@ -123,12 +148,36 @@ static inline target_ulong get_exception_base(MIPSGCRVPState *vps)
     return (int32_t)(vps->reset_base & GCR_CL_RESET_BASE_RESETBASE_MSK);
 }
 
+static inline void set_redirect(MIPSGCRState *gcr,
+                                MIPSGCRVPState *vps, target_ulong data)
+{
+    int new_vpid = data & GCR_CL_REDIRECT_VP_MSK;
+    int new_coreid = (data & GCR_CL_REDIRECT_CORE_MSK) >> GCR_CL_REDIRECT_CORE_SHF;
+
+    if (new_vpid >= gcr->num_vps) {
+        return;
+    }
+
+    if (new_coreid >= gcr->num_pcores) {
+        return;
+    }
+
+    vps->redirect = data & (GCR_CL_REDIRECT_VP_MSK | GCR_CL_REDIRECT_CORE_MSK);
+}
+
 /* Write GCR registers */
 static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size)
 {
-    MIPSGCRState *gcr = (MIPSGCRState *)opaque;
-    MIPSGCRVPState *current_vps = &gcr->vps[current_cpu->cpu_index];
-    MIPSGCRVPState *other_vps = &gcr->vps[current_vps->other];
+    MIPSGCRState *gcr = (MIPSGCRState *) opaque;
+    int redirect_corenum = mips_gcr_get_redirect_corenum(gcr);
+    int redirect_vpid = mips_gcr_get_redirect_vpid(gcr);
+    int redirect_vpnum = mips_gcr_get_redirect_vpnum(gcr);
+    int current_corenum = mips_gcr_get_current_corenum(gcr);
+    int current_vpid = mips_gcr_get_current_vpid(gcr);
+    MIPSGCRPCoreState *current_pcore = &gcr->pcs[current_corenum];
+    MIPSGCRVPState *current_vps = &current_pcore->vps[current_vpid];
+    MIPSGCRPCoreState *other_pcore = &gcr->pcs[redirect_corenum];
+    MIPSGCRVPState *other_vps = &other_pcore->vps[redirect_vpid];
 
     switch (addr) {
     case GCR_BASE_OFS:
@@ -140,6 +189,25 @@ static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size)
     case GCR_CPC_BASE_OFS:
         update_cpc_base(gcr, data);
         break;
+    case GCR_SCRATCH0_OFS:
+        gcr->scratch[0] = data;
+        break;
+    case GCR_SCRATCH1_OFS:
+        gcr->scratch[1] = data;
+        break;
+    case GCR_SEM_OFS:
+        /* Write is inhibited if the SEM_LOCK bit is already 1 */
+        if ((data & GCR_SEM_LOCK_MASK) && (gcr->sem & GCR_SEM_LOCK_MASK)) {
+            break;
+        }
+        gcr->sem = data;
+        break;
+    case MIPS_CLCB_OFS + GCR_CL_COH_EN_OFS:
+        current_pcore->coh_en = data & 1;
+        break;
+    case MIPS_COCB_OFS + GCR_CL_COH_EN_OFS:
+        other_pcore->coh_en = data & 1;
+        break;
     case MIPS_CLCB_OFS + GCR_CL_RESETBASE_OFS:
         current_vps->reset_base = data & GCR_CL_RESET_BASE_MSK;
         cpu_set_exception_base(current_cpu->cpu_index,
@@ -147,18 +215,17 @@ static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size)
         break;
     case MIPS_COCB_OFS + GCR_CL_RESETBASE_OFS:
         other_vps->reset_base = data & GCR_CL_RESET_BASE_MSK;
-        cpu_set_exception_base(current_vps->other,
+        cpu_set_exception_base(redirect_vpnum,
                                get_exception_base(other_vps));
         break;
-    case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS:
-        if ((data & GCR_CL_OTHER_MSK) < gcr->num_vps) {
-            current_vps->other = data & GCR_CL_OTHER_MSK;
-        }
+    case MIPS_CLCB_OFS + GCR_CL_REDIRECT_OFS:
+        set_redirect(gcr, current_vps, data);
         break;
-    case MIPS_COCB_OFS + GCR_CL_OTHER_OFS:
-        if ((data & GCR_CL_OTHER_MSK) < gcr->num_vps) {
-            other_vps->other = data & GCR_CL_OTHER_MSK;
-        }
+    case MIPS_COCB_OFS + GCR_CL_SCRATCH_OFS:
+        other_vps->scratch = data;
+        break;
+    case MIPS_COCB_OFS + GCR_CL_REDIRECT_OFS:
+        set_redirect(gcr, other_vps, data);
         break;
     default:
         qemu_log_mask(LOG_UNIMP, "Write %d bytes at GCR offset 0x%" HWADDR_PRIx
@@ -189,30 +256,67 @@ static void mips_gcr_init(Object *obj)
 static void mips_gcr_reset(DeviceState *dev)
 {
     MIPSGCRState *s = MIPS_GCR(dev);
-    int i;
+    int pc, vp;
 
+    update_gcr_base(s, s->gcr_base);
     update_gic_base(s, 0);
     update_cpc_base(s, 0);
 
-    for (i = 0; i < s->num_vps; i++) {
-        s->vps[i].other = 0;
-        s->vps[i].reset_base = 0xBFC00000 & GCR_CL_RESET_BASE_MSK;
-        cpu_set_exception_base(i, get_exception_base(&s->vps[i]));
+    for (pc = 0; pc < s->num_pcores; pc++) {
+        s->pcs[pc].coh_en = 1;
+        for (vp = 0; vp < s->num_vps; vp++) {
+            int vpnum = pc * s->num_vps + vp;
+
+            s->pcs[pc].vps[vp].redirect = 0;
+            s->pcs[pc].vps[vp].reset_base = 0xBFC00000 & GCR_CL_RESET_BASE_MSK;
+            cpu_set_exception_base(vpnum, get_exception_base(&s->pcs[pc].vps[vp]));
+        }
     }
 }
 
-static const VMStateDescription vmstate_mips_gcr = {
-    .name = "mips-gcr",
+static const VMStateDescription vmstate_mips_gcr_vps = {
+    .name = "mips-gcr/vps",
     .version_id = 0,
     .minimum_version_id = 0,
     .fields = (const VMStateField[]) {
+        VMSTATE_UINT32(redirect, MIPSGCRVPState),
+        VMSTATE_UINT64(reset_base, MIPSGCRVPState),
+        VMSTATE_UINT64(scratch, MIPSGCRVPState),
+        VMSTATE_END_OF_LIST()
+    },
+};
+
+static const VMStateDescription vmstate_mips_gcr_pcs = {
+    .name = "mips-gcr/pcs",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .fields = (const VMStateField[]) {
+        VMSTATE_INT32(num_vps, MIPSGCRPCoreState),
+        VMSTATE_UINT32(coh_en, MIPSGCRPCoreState),
+        VMSTATE_STRUCT_VARRAY_ALLOC(vps, MIPSGCRPCoreState, num_vps, 0,
+                            vmstate_mips_gcr_vps, MIPSGCRVPState),
+        VMSTATE_END_OF_LIST()
+    },
+};
+
+static const VMStateDescription vmstate_mips_gcr = {
+    .name = "mips-gcr",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (const VMStateField[]) {
+        VMSTATE_UINT64_ARRAY(scratch, MIPSGCRState, 2),
+        VMSTATE_UINT32(sem, MIPSGCRState),
         VMSTATE_UINT64(cpc_base, MIPSGCRState),
+        VMSTATE_UINT64(gic_base, MIPSGCRState),
+        VMSTATE_STRUCT_VARRAY_ALLOC(pcs, MIPSGCRState, num_pcores, 0,
+                            vmstate_mips_gcr_pcs, MIPSGCRPCoreState),
         VMSTATE_END_OF_LIST()
     },
 };
 
 static Property mips_gcr_properties[] = {
-    DEFINE_PROP_UINT32("num-vp", MIPSGCRState, num_vps, 1),
+    DEFINE_PROP_INT32("num-pcores", MIPSGCRState, num_pcores, 1),
+    DEFINE_PROP_INT32("num-vp", MIPSGCRState, num_vps, 1),
     DEFINE_PROP_INT32("gcr-rev", MIPSGCRState, gcr_rev, 0x800),
     DEFINE_PROP_UINT64("gcr-base", MIPSGCRState, gcr_base, GCR_BASE_ADDR),
     DEFINE_PROP_LINK("gic", MIPSGCRState, gic_mr, TYPE_MEMORY_REGION,
@@ -226,8 +330,12 @@ static void mips_gcr_realize(DeviceState *dev, Error **errp)
 {
     MIPSGCRState *s = MIPS_GCR(dev);
 
-    /* Create local set of registers for each VP */
-    s->vps = g_new(MIPSGCRVPState, s->num_vps);
+    /* Create local set of registers for each VP and each pcore */
+    s->pcs = g_new(MIPSGCRPCoreState, s->num_pcores);
+    for (int i = 0; i < s->num_pcores; i++) {
+        s->pcs[i].num_vps = s->num_vps;
+        s->pcs[i].vps = g_new(MIPSGCRVPState, s->num_vps);
+    }
 }
 
 static void mips_gcr_class_init(ObjectClass *klass, void *data)
diff --git a/include/hw/misc/mips_cmgcr.h b/include/hw/misc/mips_cmgcr.h
index db4bf5f449..f75ff660c2 100644
--- a/include/hw/misc/mips_cmgcr.h
+++ b/include/hw/misc/mips_cmgcr.h
@@ -34,16 +34,27 @@ OBJECT_DECLARE_SIMPLE_TYPE(MIPSGCRState, MIPS_GCR)
 #define GCR_GIC_STATUS_OFS  0x00D0
 #define GCR_CPC_STATUS_OFS  0x00F0
 #define GCR_L2_CONFIG_OFS   0x0130
+#define GCR_SYS_CONFIG2_OFS 0x0150
+#define GCR_SCRATCH0_OFS    0x0280
+#define GCR_SCRATCH1_OFS    0x0288
+#define GCR_SEM_OFS         0x0640
 
 /* Core Local and Core Other Block Register Map */
-#define GCR_CL_CONFIG_OFS   0x0010
-#define GCR_CL_OTHER_OFS    0x0018
-#define GCR_CL_RESETBASE_OFS 0x0020
+#define GCR_CL_COH_EN_OFS    0x0008 /* Core-Local */
+#define GCR_CL_CONFIG_OFS    0x0010 /* Core-Local */
+#define GCR_CL_REDIRECT_OFS  0x0018 /* VP-Local */
+#define GCR_CL_RESETBASE_OFS 0x0020 /* VP-Local */
+#define GCR_CL_ID_OFS        0x0028 /* Core-Local */
+#define GCR_CL_SCRATCH_OFS   0x0060 /* VP-Local */
 
 /* GCR_L2_CONFIG register fields */
 #define GCR_L2_CONFIG_BYPASS_SHF    20
 #define GCR_L2_CONFIG_BYPASS_MSK    ((0x1ULL) << GCR_L2_CONFIG_BYPASS_SHF)
 
+/* GCR_SYS_CONFIG2 register fields */
+#define GCR_SYS_CONFIG2_MAXVP_SHF    0
+#define GCR_SYS_CONFIG2_MAXVP_MSK    ((0xFULL) << GCR_SYS_CONFIG2_MAXVP_SHF)
+
 /* GCR_BASE register fields */
 #define GCR_BASE_GCRBASE_MSK     0xffffffff8000ULL
 
@@ -52,14 +63,20 @@ OBJECT_DECLARE_SIMPLE_TYPE(MIPSGCRState, MIPS_GCR)
 #define GCR_GIC_BASE_GICBASE_MSK 0xFFFFFFFE0000ULL
 #define GCR_GIC_BASE_MSK (GCR_GIC_BASE_GICEN_MSK | GCR_GIC_BASE_GICBASE_MSK)
 
+/* GCR_SEM register fields */
+#define GCR_SEM_DATA_MSK  0x00000000EFFFFFFFULL
+#define GCR_SEM_LOCK_MASK 0x0000000080000000ULL
+
 /* GCR_CPC_BASE register fields */
 #define GCR_CPC_BASE_CPCEN_MSK   1
 #define GCR_CPC_BASE_CPCBASE_MSK 0xFFFFFFFF8000ULL
 #define GCR_CPC_BASE_MSK (GCR_CPC_BASE_CPCEN_MSK | GCR_CPC_BASE_CPCBASE_MSK)
 
-/* GCR_CL_OTHER_OFS register fields */
-#define GCR_CL_OTHER_VPOTHER_MSK 0x7
-#define GCR_CL_OTHER_MSK GCR_CL_OTHER_VPOTHER_MSK
+/* GCR_CL_REDIRECT_OFS register fields */
+#define GCR_CL_REDIRECT_VP_MSK 0x7U
+#define GCR_CL_REDIRECT_VP_SHF 0
+#define GCR_CL_REDIRECT_CORE_MSK 0xF00U
+#define GCR_CL_REDIRECT_CORE_SHF 8
 
 /* GCR_CL_RESETBASE_OFS register fields */
 #define GCR_CL_RESET_BASE_RESETBASE_MSK 0xFFFFF000U
@@ -67,15 +84,28 @@ OBJECT_DECLARE_SIMPLE_TYPE(MIPSGCRState, MIPS_GCR)
 
 typedef struct MIPSGCRVPState MIPSGCRVPState;
 struct MIPSGCRVPState {
-    uint32_t other;
+    uint32_t redirect;
     uint64_t reset_base;
+    uint64_t scratch;
+};
+
+typedef struct MIPSGCRPCoreState MIPSGCRPCoreState;
+struct MIPSGCRPCoreState {
+    int32_t num_vps; /* Number of VPs in that core */
+    uint32_t coh_en;
+    /* VP Local/Other Registers */
+    MIPSGCRVPState *vps;
 };
 
 struct MIPSGCRState {
     SysBusDevice parent_obj;
 
     int32_t gcr_rev;
-    uint32_t num_vps;
+    int32_t num_pcores; /* Number of physical cores */
+    int32_t num_vps; /* Number of VPs per physical core */
+
+    uint64_t scratch[2]; /* GCR Scratch */
+    uint32_t sem; /* GCR Semaphore */
     hwaddr gcr_base;
     MemoryRegion iomem;
     MemoryRegion *cpc_mr;
@@ -84,8 +114,45 @@ struct MIPSGCRState {
     uint64_t cpc_base;
     uint64_t gic_base;
 
-    /* VP Local/Other Registers */
-    MIPSGCRVPState *vps;
+    /* Core Local/Other Registers */
+    MIPSGCRPCoreState *pcs;
 };
 
+static inline int mips_gcr_get_current_corenum(MIPSGCRState *s)
+{
+    return current_cpu->cpu_index / s->num_vps;
+}
+
+static inline int mips_gcr_get_current_vpid(MIPSGCRState *s)
+{
+    return current_cpu->cpu_index % s->num_vps;
+}
+
+static inline int mips_gcr_get_redirect_corenum(MIPSGCRState *s)
+{
+    int current_corenum = mips_gcr_get_current_corenum(s);
+    int current_vpid = mips_gcr_get_current_vpid(s);
+    MIPSGCRVPState *current_vps = &s->pcs[current_corenum].vps[current_vpid];
+
+    return (current_vps->redirect & GCR_CL_REDIRECT_CORE_MSK) >>
+            GCR_CL_REDIRECT_CORE_SHF;
+}
+
+static inline int mips_gcr_get_redirect_vpid(MIPSGCRState *s)
+{
+    int current_corenum = mips_gcr_get_current_corenum(s);
+    int current_vpid = mips_gcr_get_current_vpid(s);
+    MIPSGCRVPState *current_vps = &s->pcs[current_corenum].vps[current_vpid];
+
+    return (current_vps->redirect & GCR_CL_REDIRECT_VP_MSK) >>
+            GCR_CL_REDIRECT_VP_SHF;
+}
+
+static inline int mips_gcr_get_redirect_vpnum(MIPSGCRState *s)
+{
+    int core = mips_gcr_get_redirect_corenum(s);
+    int vpid = mips_gcr_get_redirect_vpid(s);
+    return core * s->num_vps + vpid;
+}
+
 #endif /* MIPS_CMGCR_H */

-- 
2.34.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/5] hw/msic/mips_cpc: Implement multi core support
  2024-05-06 15:31 [PATCH 0/5] hw/mips: Proper multi core support Jiaxun Yang
  2024-05-06 15:31 ` [PATCH 1/5] target/mips: Make globalnumber a CPU property Jiaxun Yang
  2024-05-06 15:31 ` [PATCH 2/5] hw/msic/mips_cmgcr: Implement multicore functions Jiaxun Yang
@ 2024-05-06 15:31 ` Jiaxun Yang
  2024-05-06 15:31 ` [PATCH 4/5] hw/mips/cps: " Jiaxun Yang
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2024-05-06 15:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Jiaxun Yang

Implement multiple physical core support for MIPS CPC
controller. Including some R/O configuration registers
and VP bring up support on multiple cores.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 hw/misc/mips_cpc.c         | 97 ++++++++++++++++++++++++++++++++++------------
 include/hw/misc/mips_cpc.h | 15 ++++++-
 2 files changed, 85 insertions(+), 27 deletions(-)

diff --git a/hw/misc/mips_cpc.c b/hw/misc/mips_cpc.c
index 1e8fd2e699..f6a2f29088 100644
--- a/hw/misc/mips_cpc.c
+++ b/hw/misc/mips_cpc.c
@@ -25,9 +25,25 @@
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
 
+#include "hw/misc/mips_cmgcr.h"
 #include "hw/misc/mips_cpc.h"
 #include "hw/qdev-properties.h"
 
+static inline int cpc_vpnum_to_corenum(MIPSCPCState *cpc, int vpnum)
+{
+    return vpnum / cpc->num_vp;
+}
+
+static inline int cpc_vpnum_to_vpid(MIPSCPCState *cpc, int vpnum)
+{
+    return vpnum % cpc->num_vp;
+}
+
+static inline MIPSCPCPCoreState *cpc_vpnum_to_pcs(MIPSCPCState *cpc, int vpnum)
+{
+    return &cpc->pcs[cpc_vpnum_to_corenum(cpc, vpnum)];
+}
+
 static inline uint64_t cpc_vp_run_mask(MIPSCPCState *cpc)
 {
     return (1ULL << cpc->num_vp) - 1;
@@ -39,36 +55,41 @@ static void mips_cpu_reset_async_work(CPUState *cs, run_on_cpu_data data)
 
     cpu_reset(cs);
     cs->halted = 0;
-    cpc->vp_running |= 1ULL << cs->cpu_index;
+    cpc_vpnum_to_pcs(cpc, cs->cpu_index)->vp_running |=
+            1 << cpc_vpnum_to_vpid(cpc, cs->cpu_index);
 }
 
-static void cpc_run_vp(MIPSCPCState *cpc, uint64_t vp_run)
+static void cpc_run_vp(MIPSCPCState *cpc, int pcore, uint64_t vp_run)
 {
-    CPUState *cs = first_cpu;
+    MIPSCPCPCoreState *pcs = &cpc->pcs[pcore];
 
-    CPU_FOREACH(cs) {
-        uint64_t i = 1ULL << cs->cpu_index;
-        if (i & vp_run & ~cpc->vp_running) {
+    for (int vpid = 0; vpid < cpc->num_vp; vpid++) {
+        if ((1 << vpid) & vp_run & ~pcs->vp_running) {
+            int vpnum = pcore * cpc->num_vp + vpid;
             /*
              * To avoid racing with a CPU we are just kicking off.
              * We do the final bit of preparation for the work in
              * the target CPUs context.
              */
-            async_safe_run_on_cpu(cs, mips_cpu_reset_async_work,
-                                  RUN_ON_CPU_HOST_PTR(cpc));
+            async_safe_run_on_cpu(qemu_get_cpu(vpnum),
+                                    mips_cpu_reset_async_work,
+                                    RUN_ON_CPU_HOST_PTR(cpc));
+            pcs->vp_running |= 1 << vpid;
         }
     }
 }
 
-static void cpc_stop_vp(MIPSCPCState *cpc, uint64_t vp_stop)
+static void cpc_stop_vp(MIPSCPCState *cpc, int pcore, uint64_t vp_stop)
 {
-    CPUState *cs = first_cpu;
+    MIPSCPCPCoreState *pcs = &cpc->pcs[pcore];
+
+    for (int vpid = 0; vpid < cpc->num_vp; vpid++) {
+        if ((1 << vpid) & vp_stop & pcs->vp_running) {
+            int vpnum = pcore * cpc->num_vp + vpid;
+            CPUState *cs = qemu_get_cpu(vpnum);
 
-    CPU_FOREACH(cs) {
-        uint64_t i = 1ULL << cs->cpu_index;
-        if (i & vp_stop & cpc->vp_running) {
             cpu_interrupt(cs, CPU_INTERRUPT_HALT);
-            cpc->vp_running &= ~i;
+            pcs->vp_running &= ~(1 << vpid);
         }
     }
 }
@@ -77,15 +98,20 @@ static void cpc_write(void *opaque, hwaddr offset, uint64_t data,
                       unsigned size)
 {
     MIPSCPCState *s = opaque;
+    int current_corenum = cpc_vpnum_to_corenum(s, current_cpu->cpu_index);
 
     switch (offset) {
     case CPC_CL_BASE_OFS + CPC_VP_RUN_OFS:
+        cpc_run_vp(s, current_corenum, data);
+        break;
     case CPC_CO_BASE_OFS + CPC_VP_RUN_OFS:
-        cpc_run_vp(s, data & cpc_vp_run_mask(s));
+        cpc_run_vp(s, mips_gcr_get_redirect_corenum(s->gcr), data);
         break;
     case CPC_CL_BASE_OFS + CPC_VP_STOP_OFS:
+        cpc_stop_vp(s, current_corenum, data);
+        break;
     case CPC_CO_BASE_OFS + CPC_VP_STOP_OFS:
-        cpc_stop_vp(s, data & cpc_vp_run_mask(s));
+        cpc_stop_vp(s, mips_gcr_get_redirect_corenum(s->gcr), data);
         break;
     default:
         qemu_log_mask(LOG_UNIMP,
@@ -101,9 +127,13 @@ static uint64_t cpc_read(void *opaque, hwaddr offset, unsigned size)
     MIPSCPCState *s = opaque;
 
     switch (offset) {
+    case CPC_CL_BASE_OFS + CPC_CL_STAT_CONF_OFS:
+    case CPC_CO_BASE_OFS + CPC_CL_STAT_CONF_OFS:
+        return CPC_CL_STAT_CONF_SEQ_STATE_U6 << CPC_CL_STAT_CONF_SEQ_STATE_SHF;
     case CPC_CL_BASE_OFS + CPC_VP_RUNNING_OFS:
+        return cpc_vpnum_to_pcs(s, current_cpu->cpu_index)->vp_running;
     case CPC_CO_BASE_OFS + CPC_VP_RUNNING_OFS:
-        return s->vp_running;
+        return s->pcs[mips_gcr_get_redirect_corenum(s->gcr)].vp_running;
     default:
         qemu_log_mask(LOG_UNIMP,
                       "%s: Bad offset 0x%x\n",  __func__, (int)offset);
@@ -137,9 +167,11 @@ static void mips_cpc_realize(DeviceState *dev, Error **errp)
     if (s->vp_start_running > cpc_vp_run_mask(s)) {
         error_setg(errp,
                    "incorrect vp_start_running 0x%" PRIx64 " for num_vp = %d",
-                   s->vp_running, s->num_vp);
+                   s->vp_start_running, s->num_vp);
         return;
     }
+
+    s->pcs = g_new(MIPSCPCPCoreState, s->num_pcores);
 }
 
 static void mips_cpc_reset(DeviceState *dev)
@@ -147,25 +179,40 @@ static void mips_cpc_reset(DeviceState *dev)
     MIPSCPCState *s = MIPS_CPC(dev);
 
     /* Reflect the fact that all VPs are halted on reset */
-    s->vp_running = 0;
+    for (int i = 0; i < s->num_pcores; i++) {
+        s->pcs[i].vp_running = 0;
+    }
 
-    /* Put selected VPs into run state */
-    cpc_run_vp(s, s->vp_start_running);
+    /* Put selected VPs on core 0 into run state */
+    cpc_run_vp(s, 0, s->vp_start_running);
 }
 
-static const VMStateDescription vmstate_mips_cpc = {
-    .name = "mips-cpc",
+static const VMStateDescription vmstate_mips_cpc_pcs = {
+    .name = "mips-cpc/pcs",
     .version_id = 0,
     .minimum_version_id = 0,
     .fields = (const VMStateField[]) {
-        VMSTATE_UINT64(vp_running, MIPSCPCState),
+        VMSTATE_UINT64(vp_running, MIPSCPCPCoreState),
+        VMSTATE_END_OF_LIST()
+    },
+};
+
+static const VMStateDescription vmstate_mips_cpc = {
+    .name = "mips-cpc",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (const VMStateField[]) {
+        VMSTATE_STRUCT_VARRAY_ALLOC(pcs, MIPSCPCState, num_pcores, 0,
+                                    vmstate_mips_cpc_pcs, MIPSCPCPCoreState),
         VMSTATE_END_OF_LIST()
     },
 };
 
 static Property mips_cpc_properties[] = {
-    DEFINE_PROP_UINT32("num-vp", MIPSCPCState, num_vp, 0x1),
+    DEFINE_PROP_INT32("num-vp", MIPSCPCState, num_vp, 0x1),
+    DEFINE_PROP_INT32("num-pcore", MIPSCPCState, num_pcores, 0x1),
     DEFINE_PROP_UINT64("vp-start-running", MIPSCPCState, vp_start_running, 0x1),
+    DEFINE_PROP_LINK("gcr", MIPSCPCState, gcr, TYPE_MIPS_GCR, MIPSGCRState *),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/misc/mips_cpc.h b/include/hw/misc/mips_cpc.h
index fcafbd5e00..e88acf4681 100644
--- a/include/hw/misc/mips_cpc.h
+++ b/include/hw/misc/mips_cpc.h
@@ -30,6 +30,10 @@
 #define CPC_CO_BASE_OFS     0x4000
 
 /* CPC register offsets relative to block offsets */
+#define CPC_CL_CMD_OFS      0x00
+#define CPC_CL_STAT_CONF_OFS    0x08
+#define CPC_CL_STAT_CONF_SEQ_STATE_SHF  19
+#define CPC_CL_STAT_CONF_SEQ_STATE_U6   7
 #define CPC_VP_STOP_OFS     0x20
 #define CPC_VP_RUN_OFS      0x28
 #define CPC_VP_RUNNING_OFS  0x30
@@ -37,14 +41,21 @@
 #define TYPE_MIPS_CPC "mips-cpc"
 OBJECT_DECLARE_SIMPLE_TYPE(MIPSCPCState, MIPS_CPC)
 
+typedef struct MIPSCPCPCoreState MIPSCPCPCoreState;
+struct MIPSCPCPCoreState {
+    uint64_t vp_running;
+};
+
 struct MIPSCPCState {
     SysBusDevice parent_obj;
 
-    uint32_t num_vp;
+    int32_t num_pcores;
+    int32_t num_vp;
     uint64_t vp_start_running; /* VPs running from restart */
+    MIPSGCRState *gcr;
 
     MemoryRegion mr;
-    uint64_t vp_running; /* Indicates which VPs are in the run state */
+    MIPSCPCPCoreState *pcs;
 };
 
 #endif /* MIPS_CPC_H */

-- 
2.34.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/5] hw/mips/cps: Implement multi core support
  2024-05-06 15:31 [PATCH 0/5] hw/mips: Proper multi core support Jiaxun Yang
                   ` (2 preceding siblings ...)
  2024-05-06 15:31 ` [PATCH 3/5] hw/msic/mips_cpc: Implement multi core support Jiaxun Yang
@ 2024-05-06 15:31 ` Jiaxun Yang
  2024-05-06 15:31 ` [PATCH 5/5] hw/mips/boston: " Jiaxun Yang
  2025-07-15 19:08 ` [PATCH 0/5] hw/mips: Proper " Jiaxun Yang
  5 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2024-05-06 15:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Jiaxun Yang

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



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/5] hw/mips/boston: Implement multi core support
  2024-05-06 15:31 [PATCH 0/5] hw/mips: Proper multi core support Jiaxun Yang
                   ` (3 preceding siblings ...)
  2024-05-06 15:31 ` [PATCH 4/5] hw/mips/cps: " Jiaxun Yang
@ 2024-05-06 15:31 ` Jiaxun Yang
  2025-07-15 19:08 ` [PATCH 0/5] hw/mips: Proper " Jiaxun Yang
  5 siblings, 0 replies; 8+ messages in thread
From: Jiaxun Yang @ 2024-05-06 15:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Jiaxun Yang

Implement multiple physical core support by passing topology
to CPS subsystem and generate cpu-map fdt node to decribe
new topology.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 hw/mips/boston.c | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index 1b44fb354c..4ed7d366fe 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -542,7 +542,10 @@ static const void *create_fdt(BostonState *s,
     qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
     qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
 
+    qemu_fdt_add_subnode(fdt, "/cpus/cpu-map");
     for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
+        char *map_path;
+
         name = g_strdup_printf("/cpus/cpu@%d", cpu);
         qemu_fdt_add_subnode(fdt, name);
         qemu_fdt_setprop_string(fdt, name, "compatible", "img,mips");
@@ -550,6 +553,27 @@ static const void *create_fdt(BostonState *s,
         qemu_fdt_setprop_cell(fdt, name, "reg", cpu);
         qemu_fdt_setprop_string(fdt, name, "device_type", "cpu");
         qemu_fdt_setprop_cells(fdt, name, "clocks", clk_ph, FDT_BOSTON_CLK_CPU);
+        qemu_fdt_setprop_cell(fdt, name, "phandle", qemu_fdt_alloc_phandle(fdt));
+
+        if (ms->smp.threads > 1) {
+            map_path = g_strdup_printf(
+                "/cpus/cpu-map/socket%d/cluster%d/core%d/thread%d",
+                cpu / (ms->smp.clusters * ms->smp.cores * ms->smp.threads),
+                (cpu / (ms->smp.cores * ms->smp.threads)) % ms->smp.clusters,
+                (cpu / ms->smp.threads) % ms->smp.cores,
+                cpu % ms->smp.threads);
+        } else {
+            map_path = g_strdup_printf(
+                "/cpus/cpu-map/socket%d/cluster%d/core%d",
+                cpu / (ms->smp.clusters * ms->smp.cores),
+                (cpu / ms->smp.cores) % ms->smp.clusters,
+                cpu % ms->smp.cores);
+        }
+
+        qemu_fdt_add_path(fdt, map_path);
+        qemu_fdt_setprop_phandle(fdt, map_path, "cpu", name);
+
+        g_free(map_path);
         g_free(name);
     }
 
@@ -591,6 +615,15 @@ static const void *create_fdt(BostonState *s,
     g_free(name);
     g_free(gic_name);
 
+    /* CM node */
+    name = g_strdup_printf("/soc/cm@%" HWADDR_PRIx, memmap[BOSTON_CM].base);
+    qemu_fdt_add_subnode(fdt, name);
+    qemu_fdt_setprop_string(fdt, name, "compatible", "mti,mips-cm");
+    qemu_fdt_setprop_cells(fdt, name, "reg", memmap[BOSTON_CM].base,
+                            memmap[BOSTON_CM].size);
+    g_free(name);
+
+
     /* CDMM node */
     name = g_strdup_printf("/soc/cdmm@%" HWADDR_PRIx, memmap[BOSTON_CDMM].base);
     qemu_fdt_add_subnode(fdt, name);
@@ -703,7 +736,9 @@ static void boston_mach_init(MachineState *machine)
     object_initialize_child(OBJECT(machine), "cps", &s->cps, TYPE_MIPS_CPS);
     object_property_set_str(OBJECT(&s->cps), "cpu-type", machine->cpu_type,
                             &error_fatal);
-    object_property_set_uint(OBJECT(&s->cps), "num-vp", machine->smp.cpus,
+    object_property_set_uint(OBJECT(&s->cps), "num-pcore", machine->smp.cores,
+                            &error_fatal);
+    object_property_set_uint(OBJECT(&s->cps), "num-vp", machine->smp.threads,
                             &error_fatal);
     qdev_connect_clock_in(DEVICE(&s->cps), "clk-in",
                           qdev_get_clock_out(dev, "cpu-refclk"));

-- 
2.34.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/5] hw/mips: Proper multi core support
  2024-05-06 15:31 [PATCH 0/5] hw/mips: Proper multi core support Jiaxun Yang
                   ` (4 preceding siblings ...)
  2024-05-06 15:31 ` [PATCH 5/5] hw/mips/boston: " Jiaxun Yang
@ 2025-07-15 19:08 ` Jiaxun Yang
  2025-07-28 15:52   ` Philippe Mathieu-Daudé
  5 siblings, 1 reply; 8+ messages in thread
From: Jiaxun Yang @ 2025-07-15 19:08 UTC (permalink / raw)
  To: QEMU devel, Philippe Mathieu-Daudé



在2024年5月6日周一 下午4:31,Jiaxun Yang写道:
> Hi all,
>
> This series implemented propper multiple core support for MIPS
> CPS systsm.

Ping :-)

This is a really long outstanding series, I just want to get some
review before respin.

Thanks
Jiaxun

>
> Previously all CPUs are being implemented as a smt thread in a
> single core. Now it respects topology supplied in QEMU args.
>
> To test:
> Build a latest kernel with 64r6el_defconfig (tested on 6.6,
> next-20240506).
>
> Then run:
> ```
> qemu-system-mips64el -M boston -cpu I6500 -kernel ~/linux-next/vmlinux 
> -smp 4,cores=2,threads=2 -append "console=ttyS0,115200" -nographic
> ```
> In dmesg of guest kernel:
> ```
> [    0.000000] VP topology {2,2} total 4
> ...
> [    0.085190] smp: Bringing up secondary CPUs ...
> [    0.090219] Primary instruction cache 64kB, VIPT, 4-way, linesize 64 
> bytes.
> [    0.095461] Primary data cache 64kB, 4-way, PIPT, no aliases, 
> linesize 64 bytes
> [    0.096658] CPU1 revision is: 0001b000 (MIPS I6500)
> [    0.096718] FPU revision is: 20f30300
> [    0.124711] Synchronize counters for CPU 1: done.
> [    0.940979] Primary instruction cache 64kB, VIPT, 4-way, linesize 64 
> bytes.
> [    0.941041] Primary data cache 64kB, 4-way, PIPT, no aliases, 
> linesize 64 bytes
> [    0.941256] CPU2 revision is: 0001b000 (MIPS I6500)
> [    0.941289] FPU revision is: 20f30300
> [    0.965322] Synchronize counters for CPU 2: done.
> [    1.260937] Primary instruction cache 64kB, VIPT, 4-way, linesize 64 
> bytes.
> [    1.261001] Primary data cache 64kB, 4-way, PIPT, no aliases, 
> linesize 64 bytes
> [    1.261172] CPU3 revision is: 0001b000 (MIPS I6500)
> [    1.261209] FPU revision is: 20f30300
> [    1.285390] Synchronize counters for CPU 3: done.
> [    1.346985] smp: Brought up 1 node, 4 CPUs
> ```
>
> Please review.
>
> Thanks
>
> To: qemu-devel@nongnu.org
> Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
>
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> ---
> Jiaxun Yang (5):
>       target/mips: Make globalnumber a CPU property
>       hw/msic/mips_cmgcr: Implement multicore functions
>       hw/msic/mips_cpc: Implement multi core support
>       hw/mips/cps: Implement multi core support
>       hw/mips/boston: Implement multi core support
>
>  hw/mips/boston.c             |  37 +++++++++-
>  hw/mips/cps.c                |  66 ++++++++++-------
>  hw/misc/mips_cmgcr.c         | 168 +++++++++++++++++++++++++++++++++++--------
>  hw/misc/mips_cpc.c           |  97 ++++++++++++++++++-------
>  include/hw/mips/cps.h        |   1 +
>  include/hw/misc/mips_cmgcr.h |  87 +++++++++++++++++++---
>  include/hw/misc/mips_cpc.h   |  15 +++-
>  target/mips/cpu.c            |  16 ++++-
>  target/mips/cpu.h            |  10 ++-
>  target/mips/sysemu/machine.c |   5 +-
>  10 files changed, 403 insertions(+), 99 deletions(-)
> ---
> base-commit: 248f6f62df073a3b4158fd0093863ab885feabb5
> change-id: 20240506-mips-smp-9af9e71ad8c2
>
> Best regards,
> -- 
> Jiaxun Yang <jiaxun.yang@flygoat.com>

-- 
- Jiaxun


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/5] hw/mips: Proper multi core support
  2025-07-15 19:08 ` [PATCH 0/5] hw/mips: Proper " Jiaxun Yang
@ 2025-07-28 15:52   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-07-28 15:52 UTC (permalink / raw)
  To: Jiaxun Yang, QEMU devel

On 15/7/25 21:08, Jiaxun Yang wrote:
> 
> 
> 在2024年5月6日周一 下午4:31,Jiaxun Yang写道:
>> Hi all,
>>
>> This series implemented propper multiple core support for MIPS
>> CPS systsm.
> 
> Ping :-)
> 
> This is a really long outstanding series, I just want to get some
> review before respin.

Tagged for review, sorry I missed it...

> 
> Thanks
> Jiaxun
> 
>>
>> Previously all CPUs are being implemented as a smt thread in a
>> single core. Now it respects topology supplied in QEMU args.
>>
>> To test:
>> Build a latest kernel with 64r6el_defconfig (tested on 6.6,
>> next-20240506).
>>
>> Then run:
>> ```
>> qemu-system-mips64el -M boston -cpu I6500 -kernel ~/linux-next/vmlinux
>> -smp 4,cores=2,threads=2 -append "console=ttyS0,115200" -nographic
>> ```
>> In dmesg of guest kernel:
>> ```
>> [    0.000000] VP topology {2,2} total 4
>> ...
>> [    0.085190] smp: Bringing up secondary CPUs ...
>> [    0.090219] Primary instruction cache 64kB, VIPT, 4-way, linesize 64
>> bytes.
>> [    0.095461] Primary data cache 64kB, 4-way, PIPT, no aliases,
>> linesize 64 bytes
>> [    0.096658] CPU1 revision is: 0001b000 (MIPS I6500)
>> [    0.096718] FPU revision is: 20f30300
>> [    0.124711] Synchronize counters for CPU 1: done.
>> [    0.940979] Primary instruction cache 64kB, VIPT, 4-way, linesize 64
>> bytes.
>> [    0.941041] Primary data cache 64kB, 4-way, PIPT, no aliases,
>> linesize 64 bytes
>> [    0.941256] CPU2 revision is: 0001b000 (MIPS I6500)
>> [    0.941289] FPU revision is: 20f30300
>> [    0.965322] Synchronize counters for CPU 2: done.
>> [    1.260937] Primary instruction cache 64kB, VIPT, 4-way, linesize 64
>> bytes.
>> [    1.261001] Primary data cache 64kB, 4-way, PIPT, no aliases,
>> linesize 64 bytes
>> [    1.261172] CPU3 revision is: 0001b000 (MIPS I6500)
>> [    1.261209] FPU revision is: 20f30300
>> [    1.285390] Synchronize counters for CPU 3: done.
>> [    1.346985] smp: Brought up 1 node, 4 CPUs
>> ```
>>
>> Please review.
>>
>> Thanks
>>
>> To: qemu-devel@nongnu.org
>> Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
>>
>> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>> ---
>> Jiaxun Yang (5):
>>        target/mips: Make globalnumber a CPU property
>>        hw/msic/mips_cmgcr: Implement multicore functions
>>        hw/msic/mips_cpc: Implement multi core support
>>        hw/mips/cps: Implement multi core support
>>        hw/mips/boston: Implement multi core support
>>
>>   hw/mips/boston.c             |  37 +++++++++-
>>   hw/mips/cps.c                |  66 ++++++++++-------
>>   hw/misc/mips_cmgcr.c         | 168 +++++++++++++++++++++++++++++++++++--------
>>   hw/misc/mips_cpc.c           |  97 ++++++++++++++++++-------
>>   include/hw/mips/cps.h        |   1 +
>>   include/hw/misc/mips_cmgcr.h |  87 +++++++++++++++++++---
>>   include/hw/misc/mips_cpc.h   |  15 +++-
>>   target/mips/cpu.c            |  16 ++++-
>>   target/mips/cpu.h            |  10 ++-
>>   target/mips/sysemu/machine.c |   5 +-
>>   10 files changed, 403 insertions(+), 99 deletions(-)
>> ---
>> base-commit: 248f6f62df073a3b4158fd0093863ab885feabb5
>> change-id: 20240506-mips-smp-9af9e71ad8c2
>>
>> Best regards,
>> -- 
>> Jiaxun Yang <jiaxun.yang@flygoat.com>
> 



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-07-28 15:52 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-06 15:31 [PATCH 0/5] hw/mips: Proper multi core support Jiaxun Yang
2024-05-06 15:31 ` [PATCH 1/5] target/mips: Make globalnumber a CPU property Jiaxun Yang
2024-05-06 15:31 ` [PATCH 2/5] hw/msic/mips_cmgcr: Implement multicore functions Jiaxun Yang
2024-05-06 15:31 ` [PATCH 3/5] hw/msic/mips_cpc: Implement multi core support Jiaxun Yang
2024-05-06 15:31 ` [PATCH 4/5] hw/mips/cps: " Jiaxun Yang
2024-05-06 15:31 ` [PATCH 5/5] hw/mips/boston: " Jiaxun Yang
2025-07-15 19:08 ` [PATCH 0/5] hw/mips: Proper " Jiaxun Yang
2025-07-28 15:52   ` Philippe Mathieu-Daudé

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).