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