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