On 8. 8. 25. 18:26, Philippe Mathieu-Daudé wrote: > CAUTION: This email originated from outside of the organization. Do > not click links or open attachments unless you recognize the sender > and know the content is safe. > > > On 17/7/25 11:38, Djordje Todorovic wrote: >> Add support for the Coherent Processing System for RISC-V. >> This enables SMP support for RISC-V boards that require >> cache-coherent multiprocessor systems. >> >> Signed-off-by: Chao-ying Fu <c...@mips.com> >> Signed-off-by: Djordje Todorovic <djordje.todoro...@htecgroup.com> >> --- >> hw/misc/Kconfig | 5 ++ >> hw/riscv/cps.c | 197 +++++++++++++++++++++++++++++++++++++++++ >> hw/riscv/meson.build | 2 + >> include/hw/riscv/cps.h | 76 ++++++++++++++++ >> 4 files changed, 280 insertions(+) >> create mode 100644 hw/riscv/cps.c >> create mode 100644 include/hw/riscv/cps.h > > >> +static void main_cpu_reset(void *opaque) >> +{ >> + RISCVCPU *cpu = opaque; >> + CPUState *cs = CPU(cpu); > > If you call in [*]: > > qemu_register_reset(main_cpu_reset, s->cpus[i]); > > then here you can just do: > > CPUState *cs = opaque; > >> + >> + cpu_reset(cs); >> +} >> + >> +static void riscv_cps_realize(DeviceState *dev, Error **errp) >> +{ >> + RISCVCPSState *s = RISCV_CPS(dev); >> + RISCVCPU *cpu; >> + int i; >> + > > Please check num_vp range. > >> + /* Allocate CPU array */ >> + s->cpus = g_new0(CPUState *, s->num_vp); >> + >> + /* Set up cpu_index and mhartid for avaiable CPUs. */ >> + int harts_in_cluster = s->num_hart * s->num_core; >> + int num_of_clusters = s->num_vp / harts_in_cluster; >> + for (i = 0; i < s->num_vp; i++) { >> + cpu = RISCV_CPU(object_new(s->cpu_type)); >> + >> + /* All VPs are halted on reset. Leave powering up to CPC. */ >> + object_property_set_bool(OBJECT(cpu), "start-powered-off", >> true, >> + &error_abort); >> + >> + if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) { >> + return; >> + } >> + >> + /* Store CPU in array */ >> + s->cpus[i] = CPU(cpu); >> + >> + /* Set up mhartid */ >> + int cluster_id = i / harts_in_cluster; >> + int hart_id = (i % harts_in_cluster) % s->num_hart; >> + int core_id = (i % harts_in_cluster) / s->num_hart; >> + int mhartid = (cluster_id << MHARTID_CLUSTER_SHIFT) + >> + (core_id << MHARTID_CORE_SHIFT) + >> + (hart_id << MHARTID_HART_SHIFT); >> + cpu->env.mhartid = mhartid; >> + qemu_register_reset(main_cpu_reset, cpu); > > [*] > >> + } >> + >> + /* Cluster Power Controller */ >> + object_initialize_child(OBJECT(dev), "cpc", &s->cpc, >> TYPE_RISCV_CPC); >> + object_property_set_uint(OBJECT(&s->cpc), "cluster-id", 0, >> + &error_abort); >> + object_property_set_uint(OBJECT(&s->cpc), "num-vp", s->num_vp, >> + &error_abort); >> + object_property_set_uint(OBJECT(&s->cpc), "num-hart", s->num_hart, >> + &error_abort); >> + object_property_set_uint(OBJECT(&s->cpc), "num-core", s->num_core, >> + &error_abort); >> + object_property_set_int(OBJECT(&s->cpc), "vp-start-running", 1, >> + &error_abort); > > (1 is already the default) > >> + >> + /* Pass CPU array to CPC */ >> + s->cpc.cpus = s->cpus; > > Please do that using a link property. > >> + >> + if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpc), errp)) { >> + return; >> + } >> + >> + memory_region_add_subregion(&s->container, 0, >> + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpc), 0)); >> + >> + /* Global Configuration Registers */ >> + object_initialize_child(OBJECT(dev), "gcr", &s->gcr, >> TYPE_RISCV_GCR); >> + object_property_set_uint(OBJECT(&s->gcr), "cluster-id", 0, >> + &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", 0xa00, >> + &error_abort); >> + object_property_set_int(OBJECT(&s->gcr), "gcr-base", s->gcr_base, >> + &error_abort); >> + object_property_set_link(OBJECT(&s->gcr), "cpc", >> OBJECT(&s->cpc.mr), >> + &error_abort); >> + if (!sysbus_realize(SYS_BUS_DEVICE(&s->gcr), errp)) { >> + return; >> + } >> + >> + memory_region_add_subregion(&s->container, s->gcr_base, >> + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gcr), 0)); >> + >> + for (i = 0; i < num_of_clusters; i++) { >> + uint64_t cm_base = GLOBAL_CM_BASE + (CM_SIZE * i); >> + uint32_t hartid_base = i << MHARTID_CLUSTER_SHIFT; >> + s->aplic = riscv_aplic_create(cm_base + AIA_PLIC_M_OFFSET, >> + AIA_PLIC_M_SIZE, >> + hartid_base, /* hartid_base */ >> + MAX_HARTS, /* num_harts */ >> + APLIC_NUM_SOURCES, >> + APLIC_NUM_PRIO_BITS, >> + false, true, NULL); >> + riscv_aplic_create(cm_base + AIA_PLIC_S_OFFSET, >> + AIA_PLIC_S_SIZE, >> + hartid_base, /* hartid_base */ >> + MAX_HARTS, /* num_harts */ >> + APLIC_NUM_SOURCES, >> + APLIC_NUM_PRIO_BITS, >> + false, false, s->aplic); >> + /* PLIC changes msi_nonbroken to ture. We revert the change. */ >> + msi_nonbroken = false; >> + riscv_aclint_swi_create(cm_base + AIA_CLINT_OFFSET, >> + hartid_base, MAX_HARTS, false); >> + riscv_aclint_mtimer_create(cm_base + AIA_CLINT_OFFSET + >> + RISCV_ACLINT_SWI_SIZE, >> + RISCV_ACLINT_DEFAULT_MTIMER_SIZE, >> + hartid_base, >> + MAX_HARTS, >> + RISCV_ACLINT_DEFAULT_MTIMECMP, >> + RISCV_ACLINT_DEFAULT_MTIME, >> + RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, false); >> + } >> +}
Thank you! I will address it within v7.