12 #include <linux/kernel.h>
14 #include <linux/module.h>
17 #include <linux/string.h>
18 #include <linux/errno.h>
19 #include <linux/slab.h>
21 #include <asm/setup.h>
23 #include <asm/machdep.h>
30 return ((
char *)blob) +
39 unsigned long node,
const char *
name,
42 unsigned long p =
node;
59 p =
ALIGN(p, sz >= 8 ? 8 : 4);
63 pr_warning(
"Can't find property index name !\n");
66 if (
strcmp(name, nstr) == 0) {
87 unsigned long node,
const char *compat)
90 unsigned long cplen,
l,
score = 0;
97 if (of_compat_cmp(cp, compat,
strlen(compat)) == 0)
111 const char *
const *compat)
120 if (tmp && (score == 0 || (tmp < score)))
128 static void *unflatten_dt_alloc(
unsigned long *
mem,
unsigned long size,
133 *mem =
ALIGN(*mem, align);
154 unsigned long fpsize)
160 unsigned int l, allocl;
166 pr_err(
"Weird tag at start of node: %x\n", tag);
171 l = allocl =
strlen(pathp) + 1;
172 *p =
ALIGN(*p + l, 4);
179 if ((*pathp) !=
'/') {
198 np = unflatten_dt_alloc(&mem,
sizeof(
struct device_node) + allocl,
201 memset(np, 0,
sizeof(*np));
209 if ((
strlen(fn) + l + 1) != allocl) {
210 pr_debug(
"%s: p: %d, l: %d, a: %d\n",
230 dad->
next->sibling = np;
233 kref_init(&np->
kref);
252 *p =
ALIGN(*p, sz >= 8 ? 8 : 4);
256 pr_info(
"Can't find property name in list !\n");
259 if (
strcmp(pname,
"name") == 0)
262 pp = unflatten_dt_alloc(&mem,
sizeof(
struct property),
270 if ((
strcmp(pname,
"phandle") == 0) ||
271 (
strcmp(pname,
"linux,phandle") == 0)) {
278 if (
strcmp(pname,
"ibm,phandle") == 0)
282 pp->
value = (
void *)*p;
286 *p =
ALIGN((*p) + sz, 4);
292 char *
p1 = pathp, *
ps = pathp, *pa =
NULL;
305 pp = unflatten_dt_alloc(&mem,
sizeof(
struct property) + sz,
314 ((
char *)pp->
value)[sz - 1] = 0;
315 pr_debug(
"fixed up name for %s -> %s\n", pathp,
333 mem = unflatten_dt_node(blob, mem, p, np, allnextpp,
338 pr_err(
"Weird tag at end of node: %x\n", tag);
364 pr_debug(
" -> unflatten_device_tree()\n");
367 pr_debug(
"No device tree pointer\n");
371 pr_debug(
"Unflattening device tree:\n");
377 pr_err(
"Invalid device tree blob header\n");
382 start = ((
unsigned long)blob) +
384 size = unflatten_dt_node(blob, 0, &start,
NULL,
NULL, 0);
385 size = (size | 3) + 1;
387 pr_debug(
" size is %lx, allocating...\n", size);
390 mem = (
unsigned long)
391 dt_alloc(size + 4, __alignof__(
struct device_node));
395 pr_debug(
" unflattening %lx...\n", mem);
398 start = ((
unsigned long)blob) +
400 unflatten_dt_node(blob, mem, &start,
NULL, &allnextp, 0);
402 pr_warning(
"Weird tag at end of tree: %08x\n", *((
u32 *)start));
404 pr_warning(
"End of tree marker overwritten: %08x\n",
408 pr_debug(
" <- unflatten_device_tree()\n");
411 static void *kernel_tree_alloc(
u64 size,
u64 align)
429 __unflatten_device_tree(device_tree, mynodes, &kernel_tree_alloc);
439 #ifdef CONFIG_OF_EARLY_FLATTREE
450 int __init of_scan_flat_dt(
int (*it)(
unsigned long node,
451 const char *uname,
int depth,
455 unsigned long p = ((
unsigned long)initial_boot_params) +
477 p =
ALIGN(p, sz >= 8 ? 8 : 4);
483 pr_err(
"Invalid tag %x in flat device tree!\n", tag);
489 if ((*pathp) ==
'/') {
491 for (lp =
NULL, np = pathp; *np; np++)
497 rc = it(p, pathp, depth, data);
508 unsigned long __init of_get_flat_dt_root(
void)
510 unsigned long p = ((
unsigned long)initial_boot_params) +
526 void *
__init of_get_flat_dt_prop(
unsigned long node,
const char *
name,
537 int __init of_flat_dt_is_compatible(
unsigned long node,
const char *compat)
545 int __init of_flat_dt_match(
unsigned long node,
const char *
const *compat)
550 #ifdef CONFIG_BLK_DEV_INITRD
555 void __init early_init_dt_check_for_initrd(
unsigned long node)
560 pr_debug(
"Looking for initrd properties... ");
562 prop = of_get_flat_dt_prop(node,
"linux,initrd-start", &len);
565 start = of_read_ulong(prop, len/4);
567 prop = of_get_flat_dt_prop(node,
"linux,initrd-end", &len);
570 end = of_read_ulong(prop, len/4);
573 pr_debug(
"initrd_start=0x%lx initrd_end=0x%lx\n", start, end);
576 inline void early_init_dt_check_for_initrd(
unsigned long node)
584 int __init early_init_dt_scan_root(
unsigned long node,
const char *uname,
592 dt_root_size_cells = OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
593 dt_root_addr_cells = OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
595 prop = of_get_flat_dt_prop(node,
"#size-cells",
NULL);
598 pr_debug(
"dt_root_size_cells = %x\n", dt_root_size_cells);
600 prop = of_get_flat_dt_prop(node,
"#address-cells",
NULL);
603 pr_debug(
"dt_root_addr_cells = %x\n", dt_root_addr_cells);
614 return of_read_number(p, s);
620 int __init early_init_dt_scan_memory(
unsigned long node,
const char *uname,
621 int depth,
void *data)
623 char *
type = of_get_flat_dt_prop(node,
"device_type",
NULL);
633 if (depth != 1 ||
strcmp(uname,
"memory@0") != 0)
635 }
else if (
strcmp(type,
"memory") != 0)
638 reg = of_get_flat_dt_prop(node,
"linux,usable-memory", &l);
640 reg = of_get_flat_dt_prop(node,
"reg", &l);
644 endp = reg + (l /
sizeof(
__be32));
646 pr_debug(
"memory scan node %s, reg size %ld, data: %x %x %x %x,\n",
647 uname, l, reg[0], reg[1], reg[2], reg[3]);
649 while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
652 base = dt_mem_next_cell(dt_root_addr_cells, ®);
653 size = dt_mem_next_cell(dt_root_size_cells, ®);
657 pr_debug(
" - %llx , %llx\n", (
unsigned long long)base,
658 (
unsigned long long)size);
666 int __init early_init_dt_scan_chosen(
unsigned long node,
const char *uname,
667 int depth,
void *data)
672 pr_debug(
"search \"chosen\", depth: %d, uname: %s\n", depth, uname);
674 if (depth != 1 || !data ||
675 (
strcmp(uname,
"chosen") != 0 &&
strcmp(uname,
"chosen@0") != 0))
678 early_init_dt_check_for_initrd(node);
681 p = of_get_flat_dt_prop(node,
"bootargs", &l);
682 if (p !=
NULL && l > 0)
690 #ifdef CONFIG_CMDLINE
691 #ifndef CONFIG_CMDLINE_FORCE
692 if (!((
char *)data)[0])
697 pr_debug(
"Command line is: %s\n", (
char*)data);
711 void __init unflatten_device_tree(
void)
713 __unflatten_device_tree(initial_boot_params, &
allnodes,