* [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 = ¤t_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 = ¤t_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).