On 24.06.2013, at 12:22, Peter Maydell wrote: > We already have a qemu_devtree_setprop_cells() which sets a dtb > property to an array of cells whose values are specified by varargs. > However for the fairly common case of setting a property to a list > of addresses or of address,size pairs the number of cells used by > each element in the list depends on the parent's #address-cells > and #size-cells properties. To make this easier we provide an analogous > qemu_devtree_setprop_sized_cells() function which allows the number > of cells used by each element to be specified. > > Signed-off-by: Peter Maydell <peter.mayd...@linaro.org>
This looks pretty complicated for something actually quite simple: All you want is to pass in a number of 64bit values, rather than 32bit ones, right? There's got to be an easier way to implement that. Alex > --- > device_tree.c | 48 ++++++++++++++++++++++++++++++++++++++++++ > include/sysemu/device_tree.h | 29 +++++++++++++++++++++++++ > 2 files changed, 77 insertions(+) > > diff --git a/device_tree.c b/device_tree.c > index 69be9da..15a081c 100644 > --- a/device_tree.c > +++ b/device_tree.c > @@ -319,3 +319,51 @@ void qemu_devtree_dumpdtb(void *fdt, int size) > } > > } > + > +int qemu_devtree_setprop_sized_cells(void *fdt, const char *node_path, > + const char *property, ...) > +{ > + uint32_t *propcells; > + uint32_t propsize = 0; > + va_list ap; > + uint32_t ncells; > + uint64_t value; > + int i, argnum; > + > + va_start(ap, property); > + for (;;) { > + ncells = va_arg(ap, uint32_t); > + if (!ncells) { > + break; > + } > + assert(ncells < 3); > + propsize += ncells; > + value = va_arg(ap, uint64_t); > + } > + va_end(ap); > + > + propcells = g_new0(uint32_t, propsize); > + > + i = 0; > + va_start(ap, property); > + for (argnum = 1; ; argnum++) { > + uint32_t hival; > + > + ncells = va_arg(ap, uint32_t); > + if (!ncells) { > + break; > + } > + value = va_arg(ap, uint64_t); > + hival = cpu_to_be32(value >> 32); > + if (ncells > 1) { > + propcells[i++] = hival; > + } else if (hival != 0) { > + return argnum; > + } > + propcells[i++] = cpu_to_be32(value); > + } > + va_end(ap); > + > + return qemu_devtree_setprop(fdt, node_path, property, propcells, > + propsize * sizeof(uint32_t)); > +} > diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h > index f0b3f35..d7691f9 100644 > --- a/include/sysemu/device_tree.h > +++ b/include/sysemu/device_tree.h > @@ -51,4 +51,33 @@ int qemu_devtree_add_subnode(void *fdt, const char *name); > > void qemu_devtree_dumpdtb(void *fdt, int size); > > +/** > + * qemu_devtree_setprop_sized_cells: > + * @fdt: device tree blob > + * @node_path: node to set property on > + * @property: property to set > + * @...: 0-terminated list of uint32_t number-of-cells, uint64_t value pairs > + * > + * Set the specified property on the specified node in the device tree > + * to be an array of cells. The values of the cells are specified via > + * the varargs list, which alternates between "number of cells used by > + * this value" and "value" (terminated when number-of-cells is zero). > + * number-of-cells must be either 1 or 2 (other values will assert()). > + * > + * This function is useful because device tree nodes often have cell arrays > + * which are either lists of addresses or lists of address,size tuples, but > + * the number of cells used for each element vary depending on the > + * #address-cells and #size-cells properties of their parent node. > + * If you know all your cell elements are one cell wide you can use the > + * simpler qemu_devtree_setprop_cells(). > + * > + * Return value: 0 on success, <0 if setting the property failed, > + * n (for n>0) if value n wouldn't fit in the required number of cells. > + * (This slightly odd convention is for the benefit of callers who might > + * wish to print different error messages depending on which value > + * was too large to fit, since values might be user-specified.) > + */ > +int qemu_devtree_setprop_sized_cells(void *fdt, const char *node_path, > + const char *property, ...); > + > #endif /* __DEVICE_TREE_H__ */ > -- > 1.7.9.5 >