On Fri, Aug 17, 2012 at 05:39:56PM +0100, Peter Maydell wrote: > ARM board device tree blobs have moved to specifying addresses and > sizes as 64 bit values (2 cells) rather than 32 bit (1 cell); update > bootwrapper so it can handle these rather than stopping with an error. Assuming that you've tested this, of course: Acked-by: Dave Martin <dave.martin@xxxxxxxxxx> > > Signed-off-by: Peter Maydell <peter.maydell@xxxxxxxxxx> > --- > v1->v2: correct assumption that size-cells == address-cells when > checking whether existing memory size field is zero > > semi_loader.c | 37 +++++++++++++++++++++++++++---------- > 1 file changed, 27 insertions(+), 10 deletions(-) > > diff --git a/semi_loader.c b/semi_loader.c > index 6677527..2a30c5a 100644 > --- a/semi_loader.c > +++ b/semi_loader.c > @@ -103,6 +103,7 @@ static void update_fdt(void **dest, struct loader_info *info) > int _chosen; > void *fdt; > uint32_t const *p; > + int addrcells, sizecells; > > if(!info->fdt_start) > return; > @@ -113,17 +114,21 @@ static void update_fdt(void **dest, struct loader_info *info) > > /* > * Sanity-check address sizes, since addresses and sizes which do > - * not take up exactly 4 bytes are not supported. > + * not take up exactly 4 or 8 bytes are not supported. > */ > { > if(!(p = fdt_getprop(fdt, 0, "#address-cells", &e))) > goto libfdt_error; > - else if(e != 4 || fdt32_to_cpu(*p) != 1) > + else if(e != 4) > goto size_error; > - > + addrcells = fdt32_to_cpu(*p); > if(!(p = fdt_getprop(fdt, 0, "#size-cells", &e))) > goto libfdt_error; > - else if(e != 4 || fdt32_to_cpu(*p) != 1) > + else if(e != 4) > + goto size_error; > + sizecells = fdt32_to_cpu(*p); > + if ((addrcells != 1 && addrcells != 2) || > + (sizecells != 1 && sizecells != 2)) > goto size_error; > } > > @@ -137,7 +142,7 @@ static void update_fdt(void **dest, struct loader_info *info) > { > int offset, depth = 0; > int _memory; > - uint32_t reg[2]; > + uint32_t reg[4]; > > for(offset = fdt_next_node(fdt, 0, &depth); offset >= 0; > offset = fdt_next_node(fdt, offset, &depth)) { > @@ -153,7 +158,10 @@ static void update_fdt(void **dest, struct loader_info *info) > if(e < 0) > goto libfdt_error; > > - if(fdt32_to_cpu(p[1]) != 0) > + /* Check whether the <size> part of the <addr>,<size> tuple is nonzero */ > + if(fdt32_to_cpu(p[addrcells]) != 0) > + goto no_add_memory; > + if(sizecells == 2 && fdt32_to_cpu(p[addrcells + 1]) != 0) > goto no_add_memory; > } > } > @@ -162,9 +170,15 @@ static void update_fdt(void **dest, struct loader_info *info) > goto libfdt_error; > _memory = e; > > - reg[0] = cpu_to_fdt32(PHYS_OFFSET); > - reg[1] = cpu_to_fdt32(PHYS_SIZE); > - if((e = fdt_setprop(fdt, _memory, "reg", ®, sizeof reg)) < 0) > + /* This assumes PHYS_OFFSET and PHYS_SIZE are 32 bits, though > + * the fdt cells we put them in may not be. > + */ > + reg[0] = reg[1] = reg[2] = reg[3] = 0; > + reg[addrcells - 1] = cpu_to_fdt32(PHYS_OFFSET); > + reg[addrcells + sizecells - 1] = cpu_to_fdt32(PHYS_SIZE); > + > + if((e = fdt_setprop(fdt, _memory, "reg", ®, > + sizeof(reg[0]) * (addrcells + sizecells))) < 0) > goto libfdt_error; > > if((e = fdt_setprop_string(fdt, _memory, "device_type", > @@ -186,7 +200,10 @@ no_add_memory: > > if(info->initrd_start) { > uint32_t initrd_end = info->initrd_start + info->initrd_size; > - > + /* It's not documented whether these cells should honour > + * #address-cells. Currently the kernel accepts them as being > + * addresses of either size, so we leave them as 32 bits for now. > + */ > if((e = fdt_setprop_cell(fdt, _chosen, "linux,initrd-start", > info->initrd_start)) < 0) > goto libfdt_error; > -- > 1.7.9.5 > _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm