livetree.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  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 occured, 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. struct node *chain_node(struct node *first, struct node *list)
  174. {
  175. assert(first->next_sibling == NULL);
  176. first->next_sibling = list;
  177. return first;
  178. }
  179. void add_property(struct node *node, struct property *prop)
  180. {
  181. struct property **p;
  182. prop->next = NULL;
  183. p = &node->proplist;
  184. while (*p)
  185. p = &((*p)->next);
  186. *p = prop;
  187. }
  188. void delete_property_by_name(struct node *node, char *name)
  189. {
  190. struct property *prop = node->proplist;
  191. while (prop) {
  192. if (!strcmp(prop->name, name)) {
  193. delete_property(prop);
  194. return;
  195. }
  196. prop = prop->next;
  197. }
  198. }
  199. void delete_property(struct property *prop)
  200. {
  201. prop->deleted = 1;
  202. delete_labels(&prop->labels);
  203. }
  204. void add_child(struct node *parent, struct node *child)
  205. {
  206. struct node **p;
  207. child->next_sibling = NULL;
  208. child->parent = parent;
  209. p = &parent->children;
  210. while (*p)
  211. p = &((*p)->next_sibling);
  212. *p = child;
  213. }
  214. void delete_node_by_name(struct node *parent, char *name)
  215. {
  216. struct node *node = parent->children;
  217. while (node) {
  218. if (!strcmp(node->name, name)) {
  219. delete_node(node);
  220. return;
  221. }
  222. node = node->next_sibling;
  223. }
  224. }
  225. void delete_node(struct node *node)
  226. {
  227. struct property *prop;
  228. struct node *child;
  229. node->deleted = 1;
  230. for_each_child(node, child)
  231. delete_node(child);
  232. for_each_property(node, prop)
  233. delete_property(prop);
  234. delete_labels(&node->labels);
  235. }
  236. struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
  237. {
  238. struct reserve_info *new = xmalloc(sizeof(*new));
  239. memset(new, 0, sizeof(*new));
  240. new->re.address = address;
  241. new->re.size = size;
  242. return new;
  243. }
  244. struct reserve_info *chain_reserve_entry(struct reserve_info *first,
  245. struct reserve_info *list)
  246. {
  247. assert(first->next == NULL);
  248. first->next = list;
  249. return first;
  250. }
  251. struct reserve_info *add_reserve_entry(struct reserve_info *list,
  252. struct reserve_info *new)
  253. {
  254. struct reserve_info *last;
  255. new->next = NULL;
  256. if (! list)
  257. return new;
  258. for (last = list; last->next; last = last->next)
  259. ;
  260. last->next = new;
  261. return list;
  262. }
  263. struct boot_info *build_boot_info(struct reserve_info *reservelist,
  264. struct node *tree, uint32_t boot_cpuid_phys)
  265. {
  266. struct boot_info *bi;
  267. bi = xmalloc(sizeof(*bi));
  268. bi->reservelist = reservelist;
  269. bi->dt = tree;
  270. bi->boot_cpuid_phys = boot_cpuid_phys;
  271. return bi;
  272. }
  273. /*
  274. * Tree accessor functions
  275. */
  276. const char *get_unitname(struct node *node)
  277. {
  278. if (node->name[node->basenamelen] == '\0')
  279. return "";
  280. else
  281. return node->name + node->basenamelen + 1;
  282. }
  283. struct property *get_property(struct node *node, const char *propname)
  284. {
  285. struct property *prop;
  286. for_each_property(node, prop)
  287. if (streq(prop->name, propname))
  288. return prop;
  289. return NULL;
  290. }
  291. cell_t propval_cell(struct property *prop)
  292. {
  293. assert(prop->val.len == sizeof(cell_t));
  294. return fdt32_to_cpu(*((cell_t *)prop->val.val));
  295. }
  296. struct property *get_property_by_label(struct node *tree, const char *label,
  297. struct node **node)
  298. {
  299. struct property *prop;
  300. struct node *c;
  301. *node = tree;
  302. for_each_property(tree, prop) {
  303. struct label *l;
  304. for_each_label(prop->labels, l)
  305. if (streq(l->label, label))
  306. return prop;
  307. }
  308. for_each_child(tree, c) {
  309. prop = get_property_by_label(c, label, node);
  310. if (prop)
  311. return prop;
  312. }
  313. *node = NULL;
  314. return NULL;
  315. }
  316. struct marker *get_marker_label(struct node *tree, const char *label,
  317. struct node **node, struct property **prop)
  318. {
  319. struct marker *m;
  320. struct property *p;
  321. struct node *c;
  322. *node = tree;
  323. for_each_property(tree, p) {
  324. *prop = p;
  325. m = p->val.markers;
  326. for_each_marker_of_type(m, LABEL)
  327. if (streq(m->ref, label))
  328. return m;
  329. }
  330. for_each_child(tree, c) {
  331. m = get_marker_label(c, label, node, prop);
  332. if (m)
  333. return m;
  334. }
  335. *prop = NULL;
  336. *node = NULL;
  337. return NULL;
  338. }
  339. struct node *get_subnode(struct node *node, const char *nodename)
  340. {
  341. struct node *child;
  342. for_each_child(node, child)
  343. if (streq(child->name, nodename))
  344. return child;
  345. return NULL;
  346. }
  347. struct node *get_node_by_path(struct node *tree, const char *path)
  348. {
  349. const char *p;
  350. struct node *child;
  351. if (!path || ! (*path)) {
  352. if (tree->deleted)
  353. return NULL;
  354. return tree;
  355. }
  356. while (path[0] == '/')
  357. path++;
  358. p = strchr(path, '/');
  359. for_each_child(tree, child) {
  360. if (p && strneq(path, child->name, p-path))
  361. return get_node_by_path(child, p+1);
  362. else if (!p && streq(path, child->name))
  363. return child;
  364. }
  365. return NULL;
  366. }
  367. struct node *get_node_by_label(struct node *tree, const char *label)
  368. {
  369. struct node *child, *node;
  370. struct label *l;
  371. assert(label && (strlen(label) > 0));
  372. for_each_label(tree->labels, l)
  373. if (streq(l->label, label))
  374. return tree;
  375. for_each_child(tree, child) {
  376. node = get_node_by_label(child, label);
  377. if (node)
  378. return node;
  379. }
  380. return NULL;
  381. }
  382. struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
  383. {
  384. struct node *child, *node;
  385. assert((phandle != 0) && (phandle != -1));
  386. if (tree->phandle == phandle) {
  387. if (tree->deleted)
  388. return NULL;
  389. return tree;
  390. }
  391. for_each_child(tree, child) {
  392. node = get_node_by_phandle(child, phandle);
  393. if (node)
  394. return node;
  395. }
  396. return NULL;
  397. }
  398. struct node *get_node_by_ref(struct node *tree, const char *ref)
  399. {
  400. if (streq(ref, "/"))
  401. return tree;
  402. else if (ref[0] == '/')
  403. return get_node_by_path(tree, ref);
  404. else
  405. return get_node_by_label(tree, ref);
  406. }
  407. cell_t get_node_phandle(struct node *root, struct node *node)
  408. {
  409. static cell_t phandle = 1; /* FIXME: ick, static local */
  410. if ((node->phandle != 0) && (node->phandle != -1))
  411. return node->phandle;
  412. while (get_node_by_phandle(root, phandle))
  413. phandle++;
  414. node->phandle = phandle;
  415. if (!get_property(node, "linux,phandle")
  416. && (phandle_format & PHANDLE_LEGACY))
  417. add_property(node,
  418. build_property("linux,phandle",
  419. data_append_cell(empty_data, phandle)));
  420. if (!get_property(node, "phandle")
  421. && (phandle_format & PHANDLE_EPAPR))
  422. add_property(node,
  423. build_property("phandle",
  424. data_append_cell(empty_data, phandle)));
  425. /* If the node *does* have a phandle property, we must
  426. * be dealing with a self-referencing phandle, which will be
  427. * fixed up momentarily in the caller */
  428. return node->phandle;
  429. }
  430. uint32_t guess_boot_cpuid(struct node *tree)
  431. {
  432. struct node *cpus, *bootcpu;
  433. struct property *reg;
  434. cpus = get_node_by_path(tree, "/cpus");
  435. if (!cpus)
  436. return 0;
  437. bootcpu = cpus->children;
  438. if (!bootcpu)
  439. return 0;
  440. reg = get_property(bootcpu, "reg");
  441. if (!reg || (reg->val.len != sizeof(uint32_t)))
  442. return 0;
  443. /* FIXME: Sanity check node? */
  444. return propval_cell(reg);
  445. }
  446. static int cmp_reserve_info(const void *ax, const void *bx)
  447. {
  448. const struct reserve_info *a, *b;
  449. a = *((const struct reserve_info * const *)ax);
  450. b = *((const struct reserve_info * const *)bx);
  451. if (a->re.address < b->re.address)
  452. return -1;
  453. else if (a->re.address > b->re.address)
  454. return 1;
  455. else if (a->re.size < b->re.size)
  456. return -1;
  457. else if (a->re.size > b->re.size)
  458. return 1;
  459. else
  460. return 0;
  461. }
  462. static void sort_reserve_entries(struct boot_info *bi)
  463. {
  464. struct reserve_info *ri, **tbl;
  465. int n = 0, i = 0;
  466. for (ri = bi->reservelist;
  467. ri;
  468. ri = ri->next)
  469. n++;
  470. if (n == 0)
  471. return;
  472. tbl = xmalloc(n * sizeof(*tbl));
  473. for (ri = bi->reservelist;
  474. ri;
  475. ri = ri->next)
  476. tbl[i++] = ri;
  477. qsort(tbl, n, sizeof(*tbl), cmp_reserve_info);
  478. bi->reservelist = tbl[0];
  479. for (i = 0; i < (n-1); i++)
  480. tbl[i]->next = tbl[i+1];
  481. tbl[n-1]->next = NULL;
  482. free(tbl);
  483. }
  484. static int cmp_prop(const void *ax, const void *bx)
  485. {
  486. const struct property *a, *b;
  487. a = *((const struct property * const *)ax);
  488. b = *((const struct property * const *)bx);
  489. return strcmp(a->name, b->name);
  490. }
  491. static void sort_properties(struct node *node)
  492. {
  493. int n = 0, i = 0;
  494. struct property *prop, **tbl;
  495. for_each_property_withdel(node, prop)
  496. n++;
  497. if (n == 0)
  498. return;
  499. tbl = xmalloc(n * sizeof(*tbl));
  500. for_each_property_withdel(node, prop)
  501. tbl[i++] = prop;
  502. qsort(tbl, n, sizeof(*tbl), cmp_prop);
  503. node->proplist = tbl[0];
  504. for (i = 0; i < (n-1); i++)
  505. tbl[i]->next = tbl[i+1];
  506. tbl[n-1]->next = NULL;
  507. free(tbl);
  508. }
  509. static int cmp_subnode(const void *ax, const void *bx)
  510. {
  511. const struct node *a, *b;
  512. a = *((const struct node * const *)ax);
  513. b = *((const struct node * const *)bx);
  514. return strcmp(a->name, b->name);
  515. }
  516. static void sort_subnodes(struct node *node)
  517. {
  518. int n = 0, i = 0;
  519. struct node *subnode, **tbl;
  520. for_each_child_withdel(node, subnode)
  521. n++;
  522. if (n == 0)
  523. return;
  524. tbl = xmalloc(n * sizeof(*tbl));
  525. for_each_child_withdel(node, subnode)
  526. tbl[i++] = subnode;
  527. qsort(tbl, n, sizeof(*tbl), cmp_subnode);
  528. node->children = tbl[0];
  529. for (i = 0; i < (n-1); i++)
  530. tbl[i]->next_sibling = tbl[i+1];
  531. tbl[n-1]->next_sibling = NULL;
  532. free(tbl);
  533. }
  534. static void sort_node(struct node *node)
  535. {
  536. struct node *c;
  537. sort_properties(node);
  538. sort_subnodes(node);
  539. for_each_child_withdel(node, c)
  540. sort_node(c);
  541. }
  542. void sort_tree(struct boot_info *bi)
  543. {
  544. sort_reserve_entries(bi);
  545. sort_node(bi->dt);
  546. }