Skip to content

Commit

Permalink
[POWERPC] bootwrapper: dt_xlate_range() bugfixes
Browse files Browse the repository at this point in the history
1. The check whether ranges fits in the buffer was using elements rather
than bytes.
2. Empty ranges were not properly treated as transparent, and missing
ranges were treated as transparent.
3. The loop terminated when translating from the root rather than to.  Once
bug #2 was fixed, it failed due to a missing ranges in the root node.
4. In decoding the ranges property, the #size-cells used was that of
the parent, not the child.

Signed-off-by: Scott Wood <scottwood@freescale.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Scott Wood authored and Paul Mackerras committed Aug 22, 2007
1 parent 643d3c1 commit 0602801
Showing 1 changed file with 13 additions and 7 deletions.
20 changes: 13 additions & 7 deletions arch/powerpc/boot/devtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,
u32 this_addr[MAX_ADDR_CELLS];
void *parent;
u64 ret_addr, ret_size;
u32 naddr, nsize, prev_naddr;
u32 naddr, nsize, prev_naddr, prev_nsize;
int buflen, offset;

parent = get_parent(node);
Expand All @@ -233,7 +233,7 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,
offset = (naddr + nsize) * res;

if (reglen < offset + naddr + nsize ||
sizeof(dt_xlate_buf) < offset + naddr + nsize)
sizeof(dt_xlate_buf) < (offset + naddr + nsize) * 4)
return 0;

copy_val(last_addr, dt_xlate_buf + offset, naddr);
Expand All @@ -244,20 +244,26 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,
ret_size |= dt_xlate_buf[offset + naddr + 1];
}

while ((node = get_parent(node))) {
for (;;) {
prev_naddr = naddr;
prev_nsize = nsize;
node = parent;

get_reg_format(node, &naddr, &nsize);
parent = get_parent(node);
if (!parent)
break;

get_reg_format(parent, &naddr, &nsize);

buflen = getprop(node, "ranges", dt_xlate_buf,
sizeof(dt_xlate_buf));
if (buflen < 0)
if (buflen == 0)
continue;
if (buflen > sizeof(dt_xlate_buf))
if (buflen < 0 || buflen > sizeof(dt_xlate_buf))
return 0;

offset = find_range(last_addr, dt_xlate_buf, prev_naddr,
naddr, nsize, buflen / 4);
naddr, prev_nsize, buflen / 4);

if (offset < 0)
return 0;
Expand Down

0 comments on commit 0602801

Please sign in to comment.