1
0
Fork 0

of/fdt: Clean up casting in unflattening path

The flat tree unflatting path is using unsigned longs to carry around
virtual address pointers to the device tree and the allocated memory
used to unpack it. This is a little insane since every access to them
needs to be cast to a pointer type before using it. This patch changes
the data type to void* for the 'start' and 'mem' pointers and reworks
the unflattening functions to use those values directly which results in
slightly simpler code.

Signed-off-by: Grant Likely <grant.likely@linaro.org>
wifi-calibration
Grant Likely 2013-08-29 13:30:35 +01:00
parent 92d31610aa
commit 4485681939
1 changed files with 30 additions and 33 deletions

View File

@ -126,13 +126,13 @@ int of_fdt_match(struct boot_param_header *blob, unsigned long node,
return score; return score;
} }
static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size, static void *unflatten_dt_alloc(void **mem, unsigned long size,
unsigned long align) unsigned long align)
{ {
void *res; void *res;
*mem = ALIGN(*mem, align); *mem = PTR_ALIGN(*mem, align);
res = (void *)*mem; res = *mem;
*mem += size; *mem += size;
return res; return res;
@ -147,9 +147,9 @@ static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
* @allnextpp: pointer to ->allnext from last allocated device_node * @allnextpp: pointer to ->allnext from last allocated device_node
* @fpsize: Size of the node path up at the current depth. * @fpsize: Size of the node path up at the current depth.
*/ */
static unsigned long unflatten_dt_node(struct boot_param_header *blob, static void * unflatten_dt_node(struct boot_param_header *blob,
unsigned long mem, void *mem,
unsigned long *p, void **p,
struct device_node *dad, struct device_node *dad,
struct device_node ***allnextpp, struct device_node ***allnextpp,
unsigned long fpsize) unsigned long fpsize)
@ -162,15 +162,15 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
int has_name = 0; int has_name = 0;
int new_format = 0; int new_format = 0;
tag = be32_to_cpup((__be32 *)(*p)); tag = be32_to_cpup(*p);
if (tag != OF_DT_BEGIN_NODE) { if (tag != OF_DT_BEGIN_NODE) {
pr_err("Weird tag at start of node: %x\n", tag); pr_err("Weird tag at start of node: %x\n", tag);
return mem; return mem;
} }
*p += 4; *p += 4;
pathp = (char *)*p; pathp = *p;
l = allocl = strlen(pathp) + 1; l = allocl = strlen(pathp) + 1;
*p = ALIGN(*p + l, 4); *p = PTR_ALIGN(*p + l, 4);
/* version 0x10 has a more compact unit name here instead of the full /* version 0x10 has a more compact unit name here instead of the full
* path. we accumulate the full path size using "fpsize", we'll rebuild * path. we accumulate the full path size using "fpsize", we'll rebuild
@ -239,7 +239,7 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
u32 sz, noff; u32 sz, noff;
char *pname; char *pname;
tag = be32_to_cpup((__be32 *)(*p)); tag = be32_to_cpup(*p);
if (tag == OF_DT_NOP) { if (tag == OF_DT_NOP) {
*p += 4; *p += 4;
continue; continue;
@ -247,11 +247,11 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
if (tag != OF_DT_PROP) if (tag != OF_DT_PROP)
break; break;
*p += 4; *p += 4;
sz = be32_to_cpup((__be32 *)(*p)); sz = be32_to_cpup(*p);
noff = be32_to_cpup((__be32 *)((*p) + 4)); noff = be32_to_cpup(*p + 4);
*p += 8; *p += 8;
if (be32_to_cpu(blob->version) < 0x10) if (be32_to_cpu(blob->version) < 0x10)
*p = ALIGN(*p, sz >= 8 ? 8 : 4); *p = PTR_ALIGN(*p, sz >= 8 ? 8 : 4);
pname = of_fdt_get_string(blob, noff); pname = of_fdt_get_string(blob, noff);
if (pname == NULL) { if (pname == NULL) {
@ -281,11 +281,11 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
np->phandle = be32_to_cpup((__be32 *)*p); np->phandle = be32_to_cpup((__be32 *)*p);
pp->name = pname; pp->name = pname;
pp->length = sz; pp->length = sz;
pp->value = (void *)*p; pp->value = *p;
*prev_pp = pp; *prev_pp = pp;
prev_pp = &pp->next; prev_pp = &pp->next;
} }
*p = ALIGN((*p) + sz, 4); *p = PTR_ALIGN((*p) + sz, 4);
} }
/* with version 0x10 we may not have the name property, recreate /* with version 0x10 we may not have the name property, recreate
* it here from the unit name if absent * it here from the unit name if absent
@ -334,7 +334,7 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
else else
mem = unflatten_dt_node(blob, mem, p, np, allnextpp, mem = unflatten_dt_node(blob, mem, p, np, allnextpp,
fpsize); fpsize);
tag = be32_to_cpup((__be32 *)(*p)); tag = be32_to_cpup(*p);
} }
if (tag != OF_DT_END_NODE) { if (tag != OF_DT_END_NODE) {
pr_err("Weird tag at end of node: %x\n", tag); pr_err("Weird tag at end of node: %x\n", tag);
@ -360,7 +360,8 @@ static void __unflatten_device_tree(struct boot_param_header *blob,
struct device_node **mynodes, struct device_node **mynodes,
void * (*dt_alloc)(u64 size, u64 align)) void * (*dt_alloc)(u64 size, u64 align))
{ {
unsigned long start, mem, size; unsigned long size;
void *start, *mem;
struct device_node **allnextp = mynodes; struct device_node **allnextp = mynodes;
pr_debug(" -> unflatten_device_tree()\n"); pr_debug(" -> unflatten_device_tree()\n");
@ -381,32 +382,28 @@ static void __unflatten_device_tree(struct boot_param_header *blob,
} }
/* First pass, scan for size */ /* First pass, scan for size */
start = ((unsigned long)blob) + start = ((void *)blob) + be32_to_cpu(blob->off_dt_struct);
be32_to_cpu(blob->off_dt_struct); size = (unsigned long)unflatten_dt_node(blob, 0, &start, NULL, NULL, 0);
size = unflatten_dt_node(blob, 0, &start, NULL, NULL, 0); size = ALIGN(size, 4);
size = (size | 3) + 1;
pr_debug(" size is %lx, allocating...\n", size); pr_debug(" size is %lx, allocating...\n", size);
/* Allocate memory for the expanded device tree */ /* Allocate memory for the expanded device tree */
mem = (unsigned long) mem = dt_alloc(size + 4, __alignof__(struct device_node));
dt_alloc(size + 4, __alignof__(struct device_node)); memset(mem, 0, size);
memset((void *)mem, 0, size); *(__be32 *)(mem + size) = cpu_to_be32(0xdeadbeef);
((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef); pr_debug(" unflattening %p...\n", mem);
pr_debug(" unflattening %lx...\n", mem);
/* Second pass, do actual unflattening */ /* Second pass, do actual unflattening */
start = ((unsigned long)blob) + start = ((void *)blob) + be32_to_cpu(blob->off_dt_struct);
be32_to_cpu(blob->off_dt_struct);
unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0); unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0);
if (be32_to_cpup((__be32 *)start) != OF_DT_END) if (be32_to_cpup(start) != OF_DT_END)
pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); pr_warning("Weird tag at end of tree: %08x\n", be32_to_cpup(start));
if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef) if (be32_to_cpup(mem + size) != 0xdeadbeef)
pr_warning("End of tree marker overwritten: %08x\n", pr_warning("End of tree marker overwritten: %08x\n",
be32_to_cpu(((__be32 *)mem)[size / 4])); be32_to_cpup(mem + size));
*allnextp = NULL; *allnextp = NULL;
pr_debug(" <- unflatten_device_tree()\n"); pr_debug(" <- unflatten_device_tree()\n");