From: Ruslan Ruslichenko <Ruslan_Ruslichenko@epam.com>
Add support for grouping CPUs into clusters during
FDT machine instantiation.
The clusters are automatically created if CPU parent
is not already an existing cluster.
Signed-off-by: Ruslan Ruslichenko <Ruslan_Ruslichenko@epam.com>
---
hw/core/fdt_generic.c | 77 +++++++++++++++++++++++++++++++++++
include/hw/core/fdt_generic.h | 13 ++++++
2 files changed, 90 insertions(+)
diff --git a/hw/core/fdt_generic.c b/hw/core/fdt_generic.c
index b3ef0b7d0a..3c28f42491 100644
--- a/hw/core/fdt_generic.c
+++ b/hw/core/fdt_generic.c
@@ -31,6 +31,7 @@
#include "migration/vmstate.h"
#include "qemu/coroutine.h"
#include "qemu/log.h"
+#include "hw/cpu/cluster.h"
#include "system/reset.h"
#ifndef FDT_GENERIC_ERR_DEBUG
@@ -175,6 +176,75 @@ int fdt_init_has_opaque(FDTMachineInfo *fdti, char *node_path)
return 0;
}
+static int get_next_cpu_cluster_id(void)
+{
+ static int i;
+
+ return i++;
+}
+
+void fdt_init_register_user_cpu_cluster(FDTMachineInfo *fdti, Object *cluster)
+{
+ int i = get_next_cpu_cluster_id();
+ DeviceState *dev = DEVICE(cluster);
+ FDTCPUCluster *cl;
+
+ qdev_prop_set_uint32(dev, "cluster-id", i);
+
+ cl = g_new0(FDTCPUCluster, 1);
+ cl->cpu_cluster = cluster;
+ cl->next = fdti->clusters;
+ cl->user = true;
+
+ fdti->clusters = cl;
+
+ DB_PRINT(0, "%s: Registered user-defined cpu cluster with id %d\n",
+ object_get_canonical_path(cluster), i);
+}
+
+static void *fdt_init_add_cpu_cluster(FDTMachineInfo *fdti, char *compat)
+{
+ FDTCPUCluster *cl = g_malloc0(sizeof(*cl));
+ int i = get_next_cpu_cluster_id();
+ char *name = g_strdup_printf("cluster%d", i);
+ Object *obj;
+
+ obj = object_new(TYPE_CPU_CLUSTER);
+ object_property_add_child(object_get_root(), name, OBJECT(obj));
+ qdev_prop_set_uint32(DEVICE(obj), "cluster-id", i);
+
+ cl->cpu_type = g_strdup(compat);
+ cl->cpu_cluster = obj;
+ cl->next = fdti->clusters;
+
+ fdti->clusters = cl;
+
+ g_free(name);
+
+ return obj;
+}
+
+void *fdt_init_get_cpu_cluster(FDTMachineInfo *fdti, Object *parent,
+ char *compat)
+{
+ FDTCPUCluster *cl = fdti->clusters;
+
+ if (object_dynamic_cast(parent, TYPE_CPU_CLUSTER)) {
+ /* The direct parent of this CPU is a CPU cluster. Use it. */
+ return parent;
+ }
+
+ while (cl) {
+ if (!cl->user && !strcmp(compat, cl->cpu_type)) {
+ return cl->cpu_cluster;
+ }
+ cl = cl->next;
+ }
+
+ /* No cluster found so create and return a new one */
+ return fdt_init_add_cpu_cluster(fdti, compat);
+}
+
void *fdt_init_get_opaque(FDTMachineInfo *fdti, char *node_path)
{
FDTDevOpaque *dp;
@@ -199,8 +269,15 @@ FDTMachineInfo *fdt_init_new_fdti(void *fdt)
void fdt_init_destroy_fdti(FDTMachineInfo *fdti)
{
+ FDTCPUCluster *cl = fdti->clusters;
FDTDevOpaque *dp;
+ while (cl) {
+ FDTCPUCluster *tmp = cl;
+ cl = cl->next;
+ g_free(tmp->cpu_type);
+ g_free(tmp);
+ }
for (dp = fdti->dev_opaques; dp->node_path; dp++) {
g_free(dp->node_path);
}
diff --git a/include/hw/core/fdt_generic.h b/include/hw/core/fdt_generic.h
index a21e3c2440..46b7dc084b 100644
--- a/include/hw/core/fdt_generic.h
+++ b/include/hw/core/fdt_generic.h
@@ -17,6 +17,13 @@ typedef struct FDTDevOpaque {
void *opaque;
} FDTDevOpaque;
+typedef struct FDTCPUCluster {
+ char *cpu_type;
+ void *cpu_cluster;
+ void *next;
+ bool user;
+} FDTCPUCluster;
+
typedef struct FDTMachineInfo {
/* the fdt blob */
void *fdt;
@@ -26,6 +33,8 @@ typedef struct FDTMachineInfo {
FDTDevOpaque *dev_opaques;
/* recheck coroutine queue */
CoQueue *cq;
+ /* list of all CPU clusters */
+ FDTCPUCluster *clusters;
} FDTMachineInfo;
/*
@@ -73,6 +82,10 @@ void fdt_init_set_opaque(FDTMachineInfo *fdti, char *node_path, void *opaque);
int fdt_init_has_opaque(FDTMachineInfo *fdti, char *node_path);
void *fdt_init_get_opaque(FDTMachineInfo *fdti, char *node_path);
+void *fdt_init_get_cpu_cluster(FDTMachineInfo *fdti, Object *parent,
+ char *compat);
+void fdt_init_register_user_cpu_cluster(FDTMachineInfo *fdti, Object *cluster);
+
/* statically register a FDTInitFn as being associate with a compatibility */
#define fdt_register_compatibility_opaque(function, compat, n, opaque) \
--
2.43.0