4 static int node_offset(void *fdt, const char *node_path)
6 int offset = fdt_path_offset(fdt, node_path);
7 if (offset == -FDT_ERR_NOTFOUND)
8 offset = fdt_add_subnode(fdt, 0, node_path);
12 static int setprop(void *fdt, const char *node_path, const char *property,
13 uint32_t *val_array, int size)
15 int offset = node_offset(fdt, node_path);
18 return fdt_setprop(fdt, offset, property, val_array, size);
21 static int setprop_string(void *fdt, const char *node_path,
22 const char *property, const char *string)
24 int offset = node_offset(fdt, node_path);
27 return fdt_setprop_string(fdt, offset, property, string);
30 static int setprop_cell(void *fdt, const char *node_path,
31 const char *property, uint32_t val)
33 int offset = node_offset(fdt, node_path);
36 return fdt_setprop_cell(fdt, offset, property, val);
40 * Convert and fold provided ATAGs into the provided FDT.
43 * = 0 -> pretend success
44 * = 1 -> bad ATAG (may retry with another possible ATAG pointer)
45 * < 0 -> error from libfdt
47 int atags_to_fdt(void *atag_list, void *fdt, int total_space)
49 struct tag *atag = atag_list;
50 uint32_t mem_reg_property[2 * NR_BANKS];
54 /* make sure we've got an aligned pointer */
55 if ((u32)atag_list & 0x3)
58 /* if we get a DTB here we're done already */
59 if (*(u32 *)atag_list == fdt32_to_cpu(FDT_MAGIC))
62 /* validate the ATAG */
63 if (atag->hdr.tag != ATAG_CORE ||
64 (atag->hdr.size != tag_size(tag_core) &&
68 /* let's give it all the room it could need */
69 ret = fdt_open_into(fdt, fdt, total_space);
73 for_each_tag(atag, atag_list) {
74 if (atag->hdr.tag == ATAG_CMDLINE) {
75 setprop_string(fdt, "/chosen", "bootargs",
76 atag->u.cmdline.cmdline);
77 } else if (atag->hdr.tag == ATAG_MEM) {
78 if (memcount >= sizeof(mem_reg_property)/4)
80 mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start);
81 mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size);
82 } else if (atag->hdr.tag == ATAG_INITRD2) {
83 uint32_t initrd_start, initrd_size;
84 initrd_start = atag->u.initrd.start;
85 initrd_size = atag->u.initrd.size;
86 setprop_cell(fdt, "/chosen", "linux,initrd-start",
88 setprop_cell(fdt, "/chosen", "linux,initrd-end",
89 initrd_start + initrd_size);
94 setprop(fdt, "/memory", "reg", mem_reg_property, 4*memcount);