base.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-08-25 GuEe-GUI first version
  9. */
  10. #include <rtthread.h>
  11. #include <drivers/ofw.h>
  12. #include <drivers/ofw_io.h>
  13. #include <drivers/ofw_fdt.h>
  14. #include <drivers/ofw_raw.h>
  15. #define DBG_TAG "rtdm.ofw"
  16. #define DBG_LVL DBG_INFO
  17. #include <rtdbg.h>
  18. #include "ofw_internal.h"
  19. struct rt_ofw_node *ofw_node_root = RT_NULL;
  20. struct rt_ofw_node *ofw_node_cpus = RT_NULL;
  21. struct rt_ofw_node *ofw_node_chosen = RT_NULL;
  22. struct rt_ofw_node *ofw_node_aliases = RT_NULL;
  23. struct rt_ofw_node *ofw_node_reserved_memory = RT_NULL;
  24. static rt_phandle _phandle_range[2] = { 1, 1 };
  25. static struct rt_ofw_node **_phandle_hash = RT_NULL;
  26. static rt_list_t _aliases_nodes = RT_LIST_OBJECT_INIT(_aliases_nodes);
  27. rt_err_t ofw_phandle_hash_reset(rt_phandle min, rt_phandle max)
  28. {
  29. rt_err_t err = RT_EOK;
  30. struct rt_ofw_node **hash_ptr = RT_NULL;
  31. max = RT_ALIGN(max, OFW_NODE_MIN_HASH);
  32. if (max > _phandle_range[1])
  33. {
  34. rt_size_t size = sizeof(*_phandle_hash) * (max - min);
  35. if (!_phandle_hash)
  36. {
  37. hash_ptr = rt_calloc(1, size);
  38. }
  39. else
  40. {
  41. hash_ptr = rt_realloc(_phandle_hash, size);
  42. if (hash_ptr)
  43. {
  44. rt_size_t old_max = _phandle_range[1];
  45. rt_memset(&hash_ptr[old_max], 0, sizeof(_phandle_hash) * (max - old_max));
  46. }
  47. }
  48. }
  49. if (hash_ptr)
  50. {
  51. /* We always reset min value only once */
  52. if (min)
  53. {
  54. _phandle_range[0] = min;
  55. }
  56. _phandle_range[1] = max;
  57. _phandle_hash = hash_ptr;
  58. }
  59. else
  60. {
  61. err = -RT_ENOMEM;
  62. }
  63. return err;
  64. }
  65. static void ofw_prop_destroy(struct rt_ofw_prop *prop)
  66. {
  67. struct rt_ofw_prop *next;
  68. while (prop)
  69. {
  70. next = prop->next;
  71. rt_free(prop);
  72. prop = next;
  73. }
  74. }
  75. static struct rt_ofw_node *ofw_get_next_node(struct rt_ofw_node *prev)
  76. {
  77. struct rt_ofw_node *np;
  78. /*
  79. * Walk:
  80. *
  81. * / { ------------------------ [0] (START) has child, goto child.
  82. *
  83. * node0 { ---------------- [1] has child, goto child.
  84. *
  85. * node0_0 { ---------- [2] no child, has sibling, goto sibling.
  86. * };
  87. *
  88. * node0_1 { ---------- [3] no sibling now.
  89. * upward while the parent has sibling.
  90. * };
  91. * };
  92. *
  93. * node1 { ---------------- [4] come from node0 who find the sibling:
  94. * node1, node1 has child, goto child.
  95. *
  96. * node1_0 { ---------- [5] has child, goto child.
  97. *
  98. * node1_0_0 { ---- [6] no sibling now.
  99. * upward while the parent has sibling.
  100. * (END) in the root.
  101. * };
  102. * };
  103. * };
  104. * };
  105. */
  106. if (!prev)
  107. {
  108. np = ofw_node_root;
  109. }
  110. else if (prev->child)
  111. {
  112. np = prev->child;
  113. }
  114. else
  115. {
  116. np = prev;
  117. while (np->parent && !np->sibling)
  118. {
  119. np = np->parent;
  120. }
  121. np = np->sibling;
  122. }
  123. return np;
  124. }
  125. static void ofw_node_destroy(struct rt_ofw_node *np)
  126. {
  127. struct rt_ofw_node *prev;
  128. if (np->parent)
  129. {
  130. /* Ask parent and prev sibling we are destroy. */
  131. prev = np->parent->child;
  132. if (prev == np)
  133. {
  134. np->parent->child = RT_NULL;
  135. }
  136. else
  137. {
  138. while (prev->sibling != np)
  139. {
  140. prev = prev->sibling;
  141. }
  142. prev->sibling = np->sibling;
  143. }
  144. }
  145. while (np)
  146. {
  147. if (rt_ofw_node_test_flag(np, RT_OFW_F_SYSTEM) == RT_FALSE)
  148. {
  149. LOG_E("%s is system node", np->full_name);
  150. RT_ASSERT(0);
  151. }
  152. prev = np;
  153. np = ofw_get_next_node(np);
  154. ofw_prop_destroy(prev->props);
  155. rt_free(prev);
  156. }
  157. }
  158. rt_err_t rt_ofw_node_destroy(struct rt_ofw_node *np)
  159. {
  160. rt_err_t err = RT_EOK;
  161. if (np)
  162. {
  163. if (rt_ref_read(&np->ref) <= 1)
  164. {
  165. ofw_node_destroy(np);
  166. }
  167. else
  168. {
  169. err = -RT_EBUSY;
  170. }
  171. }
  172. else
  173. {
  174. err = -RT_EINVAL;
  175. }
  176. return err;
  177. }
  178. struct rt_ofw_node *rt_ofw_node_get(struct rt_ofw_node *np)
  179. {
  180. if (np)
  181. {
  182. LOG_D("%s get ref = %d", np->full_name, rt_ref_read(&np->ref));
  183. rt_ref_get(&np->ref);
  184. }
  185. return np;
  186. }
  187. static void ofw_node_release(struct rt_ref *r)
  188. {
  189. struct rt_ofw_node *np = rt_container_of(r, struct rt_ofw_node, ref);
  190. LOG_E("%s is release", np->full_name);
  191. RT_ASSERT(0);
  192. }
  193. void rt_ofw_node_put(struct rt_ofw_node *np)
  194. {
  195. if (np)
  196. {
  197. LOG_D("%s put ref = %d", np->full_name, rt_ref_read(&np->ref));
  198. rt_ref_put(&np->ref, &ofw_node_release);
  199. }
  200. }
  201. rt_bool_t rt_ofw_node_tag_equ(const struct rt_ofw_node *np, const char *tag)
  202. {
  203. rt_bool_t ret = RT_FALSE;
  204. if (np && tag)
  205. {
  206. const char *node_name = rt_fdt_node_name(np->full_name);
  207. rt_size_t tag_len = rt_strchrnul(node_name, '@') - node_name;
  208. ret = (rt_strlen(tag) == tag_len && !rt_strncmp(node_name, tag, tag_len));
  209. }
  210. return ret;
  211. }
  212. rt_bool_t rt_ofw_node_tag_prefix(const struct rt_ofw_node *np, const char *prefix)
  213. {
  214. rt_bool_t ret = RT_FALSE;
  215. if (np && prefix)
  216. {
  217. ret = !rt_strncmp(rt_fdt_node_name(np->full_name), prefix, rt_strlen(prefix));
  218. }
  219. return ret;
  220. }
  221. static int ofw_prop_index_of_string(struct rt_ofw_prop *prop, const char *string,
  222. rt_int32_t (*cmp)(const char *cs, const char *ct))
  223. {
  224. int index = -1;
  225. rt_size_t len = prop->length, slen = 0;
  226. const char *value = prop->value;
  227. for (int idx = 0; len > 0; ++idx)
  228. {
  229. /* Add '\0' */
  230. slen = rt_strlen(value) + 1;
  231. if (!cmp(value, string))
  232. {
  233. index = idx;
  234. break;
  235. }
  236. len -= slen;
  237. value += slen;
  238. }
  239. return index;
  240. }
  241. static rt_int32_t ofw_strcasecmp(const char *cs, const char *ct)
  242. {
  243. extern rt_int32_t strcasecmp(const char *cs, const char *ct);
  244. return rt_strcasecmp(cs, ct);
  245. }
  246. static int ofw_prop_index_of_compatible(struct rt_ofw_prop *prop, const char *compatible)
  247. {
  248. return ofw_prop_index_of_string(prop, compatible, ofw_strcasecmp);
  249. }
  250. static int ofw_node_index_of_compatible(const struct rt_ofw_node *np, const char *compatible)
  251. {
  252. int idx = -1;
  253. struct rt_ofw_prop *prop = rt_ofw_get_prop(np, "compatible", RT_NULL);
  254. if (prop)
  255. {
  256. idx = ofw_prop_index_of_compatible(prop, compatible);
  257. }
  258. return idx;
  259. }
  260. rt_bool_t rt_ofw_machine_is_compatible(const char *compatible)
  261. {
  262. return ofw_node_index_of_compatible(ofw_node_root, compatible) >= 0;
  263. }
  264. /*
  265. * Property status:
  266. *
  267. * "okay" or "ok":
  268. * Indicates the device is operational.
  269. *
  270. * "disabled":
  271. * Indicates that the device is not presently operational, but it might
  272. * become operational in the future (for example, something is not
  273. * plugged in, or switched off).
  274. * Refer to the device binding for details on what disabled means for a
  275. * given device.
  276. *
  277. * "reserved":
  278. * Indicates that the device is operational, but should not be used.
  279. * Typically this is used for devices that are controlled by another
  280. * software component, such as platform firmware.
  281. *
  282. * "fail":
  283. * Indicates that the device is not operational. A serious error was
  284. * detected in the device, and it is unlikely to become operational
  285. * without repair.
  286. *
  287. * "fail-sss":
  288. * Indicates that the device is not operational. A serious error was
  289. * detected in the device and it is unlikely to become operational
  290. * without repair. The sss portion of the value is specific to the
  291. * device and indicates the error condition detected.
  292. */
  293. static rt_bool_t ofw_node_is_fail(const struct rt_ofw_node *np)
  294. {
  295. rt_bool_t res = RT_FALSE;
  296. const char *status = rt_ofw_prop_read_raw(np, "status", RT_NULL);
  297. if (status)
  298. {
  299. res = !rt_strcmp(status, "fail") || !rt_strncmp(status, "fail-", 5);
  300. }
  301. return res;
  302. }
  303. static rt_bool_t ofw_node_is_available(const struct rt_ofw_node *np)
  304. {
  305. rt_bool_t res = RT_TRUE;
  306. const char *status = rt_ofw_prop_read_raw(np, "status", RT_NULL);
  307. if (status)
  308. {
  309. res = !rt_strcmp(status, "okay") || !rt_strcmp(status, "ok");
  310. }
  311. return res;
  312. }
  313. rt_bool_t rt_ofw_node_is_available(const struct rt_ofw_node *np)
  314. {
  315. return np ? ofw_node_is_available(np) : RT_FALSE;
  316. }
  317. rt_bool_t rt_ofw_node_is_compatible(const struct rt_ofw_node *np, const char *compatible)
  318. {
  319. rt_bool_t res = RT_FALSE;
  320. if (np)
  321. {
  322. res = ofw_node_index_of_compatible(np, compatible) >= 0;
  323. }
  324. return res;
  325. }
  326. static struct rt_ofw_node_id *ofw_prop_match(struct rt_ofw_prop *prop, const struct rt_ofw_node_id *ids)
  327. {
  328. int best_index = RT_UINT32_MAX >> 1, index;
  329. struct rt_ofw_node_id *found_id = RT_NULL, *id;
  330. for (id = (struct rt_ofw_node_id *)ids; id->compatible[0]; ++id)
  331. {
  332. index = ofw_prop_index_of_compatible(prop, id->compatible);
  333. if (index >= 0 && index < best_index)
  334. {
  335. found_id = id;
  336. best_index = index;
  337. }
  338. }
  339. return found_id;
  340. }
  341. struct rt_ofw_node_id *rt_ofw_prop_match(struct rt_ofw_prop *prop, const struct rt_ofw_node_id *ids)
  342. {
  343. struct rt_ofw_node_id *id = RT_NULL;
  344. if (prop && ids && !rt_strcmp(prop->name, "compatible"))
  345. {
  346. id = ofw_prop_match(prop, ids);
  347. }
  348. return id;
  349. }
  350. struct rt_ofw_node_id *rt_ofw_node_match(struct rt_ofw_node *np, const struct rt_ofw_node_id *ids)
  351. {
  352. struct rt_ofw_prop *prop;
  353. struct rt_ofw_node_id *id = RT_NULL;
  354. if (np && ids && (prop = rt_ofw_get_prop(np, "compatible", RT_NULL)))
  355. {
  356. id = ofw_prop_match(prop, ids);
  357. }
  358. return id;
  359. }
  360. struct rt_ofw_node *rt_ofw_find_node_by_tag(struct rt_ofw_node *from, const char *tag)
  361. {
  362. struct rt_ofw_node *np = RT_NULL;
  363. if (tag)
  364. {
  365. rt_ofw_foreach_nodes(from, np)
  366. {
  367. if (rt_ofw_node_tag_equ(np, tag))
  368. {
  369. break;
  370. }
  371. }
  372. }
  373. return np;
  374. }
  375. struct rt_ofw_node *rt_ofw_find_node_by_prop_r(struct rt_ofw_node *from, const char *propname,
  376. const struct rt_ofw_prop **out_prop)
  377. {
  378. struct rt_ofw_node *np = RT_NULL;
  379. if (propname)
  380. {
  381. rt_ofw_foreach_nodes(from, np)
  382. {
  383. struct rt_ofw_prop *prop = rt_ofw_get_prop(np, propname, RT_NULL);
  384. if (prop)
  385. {
  386. if (out_prop)
  387. {
  388. *out_prop = prop;
  389. }
  390. break;
  391. }
  392. }
  393. }
  394. return np;
  395. }
  396. struct rt_ofw_node *rt_ofw_find_node_by_name(struct rt_ofw_node *from, const char *name)
  397. {
  398. struct rt_ofw_node *np = RT_NULL;
  399. if (name)
  400. {
  401. rt_ofw_foreach_nodes(from, np)
  402. {
  403. if (np->name && !rt_strcmp(np->name, name))
  404. {
  405. np = rt_ofw_node_get(np);
  406. break;
  407. }
  408. }
  409. }
  410. return np;
  411. }
  412. struct rt_ofw_node *rt_ofw_find_node_by_type(struct rt_ofw_node *from, const char *type)
  413. {
  414. struct rt_ofw_node *np = RT_NULL;
  415. if (type)
  416. {
  417. rt_ofw_foreach_nodes(from, np)
  418. {
  419. if (rt_ofw_node_is_type(np, type))
  420. {
  421. break;
  422. }
  423. }
  424. }
  425. return np;
  426. }
  427. struct rt_ofw_node *rt_ofw_find_node_by_compatible(struct rt_ofw_node *from, const char *compatible)
  428. {
  429. struct rt_ofw_node *np = RT_NULL;
  430. if (compatible)
  431. {
  432. rt_ofw_foreach_nodes(from, np)
  433. {
  434. if (ofw_node_index_of_compatible(np, compatible) >= 0)
  435. {
  436. break;
  437. }
  438. }
  439. }
  440. return np;
  441. }
  442. struct rt_ofw_node *rt_ofw_find_node_by_ids_r(struct rt_ofw_node *from, const struct rt_ofw_node_id *ids,
  443. const struct rt_ofw_node_id **out_id)
  444. {
  445. struct rt_ofw_node *np = RT_NULL;
  446. if (ids)
  447. {
  448. rt_ofw_foreach_nodes(from, np)
  449. {
  450. struct rt_ofw_node_id *id = rt_ofw_node_match(np, ids);
  451. if (id)
  452. {
  453. if (out_id)
  454. {
  455. *out_id = id;
  456. }
  457. break;
  458. }
  459. }
  460. }
  461. return np;
  462. }
  463. struct rt_ofw_node *rt_ofw_find_node_by_path(const char *path)
  464. {
  465. struct rt_ofw_node *np, *parent, *tmp;
  466. if (path)
  467. {
  468. if (!rt_strcmp(path, "/"))
  469. {
  470. np = ofw_node_root;
  471. }
  472. else
  473. {
  474. ++path;
  475. parent = rt_ofw_node_get(ofw_node_root);
  476. while (*path)
  477. {
  478. const char *next = rt_strchrnul(path, '/');
  479. rt_size_t len = next - path;
  480. tmp = RT_NULL;
  481. rt_ofw_foreach_child_node(parent, np)
  482. {
  483. if (!rt_strncmp(np->full_name, path, len))
  484. {
  485. rt_ofw_node_put(parent);
  486. parent = np;
  487. tmp = np;
  488. break;
  489. }
  490. }
  491. if (!tmp)
  492. {
  493. rt_ofw_node_put(parent);
  494. break;
  495. }
  496. path += len;
  497. }
  498. np = tmp;
  499. }
  500. rt_ofw_node_get(np);
  501. }
  502. return np;
  503. }
  504. struct rt_ofw_node *rt_ofw_find_node_by_phandle(rt_phandle phandle)
  505. {
  506. struct rt_ofw_node *np = RT_NULL;
  507. if (phandle >= OFW_PHANDLE_MIN && phandle <= OFW_PHANDLE_MAX)
  508. {
  509. /* rebase from zero */
  510. rt_phandle poff = phandle - _phandle_range[0];
  511. np = _phandle_hash[poff];
  512. if (!np)
  513. {
  514. rt_ofw_foreach_allnodes(np)
  515. {
  516. if (np->phandle == phandle)
  517. {
  518. _phandle_hash[poff] = np;
  519. break;
  520. }
  521. }
  522. }
  523. else
  524. {
  525. rt_ofw_node_get(np);
  526. }
  527. }
  528. return np;
  529. }
  530. struct rt_ofw_node *rt_ofw_get_parent(const struct rt_ofw_node *np)
  531. {
  532. if (np)
  533. {
  534. np = rt_ofw_node_get(np->parent);
  535. }
  536. return (struct rt_ofw_node *)np;
  537. }
  538. struct rt_ofw_node *rt_ofw_get_child_by_tag(const struct rt_ofw_node *parent, const char *tag)
  539. {
  540. struct rt_ofw_node *child = RT_NULL;
  541. if (parent && tag)
  542. {
  543. rt_ofw_foreach_child_node(parent, child)
  544. {
  545. if (rt_ofw_node_tag_equ(child, tag))
  546. {
  547. break;
  548. }
  549. }
  550. }
  551. return child;
  552. }
  553. struct rt_ofw_node *rt_ofw_get_child_by_compatible(const struct rt_ofw_node *parent, const char *compatible)
  554. {
  555. struct rt_ofw_node *child = RT_NULL;
  556. if (parent && compatible)
  557. {
  558. rt_ofw_foreach_child_node(parent, child)
  559. {
  560. if (ofw_node_index_of_compatible(child, compatible) >= 0)
  561. {
  562. break;
  563. }
  564. }
  565. }
  566. return child;
  567. }
  568. int rt_ofw_get_child_count(const struct rt_ofw_node *np)
  569. {
  570. int nr;
  571. if (np)
  572. {
  573. struct rt_ofw_node *child;
  574. nr = 0;
  575. rt_ofw_foreach_child_node(np, child)
  576. {
  577. ++nr;
  578. }
  579. }
  580. else
  581. {
  582. nr = -RT_EINVAL;
  583. }
  584. return nr;
  585. }
  586. int rt_ofw_get_available_child_count(const struct rt_ofw_node *np)
  587. {
  588. int nr;
  589. if (np)
  590. {
  591. struct rt_ofw_node *child;
  592. nr = 0;
  593. rt_ofw_foreach_available_child_node(np, child)
  594. {
  595. ++nr;
  596. }
  597. }
  598. else
  599. {
  600. nr = -RT_EINVAL;
  601. }
  602. return nr;
  603. }
  604. struct rt_ofw_node *rt_ofw_get_next_node(struct rt_ofw_node *prev)
  605. {
  606. struct rt_ofw_node *np;
  607. np = rt_ofw_node_get(ofw_get_next_node(prev));
  608. rt_ofw_node_put(prev);
  609. return np;
  610. }
  611. struct rt_ofw_node *rt_ofw_get_next_parent(struct rt_ofw_node *prev)
  612. {
  613. struct rt_ofw_node *next = RT_NULL;
  614. if (prev)
  615. {
  616. next = rt_ofw_node_get(prev->parent);
  617. rt_ofw_node_put(prev);
  618. }
  619. return next;
  620. }
  621. struct rt_ofw_node *rt_ofw_get_next_child(const struct rt_ofw_node *parent, struct rt_ofw_node *prev)
  622. {
  623. struct rt_ofw_node *next = RT_NULL;
  624. if (parent)
  625. {
  626. next = prev ? prev->sibling : parent->child;
  627. rt_ofw_node_put(prev);
  628. rt_ofw_node_get(next);
  629. }
  630. return next;
  631. }
  632. struct rt_ofw_node *rt_ofw_get_next_available_child(const struct rt_ofw_node *parent, struct rt_ofw_node *prev)
  633. {
  634. struct rt_ofw_node *next = RT_NULL;
  635. if (parent)
  636. {
  637. next = prev;
  638. do {
  639. next = rt_ofw_get_next_child(parent, next);
  640. } while (next && !ofw_node_is_available(next));
  641. }
  642. return next;
  643. }
  644. struct rt_ofw_node *rt_ofw_get_cpu_node(int cpu, int *thread, rt_bool_t (*match_cpu_hwid)(int cpu, rt_uint64_t hwid))
  645. {
  646. const char *propname = "reg";
  647. struct rt_ofw_node *cpu_np = RT_NULL;
  648. /*
  649. * "reg" (some of the obsolete arch may be other names):
  650. * The value of reg is a <prop-encoded-array> that defines a unique
  651. * CPU/thread id for the CPU/threads represented by the CPU node.
  652. *
  653. * If a CPU supports more than one thread (i.e. multiple streams of
  654. * execution) the reg property is an array with 1 element per thread. The
  655. * #address-cells on the /cpus node specifies how many cells each element
  656. * of the array takes. Software can determine the number of threads by
  657. * dividing the size of reg by the parent node’s #address-cells:
  658. *
  659. * thread-number = reg-cells / address-cells
  660. *
  661. * If a CPU/thread can be the target of an external interrupt the reg
  662. * property value must be a unique CPU/thread id that is addressable by the
  663. * interrupt controller.
  664. *
  665. * If a CPU/thread cannot be the target of an external interrupt, then reg
  666. * must be unique and out of bounds of the range addressed by the interrupt
  667. * controller
  668. *
  669. * If a CPU/thread’s PIR (pending interrupt register) is modifiable, a
  670. * client program should modify PIR to match the reg property value. If PIR
  671. * cannot be modified and the PIR value is distinct from the interrupt
  672. * controller number space, the CPUs binding may define a binding-specific
  673. * representation of PIR values if desired.
  674. */
  675. rt_ofw_foreach_cpu_node(cpu_np)
  676. {
  677. rt_ssize_t prop_len;
  678. rt_bool_t is_end = RT_FALSE;
  679. int tid, addr_cells = rt_ofw_io_addr_cells(cpu_np);
  680. const fdt32_t *cell = rt_ofw_prop_read_raw(cpu_np, propname, &prop_len);
  681. if (!cell && !addr_cells)
  682. {
  683. if (match_cpu_hwid && match_cpu_hwid(cpu, 0))
  684. {
  685. break;
  686. }
  687. continue;
  688. }
  689. if (!match_cpu_hwid)
  690. {
  691. continue;
  692. }
  693. prop_len /= sizeof(*cell) * addr_cells;
  694. for (tid = 0; tid < prop_len; ++tid)
  695. {
  696. rt_uint64_t hwid = rt_fdt_read_number(cell, addr_cells);
  697. if (match_cpu_hwid(cpu, hwid))
  698. {
  699. if (thread)
  700. {
  701. *thread = tid;
  702. }
  703. is_end = RT_TRUE;
  704. break;
  705. }
  706. cell += addr_cells;
  707. }
  708. if (is_end)
  709. {
  710. break;
  711. }
  712. }
  713. return cpu_np;
  714. }
  715. struct rt_ofw_node *rt_ofw_get_next_cpu_node(struct rt_ofw_node *prev)
  716. {
  717. struct rt_ofw_node *cpu_np;
  718. if (prev)
  719. {
  720. cpu_np = prev->sibling;
  721. rt_ofw_node_put(prev);
  722. }
  723. else
  724. {
  725. cpu_np = ofw_node_cpus->child;
  726. }
  727. for (; cpu_np; cpu_np = cpu_np->sibling)
  728. {
  729. if (ofw_node_is_fail(cpu_np))
  730. {
  731. continue;
  732. }
  733. if (!(rt_ofw_node_tag_equ(cpu_np, "cpu") || rt_ofw_node_is_type(cpu_np, "cpu")))
  734. {
  735. continue;
  736. }
  737. if (rt_ofw_node_get(cpu_np))
  738. {
  739. break;
  740. }
  741. }
  742. return cpu_np;
  743. }
  744. struct rt_ofw_node *rt_ofw_get_cpu_state_node(struct rt_ofw_node *cpu_np, int index)
  745. {
  746. struct rt_ofw_cell_args args;
  747. struct rt_ofw_node *np = RT_NULL, *state_np;
  748. rt_err_t err = rt_ofw_parse_phandle_cells(cpu_np, "power-domains", "#power-domain-cells", 0, &args);
  749. if (!err)
  750. {
  751. state_np = rt_ofw_parse_phandle(args.data, "domain-idle-states", index);
  752. rt_ofw_node_put(args.data);
  753. if (state_np)
  754. {
  755. np = state_np;
  756. }
  757. }
  758. if (!np)
  759. {
  760. int count = 0;
  761. rt_uint32_t phandle;
  762. const fdt32_t *cell;
  763. struct rt_ofw_prop *prop;
  764. rt_ofw_foreach_prop_u32(cpu_np, "cpu-idle-states", prop, cell, phandle)
  765. {
  766. if (count == index)
  767. {
  768. np = rt_ofw_find_node_by_phandle((rt_phandle)phandle);
  769. break;
  770. }
  771. ++count;
  772. }
  773. }
  774. return np;
  775. }
  776. rt_uint64_t rt_ofw_get_cpu_id(struct rt_ofw_node *cpu_np)
  777. {
  778. rt_uint64_t cpuid = ~0ULL;
  779. if (cpu_np)
  780. {
  781. rt_uint64_t idx = 0;
  782. struct rt_ofw_node *np = ofw_node_cpus->child;
  783. for (; np; np = np->sibling)
  784. {
  785. if (!(rt_ofw_node_tag_equ(cpu_np, "cpu") || rt_ofw_node_is_type(cpu_np, "cpu")))
  786. {
  787. continue;
  788. }
  789. if (cpu_np == np)
  790. {
  791. cpuid = idx;
  792. break;
  793. }
  794. ++idx;
  795. }
  796. if ((rt_int64_t)cpuid < 0 && !rt_ofw_prop_read_u64(cpu_np, "rt-thread,cpuid", &idx))
  797. {
  798. cpuid = idx;
  799. }
  800. }
  801. return cpuid;
  802. }
  803. rt_uint64_t rt_ofw_get_cpu_hwid(struct rt_ofw_node *cpu_np, unsigned int thread)
  804. {
  805. rt_uint64_t thread_id, hwid = ~0ULL;
  806. if (cpu_np && thread >= 0 && !rt_ofw_get_address(cpu_np, thread, &thread_id, RT_NULL))
  807. {
  808. hwid = thread_id;
  809. }
  810. return hwid;
  811. }
  812. rt_err_t ofw_alias_scan(void)
  813. {
  814. rt_err_t err = RT_EOK;
  815. struct rt_ofw_prop *prop;
  816. struct rt_ofw_node *np = ofw_node_aliases, *tmp;
  817. rt_ofw_foreach_prop(np, prop)
  818. {
  819. int id = 0, rate = 1;
  820. struct alias_info *info;
  821. const char *name = prop->name, *end;
  822. /* Maybe the bootloader will set the name, or other nodes reference the aliases */
  823. if (!rt_strcmp(name, "name") || !rt_strcmp(name, "phandle"))
  824. {
  825. continue;
  826. }
  827. if (!(tmp = rt_ofw_find_node_by_path(prop->value)))
  828. {
  829. continue;
  830. }
  831. end = name + rt_strlen(name);
  832. while (*end && !(*end >= '0' && *end <= '9'))
  833. {
  834. --end;
  835. }
  836. while (*end && (*end >= '0' && *end <= '9'))
  837. {
  838. id += (*end - '0') * rate;
  839. rate *= 10;
  840. --end;
  841. }
  842. info = rt_malloc(sizeof(*info));
  843. if (!info)
  844. {
  845. err = -RT_ENOMEM;
  846. break;
  847. }
  848. rt_list_init(&info->list);
  849. info->id = id;
  850. info->tag = name;
  851. info->tag_len = end - name;
  852. info->np = tmp;
  853. rt_list_insert_after(&_aliases_nodes, &info->list);
  854. }
  855. return err;
  856. }
  857. struct rt_ofw_node *rt_ofw_get_alias_node(const char *tag, int id)
  858. {
  859. struct alias_info *info;
  860. struct rt_ofw_node *np = RT_NULL;
  861. if (tag && id >= 0)
  862. {
  863. rt_list_for_each_entry(info, &_aliases_nodes, list)
  864. {
  865. if (rt_strncmp(info->tag, tag, info->tag_len))
  866. {
  867. continue;
  868. }
  869. if (info->id == id)
  870. {
  871. np = info->np;
  872. break;
  873. }
  874. }
  875. }
  876. return np;
  877. }
  878. int rt_ofw_get_alias_id(struct rt_ofw_node *np, const char *tag)
  879. {
  880. int id;
  881. struct alias_info *info;
  882. if (np && tag)
  883. {
  884. id = -1;
  885. rt_list_for_each_entry(info, &_aliases_nodes, list)
  886. {
  887. if (rt_strncmp(info->tag, tag, info->tag_len))
  888. {
  889. continue;
  890. }
  891. if (info->np == np)
  892. {
  893. id = info->id;
  894. break;
  895. }
  896. }
  897. }
  898. else
  899. {
  900. id = -RT_EINVAL;
  901. }
  902. return id;
  903. }
  904. int rt_ofw_get_alias_last_id(const char *tag)
  905. {
  906. int id;
  907. struct alias_info *info;
  908. if (tag)
  909. {
  910. id = -1;
  911. rt_list_for_each_entry(info, &_aliases_nodes, list)
  912. {
  913. if (rt_strncmp(info->tag, tag, info->tag_len))
  914. {
  915. continue;
  916. }
  917. if (info->id > id)
  918. {
  919. id = info->id;
  920. }
  921. }
  922. }
  923. else
  924. {
  925. id = -RT_EINVAL;
  926. }
  927. return id;
  928. }
  929. struct rt_ofw_node *rt_ofw_parse_phandle(const struct rt_ofw_node *np, const char *phandle_name, int index)
  930. {
  931. struct rt_ofw_cell_args args;
  932. struct rt_ofw_node *ref_np = RT_NULL;
  933. if (!rt_ofw_parse_phandle_cells(np, phandle_name, RT_NULL, index, &args))
  934. {
  935. ref_np = args.data;
  936. }
  937. return ref_np;
  938. }
  939. static rt_err_t ofw_parse_phandle_cells(const struct rt_ofw_node *np, const char *list_name, const char *cells_name,
  940. int index, struct rt_ofw_cell_args *out_args)
  941. {
  942. rt_err_t err = -RT_EEMPTY;
  943. rt_uint32_t value;
  944. rt_size_t count = 0;
  945. const fdt32_t *cell;
  946. struct rt_ofw_prop *prop;
  947. /*
  948. * List:
  949. *
  950. * phandle1: node1 {
  951. * #list-cells = <2>;
  952. * };
  953. *
  954. * phandle2: node2 {
  955. * #list-cells = <1>;
  956. * };
  957. *
  958. * node3 {
  959. * list = <&phandle1 0xaa 0xbb>, <&phandle2 0xcc>;
  960. * };
  961. *
  962. * if call:
  963. * rt_ofw_parse_phandle_cells(node3, "list", "#list-cells", 0, &args):
  964. *
  965. * args.data = node1;
  966. * args.args_count = 2;
  967. * args.args[0] = 0xaa;
  968. * args.args[1] = 0xbb;
  969. *
  970. * rt_ofw_parse_phandle_cells(node3, "list", "#list-cells", 1, &args):
  971. *
  972. * args.data = node2;
  973. * args.args_count = 1;
  974. * args.args[0] = 0xcc;
  975. */
  976. rt_ofw_foreach_prop_u32(np, list_name, prop, cell, value)
  977. {
  978. rt_uint32_t cells_count = 0;
  979. struct rt_ofw_node *phandle_np = rt_ofw_find_node_by_phandle((rt_phandle)value);
  980. /* if phandle node is undefined, we assume that the cels_count is 0 */
  981. if (cells_name && phandle_np)
  982. {
  983. rt_ofw_prop_read_u32(phandle_np, cells_name, &cells_count);
  984. }
  985. if (count++ == index)
  986. {
  987. for (int idx = 0; idx < cells_count; ++idx)
  988. {
  989. cell = rt_ofw_prop_next_u32(prop, cell, &value);
  990. out_args->args[idx] = value;
  991. }
  992. out_args->args_count = cells_count;
  993. out_args->data = phandle_np;
  994. if (out_args->data)
  995. {
  996. err = RT_EOK;
  997. }
  998. break;
  999. }
  1000. cell += cells_count;
  1001. }
  1002. return err;
  1003. }
  1004. rt_err_t rt_ofw_parse_phandle_cells(const struct rt_ofw_node *np, const char *list_name, const char *cells_name,
  1005. int index, struct rt_ofw_cell_args *out_args)
  1006. {
  1007. rt_err_t err;
  1008. if (np && list_name && index >= 0 && out_args)
  1009. {
  1010. err = ofw_parse_phandle_cells(np, list_name, cells_name, index, out_args);
  1011. }
  1012. else
  1013. {
  1014. err = -RT_EINVAL;
  1015. }
  1016. return err;
  1017. }
  1018. int rt_ofw_count_phandle_cells(const struct rt_ofw_node *np, const char *list_name, const char *cells_name)
  1019. {
  1020. int count;
  1021. if (np && list_name)
  1022. {
  1023. count = -1;
  1024. if (!cells_name)
  1025. {
  1026. rt_ssize_t length;
  1027. if (rt_ofw_get_prop(np, list_name, &length))
  1028. {
  1029. count = length / sizeof(fdt32_t);
  1030. }
  1031. }
  1032. else
  1033. {
  1034. int index = count = 0;
  1035. struct rt_ofw_cell_args args;
  1036. while (!ofw_parse_phandle_cells(np, list_name, cells_name, index, &args))
  1037. {
  1038. ++index;
  1039. ++count;
  1040. }
  1041. }
  1042. }
  1043. else
  1044. {
  1045. count = -RT_EINVAL;
  1046. }
  1047. return count;
  1048. }
  1049. struct rt_ofw_prop *rt_ofw_get_prop(const struct rt_ofw_node *np, const char *name, rt_ssize_t *out_length)
  1050. {
  1051. struct rt_ofw_prop *prop = RT_NULL;
  1052. if (np && name)
  1053. {
  1054. rt_ofw_foreach_prop(np, prop)
  1055. {
  1056. if (!rt_strcmp(prop->name, name))
  1057. {
  1058. if (out_length)
  1059. {
  1060. *out_length = prop->length;
  1061. }
  1062. break;
  1063. }
  1064. }
  1065. }
  1066. return prop;
  1067. }
  1068. #define OFW_PROP_READ_UXX_ARRAY_INDEX(bit) \
  1069. int rt_ofw_prop_read_u##bit##_array_index( \
  1070. const struct rt_ofw_node *np, const char *propname, \
  1071. int index, int nr, rt_uint##bit##_t *out_values) \
  1072. { \
  1073. int res, max_nr; \
  1074. if (np && propname && index >= 0 && nr >= 0 && out_values) \
  1075. { \
  1076. rt_ssize_t len; \
  1077. const fdt##bit##_t *elm; \
  1078. elm = rt_ofw_prop_read_raw(np, propname, &len); \
  1079. max_nr = len / sizeof(*elm); \
  1080. if (elm && index < max_nr) \
  1081. { \
  1082. elm += index; \
  1083. max_nr -= index; \
  1084. res = nr > max_nr ? max_nr : nr; \
  1085. for (nr = 0; nr < res; ++nr) \
  1086. { \
  1087. *out_values++ = fdt##bit##_to_cpu(*elm++); \
  1088. } \
  1089. } \
  1090. else \
  1091. { \
  1092. res = -RT_EEMPTY; \
  1093. } \
  1094. } \
  1095. else \
  1096. { \
  1097. res = -RT_EINVAL; \
  1098. } \
  1099. return res; \
  1100. }
  1101. OFW_PROP_READ_UXX_ARRAY_INDEX(8)
  1102. OFW_PROP_READ_UXX_ARRAY_INDEX(16)
  1103. OFW_PROP_READ_UXX_ARRAY_INDEX(32)
  1104. OFW_PROP_READ_UXX_ARRAY_INDEX(64)
  1105. #undef OFW_PROP_READ_UXX_ARRAY_INDEX
  1106. int rt_ofw_prop_read_string_array_index(const struct rt_ofw_node *np, const char *propname,
  1107. int index, int nr, const char **out_strings)
  1108. {
  1109. int res = 0;
  1110. if (np && propname && index >= 0 && nr >= 0 && out_strings)
  1111. {
  1112. rt_ssize_t len, slen = 0;
  1113. const char *value = rt_ofw_prop_read_raw(np, propname, &len);
  1114. if (value)
  1115. {
  1116. nr += index;
  1117. for (int idx = 0; idx < nr && len > 0; ++idx)
  1118. {
  1119. /* Add '\0' */
  1120. slen = rt_strlen(value) + 1;
  1121. if (idx >= index)
  1122. {
  1123. *out_strings++ = value;
  1124. ++res;
  1125. }
  1126. len -= slen;
  1127. value += slen;
  1128. }
  1129. }
  1130. else
  1131. {
  1132. res = -RT_EEMPTY;
  1133. }
  1134. }
  1135. else
  1136. {
  1137. res = -RT_EINVAL;
  1138. }
  1139. return res;
  1140. }
  1141. int rt_ofw_prop_count_of_size(const struct rt_ofw_node *np, const char *propname, int size)
  1142. {
  1143. int count;
  1144. if (np && propname && size > 0)
  1145. {
  1146. rt_ssize_t len;
  1147. count = -RT_EEMPTY;
  1148. if (rt_ofw_get_prop(np, propname, &len))
  1149. {
  1150. count = len / size;
  1151. }
  1152. }
  1153. else
  1154. {
  1155. count = -RT_EINVAL;
  1156. }
  1157. return count;
  1158. }
  1159. static rt_int32_t ofw_strcmp(const char *cs, const char *ct)
  1160. {
  1161. return rt_strcmp(cs, ct);
  1162. }
  1163. int rt_ofw_prop_index_of_string(const struct rt_ofw_node *np, const char *propname, const char *string)
  1164. {
  1165. int idx;
  1166. if (np && propname && string)
  1167. {
  1168. struct rt_ofw_prop *prop = rt_ofw_get_prop(np, propname, RT_NULL);
  1169. idx = -1;
  1170. if (prop)
  1171. {
  1172. idx = ofw_prop_index_of_string(prop, string, ofw_strcmp);
  1173. }
  1174. }
  1175. else
  1176. {
  1177. idx = -RT_EINVAL;
  1178. }
  1179. return idx;
  1180. }
  1181. const fdt32_t *rt_ofw_prop_next_u32(struct rt_ofw_prop *prop, const fdt32_t *cur, rt_uint32_t *out_value)
  1182. {
  1183. if (prop && out_value)
  1184. {
  1185. if (cur)
  1186. {
  1187. ++cur;
  1188. if ((void *)cur >= prop->value + prop->length)
  1189. {
  1190. cur = RT_NULL;
  1191. }
  1192. }
  1193. else
  1194. {
  1195. cur = prop->value;
  1196. }
  1197. if (cur)
  1198. {
  1199. *out_value = fdt32_to_cpu(*cur);
  1200. }
  1201. }
  1202. else
  1203. {
  1204. cur = RT_NULL;
  1205. }
  1206. return cur;
  1207. }
  1208. const char *rt_ofw_prop_next_string(struct rt_ofw_prop *prop, const char *cur)
  1209. {
  1210. if (prop)
  1211. {
  1212. if (cur)
  1213. {
  1214. cur += rt_strlen(cur) + 1;
  1215. if ((void *)cur >= prop->value + prop->length)
  1216. {
  1217. cur = RT_NULL;
  1218. }
  1219. }
  1220. else
  1221. {
  1222. cur = prop->value;
  1223. }
  1224. }
  1225. else
  1226. {
  1227. cur = RT_NULL;
  1228. }
  1229. return cur;
  1230. }