@@ -222,6 +222,7 @@ hw-obj-$(CONFIG_USB_REDIR) += usb-redir.o
hw-obj-$(CONFIG_FDT) += fdt_generic.o
hw-obj-$(CONFIG_FDT) += fdt_generic_util.o
+hw-obj-$(CONFIG_FDT) += fdt_generic_qdev.o
# PPC devices
hw-obj-$(CONFIG_OPENPIC) += openpic.o
new file mode 100644
@@ -0,0 +1,75 @@
+#include "fdt_generic_qdev.h"
+#include "fdt_generic_util.h"
+#include "net.h"
+
+#define D(a)
+
+int fdt_init_qdev(char *node_path, FDTMachineInfo *fdti, void *opaque)
+{
+ int err;
+ qemu_irq irq;
+ target_phys_addr_t base;
+ DeviceState *dev;
+ FDTQDevOps *ops = opaque;
+ struct FDTQDevPropMapping *props =
+ (ops && ops->map) ? ops->map(node_path, fdti) : NULL;
+ struct FDTQDevPropMapping *propsi;
+
+ /* create the device */
+ if (!ops || !ops->dev_name) {
+ return 1;
+ }
+ dev = qdev_create(NULL, ops->dev_name);
+ D(fprintf(stderr, "FDT: Creating QDEV model %s %s %d\n",
+ ops->dev_name, ops->is_nic ? "(nic)" : "", ops->is_intc);)
+ /* connect nic if appropriate */
+ if (ops->is_nic) {
+ qemu_check_nic_model(&nd_table[0], ops->dev_name);
+ qdev_set_nic_properties(dev, &nd_table[0]);
+ }
+ /* connect custom properties */
+ for (propsi = props; propsi && propsi->name; propsi++) {
+ enum PropertyType type;
+ if (!qdev_prop_get_type(dev, propsi->name, &type)) {
+ qdev_prop_set(dev, propsi->name, &propsi->src, type);
+ D(fprintf(stderr, "\tFDT: setting qdev prop %s %d (u32) %p (p)\n",
+ propsi->name, propsi->src.u32, propsi->src.p);)
+ }
+ if (propsi->freesrc) {
+ g_free(propsi->src.p);
+ }
+ }
+ qdev_init_nofail(dev);
+ /* map slave attachment */
+ base = qemu_devtree_getprop(fdti->fdt, NULL, node_path, "reg", 0, 0);
+ sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+ /* connect irq */
+ {
+ char irq_info[1024];
+ /* FIXME: add support for multiple IRQs */
+ irq = fdt_get_irq_info(fdti, node_path, 0, &err, irq_info);
+ /* INTCs inferr their top level, if no IRQ connection specified */
+ if (err && ops->is_intc) {
+ irq = fdti->irq_base[0];
+ err = 0;
+ }
+ if (!err) {
+ sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
+ fprintf(stderr, "FDT: (%s) connected irq %s\n", ops->dev_name, irq_info);
+ }
+ }
+ /* create interrupt controller connections if appropriate */
+ if (ops->is_intc) {
+ int i;
+ qemu_irq *irqs = g_malloc0(sizeof(*irqs) * ops->is_intc);
+ for (i = 0; i < ops->is_intc; i++) {
+ irqs[i] = qdev_get_gpio_in(dev, i);
+ }
+ fdt_init_set_opaque(fdti, node_path, irqs);
+ }
+
+ if (props) {
+ g_free(props);
+ }
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,46 @@
+#ifndef FDT_GENERIC_QDEV_H
+#define FDT_GENERIC_QDEV_H
+
+#include "fdt_generic.h"
+#include "qdev.h"
+
+typedef struct FDTQDevPropMapping {
+ const char *name;
+ union {
+ /* TODO: add support for structure type QDEV props */
+ uint8_t u8;
+ uint16_t u16;
+ uint32_t u32;
+ void *p;
+ } src;
+ int freesrc;
+} FDTQDevPropMapping;
+
+typedef FDTQDevPropMapping* (*FDTQDevMapFn)(char *, FDTMachineInfo *);
+
+typedef struct FDTQDevOps {
+ const char *dev_name;
+ /* TODO: implement */
+ const int *irq_map;
+ const int is_nic;
+ /* FIXME: Add mechanism for dynamically chnginging number of intc IRQs */
+ const int is_intc;
+ FDTQDevMapFn map;
+} FDTQDevOps;
+
+/* FDT init functions for qdev models */
+
+int fdt_init_qdev(char *, FDTMachineInfo *, void *);
+
+/* statically register a FDTQDevMapFn as being associate with a compatibility */
+
+#define fdt_qdev_register_compatibility_n(ops, compat, n) \
+static void __attribute__((constructor)) \
+function ## n ## _register_imp (void) { \
+ add_to_compat_table(fdt_init_qdev, compat, ops); \
+}
+
+#define fdt_qdev_register_compatibility(ops, compat) \
+fdt_qdev_register_compatibility_n(ops, compat, 0);
+
+#endif /* FDT_GENERIC_QDEV_H */
Support for setting up qdev models for use by the fdt-generic framwork. A single fdt init function is shared by all qdev models and the qdev model registers a handler function that maps fdt properties to qdev properties. Support for basic interrupt controllers and nics is there. Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com> --- Makefile.objs | 1 + hw/fdt_generic_qdev.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ hw/fdt_generic_qdev.h | 46 ++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 0 deletions(-) create mode 100644 hw/fdt_generic_qdev.c create mode 100644 hw/fdt_generic_qdev.h