qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 3/5] PCI: Convert pci_info() to QObject


From: Luiz Capitulino
Subject: Re: [Qemu-devel] [PATCH 3/5] PCI: Convert pci_info() to QObject
Date: Tue, 19 Jan 2010 18:27:23 -0200

On Mon, 18 Jan 2010 18:16:21 +0100
Markus Armbruster <address@hidden> wrote:

> > +static QObject *pci_get_dev_class(const PCIDevice *dev)
> > +{
> > +    int class;
> > +    const char *str = "";
> > +    const pci_class_desc *desc;
> > +
> > +    class = pci_get_word(dev->config + PCI_CLASS_DEVICE);
> >      desc = pci_class_descriptions;
> >      while (desc->desc && class != desc->class)
> >          desc++;
> > +
> >      if (desc->desc) {
> [...]
> > +        str = desc->desc;
> > +    }
> > +
> > +    return qobject_from_jsonf("{ 'desc': %s, 'class': %d }", str, class);
> > +}
> 
> This yields 'desc': '' for unknown class.  I find that a bit unnatural.

 Right, good catch.

> If we don't have a desc, put none into the dictionary.

 The right thing would be to have null there, but the standard
so far is just to drop the key (which is what I'm going to do here).

> > +static QObject *pci_get_dev_id(const PCIDevice *dev)
> > +{
> > +    return qobject_from_jsonf("{ 'device': %d, 'vendor': %d }",
> > +                              pci_get_word(dev->config + PCI_VENDOR_ID),
> > +                              pci_get_word(dev->config + PCI_DEVICE_ID));
> > +}
> > +
> > +static QObject *pci_get_regions_list(const PCIDevice *dev)
> > +{
> > +    int i;
> > +    QList *regions_list;
> > +
> > +    regions_list = qlist_new();
> > +
> > +    for (i = 0; i < PCI_NUM_REGIONS; i++) {
> > +        const PCIIORegion *r = &dev->io_regions[i];
> >          if (r->size != 0) {
> 
> You're struggling with long lines in this function.  "if (!r->size)
> continue" avoids nesting.  Matter of taste, of course.

 I agree.

> > -            monitor_printf(mon, "      BAR%d: ", i);
> > +            QObject *obj;
> >              if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
> > -                monitor_printf(mon, "I/O at 0x%04"FMT_PCIBUS
> > -                               " [0x%04"FMT_PCIBUS"].\n",
> > -                               r->addr, r->addr + r->size - 1);
> > +                obj = qobject_from_jsonf("{ 'bar': %d, 'type': 'io', "
> > +                                         "'address': %" PRId64 ", "
> > +                                         "'size': %" PRId64 " }",
> > +                                         i, r->addr, r->size);
> >              } else {
> > -                const char *type = r->type & PCI_BASE_ADDRESS_MEM_TYPE_64 ?
> > -                    "64 bit" : "32 bit";
> > -                const char *prefetch =
> > -                    r->type & PCI_BASE_ADDRESS_MEM_PREFETCH ?
> > -                    " prefetchable" : "";
> > -
> > -                monitor_printf(mon, "%s%s memory at 0x%08"FMT_PCIBUS
> > -                               " [0x%08"FMT_PCIBUS"].\n",
> > -                               type, prefetch,
> > -                               r->addr, r->addr + r->size - 1);
> > +                int mem_type_64 = r->type & PCI_BASE_ADDRESS_MEM_TYPE_64;
> > +
> > +                obj = qobject_from_jsonf("{ 'bar': %d, 'type': 'memory', "
> > +                                         "'mem_type_64': %i, 'prefetch': 
> > %i, "
> > +                                         "'address': %" PRId64 ", "
> > +                                         "'size': %" PRId64 " }",
> > +                                         i, mem_type_64,
> > +                                         r->type 
> > &PCI_BASE_ADDRESS_MEM_PREFETCH,
> > +                                         r->addr, r->size);
> >              }
> > +            qlist_append_obj(regions_list, obj);
> >          }
> >      }
> > -    monitor_printf(mon, "      id \"%s\"\n", d->qdev.id ? d->qdev.id : "");
> > -    if (class == 0x0604 && d->config[0x19] != 0) {
> > -        pci_for_each_device(bus, d->config[0x19], pci_info_device);
> > +
> > +    return QOBJECT(regions_list);
> > +}
> > +
> > +static QObject *pci_get_dev_dict(const PCIDevice *dev, int bus_num)
> > +{
> > +    QObject *obj;
> > +
> > +    obj = qobject_from_jsonf("{ 'bus': %d, 'slot': %d, 'function': %d,"    
> >                                    "'class_info': %p, 'id': %p, 'regions': 
> > %p,"
> > +                              " 'qdev_id': %s }",
> > +                              bus_num,
> > +                              PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
> > +                              pci_get_dev_class(dev), pci_get_dev_id(dev),
> > +                              pci_get_regions_list(dev),
> > +                              dev->qdev.id ? dev->qdev.id : "");
> 
> Why repeat the bus number?  See below.
> 
> > +
> > +    if (dev->config[PCI_INTERRUPT_PIN] != 0) {
> > +        QDict *qdict = qobject_to_qdict(obj);
> > +        qdict_put(qdict, "irq", 
> > qint_from_int(dev->config[PCI_INTERRUPT_LINE]));
> >      }
> > +
> > +    return obj;
> >  }
> >  
> > -static void pci_for_each_device_under_bus(PCIBus *bus,
> > -                                          void (*fn)(PCIBus *b, PCIDevice 
> > *d))
> > +static QObject *pci_get_devices_list(PCIBus *bus, int bus_num)
> >  {
> > -    PCIDevice *d;
> >      int devfn;
> > +    PCIDevice *dev;
> > +    QList *dev_list;
> >  
> > -    for(devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
> > -        d = bus->devices[devfn];
> > -        if (d)
> > -            fn(bus, d);
> > +    dev_list = qlist_new();
> > +
> > +    for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
> > +        dev = bus->devices[devfn];
> > +        if (dev) {
> > +            qlist_append_obj(dev_list, pci_get_dev_dict(dev, bus_num));
> > +        }
> >      }
> > +
> > +    return QOBJECT(dev_list);
> >  }
> >  
> > -void pci_for_each_device(PCIBus *bus, int bus_num,
> > -                         void (*fn)(PCIBus *b, PCIDevice *d))
> > +static QObject *pci_get_bus_dict(PCIBus *bus, int bus_num)
> >  {
> >      bus = pci_find_bus(bus, bus_num);
> > -
> >      if (bus) {
> > -        pci_for_each_device_under_bus(bus, fn);
> > +        return qobject_from_jsonf("{ 'bus': %d, 'devices': %p }",
> > +                                  bus_num, pci_get_devices_list(bus, 
> > bus_num));
> >      }
> > +
> > +    return NULL;
> >  }
> >  
> > -void pci_info(Monitor *mon)
> > +/**
> > + * do_pci_info(): PCI buses and devices information
> > + *
> > + * The returned QObject is a QList of all buses. Each bus is
> > + * represented by a QDict, which has a key with a QList of all
> > + * PCI devices attached to it. Each device is represented by
> > + * a QDict.
> > + *
> > + * The bus QDict contains the following:
> > + *
> > + * - "bus": bus number
> > + * - "devices": a QList of QDicts, each QDict represents a PCI
> > + *   device
> > + *
> > + * The PCI device QDict contains the following:
> > + *
> > + * - "bus": bus number
> 
> This is redundant, because a device QDict is always contained in a bus
> QDict, which has the bus number.

 Turns out I find this redundancy convenient for clients, because if
you pass the device dict down to a function you have the bus number
there if you need it (otherwise you'd need to pass the bus number
too).

 I'm writing a shell in Python and found this convenient, is it that
bad?

> > + * - "slot": slot number
> > + * - "function": function number
> > + * - "class_info": a QDict containing:
> > + *      - "desc": device class description
> > + *      - "class": device class number
> 
> Need to document how unknown classes are encoded (now: "desc" has value
> "").

 I'll make this optional.

> > + * - "id": a QDict containing:
> > + *      - "device": device ID
> > + *      - "vendor": vendor ID
> > + * - "irq": device's IRQ if assigned (optional)
> > + * - "qdev_id": qdev id string
> > + * - "regions": a QList of QDicts, each QDict represents a
> > + *   memory region of this device
> > + *
> > + * The region QDict can be an I/O region or a memory region,
> > + * the I/O region contains the following:
> 
> "An I/O region QDict", because there can be more than one.

 Ok.

> > + *
> > + * - "type": "io"
> > + * - "bar": BAR number
> > + * - "address": memory address
> > + * - "size": memory size
> > + *
> > + * The memory region QDict contains the following:
> 
> Likewise, "A memory region QDict".

 Ok.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]