From: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
To: qemu-devel-qX2TKyscuCcdnm+yROfE0A@public.gmane.org,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
jeremy.kerr-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org
Subject: [RFC PATCH 2/7] devicetree: auto-populate the device tree with qdev data
Date: Tue, 06 Apr 2010 22:10:08 -0600 [thread overview]
Message-ID: <20100407041007.20274.1368.stgit@angua> (raw)
In-Reply-To: <20100407040129.20274.44284.stgit@angua>
This patch adds hooks to the qemu device model to auto-generate device
tree nodes from the registered qemu devices, and calls the device tree
populate hook when booting ARM platforms.
Signed-off-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
---
hw/arm_boot.c | 3 ++
hw/qdev.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/qdev.h | 8 +++++
3 files changed, 102 insertions(+), 0 deletions(-)
diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index 740a446..33c7356 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -13,6 +13,7 @@
#include "sysemu.h"
#include "loader.h"
#include "elf.h"
+#include "qdev.h"
#ifdef CONFIG_FDT
#include "device_tree.h"
@@ -211,6 +212,8 @@ static int load_dtb(target_phys_addr_t addr, struct arm_boot_info *binfo)
}
qemu_free(filename);
+ qdev_fdt_populate(fdt);
+
rc = qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
sizeof(mem_reg_property));
if (rc < 0)
diff --git a/hw/qdev.c b/hw/qdev.c
index d19d531..b177c3d 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -748,3 +748,94 @@ void do_device_del(Monitor *mon, const QDict *qdict)
}
qdev_unplug(dev);
}
+
+#ifdef CONFIG_FDT
+#include <libfdt.h>
+static int qbus_fdt_add_bus(void *fdt, BusState *bus, int dev_offset);
+static int qdev_fdt_add_device(void *fdt, DeviceState *dev, int bus_offset)
+{
+ BusState *child;
+ int dev_offset, rc;
+ char name[sizeof(dev->info->name) + 9];
+ static int unique = 0;
+
+ sprintf(name, "%s@%x", dev->info->name, unique++);
+ dev_offset = fdt_add_subnode(fdt, bus_offset, name);
+ if (dev_offset < 0) {
+ qemu_error("Couldn't add FDT node for device %s\n", dev->info->name);
+ return dev_offset;
+ }
+
+ rc = fdt_setprop_cell(fdt, dev_offset, "phandle", (uint64_t)dev);
+ if (rc < 0) {
+ qemu_error("Could not add phandle property to device %s\n",
+ dev->info->name);
+ return rc;
+ }
+
+ if (dev->info->fdt_populate) {
+ int rc = dev->info->fdt_populate(dev, fdt, dev_offset);
+ if (rc < 0) {
+ qemu_error("dev->info->fdt_populate() failed on %s\n",
+ dev->info->name);
+ return rc;
+ }
+ }
+
+ QLIST_FOREACH(child, &dev->child_bus, sibling) {
+ int rc = qbus_fdt_add_bus(fdt, child, dev_offset);
+ if (rc < 0) {
+ qemu_error("qbus_fdt_add_bus() failed on dev:%s bus:%s\n",
+ dev->info->name, child->info->name);
+ return rc;
+ }
+ }
+
+ return dev_offset;
+}
+
+static int qbus_fdt_add_bus(void *fdt, BusState *bus, int dev_offset)
+{
+ struct DeviceState *dev;
+ int bus_offset;
+
+ bus_offset = fdt_add_subnode(fdt, dev_offset, bus->name);
+ if (bus_offset < 0) {
+ qemu_error("Couldn't add FDT node for bus %s\n", bus->name);
+ return bus_offset;
+ }
+
+ if (bus->info->fdt_populate) {
+ int rc = bus->info->fdt_populate(bus, fdt, bus_offset);
+ if (rc < 0) {
+ qemu_error("bus->info->fdt_populate() failed on %s\n",
+ bus->info->name);
+ return rc;
+ }
+ }
+
+ QLIST_FOREACH(dev, &bus->children, sibling) {
+ int rc = qdev_fdt_add_device(fdt, dev, bus_offset);
+ if (rc < 0) {
+ qemu_error("qbus_fdt_add_device() failed on bus:%s dev:%s\n",
+ bus->info->name, dev->info->name);
+ return rc;
+ }
+ }
+
+ return bus_offset;
+}
+
+int qdev_fdt_populate(void *fdt)
+{
+ int offset = fdt_path_offset(fdt, "/");
+ if (offset < 0)
+ return offset;
+
+ if (main_system_bus)
+ qbus_fdt_add_bus(fdt, main_system_bus, offset);
+
+ return offset;
+}
+#endif /* CONFIG_FDT */
+
diff --git a/hw/qdev.h b/hw/qdev.h
index 41642ee..d549d43 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -43,10 +43,12 @@ struct DeviceState {
};
typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent);
+typedef int (*bus_fdt_populatefn)(BusState *bus, void *fdt, int offset);
struct BusInfo {
const char *name;
size_t size;
bus_dev_printfn print_dev;
+ bus_fdt_populatefn fdt_populate;
Property *props;
};
@@ -119,6 +121,7 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
typedef int (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
typedef int (*qdev_event)(DeviceState *dev);
typedef void (*qdev_resetfn)(DeviceState *dev);
+typedef int (*qdev_fdt_populatefn)(DeviceState *dev, void *fdt, int offset);
struct DeviceInfo {
const char *name;
@@ -130,6 +133,7 @@ struct DeviceInfo {
/* callbacks */
qdev_resetfn reset;
+ qdev_fdt_populatefn fdt_populate;
/* device state */
const VMStateDescription *vmsd;
@@ -272,4 +276,8 @@ void qdev_prop_set_compat(DeviceState *dev);
/* This is a nasty hack to allow passing a NULL bus to qdev_create. */
extern struct BusInfo system_bus_info;
+#ifdef CONFIG_FDT
+int qdev_fdt_populate(void *fdt);
+#endif
+
#endif
WARNING: multiple messages have this Message-ID (diff)
From: Grant Likely <grant.likely@secretlab.ca>
To: qemu-devel@nongnu.org, devicetree-discuss@lists.ozlabs.org,
jeremy.kerr@canonical.com
Subject: [Qemu-devel] [RFC PATCH 2/7] devicetree: auto-populate the device tree with qdev data
Date: Tue, 06 Apr 2010 22:10:08 -0600 [thread overview]
Message-ID: <20100407041007.20274.1368.stgit@angua> (raw)
In-Reply-To: <20100407040129.20274.44284.stgit@angua>
This patch adds hooks to the qemu device model to auto-generate device
tree nodes from the registered qemu devices, and calls the device tree
populate hook when booting ARM platforms.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
hw/arm_boot.c | 3 ++
hw/qdev.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/qdev.h | 8 +++++
3 files changed, 102 insertions(+), 0 deletions(-)
diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index 740a446..33c7356 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -13,6 +13,7 @@
#include "sysemu.h"
#include "loader.h"
#include "elf.h"
+#include "qdev.h"
#ifdef CONFIG_FDT
#include "device_tree.h"
@@ -211,6 +212,8 @@ static int load_dtb(target_phys_addr_t addr, struct arm_boot_info *binfo)
}
qemu_free(filename);
+ qdev_fdt_populate(fdt);
+
rc = qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
sizeof(mem_reg_property));
if (rc < 0)
diff --git a/hw/qdev.c b/hw/qdev.c
index d19d531..b177c3d 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -748,3 +748,94 @@ void do_device_del(Monitor *mon, const QDict *qdict)
}
qdev_unplug(dev);
}
+
+#ifdef CONFIG_FDT
+#include <libfdt.h>
+static int qbus_fdt_add_bus(void *fdt, BusState *bus, int dev_offset);
+static int qdev_fdt_add_device(void *fdt, DeviceState *dev, int bus_offset)
+{
+ BusState *child;
+ int dev_offset, rc;
+ char name[sizeof(dev->info->name) + 9];
+ static int unique = 0;
+
+ sprintf(name, "%s@%x", dev->info->name, unique++);
+ dev_offset = fdt_add_subnode(fdt, bus_offset, name);
+ if (dev_offset < 0) {
+ qemu_error("Couldn't add FDT node for device %s\n", dev->info->name);
+ return dev_offset;
+ }
+
+ rc = fdt_setprop_cell(fdt, dev_offset, "phandle", (uint64_t)dev);
+ if (rc < 0) {
+ qemu_error("Could not add phandle property to device %s\n",
+ dev->info->name);
+ return rc;
+ }
+
+ if (dev->info->fdt_populate) {
+ int rc = dev->info->fdt_populate(dev, fdt, dev_offset);
+ if (rc < 0) {
+ qemu_error("dev->info->fdt_populate() failed on %s\n",
+ dev->info->name);
+ return rc;
+ }
+ }
+
+ QLIST_FOREACH(child, &dev->child_bus, sibling) {
+ int rc = qbus_fdt_add_bus(fdt, child, dev_offset);
+ if (rc < 0) {
+ qemu_error("qbus_fdt_add_bus() failed on dev:%s bus:%s\n",
+ dev->info->name, child->info->name);
+ return rc;
+ }
+ }
+
+ return dev_offset;
+}
+
+static int qbus_fdt_add_bus(void *fdt, BusState *bus, int dev_offset)
+{
+ struct DeviceState *dev;
+ int bus_offset;
+
+ bus_offset = fdt_add_subnode(fdt, dev_offset, bus->name);
+ if (bus_offset < 0) {
+ qemu_error("Couldn't add FDT node for bus %s\n", bus->name);
+ return bus_offset;
+ }
+
+ if (bus->info->fdt_populate) {
+ int rc = bus->info->fdt_populate(bus, fdt, bus_offset);
+ if (rc < 0) {
+ qemu_error("bus->info->fdt_populate() failed on %s\n",
+ bus->info->name);
+ return rc;
+ }
+ }
+
+ QLIST_FOREACH(dev, &bus->children, sibling) {
+ int rc = qdev_fdt_add_device(fdt, dev, bus_offset);
+ if (rc < 0) {
+ qemu_error("qbus_fdt_add_device() failed on bus:%s dev:%s\n",
+ bus->info->name, dev->info->name);
+ return rc;
+ }
+ }
+
+ return bus_offset;
+}
+
+int qdev_fdt_populate(void *fdt)
+{
+ int offset = fdt_path_offset(fdt, "/");
+ if (offset < 0)
+ return offset;
+
+ if (main_system_bus)
+ qbus_fdt_add_bus(fdt, main_system_bus, offset);
+
+ return offset;
+}
+#endif /* CONFIG_FDT */
+
diff --git a/hw/qdev.h b/hw/qdev.h
index 41642ee..d549d43 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -43,10 +43,12 @@ struct DeviceState {
};
typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent);
+typedef int (*bus_fdt_populatefn)(BusState *bus, void *fdt, int offset);
struct BusInfo {
const char *name;
size_t size;
bus_dev_printfn print_dev;
+ bus_fdt_populatefn fdt_populate;
Property *props;
};
@@ -119,6 +121,7 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
typedef int (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
typedef int (*qdev_event)(DeviceState *dev);
typedef void (*qdev_resetfn)(DeviceState *dev);
+typedef int (*qdev_fdt_populatefn)(DeviceState *dev, void *fdt, int offset);
struct DeviceInfo {
const char *name;
@@ -130,6 +133,7 @@ struct DeviceInfo {
/* callbacks */
qdev_resetfn reset;
+ qdev_fdt_populatefn fdt_populate;
/* device state */
const VMStateDescription *vmsd;
@@ -272,4 +276,8 @@ void qdev_prop_set_compat(DeviceState *dev);
/* This is a nasty hack to allow passing a NULL bus to qdev_create. */
extern struct BusInfo system_bus_info;
+#ifdef CONFIG_FDT
+int qdev_fdt_populate(void *fdt);
+#endif
+
#endif
next prev parent reply other threads:[~2010-04-07 4:10 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-04-07 4:09 [RFC PATCH 0/7] QEMU patches to generate FDT from qdevs Grant Likely
2010-04-07 4:09 ` [Qemu-devel] " Grant Likely
2010-04-07 4:10 ` [RFC PATCH 1/7] devicetree: Add 8k instead of double dtb size when reserving extra memory Grant Likely
2010-04-07 4:10 ` [Qemu-devel] " Grant Likely
2010-04-09 12:00 ` Paul Brook
2010-04-09 12:00 ` Paul Brook
[not found] ` <201004091300.57740.paul-qD8j1LwMmJjtCj0u4l0SBw@public.gmane.org>
2010-04-09 14:55 ` Grant Likely
2010-04-09 14:55 ` Grant Likely
2010-04-07 4:10 ` Grant Likely [this message]
2010-04-07 4:10 ` [Qemu-devel] [RFC PATCH 2/7] devicetree: auto-populate the device tree with qdev data Grant Likely
2010-04-07 4:10 ` [RFC PATCH 3/7] devicetree: add helper for determining IRQ properties in the device tree Grant Likely
2010-04-07 4:10 ` [Qemu-devel] " Grant Likely
2010-04-07 4:10 ` [RFC PATCH 4/7] devicetree: Add sysbus fdt populate hooks Grant Likely
2010-04-07 4:10 ` [Qemu-devel] " Grant Likely
2010-04-07 4:10 ` [RFC PATCH 5/7] devicetree: Add helper to register devices with an fdt_populate hook Grant Likely
2010-04-07 4:10 ` [Qemu-devel] " Grant Likely
2010-04-07 4:10 ` [RFC PATCH 6/7] devicetree: Add fdt_populate hook to pl011 device Grant Likely
2010-04-07 4:10 ` [Qemu-devel] " Grant Likely
2010-04-07 4:10 ` [RFC PATCH 7/7] devicetree: Add fdt_populate hook to smc91x device Grant Likely
2010-04-07 4:10 ` [Qemu-devel] " Grant Likely
2010-04-07 7:01 ` [RFC PATCH 0/7] QEMU patches to generate FDT from qdevs Jeremy Kerr
2010-04-07 7:01 ` [Qemu-devel] " Jeremy Kerr
[not found] ` <201004071501.34711.jeremy.kerr-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
2010-04-07 20:58 ` Grant Likely
2010-04-07 20:58 ` [Qemu-devel] " Grant Likely
2010-04-07 19:10 ` [Qemu-devel] " Blue Swirl
2010-04-07 19:10 ` Blue Swirl
[not found] ` <k2kf43fc5581004071210v810be251nf77b7ab469004e5c-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-04-07 20:57 ` Grant Likely
2010-04-07 20:57 ` Grant Likely
2010-04-09 12:07 ` Paul Brook
2010-04-09 12:07 ` Paul Brook
[not found] ` <201004091307.22473.paul-qD8j1LwMmJjtCj0u4l0SBw@public.gmane.org>
2010-04-09 14:47 ` Grant Likely
2010-04-09 14:47 ` Grant Likely
[not found] ` <h2ofa686aa41004090747w2422cedasb6f4b51633637816-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-04-09 15:57 ` Paul Brook
2010-04-09 15:57 ` Paul Brook
[not found] ` <201004091657.10684.paul-qD8j1LwMmJjtCj0u4l0SBw@public.gmane.org>
2010-04-09 16:35 ` Grant Likely
2010-04-09 16:35 ` Grant Likely
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100407041007.20274.1368.stgit@angua \
--to=grant.likely-s3s/wqlpoipyb63q8fvjnq@public.gmane.org \
--cc=devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org \
--cc=jeremy.kerr-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org \
--cc=qemu-devel-qX2TKyscuCcdnm+yROfE0A@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.