livetree.c 20 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. /*
  2. * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
  3. *
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  18. * USA
  19. */
  20. #include "dtc.h"
  21. /*
  22. * Tree building functions
  23. */
  24. void add_label(struct label **labels, char *label)
  25. {
  26. struct label *new;
  27. /* Make sure the label isn't already there */
  28. for_each_label_withdel(*labels, new)
  29. if (streq(new->label, label)) {
  30. new->deleted = 0;
  31. return;
  32. }
  33. new = xmalloc(sizeof(*new));
  34. memset(new, 0, sizeof(*new));
  35. new->label = label;
  36. new->next = *labels;
  37. *labels = new;
  38. }
  39. void delete_labels(struct label **labels)
  40. {
  41. struct label *label;
  42. for_each_label(*labels, label)
  43. label->deleted = 1;
  44. }
  45. struct property *build_property(char *name, struct data val)
  46. {
  47. struct property *new = xmalloc(sizeof(*new));
  48. memset(new, 0, sizeof(*new));
  49. new->name = name;
  50. new->val = val;
  51. return new;
  52. }
  53. struct property *build_property_delete(char *name)
  54. {
  55. struct property *new = xmalloc(sizeof(*new));
  56. memset(new, 0, sizeof(*new));
  57. new->name = name;
  58. new->deleted = 1;
  59. return new;
  60. }
  61. struct property *chain_property(struct property *first, struct property *list)
  62. {
  63. assert(first->next == NULL);
  64. first->next = list;
  65. return first;
  66. }
  67. struct property *reverse_properties(struct property *first)
  68. {
  69. struct property *p = first;
  70. struct property *head = NULL;
  71. struct property *next;
  72. while (p) {
  73. next = p->next;
  74. p->next = head;
  75. head = p;
  76. p = next;
  77. }
  78. return head;
  79. }
  80. struct node *build_node(struct property *proplist, struct node *children)
  81. {
  82. struct node *new = xmalloc(sizeof(*new));
  83. struct node *child;
  84. memset(new, 0, sizeof(*new));
  85. new->proplist = reverse_properties(proplist);
  86. new->children = children;
  87. for_each_child(new, child) {
  88. child->parent = new;
  89. }
  90. return new;
  91. }
  92. struct node *build_node_delete(void)
  93. {
  94. struct node *new = xmalloc(sizeof(*new));
  95. memset(new, 0, sizeof(*new));
  96. new->deleted = 1;
  97. return new;
  98. }
  99. struct node *name_node(struct node *node, char *name)
  100. {
  101. assert(node->name == NULL);
  102. node->name = name;
  103. return node;
  104. }
  105. struct node *merge_nodes(struct node *old_node, struct node *new_node)
  106. {
  107. struct property *new_prop, *old_prop;
  108. struct node *new_child, *old_child;
  109. struct label *l;
  110. old_node->deleted = 0;
  111. /* Add new node labels to old node */
  112. for_each_label_withdel(new_node->labels, l)
  113. add_label(&old_node->labels, l->label);
  114. /* Move properties from the new node to the old node. If there
  115. * is a collision, replace the old value with the new */
  116. while (new_node->proplist) {
  117. /* Pop the property off the list */
  118. new_prop = new_node->proplist;
  119. new_node->proplist = new_prop->next;
  120. new_prop->next = NULL;
  121. if (new_prop->deleted) {
  122. delete_property_by_name(old_node, new_prop->name);
  123. free(new_prop);
  124. continue;
  125. }
  126. /* Look for a collision, set new value if there is */
  127. for_each_property_withdel(old_node, old_prop) {
  128. if (streq(old_prop->name, new_prop->name)) {
  129. /* Add new labels to old property */
  130. for_each_label_withdel(new_prop->labels, l)
  131. add_label(&old_prop->labels, l->label);
  132. old_prop->val = new_prop->val;
  133. old_prop->deleted = 0;
  134. free(new_prop);
  135. new_prop = NULL;
  136. break;
  137. }
  138. }
  139. /* if no collision occurred, add property to the old node. */
  140. if (new_prop)
  141. add_property(old_node, new_prop);
  142. }
  143. /* Move the override child nodes into the primary node. If
  144. * there is a collision, then merge the nodes. */
  145. while (new_node->children) {
  146. /* Pop the child node off the list */
  147. new_child = new_node->children;
  148. new_node->children = new_child->next_sibling;
  149. new_child->parent = NULL;
  150. new_child->next_sibling = NULL;
  151. if (new_child->deleted) {
  152. delete_node_by_name(old_node, new_child->name);
  153. free(new_child);
  154. continue;
  155. }
  156. /* Search for a collision. Merge if there is */
  157. for_each_child_withdel(old_node, old_child) {
  158. if (streq(old_child->name, new_child->name)) {
  159. merge_nodes(old_child, new_child);
  160. new_child = NULL;
  161. break;
  162. }
  163. }
  164. /* if no collision occurred, add child to the old node. */
  165. if (new_child)
  166. add_child(old_node, new_child);
  167. }
  168. /* The new node contents are now merged into the old node. Free
  169. * the new node. */
  170. free(new_node);
  171. return old_node;
  172. }
  173. void add_orphan_node(struct node *dt, struct node *new_node, char *ref)
  174. {
  175. static unsigned int next_orphan_fragment = 0;
  176. struct node *node;
  177. struct property *p;
  178. struct data d = empty_data;
  179. char *name;
  180. d = data_add_marker(d, REF_PHANDLE, ref);
  181. d = data_append_integer(d, 0xffffffff, 32);
  182. p = build_property("target", d);
  183. xasprintf(&name, "fragment@%u",
  184. next_orphan_fragment++);
  185. name_node(new_node, "__overlay__");
  186. node = build_node(p, new_node);
  187. name_node(node, name);
  188. add_child(dt, node);
  189. }
  190. struct node *chain_node(struct node *first, struct node *list)
  191. {
  192. assert(first->next_sibling == NULL);
  193. first->next_sibling = list;
  194. return first;
  195. }
  196. void add_property(struct node *node, struct property *prop)
  197. {
  198. struct property **p;
  199. prop->next = NULL;
  200. p = &node->proplist;
  201. while (*p)
  202. p = &((*p)->next);
  203. *p = prop;
  204. }
  205. void delete_property_by_name(struct node *node, char *name)
  206. {
  207. struct property *prop = node->proplist;
  208. while (prop) {
  209. if (streq(prop->name, name)) {
  210. delete_property(prop);
  211. return;
  212. }
  213. prop = prop->next;
  214. }
  215. }
  216. void delete_property(struct property *prop)
  217. {
  218. prop->deleted = 1;
  219. delete_labels(&prop->labels);
  220. }
  221. void add_child(struct node *parent, struct node *child)
  222. {
  223. struct node **p;
  224. child->next_sibling = NULL;
  225. child->parent = parent;
  226. p = &parent->children;
  227. while (*p)
  228. p = &((*p)->next_sibling);
  229. *p = child;
  230. }
  231. void delete_node_by_name(struct node *parent, char *name)
  232. {
  233. struct node *node = parent->children;
  234. while (node) {
  235. if (streq(node->name, name)) {
  236. delete_node(node);
  237. return;
  238. }
  239. node = node->next_sibling;
  240. }
  241. }
  242. void delete_node(struct node *node)
  243. {
  244. struct property *prop;
  245. struct node *child;
  246. node->deleted = 1;
  247. for_each_child(node, child)
  248. delete_node(child);
  249. for_each_property(node, prop)
  250. delete_property(prop);
  251. delete_labels(&node->labels);
  252. }
  253. void append_to_property(struct node *node,
  254. char *name, const void *data, int len)
  255. {
  256. struct data d;
  257. struct property *p;
  258. p = get_property(node, name);
  259. if (p) {
  260. d = data_append_data(p->val, data, len);
  261. p->val = d;
  262. } else {
  263. d = data_append_data(empty_data, data, len);
  264. p = build_property(name, d);
  265. add_property(node, p);
  266. }
  267. }
  268. struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
  269. {
  270. struct reserve_info *new = xmalloc(sizeof(*new));
  271. memset(new, 0, sizeof(*new));
  272. new->address = address;
  273. new->size = size;
  274. return new;
  275. }
  276. struct reserve_info *chain_reserve_entry(struct reserve_info *first,
  277. struct reserve_info *list)
  278. {
  279. assert(first->next == NULL);
  280. first->next = list;
  281. return first;
  282. }
  283. struct reserve_info *add_reserve_entry(struct reserve_info *list,
  284. struct reserve_info *new)
  285. {
  286. struct reserve_info *last;
  287. new->next = NULL;
  288. if (! list)
  289. return new;
  290. for (last = list; last->next; last = last->next)
  291. ;
  292. last->next = new;
  293. return list;
  294. }
  295. struct dt_info *build_dt_info(unsigned int dtsflags,
  296. struct reserve_info *reservelist,
  297. struct node *tree, uint32_t boot_cpuid_phys)
  298. {
  299. struct dt_info *dti;
  300. dti = xmalloc(sizeof(*dti));
  301. dti->dtsflags = dtsflags;
  302. dti->reservelist = reservelist;
  303. dti->dt = tree;
  304. dti->boot_cpuid_phys = boot_cpuid_phys;
  305. return dti;
  306. }
  307. /*
  308. * Tree accessor functions
  309. */
  310. const char *get_unitname(struct node *node)
  311. {
  312. if (node->name[node->basenamelen] == '\0')
  313. return "";
  314. else
  315. return node->name + node->basenamelen + 1;
  316. }
  317. struct property *get_property(struct node *node, const char *propname)
  318. {
  319. struct property *prop;
  320. for_each_property(node, prop)
  321. if (streq(prop->name, propname))
  322. return prop;
  323. return NULL;
  324. }
  325. cell_t propval_cell(struct property *prop)
  326. {
  327. assert(prop->val.len == sizeof(cell_t));
  328. return fdt32_to_cpu(*((fdt32_t *)prop->val.val));
  329. }
  330. cell_t propval_cell_n(struct property *prop, int n)
  331. {
  332. assert(prop->val.len / sizeof(cell_t) >= n);
  333. return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n));
  334. }
  335. struct property *get_property_by_label(struct node *tree, const char *label,
  336. struct node **node)
  337. {
  338. struct property *prop;
  339. struct node *c;
  340. *node = tree;
  341. for_each_property(tree, prop) {
  342. struct label *l;
  343. for_each_label(prop->labels, l)
  344. if (streq(l->label, label))
  345. return prop;
  346. }
  347. for_each_child(tree, c) {
  348. prop = get_property_by_label(c, label, node);
  349. if (prop)
  350. return prop;
  351. }
  352. *node = NULL;
  353. return NULL;
  354. }
  355. struct marker *get_marker_label(struct node *tree, const char *label,
  356. struct node **node, struct property **prop)
  357. {
  358. struct marker *m;
  359. struct property *p;
  360. struct node *c;
  361. *node = tree;
  362. for_each_property(tree, p) {
  363. *prop = p;
  364. m = p->val.markers;
  365. for_each_marker_of_type(m, LABEL)
  366. if (streq(m->ref, label))
  367. return m;
  368. }
  369. for_each_child(tree, c) {
  370. m = get_marker_label(c, label, node, prop);
  371. if (m)
  372. return m;
  373. }
  374. *prop = NULL;
  375. *node = NULL;
  376. return NULL;
  377. }
  378. struct node *get_subnode(struct node *node, const char *nodename)
  379. {
  380. struct node *child;
  381. for_each_child(node, child)
  382. if (streq(child->name, nodename))
  383. return child;
  384. return NULL;
  385. }
  386. struct node *get_node_by_path(struct node *tree, const char *path)
  387. {
  388. const char *p;
  389. struct node *child;
  390. if (!path || ! (*path)) {
  391. if (tree->deleted)
  392. return NULL;
  393. return tree;
  394. }
  395. while (path[0] == '/')
  396. path++;
  397. p = strchr(path, '/');
  398. for_each_child(tree, child) {
  399. if (p && (strlen(child->name) == p-path) &&
  400. strneq(path, child->name, p-path))
  401. return get_node_by_path(child, p+1);
  402. else if (!p && streq(path, child->name))
  403. return child;
  404. }
  405. return NULL;
  406. }
  407. struct node *get_node_by_label(struct node *tree, const char *label)
  408. {
  409. struct node *child, *node;
  410. struct label *l;
  411. assert(label && (strlen(label) > 0));
  412. for_each_label(tree->labels, l)
  413. if (streq(l->label, label))
  414. return tree;
  415. for_each_child(tree, child) {
  416. node = get_node_by_label(child, label);
  417. if (node)
  418. return node;
  419. }
  420. return NULL;
  421. }
  422. struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
  423. {
  424. struct node *child, *node;
  425. assert((phandle != 0) && (phandle != -1));
  426. if (tree->phandle == phandle) {
  427. if (tree->deleted)
  428. return NULL;
  429. return tree;
  430. }
  431. for_each_child(tree, child) {
  432. node = get_node_by_phandle(child, phandle);
  433. if (node)
  434. return node;
  435. }
  436. return NULL;
  437. }
  438. struct node *get_node_by_ref(struct node *tree, const char *ref)
  439. {
  440. if (streq(ref, "/"))
  441. return tree;
  442. else if (ref[0] == '/')
  443. return get_node_by_path(tree, ref);
  444. else
  445. return get_node_by_label(tree, ref);
  446. }
  447. cell_t get_node_phandle(struct node *root, struct node *node)
  448. {
  449. static cell_t phandle = 1; /* FIXME: ick, static local */
  450. if ((node->phandle != 0) && (node->phandle != -1))
  451. return node->phandle;
  452. while (get_node_by_phandle(root, phandle))
  453. phandle++;
  454. node->phandle = phandle;
  455. if (!get_property(node, "linux,phandle")
  456. && (phandle_format & PHANDLE_LEGACY))
  457. add_property(node,
  458. build_property("linux,phandle",
  459. data_append_cell(empty_data, phandle)));
  460. if (!get_property(node, "phandle")
  461. && (phandle_format & PHANDLE_EPAPR))
  462. add_property(node,
  463. build_property("phandle",
  464. data_append_cell(empty_data, phandle)));
  465. /* If the node *does* have a phandle property, we must
  466. * be dealing with a self-referencing phandle, which will be
  467. * fixed up momentarily in the caller */
  468. return node->phandle;
  469. }
  470. uint32_t guess_boot_cpuid(struct node *tree)
  471. {
  472. struct node *cpus, *bootcpu;
  473. struct property *reg;
  474. cpus = get_node_by_path(tree, "/cpus");
  475. if (!cpus)
  476. return 0;
  477. bootcpu = cpus->children;
  478. if (!bootcpu)
  479. return 0;
  480. reg = get_property(bootcpu, "reg");
  481. if (!reg || (reg->val.len != sizeof(uint32_t)))
  482. return 0;
  483. /* FIXME: Sanity check node? */
  484. return propval_cell(reg);
  485. }
  486. static int cmp_reserve_info(const void *ax, const void *bx)
  487. {
  488. const struct reserve_info *a, *b;
  489. a = *((const struct reserve_info * const *)ax);
  490. b = *((const struct reserve_info * const *)bx);
  491. if (a->address < b->address)
  492. return -1;
  493. else if (a->address > b->address)
  494. return 1;
  495. else if (a->size < b->size)
  496. return -1;
  497. else if (a->size > b->size)
  498. return 1;
  499. else
  500. return 0;
  501. }
  502. static void sort_reserve_entries(struct dt_info *dti)
  503. {
  504. struct reserve_info *ri, **tbl;
  505. int n = 0, i = 0;
  506. for (ri = dti->reservelist;
  507. ri;
  508. ri = ri->next)
  509. n++;
  510. if (n == 0)
  511. return;
  512. tbl = xmalloc(n * sizeof(*tbl));
  513. for (ri = dti->reservelist;
  514. ri;
  515. ri = ri->next)
  516. tbl[i++] = ri;
  517. qsort(tbl, n, sizeof(*tbl), cmp_reserve_info);
  518. dti->reservelist = tbl[0];
  519. for (i = 0; i < (n-1); i++)
  520. tbl[i]->next = tbl[i+1];
  521. tbl[n-1]->next = NULL;
  522. free(tbl);
  523. }
  524. static int cmp_prop(const void *ax, const void *bx)
  525. {
  526. const struct property *a, *b;
  527. a = *((const struct property * const *)ax);
  528. b = *((const struct property * const *)bx);
  529. return strcmp(a->name, b->name);
  530. }
  531. static void sort_properties(struct node *node)
  532. {
  533. int n = 0, i = 0;
  534. struct property *prop, **tbl;
  535. for_each_property_withdel(node, prop)
  536. n++;
  537. if (n == 0)
  538. return;
  539. tbl = xmalloc(n * sizeof(*tbl));
  540. for_each_property_withdel(node, prop)
  541. tbl[i++] = prop;
  542. qsort(tbl, n, sizeof(*tbl), cmp_prop);
  543. node->proplist = tbl[0];
  544. for (i = 0; i < (n-1); i++)
  545. tbl[i]->next = tbl[i+1];
  546. tbl[n-1]->next = NULL;
  547. free(tbl);
  548. }
  549. static int cmp_subnode(const void *ax, const void *bx)
  550. {
  551. const struct node *a, *b;
  552. a = *((const struct node * const *)ax);
  553. b = *((const struct node * const *)bx);
  554. return strcmp(a->name, b->name);
  555. }
  556. static void sort_subnodes(struct node *node)
  557. {
  558. int n = 0, i = 0;
  559. struct node *subnode, **tbl;
  560. for_each_child_withdel(node, subnode)
  561. n++;
  562. if (n == 0)
  563. return;
  564. tbl = xmalloc(n * sizeof(*tbl));
  565. for_each_child_withdel(node, subnode)
  566. tbl[i++] = subnode;
  567. qsort(tbl, n, sizeof(*tbl), cmp_subnode);
  568. node->children = tbl[0];
  569. for (i = 0; i < (n-1); i++)
  570. tbl[i]->next_sibling = tbl[i+1];
  571. tbl[n-1]->next_sibling = NULL;
  572. free(tbl);
  573. }
  574. static void sort_node(struct node *node)
  575. {
  576. struct node *c;
  577. sort_properties(node);
  578. sort_subnodes(node);
  579. for_each_child_withdel(node, c)
  580. sort_node(c);
  581. }
  582. void sort_tree(struct dt_info *dti)
  583. {
  584. sort_reserve_entries(dti);
  585. sort_node(dti->dt);
  586. }
  587. /* utility helper to avoid code duplication */
  588. static struct node *build_and_name_child_node(struct node *parent, char *name)
  589. {
  590. struct node *node;
  591. node = build_node(NULL, NULL);
  592. name_node(node, xstrdup(name));
  593. add_child(parent, node);
  594. return node;
  595. }
  596. static struct node *build_root_node(struct node *dt, char *name)
  597. {
  598. struct node *an;
  599. an = get_subnode(dt, name);
  600. if (!an)
  601. an = build_and_name_child_node(dt, name);
  602. if (!an)
  603. die("Could not build root node /%s\n", name);
  604. return an;
  605. }
  606. static bool any_label_tree(struct dt_info *dti, struct node *node)
  607. {
  608. struct node *c;
  609. if (node->labels)
  610. return true;
  611. for_each_child(node, c)
  612. if (any_label_tree(dti, c))
  613. return true;
  614. return false;
  615. }
  616. static void generate_label_tree_internal(struct dt_info *dti,
  617. struct node *an, struct node *node,
  618. bool allocph)
  619. {
  620. struct node *dt = dti->dt;
  621. struct node *c;
  622. struct property *p;
  623. struct label *l;
  624. /* if there are labels */
  625. if (node->labels) {
  626. /* now add the label in the node */
  627. for_each_label(node->labels, l) {
  628. /* check whether the label already exists */
  629. p = get_property(an, l->label);
  630. if (p) {
  631. fprintf(stderr, "WARNING: label %s already"
  632. " exists in /%s", l->label,
  633. an->name);
  634. continue;
  635. }
  636. /* insert it */
  637. p = build_property(l->label,
  638. data_copy_mem(node->fullpath,
  639. strlen(node->fullpath) + 1));
  640. add_property(an, p);
  641. }
  642. /* force allocation of a phandle for this node */
  643. if (allocph)
  644. (void)get_node_phandle(dt, node);
  645. }
  646. for_each_child(node, c)
  647. generate_label_tree_internal(dti, an, c, allocph);
  648. }
  649. static bool any_fixup_tree(struct dt_info *dti, struct node *node)
  650. {
  651. struct node *c;
  652. struct property *prop;
  653. struct marker *m;
  654. for_each_property(node, prop) {
  655. m = prop->val.markers;
  656. for_each_marker_of_type(m, REF_PHANDLE) {
  657. if (!get_node_by_ref(dti->dt, m->ref))
  658. return true;
  659. }
  660. }
  661. for_each_child(node, c) {
  662. if (any_fixup_tree(dti, c))
  663. return true;
  664. }
  665. return false;
  666. }
  667. static void add_fixup_entry(struct dt_info *dti, struct node *fn,
  668. struct node *node, struct property *prop,
  669. struct marker *m)
  670. {
  671. char *entry;
  672. /* m->ref can only be a REF_PHANDLE, but check anyway */
  673. assert(m->type == REF_PHANDLE);
  674. /* there shouldn't be any ':' in the arguments */
  675. if (strchr(node->fullpath, ':') || strchr(prop->name, ':'))
  676. die("arguments should not contain ':'\n");
  677. xasprintf(&entry, "%s:%s:%u",
  678. node->fullpath, prop->name, m->offset);
  679. append_to_property(fn, m->ref, entry, strlen(entry) + 1);
  680. free(entry);
  681. }
  682. static void generate_fixups_tree_internal(struct dt_info *dti,
  683. struct node *fn,
  684. struct node *node)
  685. {
  686. struct node *dt = dti->dt;
  687. struct node *c;
  688. struct property *prop;
  689. struct marker *m;
  690. struct node *refnode;
  691. for_each_property(node, prop) {
  692. m = prop->val.markers;
  693. for_each_marker_of_type(m, REF_PHANDLE) {
  694. refnode = get_node_by_ref(dt, m->ref);
  695. if (!refnode)
  696. add_fixup_entry(dti, fn, node, prop, m);
  697. }
  698. }
  699. for_each_child(node, c)
  700. generate_fixups_tree_internal(dti, fn, c);
  701. }
  702. static bool any_local_fixup_tree(struct dt_info *dti, struct node *node)
  703. {
  704. struct node *c;
  705. struct property *prop;
  706. struct marker *m;
  707. for_each_property(node, prop) {
  708. m = prop->val.markers;
  709. for_each_marker_of_type(m, REF_PHANDLE) {
  710. if (get_node_by_ref(dti->dt, m->ref))
  711. return true;
  712. }
  713. }
  714. for_each_child(node, c) {
  715. if (any_local_fixup_tree(dti, c))
  716. return true;
  717. }
  718. return false;
  719. }
  720. static void add_local_fixup_entry(struct dt_info *dti,
  721. struct node *lfn, struct node *node,
  722. struct property *prop, struct marker *m,
  723. struct node *refnode)
  724. {
  725. struct node *wn, *nwn; /* local fixup node, walk node, new */
  726. fdt32_t value_32;
  727. char **compp;
  728. int i, depth;
  729. /* walk back retreiving depth */
  730. depth = 0;
  731. for (wn = node; wn; wn = wn->parent)
  732. depth++;
  733. /* allocate name array */
  734. compp = xmalloc(sizeof(*compp) * depth);
  735. /* store names in the array */
  736. for (wn = node, i = depth - 1; wn; wn = wn->parent, i--)
  737. compp[i] = wn->name;
  738. /* walk the path components creating nodes if they don't exist */
  739. for (wn = lfn, i = 1; i < depth; i++, wn = nwn) {
  740. /* if no node exists, create it */
  741. nwn = get_subnode(wn, compp[i]);
  742. if (!nwn)
  743. nwn = build_and_name_child_node(wn, compp[i]);
  744. }
  745. free(compp);
  746. value_32 = cpu_to_fdt32(m->offset);
  747. append_to_property(wn, prop->name, &value_32, sizeof(value_32));
  748. }
  749. static void generate_local_fixups_tree_internal(struct dt_info *dti,
  750. struct node *lfn,
  751. struct node *node)
  752. {
  753. struct node *dt = dti->dt;
  754. struct node *c;
  755. struct property *prop;
  756. struct marker *m;
  757. struct node *refnode;
  758. for_each_property(node, prop) {
  759. m = prop->val.markers;
  760. for_each_marker_of_type(m, REF_PHANDLE) {
  761. refnode = get_node_by_ref(dt, m->ref);
  762. if (refnode)
  763. add_local_fixup_entry(dti, lfn, node, prop, m, refnode);
  764. }
  765. }
  766. for_each_child(node, c)
  767. generate_local_fixups_tree_internal(dti, lfn, c);
  768. }
  769. void generate_label_tree(struct dt_info *dti, char *name, bool allocph)
  770. {
  771. if (!any_label_tree(dti, dti->dt))
  772. return;
  773. generate_label_tree_internal(dti, build_root_node(dti->dt, name),
  774. dti->dt, allocph);
  775. }
  776. void generate_fixups_tree(struct dt_info *dti, char *name)
  777. {
  778. if (!any_fixup_tree(dti, dti->dt))
  779. return;
  780. generate_fixups_tree_internal(dti, build_root_node(dti->dt, name),
  781. dti->dt);
  782. }
  783. void generate_local_fixups_tree(struct dt_info *dti, char *name)
  784. {
  785. if (!any_local_fixup_tree(dti, dti->dt))
  786. return;
  787. generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, name),
  788. dti->dt);
  789. }