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

Re: [Xen-devel] [PATCH V2 09/33] xen/arm: Add helpers to retrieve an address from the device tree



On Wed, 2013-05-08 at 03:33 +0100, Julien Grall wrote:
> Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>
> ---
>  xen/common/device_tree.c      |  343 
> +++++++++++++++++++++++++++++++++++++++++
>  xen/include/xen/device_tree.h |   22 +++
>  2 files changed, 365 insertions(+)
> 
> diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
> index 449c332..8d37018 100644
> --- a/xen/common/device_tree.c
> +++ b/xen/common/device_tree.c
> @@ -62,10 +62,38 @@ static void (*dt_printk)(const char *fmt, ...) = 
> early_printk;
> 
>  #ifdef DEBUG_DT
>  # define dt_dprintk(fmt, args...) dt_printk(XENLOG_DEBUG fmt, ##args)
> +static void dt_dump_addr(const char *s, const __be32 *addr, int na)
> +{
> +    dt_dprintk("%s", s);
> +    while ( na-- )
> +        dt_dprintk(" %08x", be32_to_cpu(*(addr++)));
> +    dt_dprintk("\n");
> +}
>  #else
>  # define dt_dprintk(fmt, args...) do {} while ( 0 )
> +static void dt_dump_addr(const char *s, const __be32 *addr, int na) { }
>  #endif
> 
> +#define DT_BAD_ADDR ((u64)-1)
> +
> +/* Max address size we deal with */
> +#define DT_MAX_ADDR_CELLS 4
> +#define DT_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= DT_MAX_ADDR_CELLS)
> +#define DT_CHECK_COUNTS(na, ns) (DT_CHECK_ADDR_COUNT(na) && (ns) > 0)
> +
> +/* Callbacks for bus specific translators */
> +struct dt_bus
> +{
> +    const char *name;
> +    const char *addresses;
> +    int (*match)(const struct dt_device_node *parent);
> +    void (*count_cells)(const struct dt_device_node *child,
> +                        int *addrc, int *sizec);
> +    u64        (*map)(__be32 *addr, const __be32 *range, int na, int ns, int 
> pna);
> +       int (*translate)(__be32 *addr, u64 offset, int na);
> +       unsigned int (*get_flags)(const __be32 *addr);

Spacing is weird here. Hard tabs perhaps?

> +static int dt_translate_one(const struct dt_device_node *parent,
> +                            const struct dt_bus *bus,
> +                            const struct dt_bus *pbus,
> +                            __be32 *addr, int na, int ns,
> +                            int pna, const char *rprop)
> +{
> +    const __be32 *ranges;
> +    unsigned int rlen;
> +    int rone;
> +    u64 offset = DT_BAD_ADDR;
> +
> +    ranges = dt_get_property(parent, rprop, &rlen);
> +    if ( ranges == NULL )
> +    {
> +               dt_printk(XENLOG_ERR "DT: no ranges; cannot translate\n");
> +               return 1;
> +       }

Indentation.

> +    if ( ranges == NULL || rlen == 0 )
> +    {
> +        offset = dt_read_number(addr, na);
> +        memset(addr, 0, pna * 4);
> +        dt_dprintk("DT: empty ranges; 1:1 translation\n");
> +        goto finish;
> +    }
> +
> +    dt_dprintk("DT: walking ranges...\n");
> +
> +    /* Now walk through the ranges */
> +    rlen /= 4;
> +    rone = na + pna + ns;
> +    for ( ; rlen >= rone; rlen -= rone, ranges += rone )
> +    {
> +        offset = bus->map(addr, ranges, na, ns, pna);
> +        if ( offset != DT_BAD_ADDR )
> +            break;
> +       }

Indentation.

> +    if ( offset == DT_BAD_ADDR )
> +    {
> +        dt_dprintk("DT: not found !\n");
> +        return 1;
> +    }
> +    memcpy(addr, ranges + na, 4 * pna);
> +
> +finish:
> +    dt_dump_addr("DT: parent translation for:", addr, pna);
> +    dt_dprintk("DT: with offset: %llx\n", (unsigned long long)offset);
> +
> +    /* Translate it into parent bus space */
> +    return pbus->translate(addr, offset, pna);
> +}
> +
> +/*
> + * Translate an address from the device-tree into a CPU physical address,
> + * this walks up the tree and applies the various bus mappings on the
> + * way.
> + *
> + * Note: We consider that crossing any level with #size-cells == 0 to mean
> + * that translation is impossible (that is we are not dealing with a value
> + * that can be mapped to a cpu physical address). This is not really 
> specified
> + * that way, but this is traditionally the way IBM at least do things
> + */
> +static u64 __dt_translate_address(const struct dt_device_node *dev,
> +                                  const __be32 *in_addr, const char *rprop)
> +{
> +    const struct dt_device_node *parent = NULL;
> +    const struct dt_bus *bus, *pbus;
> +    __be32 addr[DT_MAX_ADDR_CELLS];
> +    int na, ns, pna, pns;
> +    u64 result = DT_BAD_ADDR;
> +
> +       dt_dprintk("DT: ** translation for device %s **\n", dev->full_name);

Ide...

> +
> +    /* Get parent & match bus type */
> +    parent = dt_get_parent(dev);
> +    if ( parent == NULL )
> +        goto bail;
> +    bus = dt_match_bus(parent);
> +
> +    /* Count address cells & copy address locally */
> +    bus->count_cells(dev, &na, &ns);
> +    if ( !DT_CHECK_COUNTS(na, ns) )
> +    {
> +        dt_printk(XENLOG_ERR "dt_parse: Bad cell count for %s\n",
> +                  dev->full_name);
> +        goto bail;
> +    }
> +    memcpy(addr, in_addr, na * 4);
> +
> +    dt_dprintk("DT: bus is %s (na=%d, ns=%d) on %s\n",
> +               bus->name, na, ns, parent->full_name);
> +       dt_dump_addr("DT: translating address:", addr, na);

Inde...

> diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
> index 879b75d..ce34ba5 100644
> --- a/xen/include/xen/device_tree.h
> +++ b/xen/include/xen/device_tree.h
> @@ -278,6 +278,28 @@ struct dt_device_node *dt_find_node_by_path(const char 
> *path);
>  const struct dt_device_node *dt_get_parent(const struct dt_device_node 
> *node);
> 
>  /**
> + * dt_device_get_address - Resolve an address for a device
> + * @device: the device whose address is to be resolved
> + * @index: index of the addres to resolve

address

> + * @addr: address filled by this function
> + * @size: size filled by this function
> + *
> + * This function resolves an address, walking the tree, for a give
> + * device-tree node. It returns 0 on success.
> + */
> +int dt_device_get_address(const struct dt_device_node *dev, int index,
> +                          u64 *addr, u64 *size);
> +
> +/**
> + * dt_number_of_address - Get the number of addresse for a device

addresses

> + * @device: the device whose number of address is to be retrieved
> + *
> + * Return the number of address for this device or 0 if there is no
> + * address or an error occured/

occurred

Apart from the indentation and the spelling errors I'm inclined to trust
that the actual logic is ok. So if you fix the above (and any
indentation I missed):
Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

> + */
> +unsigned int dt_number_of_address(const struct dt_device_node *device);
> +
> +/**
>   * dt_n_size_cells - Helper to retrieve the number of cell for the size
>   * @np: node to get the value
>   *
> --
> Julien Grall
> 



_______________________________________________
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®.