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.

Reply via email to