livetree.c 21 KB

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