Patchwork [RFC,04/11] qdev: pcibus_dev_info

login
register
mail settings
Submitter Nathan Baum
Date Dec. 26, 2009, 9:11 p.m.
Message ID <1261861899-1984-5-git-send-email-nathan@parenthephobia.org.uk>
Download mbox | patch
Permalink /patch/41819/
State New
Headers show

Comments

Nathan Baum - Dec. 26, 2009, 9:11 p.m.
This returns a QObject detailing the PCI-specific data about the device.

Signed-off-by: Nathan Baum <nathan@parenthephobia.org.uk>
---
 hw/pci.c |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 48 insertions(+), 0 deletions(-)
Markus Armbruster - Jan. 15, 2010, 6:06 p.m.
Nathan Baum <nathan@parenthephobia.org.uk> writes:

> This returns a QObject detailing the PCI-specific data about the device.
>
> Signed-off-by: Nathan Baum <nathan@parenthephobia.org.uk>
> ---
>  hw/pci.c |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 48 insertions(+), 0 deletions(-)
>
> diff --git a/hw/pci.c b/hw/pci.c
> index 9722fce..8688d8a 100644
> --- a/hw/pci.c
> +++ b/hw/pci.c
> @@ -27,6 +27,8 @@
>  #include "net.h"
>  #include "sysemu.h"
>  #include "loader.h"
> +#include "qjson.h"
> +#include "qint.h"
>  
>  //#define DEBUG_PCI
>  #ifdef DEBUG_PCI
> @@ -1585,6 +1587,52 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
>      }
>  }
>  
> +static QObject *pcibus_dev_info(Monitor *mon, DeviceState *dev)
> +{
> +    PCIDevice *d = (PCIDevice *)dev;
> +    const pci_class_desc *desc;
> +    PCIIORegion *r;
> +    int i, class;
> +    QObject *retval;
> +    QList *regions;
> +    
> +    retval = qobject_from_jsonf("{ 'addr': { 'bus' : %d, 'slot' : %d, 'func': %d }, "

'bus' doesn't really belong here, it's a property of the bus, not the
device.  That's why device property "addr" is just device, function.

If we want to have it here anyway, we should have 'domain' as well.
Even though we don't support PCI domains, yet.

> +                                "  'device': { 'vendor': %d, 'id': %d }, "
> +                                "  'subsystem': { 'vendor': %d, 'id': %d } "
> +                                "}",
> +                                d->config[PCI_SECONDARY_BUS],
> +                                PCI_SLOT(d->devfn),
> +                                PCI_FUNC(d->devfn),
> +                                pci_get_word(d->config + PCI_VENDOR_ID),
> +                                pci_get_word(d->config + PCI_DEVICE_ID),
> +                                pci_get_word(d->config + PCI_SUBSYSTEM_VENDOR_ID),
> +                                pci_get_word(d->config + PCI_SUBSYSTEM_ID));
> +    class = pci_get_word(d->config + PCI_CLASS_DEVICE);
> +    desc = pci_class_descriptions;
> +    while (desc->desc && class != desc->class)
> +        desc++;
> +    if (desc->desc) {
> +        qdict_put(qobject_to_qdict(retval), "class", qstring_from_str(desc->desc));
> +    } else {
> +        qdict_put(qobject_to_qdict(retval), "class", qint_from_int(class));
> +    }
> +    
> +    regions = qlist_new();
> +    qdict_put(qobject_to_qdict(retval), "regions", regions);
> +
> +    for (i = 0; i < PCI_NUM_REGIONS; i++) {
> +        r = &d->io_regions[i];
> +        if (!r->size)
> +            continue;
> +        qlist_append_obj(regions,
> +                         qobject_from_jsonf("{'type':%s,'addr':%d,'size':%d}",
> +                                            r->type & PCI_BASE_ADDRESS_SPACE_IO ? "i/o" : "mem",
> +                                            (int) r->addr,
> +                                            (int) r->size));

You need to print pcibus_t values with %FMT_PCIBUS, just like
pcibus_dev_print().  Casting to int so you can use %d can truncate the
value.

> +    }
> +    return retval;
> +}
> +
>  static PCIDeviceInfo bridge_info = {
>      .qdev.name    = "pci-bridge",
>      .qdev.size    = sizeof(PCIBridge),

Patch

diff --git a/hw/pci.c b/hw/pci.c
index 9722fce..8688d8a 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -27,6 +27,8 @@ 
 #include "net.h"
 #include "sysemu.h"
 #include "loader.h"
+#include "qjson.h"
+#include "qint.h"
 
 //#define DEBUG_PCI
 #ifdef DEBUG_PCI
@@ -1585,6 +1587,52 @@  static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
     }
 }
 
+static QObject *pcibus_dev_info(Monitor *mon, DeviceState *dev)
+{
+    PCIDevice *d = (PCIDevice *)dev;
+    const pci_class_desc *desc;
+    PCIIORegion *r;
+    int i, class;
+    QObject *retval;
+    QList *regions;
+    
+    retval = qobject_from_jsonf("{ 'addr': { 'bus' : %d, 'slot' : %d, 'func': %d }, "
+                                "  'device': { 'vendor': %d, 'id': %d }, "
+                                "  'subsystem': { 'vendor': %d, 'id': %d } "
+                                "}",
+                                d->config[PCI_SECONDARY_BUS],
+                                PCI_SLOT(d->devfn),
+                                PCI_FUNC(d->devfn),
+                                pci_get_word(d->config + PCI_VENDOR_ID),
+                                pci_get_word(d->config + PCI_DEVICE_ID),
+                                pci_get_word(d->config + PCI_SUBSYSTEM_VENDOR_ID),
+                                pci_get_word(d->config + PCI_SUBSYSTEM_ID));
+    class = pci_get_word(d->config + PCI_CLASS_DEVICE);
+    desc = pci_class_descriptions;
+    while (desc->desc && class != desc->class)
+        desc++;
+    if (desc->desc) {
+        qdict_put(qobject_to_qdict(retval), "class", qstring_from_str(desc->desc));
+    } else {
+        qdict_put(qobject_to_qdict(retval), "class", qint_from_int(class));
+    }
+    
+    regions = qlist_new();
+    qdict_put(qobject_to_qdict(retval), "regions", regions);
+
+    for (i = 0; i < PCI_NUM_REGIONS; i++) {
+        r = &d->io_regions[i];
+        if (!r->size)
+            continue;
+        qlist_append_obj(regions,
+                         qobject_from_jsonf("{'type':%s,'addr':%d,'size':%d}",
+                                            r->type & PCI_BASE_ADDRESS_SPACE_IO ? "i/o" : "mem",
+                                            (int) r->addr,
+                                            (int) r->size));
+    }
+    return retval;
+}
+
 static PCIDeviceInfo bridge_info = {
     .qdev.name    = "pci-bridge",
     .qdev.size    = sizeof(PCIBridge),