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

Re: [Xen-devel] [PATCH v2 3/3] xen: arm: handle PCI DT node ranges and interrupt-map properties



On Mon, 2015-03-16 at 16:14 +0000, Julien Grall wrote:
> Hi Ian,
> 
> On 12/03/15 17:17, Ian Campbell wrote:
> > These properties are defined in ePAPR (2.3.8 and 2.4.3.1 respectively)
> > and the OpenFirmware PCI Bus Binding Specification (IEEE Std 1275-1994).
> > 
> > This replaces the xgene specific mapping. Tested on Mustang and on a
> > model with a PCI virtio controller.
> > 
> > TODO: Use a helper iterator (e.g. dt_for_each_range) for the ranges
> > property, like is already done for interrupts using
> > dt_for_each_irq_map.
> > 
> > TODO: Should we stop calling map_device for nodes beneath this one
> > (since we should have mapped everything underneath)? I think this is
> > complex for cases which map interrupt but not ranges or vice versa,
> > perhaps meaning we need to recurse on them separately. Maybe we can
> > continue to descend and the mappings may just be harmlessly
> > instantiated twice.
> 
> There is not harm to route twice the same IRQ. Although it's pointless
> to continue.
> 
> How difficult would it be to introduce a new bus?

It's a couple of reasonably trivial hook functions (which one would
naturally just get from Linux) and a struct tying a name to those. Not
too hard.

> > +    if ( dt_device_type_is_equal(dev, "pci") )
> > +        return map_pci_device_ranges(d, dev, ranges, len);
> > +
> > +    printk("Cannot handle ranges for non-PCI device %s type %s\n",
> > +           dt_node_name(dev), dev->type);
> > +
> 
> Is the printk really necessary? It will a spurious log on platform where
> ranges is not empty (midway, arndale, foundation model...).

If the ranges is present and non-empty it's not impossible that we need
to be doing something with it. I'd rather try and figure out how to
whitelist such nodes, perhaps they lack a dev_type completely?

> In general, we should not handle ranges by default as we may overlap the
> mapping done during the domain creation (such as the GIC).
> 
> > +    /* Lets not worry for now... */
> > +    return 0;
> > +}
> > +
> > +static int map_interrupt_to_domain(const struct dt_device_node *dev,
> > +                                   const struct dt_raw_irq *dt_raw_irq,
> > +                                   void *data)
> > +{
> > +    struct domain *d = data;
> > +    struct dt_irq dt_irq;
> > +    int res;
> > +
> > +    res = dt_irq_translate(dt_raw_irq, &dt_irq);
> > +    if ( res < 0 )
> > +    {
> > +        printk(XENLOG_ERR "%s: Failed to translate IRQ: %d\n",
> > +               dt_node_name(dev), res);
> > +        return res;
> > +    }
> > +
> > +    if ( dt_irq.irq < NR_LOCAL_IRQS )
> > +    {
> > +        printk(XENLOG_ERR "%s: IRQ%"PRId32" is not a SPI\n",
> > +               dt_node_name(dev), dt_irq.irq);
> > +        return -EINVAL;
> > +    }
> > +
> > +    /* Setup the IRQ type */
> > +    res = irq_set_spi_type(dt_irq.irq, dt_irq.type);
> > +    if ( res )
> > +    {
> > +        printk(XENLOG_ERR
> > +               "%s: Unable to setup IRQ%"PRId32" to dom%d\n",
> > +               dt_node_name(dev), dt_irq.irq, d->domain_id);
> > +        return res;
> > +    }
> > +
> > +    res = route_irq_to_guest(d, dt_irq.irq, dt_node_name(dev));
> > +    if ( res < 0 )
> > +    {
> > +        printk(XENLOG_ERR "Unable to map IRQ%"PRId32" to dom%d\n",
> > +               dt_irq.irq, d->domain_id);
> > +        return res;
> > +    }
> > +
> > +    DPRINT("PCI IRQ %u mapped to guest", dt_irq.irq);
> > +
> > +    return 0;
> > +}
> > +
> > +static int map_device_interrupts(struct domain *d, const struct 
> > dt_device_node *dev)
> > +{
> > +
> > +    if ( !dt_property_read_bool(dev, "interrupt-map") )
> 
> It's strange to use dt_property_read_bool here and dt_get_property above
> to check the emptiness.
> 
> I prefer the dt_get_property version which is less confusing.
> 
> Anyway, why do you need to check interrupt-map. Can't your new helper
> deal with empty property?

It can, but the code below would log for any non-pci device, which is
undesirable if there is no interrupt-map present.


> 
> > +        return 0; /* No interrupt map to handle */
> > +
> > +    if ( dt_device_type_is_equal(dev, "pci") )
> > +        return dt_for_each_irq_map(dev, &map_interrupt_to_domain, d);
> > +
> > +    printk("Cannot handle interrupt-map for non-PCI device %s type %s\n",
> > +           dt_node_name(dev), dev->type);
> > +
> > +    /* Lets not worry for now... */
> > +    return 0;
> > +}
> > +
> > +
> >  /* Map the device in the domain */
> >  static int map_device(struct domain *d, struct dt_device_node *dev)
> >  {
> > @@ -1025,6 +1173,14 @@ static int map_device(struct domain *d, struct 
> > dt_device_node *dev)
> >          }
> >      }
> >  
> > +    res = map_device_ranges(d, dev);
> > +    if ( res )
> > +        return res;
> > +
> > +    res = map_device_interrupts(d, dev);
> 
> The name of the function doesn't make much sense. We already map the
> interrupt above (see platform get_irq).

child_interrupt perhaps?

Ian.


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.