[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] xen/arm: Retrieve the correct number of cells when building dom0 DT
commit 93be027d51dc6e7c9b4cd071d08194cc6c2306e0 Author: Julien Grall <julien.grall@xxxxxxxxxx> AuthorDate: Tue Sep 29 17:21:36 2015 +0100 Commit: Ian Campbell <ian.campbell@xxxxxxxxxx> CommitDate: Thu Oct 1 13:51:29 2015 +0100 xen/arm: Retrieve the correct number of cells when building dom0 DT The functions dt_n_*_cells return the number of cells for a "reg" property of a given node. So those numbers won't be correct if the parent of a given node is passed. This is fine today because the parent is always the root node which means there is no upper parent. Introduce new helpers dt_child_n_*_cells to retrieve the number of cells for the address and size that can be used to create the "reg" property of the immediate child of a given parent. Also introduce dt_child_set_range to pair up with dt_child_n_*_cells. Use the new helpers when creating the hypervisor and memory node where we only have the parent in hand. This is because those nodes are created from scratch by Xen and therefore we don't have a dt_device_node for them. The only thing we have is a pointer to their future parent. Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx> Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- xen/arch/arm/domain_build.c | 10 +++++----- xen/common/device_tree.c | 39 +++++++++++++++++++++++++++++++++++---- xen/include/xen/device_tree.h | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 9 deletions(-) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index 72b1845..e8f024f 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -569,7 +569,7 @@ static int make_memory_node(const struct domain *d, const struct kernel_info *kinfo) { int res, i; - int reg_size = dt_n_addr_cells(parent) + dt_n_size_cells(parent); + int reg_size = dt_child_n_addr_cells(parent) + dt_child_n_size_cells(parent); int nr_cells = reg_size*kinfo->mem.nr_banks; __be32 reg[nr_cells]; __be32 *cells; @@ -594,7 +594,7 @@ static int make_memory_node(const struct domain *d, DPRINT(" Bank %d: %#"PRIx64"->%#"PRIx64"\n", i, start, start + size); - dt_set_range(&cells, parent, start, size); + dt_child_set_range(&cells, parent, start, size); } res = fdt_property(fdt, "reg", reg, sizeof(reg)); @@ -617,8 +617,8 @@ static int make_hypervisor_node(const struct kernel_info *kinfo, __be32 *cells; int res; /* Convenience alias */ - int addrcells = dt_n_addr_cells(parent); - int sizecells = dt_n_size_cells(parent); + int addrcells = dt_child_n_addr_cells(parent); + int sizecells = dt_child_n_size_cells(parent); void *fdt = kinfo->fdt; DPRINT("Create hypervisor node\n"); @@ -643,7 +643,7 @@ static int make_hypervisor_node(const struct kernel_info *kinfo, /* reg 0 is grant table space */ cells = ®[0]; - dt_set_range(&cells, parent, kinfo->gnttab_start, kinfo->gnttab_size); + dt_child_set_range(&cells, parent, kinfo->gnttab_start, kinfo->gnttab_size); res = fdt_property(fdt, "reg", reg, dt_cells_to_size(addrcells + sizecells)); if ( res ) diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c index 18cdb6f..87c3f71 100644 --- a/xen/common/device_tree.c +++ b/xen/common/device_tree.c @@ -117,6 +117,13 @@ void dt_set_range(__be32 **cellp, const struct dt_device_node *np, dt_set_cell(cellp, dt_n_size_cells(np), size); } +void dt_child_set_range(__be32 **cellp, const struct dt_device_node *parent, + u64 address, u64 size) +{ + dt_set_cell(cellp, dt_child_n_addr_cells(parent), address); + dt_set_cell(cellp, dt_child_n_size_cells(parent), size); +} + static void __init *unflatten_dt_alloc(unsigned long *mem, unsigned long size, unsigned long align) { @@ -386,13 +393,15 @@ dt_find_matching_node(struct dt_device_node *from, return NULL; } -int dt_n_addr_cells(const struct dt_device_node *np) +static int __dt_n_addr_cells(const struct dt_device_node *np, bool_t parent) { const __be32 *ip; do { - if ( np->parent ) + if ( np->parent && !parent ) np = np->parent; + parent = false; + ip = dt_get_property(np, "#address-cells", NULL); if ( ip ) return be32_to_cpup(ip); @@ -401,13 +410,15 @@ int dt_n_addr_cells(const struct dt_device_node *np) return DT_ROOT_NODE_ADDR_CELLS_DEFAULT; } -int dt_n_size_cells(const struct dt_device_node *np) +int __dt_n_size_cells(const struct dt_device_node *np, bool_t parent) { const __be32 *ip; do { - if ( np->parent ) + if ( np->parent && !parent ) np = np->parent; + parent = false; + ip = dt_get_property(np, "#size-cells", NULL); if ( ip ) return be32_to_cpup(ip); @@ -416,6 +427,26 @@ int dt_n_size_cells(const struct dt_device_node *np) return DT_ROOT_NODE_SIZE_CELLS_DEFAULT; } +int dt_n_addr_cells(const struct dt_device_node *np) +{ + return __dt_n_addr_cells(np, false); +} + +int dt_n_size_cells(const struct dt_device_node *np) +{ + return __dt_n_size_cells(np, false); +} + +int dt_child_n_addr_cells(const struct dt_device_node *parent) +{ + return __dt_n_addr_cells(parent, true); +} + +int dt_child_n_size_cells(const struct dt_device_node *parent) +{ + return __dt_n_size_cells(parent, true); +} + /* * These are defined in Linux where much of this code comes from, but * are currently unused outside this file in the context of Xen. diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h index 46c5ba8..5c03f40 100644 --- a/xen/include/xen/device_tree.h +++ b/xen/include/xen/device_tree.h @@ -584,6 +584,25 @@ int dt_n_size_cells(const struct dt_device_node *np); int dt_n_addr_cells(const struct dt_device_node *np); /** + * dt_child_n_size_cells - Helper to retrieve the number of cell for the size + * @parent: parent of the child to get the value + * + * This function retrieves for a given device-tree node the number of + * cell for the size field of there child + */ +int dt_child_n_size_cells(const struct dt_device_node *parent); + +/** + * dt_child_n_addr_cells - Helper to retrieve the number of cell for the + * address + * @parent: parent of the child to get the value + * + * This function retrieves for a given device-tree node the number of + * cell for the address field of there child + */ +int dt_child_n_addr_cells(const struct dt_device_node *parent); + +/** * dt_device_is_available - Check if a device is available for use * * @device: Node to check for availability @@ -655,6 +674,20 @@ void dt_set_range(__be32 **cellp, const struct dt_device_node *np, u64 address, u64 size); /** + * dt_child_set_range - Write range into a series of cells + * + * @cellp: Pointer to cells + * @parent: Parent node which contains the encode for the address and the size + * @address: Start of range + * @size: Size of the range + * + * Write a range into a series of cells and update cellp to point to the + * cell just after. + */ +void dt_child_set_range(__be32 **cellp, const struct dt_device_node *parent, + u64 address, u64 size); + +/** * dt_get_range - Read a range (address/size) from a series of cells * * @cellp: Pointer to cells -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |