1 /* 2 * Functions for working with the Flattened Device Tree data format 3 * 4 * Copyright 2009 Benjamin Herrenschmidt, IBM Corp 5 * benh@kernel.crashing.org 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * version 2 as published by the Free Software Foundation. 10 */ 11 12 #include <linux/kernel.h> 13 #include <linux/initrd.h> 14 #include <linux/of.h> 15 #include <linux/of_fdt.h> 16 #include <linux/string.h> 17 #include <linux/errno.h> 18 19 #ifdef CONFIG_PPC 20 #include <asm/machdep.h> 21 #endif /* CONFIG_PPC */ 22 23 #include <asm/page.h> 24 25 int __initdata dt_root_addr_cells; 26 int __initdata dt_root_size_cells; 27 28 struct boot_param_header *initial_boot_params; 29 30 char *find_flat_dt_string(u32 offset) 31 { 32 return ((char *)initial_boot_params) + 33 be32_to_cpu(initial_boot_params->off_dt_strings) + offset; 34 } 35 36 /** 37 * of_scan_flat_dt - scan flattened tree blob and call callback on each. 38 * @it: callback function 39 * @data: context data pointer 40 * 41 * This function is used to scan the flattened device-tree, it is 42 * used to extract the memory information at boot before we can 43 * unflatten the tree 44 */ 45 int __init of_scan_flat_dt(int (*it)(unsigned long node, 46 const char *uname, int depth, 47 void *data), 48 void *data) 49 { 50 unsigned long p = ((unsigned long)initial_boot_params) + 51 be32_to_cpu(initial_boot_params->off_dt_struct); 52 int rc = 0; 53 int depth = -1; 54 55 do { 56 u32 tag = be32_to_cpup((__be32 *)p); 57 char *pathp; 58 59 p += 4; 60 if (tag == OF_DT_END_NODE) { 61 depth--; 62 continue; 63 } 64 if (tag == OF_DT_NOP) 65 continue; 66 if (tag == OF_DT_END) 67 break; 68 if (tag == OF_DT_PROP) { 69 u32 sz = be32_to_cpup((__be32 *)p); 70 p += 8; 71 if (be32_to_cpu(initial_boot_params->version) < 0x10) 72 p = ALIGN(p, sz >= 8 ? 8 : 4); 73 p += sz; 74 p = ALIGN(p, 4); 75 continue; 76 } 77 if (tag != OF_DT_BEGIN_NODE) { 78 pr_err("Invalid tag %x in flat device tree!\n", tag); 79 return -EINVAL; 80 } 81 depth++; 82 pathp = (char *)p; 83 p = ALIGN(p + strlen(pathp) + 1, 4); 84 if ((*pathp) == '/') { 85 char *lp, *np; 86 for (lp = NULL, np = pathp; *np; np++) 87 if ((*np) == '/') 88 lp = np+1; 89 if (lp != NULL) 90 pathp = lp; 91 } 92 rc = it(p, pathp, depth, data); 93 if (rc != 0) 94 break; 95 } while (1); 96 97 return rc; 98 } 99 100 /** 101 * of_get_flat_dt_root - find the root node in the flat blob 102 */ 103 unsigned long __init of_get_flat_dt_root(void) 104 { 105 unsigned long p = ((unsigned long)initial_boot_params) + 106 be32_to_cpu(initial_boot_params->off_dt_struct); 107 108 while (be32_to_cpup((__be32 *)p) == OF_DT_NOP) 109 p += 4; 110 BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE); 111 p += 4; 112 return ALIGN(p + strlen((char *)p) + 1, 4); 113 } 114 115 /** 116 * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr 117 * 118 * This function can be used within scan_flattened_dt callback to get 119 * access to properties 120 */ 121 void *__init of_get_flat_dt_prop(unsigned long node, const char *name, 122 unsigned long *size) 123 { 124 unsigned long p = node; 125 126 do { 127 u32 tag = be32_to_cpup((__be32 *)p); 128 u32 sz, noff; 129 const char *nstr; 130 131 p += 4; 132 if (tag == OF_DT_NOP) 133 continue; 134 if (tag != OF_DT_PROP) 135 return NULL; 136 137 sz = be32_to_cpup((__be32 *)p); 138 noff = be32_to_cpup((__be32 *)(p + 4)); 139 p += 8; 140 if (be32_to_cpu(initial_boot_params->version) < 0x10) 141 p = ALIGN(p, sz >= 8 ? 8 : 4); 142 143 nstr = find_flat_dt_string(noff); 144 if (nstr == NULL) { 145 pr_warning("Can't find property index name !\n"); 146 return NULL; 147 } 148 if (strcmp(name, nstr) == 0) { 149 if (size) 150 *size = sz; 151 return (void *)p; 152 } 153 p += sz; 154 p = ALIGN(p, 4); 155 } while (1); 156 } 157 158 /** 159 * of_flat_dt_is_compatible - Return true if given node has compat in compatible list 160 * @node: node to test 161 * @compat: compatible string to compare with compatible list. 162 */ 163 int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) 164 { 165 const char *cp; 166 unsigned long cplen, l; 167 168 cp = of_get_flat_dt_prop(node, "compatible", &cplen); 169 if (cp == NULL) 170 return 0; 171 while (cplen > 0) { 172 if (of_compat_cmp(cp, compat, strlen(compat)) == 0) 173 return 1; 174 l = strlen(cp) + 1; 175 cp += l; 176 cplen -= l; 177 } 178 179 return 0; 180 } 181 182 static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, 183 unsigned long align) 184 { 185 void *res; 186 187 *mem = ALIGN(*mem, align); 188 res = (void *)*mem; 189 *mem += size; 190 191 return res; 192 } 193 194 /** 195 * unflatten_dt_node - Alloc and populate a device_node from the flat tree 196 * @p: pointer to node in flat tree 197 * @dad: Parent struct device_node 198 * @allnextpp: pointer to ->allnext from last allocated device_node 199 * @fpsize: Size of the node path up at the current depth. 200 */ 201 unsigned long __init unflatten_dt_node(unsigned long mem, 202 unsigned long *p, 203 struct device_node *dad, 204 struct device_node ***allnextpp, 205 unsigned long fpsize) 206 { 207 struct device_node *np; 208 struct property *pp, **prev_pp = NULL; 209 char *pathp; 210 u32 tag; 211 unsigned int l, allocl; 212 int has_name = 0; 213 int new_format = 0; 214 215 tag = be32_to_cpup((__be32 *)(*p)); 216 if (tag != OF_DT_BEGIN_NODE) { 217 pr_err("Weird tag at start of node: %x\n", tag); 218 return mem; 219 } 220 *p += 4; 221 pathp = (char *)*p; 222 l = allocl = strlen(pathp) + 1; 223 *p = ALIGN(*p + l, 4); 224 225 /* version 0x10 has a more compact unit name here instead of the full 226 * path. we accumulate the full path size using "fpsize", we'll rebuild 227 * it later. We detect this because the first character of the name is 228 * not '/'. 229 */ 230 if ((*pathp) != '/') { 231 new_format = 1; 232 if (fpsize == 0) { 233 /* root node: special case. fpsize accounts for path 234 * plus terminating zero. root node only has '/', so 235 * fpsize should be 2, but we want to avoid the first 236 * level nodes to have two '/' so we use fpsize 1 here 237 */ 238 fpsize = 1; 239 allocl = 2; 240 } else { 241 /* account for '/' and path size minus terminal 0 242 * already in 'l' 243 */ 244 fpsize += l; 245 allocl = fpsize; 246 } 247 } 248 249 np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl, 250 __alignof__(struct device_node)); 251 if (allnextpp) { 252 memset(np, 0, sizeof(*np)); 253 np->full_name = ((char *)np) + sizeof(struct device_node); 254 if (new_format) { 255 char *fn = np->full_name; 256 /* rebuild full path for new format */ 257 if (dad && dad->parent) { 258 strcpy(fn, dad->full_name); 259 #ifdef DEBUG 260 if ((strlen(fn) + l + 1) != allocl) { 261 pr_debug("%s: p: %d, l: %d, a: %d\n", 262 pathp, (int)strlen(fn), 263 l, allocl); 264 } 265 #endif 266 fn += strlen(fn); 267 } 268 *(fn++) = '/'; 269 memcpy(fn, pathp, l); 270 } else 271 memcpy(np->full_name, pathp, l); 272 prev_pp = &np->properties; 273 **allnextpp = np; 274 *allnextpp = &np->allnext; 275 if (dad != NULL) { 276 np->parent = dad; 277 /* we temporarily use the next field as `last_child'*/ 278 if (dad->next == NULL) 279 dad->child = np; 280 else 281 dad->next->sibling = np; 282 dad->next = np; 283 } 284 kref_init(&np->kref); 285 } 286 while (1) { 287 u32 sz, noff; 288 char *pname; 289 290 tag = be32_to_cpup((__be32 *)(*p)); 291 if (tag == OF_DT_NOP) { 292 *p += 4; 293 continue; 294 } 295 if (tag != OF_DT_PROP) 296 break; 297 *p += 4; 298 sz = be32_to_cpup((__be32 *)(*p)); 299 noff = be32_to_cpup((__be32 *)((*p) + 4)); 300 *p += 8; 301 if (be32_to_cpu(initial_boot_params->version) < 0x10) 302 *p = ALIGN(*p, sz >= 8 ? 8 : 4); 303 304 pname = find_flat_dt_string(noff); 305 if (pname == NULL) { 306 pr_info("Can't find property name in list !\n"); 307 break; 308 } 309 if (strcmp(pname, "name") == 0) 310 has_name = 1; 311 l = strlen(pname) + 1; 312 pp = unflatten_dt_alloc(&mem, sizeof(struct property), 313 __alignof__(struct property)); 314 if (allnextpp) { 315 /* We accept flattened tree phandles either in 316 * ePAPR-style "phandle" properties, or the 317 * legacy "linux,phandle" properties. If both 318 * appear and have different values, things 319 * will get weird. Don't do that. */ 320 if ((strcmp(pname, "phandle") == 0) || 321 (strcmp(pname, "linux,phandle") == 0)) { 322 if (np->phandle == 0) 323 np->phandle = be32_to_cpup((__be32*)*p); 324 } 325 /* And we process the "ibm,phandle" property 326 * used in pSeries dynamic device tree 327 * stuff */ 328 if (strcmp(pname, "ibm,phandle") == 0) 329 np->phandle = be32_to_cpup((__be32 *)*p); 330 pp->name = pname; 331 pp->length = sz; 332 pp->value = (void *)*p; 333 *prev_pp = pp; 334 prev_pp = &pp->next; 335 } 336 *p = ALIGN((*p) + sz, 4); 337 } 338 /* with version 0x10 we may not have the name property, recreate 339 * it here from the unit name if absent 340 */ 341 if (!has_name) { 342 char *p1 = pathp, *ps = pathp, *pa = NULL; 343 int sz; 344 345 while (*p1) { 346 if ((*p1) == '@') 347 pa = p1; 348 if ((*p1) == '/') 349 ps = p1 + 1; 350 p1++; 351 } 352 if (pa < ps) 353 pa = p1; 354 sz = (pa - ps) + 1; 355 pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz, 356 __alignof__(struct property)); 357 if (allnextpp) { 358 pp->name = "name"; 359 pp->length = sz; 360 pp->value = pp + 1; 361 *prev_pp = pp; 362 prev_pp = &pp->next; 363 memcpy(pp->value, ps, sz - 1); 364 ((char *)pp->value)[sz - 1] = 0; 365 pr_debug("fixed up name for %s -> %s\n", pathp, 366 (char *)pp->value); 367 } 368 } 369 if (allnextpp) { 370 *prev_pp = NULL; 371 np->name = of_get_property(np, "name", NULL); 372 np->type = of_get_property(np, "device_type", NULL); 373 374 if (!np->name) 375 np->name = "<NULL>"; 376 if (!np->type) 377 np->type = "<NULL>"; 378 } 379 while (tag == OF_DT_BEGIN_NODE || tag == OF_DT_NOP) { 380 if (tag == OF_DT_NOP) 381 *p += 4; 382 else 383 mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize); 384 tag = be32_to_cpup((__be32 *)(*p)); 385 } 386 if (tag != OF_DT_END_NODE) { 387 pr_err("Weird tag at end of node: %x\n", tag); 388 return mem; 389 } 390 *p += 4; 391 return mem; 392 } 393 394 #ifdef CONFIG_BLK_DEV_INITRD 395 /** 396 * early_init_dt_check_for_initrd - Decode initrd location from flat tree 397 * @node: reference to node containing initrd location ('chosen') 398 */ 399 void __init early_init_dt_check_for_initrd(unsigned long node) 400 { 401 unsigned long start, end, len; 402 __be32 *prop; 403 404 pr_debug("Looking for initrd properties... "); 405 406 prop = of_get_flat_dt_prop(node, "linux,initrd-start", &len); 407 if (!prop) 408 return; 409 start = of_read_ulong(prop, len/4); 410 411 prop = of_get_flat_dt_prop(node, "linux,initrd-end", &len); 412 if (!prop) 413 return; 414 end = of_read_ulong(prop, len/4); 415 416 early_init_dt_setup_initrd_arch(start, end); 417 pr_debug("initrd_start=0x%lx initrd_end=0x%lx\n", start, end); 418 } 419 #else 420 inline void early_init_dt_check_for_initrd(unsigned long node) 421 { 422 } 423 #endif /* CONFIG_BLK_DEV_INITRD */ 424 425 /** 426 * early_init_dt_scan_root - fetch the top level address and size cells 427 */ 428 int __init early_init_dt_scan_root(unsigned long node, const char *uname, 429 int depth, void *data) 430 { 431 __be32 *prop; 432 433 if (depth != 0) 434 return 0; 435 436 dt_root_size_cells = OF_ROOT_NODE_SIZE_CELLS_DEFAULT; 437 dt_root_addr_cells = OF_ROOT_NODE_ADDR_CELLS_DEFAULT; 438 439 prop = of_get_flat_dt_prop(node, "#size-cells", NULL); 440 if (prop) 441 dt_root_size_cells = be32_to_cpup(prop); 442 pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells); 443 444 prop = of_get_flat_dt_prop(node, "#address-cells", NULL); 445 if (prop) 446 dt_root_addr_cells = be32_to_cpup(prop); 447 pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells); 448 449 /* break now */ 450 return 1; 451 } 452 453 u64 __init dt_mem_next_cell(int s, __be32 **cellp) 454 { 455 __be32 *p = *cellp; 456 457 *cellp = p + s; 458 return of_read_number(p, s); 459 } 460 461 /** 462 * early_init_dt_scan_memory - Look for an parse memory nodes 463 */ 464 int __init early_init_dt_scan_memory(unsigned long node, const char *uname, 465 int depth, void *data) 466 { 467 char *type = of_get_flat_dt_prop(node, "device_type", NULL); 468 __be32 *reg, *endp; 469 unsigned long l; 470 471 /* We are scanning "memory" nodes only */ 472 if (type == NULL) { 473 /* 474 * The longtrail doesn't have a device_type on the 475 * /memory node, so look for the node called /memory@0. 476 */ 477 if (depth != 1 || strcmp(uname, "memory@0") != 0) 478 return 0; 479 } else if (strcmp(type, "memory") != 0) 480 return 0; 481 482 reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l); 483 if (reg == NULL) 484 reg = of_get_flat_dt_prop(node, "reg", &l); 485 if (reg == NULL) 486 return 0; 487 488 endp = reg + (l / sizeof(__be32)); 489 490 pr_debug("memory scan node %s, reg size %ld, data: %x %x %x %x,\n", 491 uname, l, reg[0], reg[1], reg[2], reg[3]); 492 493 while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { 494 u64 base, size; 495 496 base = dt_mem_next_cell(dt_root_addr_cells, ®); 497 size = dt_mem_next_cell(dt_root_size_cells, ®); 498 499 if (size == 0) 500 continue; 501 pr_debug(" - %llx , %llx\n", (unsigned long long)base, 502 (unsigned long long)size); 503 504 early_init_dt_add_memory_arch(base, size); 505 } 506 507 return 0; 508 } 509 510 int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, 511 int depth, void *data) 512 { 513 unsigned long l; 514 char *p; 515 516 pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); 517 518 if (depth != 1 || 519 (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) 520 return 0; 521 522 early_init_dt_check_for_initrd(node); 523 524 /* Retreive command line */ 525 p = of_get_flat_dt_prop(node, "bootargs", &l); 526 if (p != NULL && l > 0) 527 strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE)); 528 529 #ifdef CONFIG_CMDLINE 530 #ifndef CONFIG_CMDLINE_FORCE 531 if (p == NULL || l == 0 || (l == 1 && (*p) == 0)) 532 #endif 533 strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); 534 #endif /* CONFIG_CMDLINE */ 535 536 early_init_dt_scan_chosen_arch(node); 537 538 pr_debug("Command line is: %s\n", cmd_line); 539 540 /* break now */ 541 return 1; 542 } 543 544 /** 545 * unflatten_device_tree - create tree of device_nodes from flat blob 546 * 547 * unflattens the device-tree passed by the firmware, creating the 548 * tree of struct device_node. It also fills the "name" and "type" 549 * pointers of the nodes so the normal device-tree walking functions 550 * can be used. 551 */ 552 void __init unflatten_device_tree(void) 553 { 554 unsigned long start, mem, size; 555 struct device_node **allnextp = &allnodes; 556 557 pr_debug(" -> unflatten_device_tree()\n"); 558 559 if (!initial_boot_params) { 560 pr_debug("No device tree pointer\n"); 561 return; 562 } 563 564 pr_debug("Unflattening device tree:\n"); 565 pr_debug("magic: %08x\n", be32_to_cpu(initial_boot_params->magic)); 566 pr_debug("size: %08x\n", be32_to_cpu(initial_boot_params->totalsize)); 567 pr_debug("version: %08x\n", be32_to_cpu(initial_boot_params->version)); 568 569 if (be32_to_cpu(initial_boot_params->magic) != OF_DT_HEADER) { 570 pr_err("Invalid device tree blob header\n"); 571 return; 572 } 573 574 /* First pass, scan for size */ 575 start = ((unsigned long)initial_boot_params) + 576 be32_to_cpu(initial_boot_params->off_dt_struct); 577 size = unflatten_dt_node(0, &start, NULL, NULL, 0); 578 size = (size | 3) + 1; 579 580 pr_debug(" size is %lx, allocating...\n", size); 581 582 /* Allocate memory for the expanded device tree */ 583 mem = early_init_dt_alloc_memory_arch(size + 4, 584 __alignof__(struct device_node)); 585 mem = (unsigned long) __va(mem); 586 587 ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef); 588 589 pr_debug(" unflattening %lx...\n", mem); 590 591 /* Second pass, do actual unflattening */ 592 start = ((unsigned long)initial_boot_params) + 593 be32_to_cpu(initial_boot_params->off_dt_struct); 594 unflatten_dt_node(mem, &start, NULL, &allnextp, 0); 595 if (be32_to_cpup((__be32 *)start) != OF_DT_END) 596 pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); 597 if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef) 598 pr_warning("End of tree marker overwritten: %08x\n", 599 be32_to_cpu(((__be32 *)mem)[size / 4])); 600 *allnextp = NULL; 601 602 /* Get pointer to OF "/chosen" node for use everywhere */ 603 of_chosen = of_find_node_by_path("/chosen"); 604 if (of_chosen == NULL) 605 of_chosen = of_find_node_by_path("/chosen@0"); 606 607 pr_debug(" <- unflatten_device_tree()\n"); 608 } 609