From: Ruslan Ruslichenko <Ruslan_Ruslichenko@epam.com>
The patch adds infrastructure to parse device tree
and associate fdt nodes and created objects.
This will be used during instantiating machine from the
devices tree.
Signed-off-by: Ruslan Ruslichenko <Ruslan_Ruslichenko@epam.com>
---
hw/core/fdt_generic.c | 70 +++++++++++++++++++++++++++++++++++
include/hw/core/fdt_generic.h | 26 ++++++++++++-
2 files changed, 95 insertions(+), 1 deletion(-)
diff --git a/hw/core/fdt_generic.c b/hw/core/fdt_generic.c
index d3ab8f9132..b3ef0b7d0a 100644
--- a/hw/core/fdt_generic.c
+++ b/hw/core/fdt_generic.c
@@ -28,7 +28,10 @@
#include "qemu/osdep.h"
#include "hw/core/fdt_generic.h"
#include "hw/core/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "qemu/coroutine.h"
#include "qemu/log.h"
+#include "system/reset.h"
#ifndef FDT_GENERIC_ERR_DEBUG
#define FDT_GENERIC_ERR_DEBUG 0
@@ -137,3 +140,70 @@ void dump_inst_bind_table(void)
printf("FDT INSTANCE BINDING TABLE:\n");
dump_table(inst_bind_list_head);
}
+
+void fdt_init_yield(FDTMachineInfo *fdti)
+{
+ static int yield_index;
+ int this_yield = yield_index++;
+
+ DB_PRINT(1, "Yield #%d\n", this_yield);
+ qemu_co_queue_wait(fdti->cq, NULL);
+ DB_PRINT(1, "Unyield #%d\n", this_yield);
+}
+
+void fdt_init_set_opaque(FDTMachineInfo *fdti, char *node_path, void *opaque)
+{
+ FDTDevOpaque *dp;
+ for (dp = fdti->dev_opaques;
+ dp->node_path && strcmp(dp->node_path, node_path);
+ dp++)
+ ;
+ if (!dp->node_path) {
+ dp->node_path = strdup(node_path);
+ }
+ dp->opaque = opaque;
+}
+
+int fdt_init_has_opaque(FDTMachineInfo *fdti, char *node_path)
+{
+ FDTDevOpaque *dp;
+ for (dp = fdti->dev_opaques; dp->node_path; dp++) {
+ if (!strcmp(dp->node_path, node_path)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void *fdt_init_get_opaque(FDTMachineInfo *fdti, char *node_path)
+{
+ FDTDevOpaque *dp;
+ for (dp = fdti->dev_opaques; dp->node_path; dp++) {
+ if (!strcmp(dp->node_path, node_path)) {
+ return dp->opaque;
+ }
+ }
+ return NULL;
+}
+
+FDTMachineInfo *fdt_init_new_fdti(void *fdt)
+{
+ FDTMachineInfo *fdti = g_malloc0(sizeof(*fdti));
+ fdti->fdt = fdt;
+ fdti->cq = g_malloc0(sizeof(*(fdti->cq)));
+ qemu_co_queue_init(fdti->cq);
+ fdti->dev_opaques = g_malloc0(sizeof(*(fdti->dev_opaques)) *
+ (devtree_get_num_nodes(fdt) + 1));
+ return fdti;
+}
+
+void fdt_init_destroy_fdti(FDTMachineInfo *fdti)
+{
+ FDTDevOpaque *dp;
+
+ for (dp = fdti->dev_opaques; dp->node_path; dp++) {
+ g_free(dp->node_path);
+ }
+ g_free(fdti->dev_opaques);
+ g_free(fdti);
+}
diff --git a/include/hw/core/fdt_generic.h b/include/hw/core/fdt_generic.h
index 614a234868..a21e3c2440 100644
--- a/include/hw/core/fdt_generic.h
+++ b/include/hw/core/fdt_generic.h
@@ -8,9 +8,33 @@
#define FDT_GENERIC_H
#include "qemu/help-texts.h"
+#include "hw/core/irq.h"
#include "system/device_tree.h"
+#include "qemu/coroutine.h"
+
+typedef struct FDTDevOpaque {
+ char *node_path;
+ void *opaque;
+} FDTDevOpaque;
+
+typedef struct FDTMachineInfo {
+ /* the fdt blob */
+ void *fdt;
+ /* irq descriptors for top level int controller */
+ qemu_irq *irq_base;
+ /* per-device specific opaques */
+ FDTDevOpaque *dev_opaques;
+ /* recheck coroutine queue */
+ CoQueue *cq;
+} FDTMachineInfo;
-typedef struct FDTMachineInfo FDTMachineInfo;
+/*
+ * create a new FDTMachineInfo. The client is responsible for setting irq_base.
+ * Client must call fdt_init_destroy_fdti to cleanup
+ */
+
+FDTMachineInfo *fdt_init_new_fdti(void *fdt);
+void fdt_init_destroy_fdti(FDTMachineInfo *fdti);
typedef int (*FDTInitFn)(char *, FDTMachineInfo *, void *);
--
2.43.0