On Wed, Jul 16, 2025 at 11:54:04AM +0200, Luc Michel wrote:
> Add a way to configure the MP affinity value of the CPUs given their
> core and cluster IDs. For the Versal APU CPUs, the MP affinity value is
> directly given by the core ID.
> 
> Signed-off-by: Luc Michel <luc.mic...@amd.com>

Reviewed-by: Francisco Iglesias <francisco.igles...@amd.com>

> ---
>  hw/arm/xlnx-versal.c | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
> index 5a08ad07b28..35c32de0159 100644
> --- a/hw/arm/xlnx-versal.c
> +++ b/hw/arm/xlnx-versal.c
> @@ -88,10 +88,18 @@ typedef struct VersalCpuClusterMap {
>      size_t num_core;
>      size_t num_cluster;
>      uint32_t qemu_cluster_id;
>      bool dtb_expose;
>  
> +    struct {
> +        uint64_t base;
> +        uint64_t core_mask;
> +        uint64_t core_shift;
> +        uint64_t cluster_mask;
> +        uint64_t cluster_shift;
> +    } mp_affinity;
> +
>      enum StartPoweredOffMode start_powered_off;
>  } VersalCpuClusterMap;
>  
>  typedef struct VersalMap {
>      VersalCpuClusterMap apu;
> @@ -196,10 +204,15 @@ static const VersalMap VERSAL_MAP = {
>          .name = "apu",
>          .cpu_model = ARM_CPU_TYPE_NAME("cortex-a72"),
>          .num_cluster = 1,
>          .num_core = 2,
>          .qemu_cluster_id = 0,
> +        .mp_affinity = {
> +            .base = 0x0,
> +            .core_mask = 0xff,
> +            .core_shift = 0,
> +        },
>          .start_powered_off = SPO_SECONDARIES,
>          .dtb_expose = true,
>          .gic = {
>              .version = 3,
>              .dist = 0xf9000000,
> @@ -565,23 +578,31 @@ static DeviceState *versal_create_cpu(Versal *s,
>                                        size_t core_idx)
>  {
>      DeviceState *cpu = qdev_new(map->cpu_model);
>      ARMCPU *arm_cpu = ARM_CPU(cpu);
>      Object *obj = OBJECT(cpu);
> +    uint64_t affinity;
>      bool start_off;
>      size_t idx = cluster_idx * map->num_core + core_idx;
>      g_autofree char *name;
>      g_autofree char *node = NULL;
>  
> +    affinity = map->mp_affinity.base;
> +    affinity |= (cluster_idx & map->mp_affinity.cluster_mask)
> +        << map->mp_affinity.cluster_shift;
> +    affinity |= (core_idx & map->mp_affinity.core_mask)
> +        << map->mp_affinity.core_shift;
> +
>      start_off = map->start_powered_off == SPO_ALL
>          || ((map->start_powered_off == SPO_SECONDARIES)
>              && (cluster_idx || core_idx));
>  
>      name = g_strdup_printf("%s[*]", map->name);
>      object_property_add_child(OBJECT(qemu_cluster), name, obj);
>      object_property_set_bool(obj, "start-powered-off", start_off,
>                               &error_abort);
> +    qdev_prop_set_uint64(cpu, "mp-affinity", affinity);
>      qdev_prop_set_int32(cpu, "core-count",  map->num_core);
>      object_property_set_link(obj, "memory", OBJECT(cpu_mr), &error_abort);
>      qdev_realize_and_unref(cpu, NULL, &error_fatal);
>  
>      if (!map->dtb_expose) {
> -- 
> 2.50.0
> 

Reply via email to