fdt.c 21 KB

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