From: Ruslan Ruslichenko <[email protected]> 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 <[email protected]> --- 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
