fdt.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023
  1. /*
  2. * Functions for working with the Flattened Device Tree data format
  3. *
  4. * Copyright 2009 Benjamin Herrenschmidt, IBM Corp
  5. * benh@kernel.crashing.org
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * version 2 as published by the Free Software Foundation.
  10. */
  11. #include <linux/kernel.h>
  12. #include <linux/initrd.h>
  13. #include <linux/memblock.h>
  14. #include <linux/of.h>
  15. #include <linux/of_fdt.h>
  16. #include <linux/of_reserved_mem.h>
  17. #include <linux/sizes.h>
  18. #include <linux/string.h>
  19. #include <linux/errno.h>
  20. #include <linux/slab.h>
  21. #include <linux/libfdt.h>
  22. #include <linux/debugfs.h>
  23. #include <linux/serial_core.h>
  24. #include <asm/setup.h> /* for COMMAND_LINE_SIZE */
  25. #include <asm/page.h>
  26. /**
  27. * of_fdt_is_compatible - Return true if given node from the given blob has
  28. * compat in its compatible list
  29. * @blob: A device tree blob
  30. * @node: node to test
  31. * @compat: compatible string to compare with compatible list.
  32. *
  33. * On match, returns a non-zero value with smaller values returned for more
  34. * specific compatible values.
  35. */
  36. int of_fdt_is_compatible(const void *blob,
  37. unsigned long node, const char *compat)
  38. {
  39. const char *cp;
  40. int cplen;
  41. unsigned long l, score = 0;
  42. cp = fdt_getprop(blob, node, "compatible", &cplen);
  43. if (cp == NULL)
  44. return 0;
  45. while (cplen > 0) {
  46. score++;
  47. if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
  48. return score;
  49. l = strlen(cp) + 1;
  50. cp += l;
  51. cplen -= l;
  52. }
  53. return 0;
  54. }
  55. /**
  56. * of_fdt_match - Return true if node matches a list of compatible values
  57. */
  58. int of_fdt_match(const void *blob, unsigned long node,
  59. const char *const *compat)
  60. {
  61. unsigned int tmp, score = 0;
  62. if (!compat)
  63. return 0;
  64. while (*compat) {
  65. tmp = of_fdt_is_compatible(blob, node, *compat);
  66. if (tmp && (score == 0 || (tmp < score)))
  67. score = tmp;
  68. compat++;
  69. }
  70. return score;
  71. }
  72. static void *unflatten_dt_alloc(void **mem, unsigned long size,
  73. unsigned long align)
  74. {
  75. void *res;
  76. *mem = PTR_ALIGN(*mem, align);
  77. res = *mem;
  78. *mem += size;
  79. return res;
  80. }
  81. /**
  82. * unflatten_dt_node - Alloc and populate a device_node from the flat tree
  83. * @blob: The parent device tree blob
  84. * @mem: Memory chunk to use for allocating device nodes and properties
  85. * @p: pointer to node in flat tree
  86. * @dad: Parent struct device_node
  87. * @allnextpp: pointer to ->allnext from last allocated device_node
  88. * @fpsize: Size of the node path up at the current depth.
  89. */
  90. static void * unflatten_dt_node(void *blob,
  91. void *mem,
  92. int *poffset,
  93. struct device_node *dad,
  94. struct device_node ***allnextpp,
  95. unsigned long fpsize)
  96. {
  97. const __be32 *p;
  98. struct device_node *np;
  99. struct property *pp, **prev_pp = NULL;
  100. const char *pathp;
  101. unsigned int l, allocl;
  102. static int depth = 0;
  103. int old_depth;
  104. int offset;
  105. int has_name = 0;
  106. int new_format = 0;
  107. pathp = fdt_get_name(blob, *poffset, &l);
  108. if (!pathp)
  109. return mem;
  110. allocl = l++;
  111. /* version 0x10 has a more compact unit name here instead of the full
  112. * path. we accumulate the full path size using "fpsize", we'll rebuild
  113. * it later. We detect this because the first character of the name is
  114. * not '/'.
  115. */
  116. if ((*pathp) != '/') {
  117. new_format = 1;
  118. if (fpsize == 0) {
  119. /* root node: special case. fpsize accounts for path
  120. * plus terminating zero. root node only has '/', so
  121. * fpsize should be 2, but we want to avoid the first
  122. * level nodes to have two '/' so we use fpsize 1 here
  123. */
  124. fpsize = 1;
  125. allocl = 2;
  126. l = 1;
  127. pathp = "";
  128. } else {
  129. /* account for '/' and path size minus terminal 0
  130. * already in 'l'
  131. */
  132. fpsize += l;
  133. allocl = fpsize;
  134. }
  135. }
  136. np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
  137. __alignof__(struct device_node));
  138. if (allnextpp) {
  139. char *fn;
  140. of_node_init(np);
  141. np->full_name = fn = ((char *)np) + sizeof(*np);
  142. if (new_format) {
  143. /* rebuild full path for new format */
  144. if (dad && dad->parent) {
  145. strcpy(fn, dad->full_name);
  146. #ifdef DEBUG
  147. if ((strlen(fn) + l + 1) != allocl) {
  148. pr_debug("%s: p: %d, l: %d, a: %d\n",
  149. pathp, (int)strlen(fn),
  150. l, allocl);
  151. }
  152. #endif
  153. fn += strlen(fn);
  154. }
  155. *(fn++) = '/';
  156. }
  157. memcpy(fn, pathp, l);
  158. prev_pp = &np->properties;
  159. **allnextpp = np;
  160. *allnextpp = &np->allnext;
  161. if (dad != NULL) {
  162. np->parent = dad;
  163. /* we temporarily use the next field as `last_child'*/
  164. if (dad->next == NULL)
  165. dad->child = np;
  166. else
  167. dad->next->sibling = np;
  168. dad->next = np;
  169. }
  170. }
  171. /* process properties */
  172. for (offset = fdt_first_property_offset(blob, *poffset);
  173. (offset >= 0);
  174. (offset = fdt_next_property_offset(blob, offset))) {
  175. const char *pname;
  176. u32 sz;
  177. if (!(p = fdt_getprop_by_offset(blob, offset, &pname, &sz))) {
  178. offset = -FDT_ERR_INTERNAL;
  179. break;
  180. }
  181. if (pname == NULL) {
  182. pr_info("Can't find property name in list !\n");
  183. break;
  184. }
  185. if (strcmp(pname, "name") == 0)
  186. has_name = 1;
  187. pp = unflatten_dt_alloc(&mem, sizeof(struct property),
  188. __alignof__(struct property));
  189. if (allnextpp) {
  190. /* We accept flattened tree phandles either in
  191. * ePAPR-style "phandle" properties, or the
  192. * legacy "linux,phandle" properties. If both
  193. * appear and have different values, things
  194. * will get weird. Don't do that. */
  195. if ((strcmp(pname, "phandle") == 0) ||
  196. (strcmp(pname, "linux,phandle") == 0)) {
  197. if (np->phandle == 0)
  198. np->phandle = be32_to_cpup(p);
  199. }
  200. /* And we process the "ibm,phandle" property
  201. * used in pSeries dynamic device tree
  202. * stuff */
  203. if (strcmp(pname, "ibm,phandle") == 0)
  204. np->phandle = be32_to_cpup(p);
  205. pp->name = (char *)pname;
  206. pp->length = sz;
  207. pp->value = (__be32 *)p;
  208. *prev_pp = pp;
  209. prev_pp = &pp->next;
  210. }
  211. }
  212. /* with version 0x10 we may not have the name property, recreate
  213. * it here from the unit name if absent
  214. */
  215. if (!has_name) {
  216. const char *p1 = pathp, *ps = pathp, *pa = NULL;
  217. int sz;
  218. while (*p1) {
  219. if ((*p1) == '@')
  220. pa = p1;
  221. if ((*p1) == '/')
  222. ps = p1 + 1;
  223. p1++;
  224. }
  225. if (pa < ps)
  226. pa = p1;
  227. sz = (pa - ps) + 1;
  228. pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
  229. __alignof__(struct property));
  230. if (allnextpp) {
  231. pp->name = "name";
  232. pp->length = sz;
  233. pp->value = pp + 1;
  234. *prev_pp = pp;
  235. prev_pp = &pp->next;
  236. memcpy(pp->value, ps, sz - 1);
  237. ((char *)pp->value)[sz - 1] = 0;
  238. pr_debug("fixed up name for %s -> %s\n", pathp,
  239. (char *)pp->value);
  240. }
  241. }
  242. if (allnextpp) {
  243. *prev_pp = NULL;
  244. np->name = of_get_property(np, "name", NULL);
  245. np->type = of_get_property(np, "device_type", NULL);
  246. if (!np->name)
  247. np->name = "<NULL>";
  248. if (!np->type)
  249. np->type = "<NULL>";
  250. }
  251. old_depth = depth;
  252. *poffset = fdt_next_node(blob, *poffset, &depth);
  253. if (depth < 0)
  254. depth = 0;
  255. while (*poffset > 0 && depth > old_depth)
  256. mem = unflatten_dt_node(blob, mem, poffset, np, allnextpp,
  257. fpsize);
  258. if (*poffset < 0 && *poffset != -FDT_ERR_NOTFOUND)
  259. pr_err("unflatten: error %d processing FDT\n", *poffset);
  260. return mem;
  261. }
  262. /**
  263. * __unflatten_device_tree - create tree of device_nodes from flat blob
  264. *
  265. * unflattens a device-tree, creating the
  266. * tree of struct device_node. It also fills the "name" and "type"
  267. * pointers of the nodes so the normal device-tree walking functions
  268. * can be used.
  269. * @blob: The blob to expand
  270. * @mynodes: The device_node tree created by the call
  271. * @dt_alloc: An allocator that provides a virtual address to memory
  272. * for the resulting tree
  273. */
  274. static void __unflatten_device_tree(void *blob,
  275. struct device_node **mynodes,
  276. void * (*dt_alloc)(u64 size, u64 align))
  277. {
  278. unsigned long size;
  279. int start;
  280. void *mem;
  281. struct device_node **allnextp = mynodes;
  282. pr_debug(" -> unflatten_device_tree()\n");
  283. if (!blob) {
  284. pr_debug("No device tree pointer\n");
  285. return;
  286. }
  287. pr_debug("Unflattening device tree:\n");
  288. pr_debug("magic: %08x\n", fdt_magic(blob));
  289. pr_debug("size: %08x\n", fdt_totalsize(blob));
  290. pr_debug("version: %08x\n", fdt_version(blob));
  291. if (fdt_check_header(blob)) {
  292. pr_err("Invalid device tree blob header\n");
  293. return;
  294. }
  295. /* First pass, scan for size */
  296. start = 0;
  297. size = (unsigned long)unflatten_dt_node(blob, NULL, &start, NULL, NULL, 0);
  298. size = ALIGN(size, 4);
  299. pr_debug(" size is %lx, allocating...\n", size);
  300. /* Allocate memory for the expanded device tree */
  301. mem = dt_alloc(size + 4, __alignof__(struct device_node));
  302. memset(mem, 0, size);
  303. *(__be32 *)(mem + size) = cpu_to_be32(0xdeadbeef);
  304. pr_debug(" unflattening %p...\n", mem);
  305. /* Second pass, do actual unflattening */
  306. start = 0;
  307. unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0);
  308. if (be32_to_cpup(mem + size) != 0xdeadbeef)
  309. pr_warning("End of tree marker overwritten: %08x\n",
  310. be32_to_cpup(mem + size));
  311. *allnextp = NULL;
  312. pr_debug(" <- unflatten_device_tree()\n");
  313. }
  314. static void *kernel_tree_alloc(u64 size, u64 align)
  315. {
  316. return kzalloc(size, GFP_KERNEL);
  317. }
  318. /**
  319. * of_fdt_unflatten_tree - create tree of device_nodes from flat blob
  320. *
  321. * unflattens the device-tree passed by the firmware, creating the
  322. * tree of struct device_node. It also fills the "name" and "type"
  323. * pointers of the nodes so the normal device-tree walking functions
  324. * can be used.
  325. */
  326. void of_fdt_unflatten_tree(unsigned long *blob,
  327. struct device_node **mynodes)
  328. {
  329. __unflatten_device_tree(blob, mynodes, &kernel_tree_alloc);
  330. }
  331. EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree);
  332. /* Everything below here references initial_boot_params directly. */
  333. int __initdata dt_root_addr_cells;
  334. int __initdata dt_root_size_cells;
  335. void *initial_boot_params;
  336. #ifdef CONFIG_OF_EARLY_FLATTREE
  337. /**
  338. * res_mem_reserve_reg() - reserve all memory described in 'reg' property
  339. */
  340. static int __init __reserved_mem_reserve_reg(unsigned long node,
  341. const char *uname)
  342. {
  343. int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
  344. phys_addr_t base, size;
  345. int len;
  346. const __be32 *prop;
  347. int nomap, first = 1;
  348. prop = of_get_flat_dt_prop(node, "reg", &len);
  349. if (!prop)
  350. return -ENOENT;
  351. if (len && len % t_len != 0) {
  352. pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n",
  353. uname);
  354. return -EINVAL;
  355. }
  356. nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
  357. while (len >= t_len) {
  358. base = dt_mem_next_cell(dt_root_addr_cells, &prop);
  359. size = dt_mem_next_cell(dt_root_size_cells, &prop);
  360. if (base && size &&
  361. early_init_dt_reserve_memory_arch(base, size, nomap) == 0)
  362. pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n",
  363. uname, &base, (unsigned long)size / SZ_1M);
  364. else
  365. pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %ld MiB\n",
  366. uname, &base, (unsigned long)size / SZ_1M);
  367. len -= t_len;
  368. if (first) {
  369. fdt_reserved_mem_save_node(node, uname, base, size);
  370. first = 0;
  371. }
  372. }
  373. return 0;
  374. }
  375. /**
  376. * __reserved_mem_check_root() - check if #size-cells, #address-cells provided
  377. * in /reserved-memory matches the values supported by the current implementation,
  378. * also check if ranges property has been provided
  379. */
  380. static int __init __reserved_mem_check_root(unsigned long node)
  381. {
  382. const __be32 *prop;
  383. prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
  384. if (!prop || be32_to_cpup(prop) != dt_root_size_cells)
  385. return -EINVAL;
  386. prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
  387. if (!prop || be32_to_cpup(prop) != dt_root_addr_cells)
  388. return -EINVAL;
  389. prop = of_get_flat_dt_prop(node, "ranges", NULL);
  390. if (!prop)
  391. return -EINVAL;
  392. return 0;
  393. }
  394. /**
  395. * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory
  396. */
  397. static int __init __fdt_scan_reserved_mem(unsigned long node, const char *uname,
  398. int depth, void *data)
  399. {
  400. static int found;
  401. const char *status;
  402. int err;
  403. if (!found && depth == 1 && strcmp(uname, "reserved-memory") == 0) {
  404. if (__reserved_mem_check_root(node) != 0) {
  405. pr_err("Reserved memory: unsupported node format, ignoring\n");
  406. /* break scan */
  407. return 1;
  408. }
  409. found = 1;
  410. /* scan next node */
  411. return 0;
  412. } else if (!found) {
  413. /* scan next node */
  414. return 0;
  415. } else if (found && depth < 2) {
  416. /* scanning of /reserved-memory has been finished */
  417. return 1;
  418. }
  419. status = of_get_flat_dt_prop(node, "status", NULL);
  420. if (status && strcmp(status, "okay") != 0 && strcmp(status, "ok") != 0)
  421. return 0;
  422. err = __reserved_mem_reserve_reg(node, uname);
  423. if (err == -ENOENT && of_get_flat_dt_prop(node, "size", NULL))
  424. fdt_reserved_mem_save_node(node, uname, 0, 0);
  425. /* scan next node */
  426. return 0;
  427. }
  428. /**
  429. * early_init_fdt_scan_reserved_mem() - create reserved memory regions
  430. *
  431. * This function grabs memory from early allocator for device exclusive use
  432. * defined in device tree structures. It should be called by arch specific code
  433. * once the early allocator (i.e. memblock) has been fully activated.
  434. */
  435. void __init early_init_fdt_scan_reserved_mem(void)
  436. {
  437. int n;
  438. u64 base, size;
  439. if (!initial_boot_params)
  440. return;
  441. /* Reserve the dtb region */
  442. early_init_dt_reserve_memory_arch(__pa(initial_boot_params),
  443. fdt_totalsize(initial_boot_params),
  444. 0);
  445. /* Process header /memreserve/ fields */
  446. for (n = 0; ; n++) {
  447. fdt_get_mem_rsv(initial_boot_params, n, &base, &size);
  448. if (!size)
  449. break;
  450. early_init_dt_reserve_memory_arch(base, size, 0);
  451. }
  452. of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);
  453. fdt_init_reserved_mem();
  454. }
  455. /**
  456. * of_scan_flat_dt - scan flattened tree blob and call callback on each.
  457. * @it: callback function
  458. * @data: context data pointer
  459. *
  460. * This function is used to scan the flattened device-tree, it is
  461. * used to extract the memory information at boot before we can
  462. * unflatten the tree
  463. */
  464. int __init of_scan_flat_dt(int (*it)(unsigned long node,
  465. const char *uname, int depth,
  466. void *data),
  467. void *data)
  468. {
  469. const void *blob = initial_boot_params;
  470. const char *pathp;
  471. int offset, rc = 0, depth = -1;
  472. for (offset = fdt_next_node(blob, -1, &depth);
  473. offset >= 0 && depth >= 0 && !rc;
  474. offset = fdt_next_node(blob, offset, &depth)) {
  475. pathp = fdt_get_name(blob, offset, NULL);
  476. if (*pathp == '/')
  477. pathp = kbasename(pathp);
  478. rc = it(offset, pathp, depth, data);
  479. }
  480. return rc;
  481. }
  482. /**
  483. * of_get_flat_dt_root - find the root node in the flat blob
  484. */
  485. unsigned long __init of_get_flat_dt_root(void)
  486. {
  487. return 0;
  488. }
  489. /**
  490. * of_get_flat_dt_size - Return the total size of the FDT
  491. */
  492. int __init of_get_flat_dt_size(void)
  493. {
  494. return fdt_totalsize(initial_boot_params);
  495. }
  496. /**
  497. * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
  498. *
  499. * This function can be used within scan_flattened_dt callback to get
  500. * access to properties
  501. */
  502. const void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
  503. int *size)
  504. {
  505. return fdt_getprop(initial_boot_params, node, name, size);
  506. }
  507. /**
  508. * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
  509. * @node: node to test
  510. * @compat: compatible string to compare with compatible list.
  511. */
  512. int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
  513. {
  514. return of_fdt_is_compatible(initial_boot_params, node, compat);
  515. }
  516. /**
  517. * of_flat_dt_match - Return true if node matches a list of compatible values
  518. */
  519. int __init of_flat_dt_match(unsigned long node, const char *const *compat)
  520. {
  521. return of_fdt_match(initial_boot_params, node, compat);
  522. }
  523. struct fdt_scan_status {
  524. const char *name;
  525. int namelen;
  526. int depth;
  527. int found;
  528. int (*iterator)(unsigned long node, const char *uname, int depth, void *data);
  529. void *data;
  530. };
  531. const char * __init of_flat_dt_get_machine_name(void)
  532. {
  533. const char *name;
  534. unsigned long dt_root = of_get_flat_dt_root();
  535. name = of_get_flat_dt_prop(dt_root, "model", NULL);
  536. if (!name)
  537. name = of_get_flat_dt_prop(dt_root, "compatible", NULL);
  538. return name;
  539. }
  540. /**
  541. * of_flat_dt_match_machine - Iterate match tables to find matching machine.
  542. *
  543. * @default_match: A machine specific ptr to return in case of no match.
  544. * @get_next_compat: callback function to return next compatible match table.
  545. *
  546. * Iterate through machine match tables to find the best match for the machine
  547. * compatible string in the FDT.
  548. */
  549. const void * __init of_flat_dt_match_machine(const void *default_match,
  550. const void * (*get_next_compat)(const char * const**))
  551. {
  552. const void *data = NULL;
  553. const void *best_data = default_match;
  554. const char *const *compat;
  555. unsigned long dt_root;
  556. unsigned int best_score = ~1, score = 0;
  557. dt_root = of_get_flat_dt_root();
  558. while ((data = get_next_compat(&compat))) {
  559. score = of_flat_dt_match(dt_root, compat);
  560. if (score > 0 && score < best_score) {
  561. best_data = data;
  562. best_score = score;
  563. }
  564. }
  565. if (!best_data) {
  566. const char *prop;
  567. int size;
  568. pr_err("\n unrecognized device tree list:\n[ ");
  569. prop = of_get_flat_dt_prop(dt_root, "compatible", &size);
  570. if (prop) {
  571. while (size > 0) {
  572. printk("'%s' ", prop);
  573. size -= strlen(prop) + 1;
  574. prop += strlen(prop) + 1;
  575. }
  576. }
  577. printk("]\n\n");
  578. return NULL;
  579. }
  580. pr_info("Machine model: %s\n", of_flat_dt_get_machine_name());
  581. return best_data;
  582. }
  583. #ifdef CONFIG_BLK_DEV_INITRD
  584. /**
  585. * early_init_dt_check_for_initrd - Decode initrd location from flat tree
  586. * @node: reference to node containing initrd location ('chosen')
  587. */
  588. static void __init early_init_dt_check_for_initrd(unsigned long node)
  589. {
  590. u64 start, end;
  591. int len;
  592. const __be32 *prop;
  593. pr_debug("Looking for initrd properties... ");
  594. prop = of_get_flat_dt_prop(node, "linux,initrd-start", &len);
  595. if (!prop)
  596. return;
  597. start = of_read_number(prop, len/4);
  598. prop = of_get_flat_dt_prop(node, "linux,initrd-end", &len);
  599. if (!prop)
  600. return;
  601. end = of_read_number(prop, len/4);
  602. initrd_start = (unsigned long)__va(start);
  603. initrd_end = (unsigned long)__va(end);
  604. initrd_below_start_ok = 1;
  605. pr_debug("initrd_start=0x%llx initrd_end=0x%llx\n",
  606. (unsigned long long)start, (unsigned long long)end);
  607. }
  608. #else
  609. static inline void early_init_dt_check_for_initrd(unsigned long node)
  610. {
  611. }
  612. #endif /* CONFIG_BLK_DEV_INITRD */
  613. #ifdef CONFIG_SERIAL_EARLYCON
  614. extern struct of_device_id __earlycon_of_table[];
  615. int __init early_init_dt_scan_chosen_serial(void)
  616. {
  617. int offset;
  618. const char *p;
  619. int l;
  620. const struct of_device_id *match = __earlycon_of_table;
  621. const void *fdt = initial_boot_params;
  622. offset = fdt_path_offset(fdt, "/chosen");
  623. if (offset < 0)
  624. offset = fdt_path_offset(fdt, "/chosen@0");
  625. if (offset < 0)
  626. return -ENOENT;
  627. p = fdt_getprop(fdt, offset, "stdout-path", &l);
  628. if (!p)
  629. p = fdt_getprop(fdt, offset, "linux,stdout-path", &l);
  630. if (!p || !l)
  631. return -ENOENT;
  632. /* Get the node specified by stdout-path */
  633. offset = fdt_path_offset(fdt, p);
  634. if (offset < 0)
  635. return -ENODEV;
  636. while (match->compatible) {
  637. unsigned long addr;
  638. if (fdt_node_check_compatible(fdt, offset, match->compatible)) {
  639. match++;
  640. continue;
  641. }
  642. addr = fdt_translate_address(fdt, offset);
  643. if (!addr)
  644. return -ENXIO;
  645. of_setup_earlycon(addr, match->data);
  646. return 0;
  647. }
  648. return -ENODEV;
  649. }
  650. static int __init setup_of_earlycon(char *buf)
  651. {
  652. if (buf)
  653. return 0;
  654. return early_init_dt_scan_chosen_serial();
  655. }
  656. early_param("earlycon", setup_of_earlycon);
  657. #endif
  658. /**
  659. * early_init_dt_scan_root - fetch the top level address and size cells
  660. */
  661. int __init early_init_dt_scan_root(unsigned long node, const char *uname,
  662. int depth, void *data)
  663. {
  664. const __be32 *prop;
  665. if (depth != 0)
  666. return 0;
  667. dt_root_size_cells = OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
  668. dt_root_addr_cells = OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
  669. prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
  670. if (prop)
  671. dt_root_size_cells = be32_to_cpup(prop);
  672. pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
  673. prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
  674. if (prop)
  675. dt_root_addr_cells = be32_to_cpup(prop);
  676. pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
  677. /* break now */
  678. return 1;
  679. }
  680. u64 __init dt_mem_next_cell(int s, const __be32 **cellp)
  681. {
  682. const __be32 *p = *cellp;
  683. *cellp = p + s;
  684. return of_read_number(p, s);
  685. }
  686. /**
  687. * early_init_dt_scan_memory - Look for an parse memory nodes
  688. */
  689. int __init early_init_dt_scan_memory(unsigned long node, const char *uname,
  690. int depth, void *data)
  691. {
  692. const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
  693. const __be32 *reg, *endp;
  694. int l;
  695. /* We are scanning "memory" nodes only */
  696. if (type == NULL) {
  697. /*
  698. * The longtrail doesn't have a device_type on the
  699. * /memory node, so look for the node called /memory@0.
  700. */
  701. if (!IS_ENABLED(CONFIG_PPC32) || depth != 1 || strcmp(uname, "memory@0") != 0)
  702. return 0;
  703. } else if (strcmp(type, "memory") != 0)
  704. return 0;
  705. reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
  706. if (reg == NULL)
  707. reg = of_get_flat_dt_prop(node, "reg", &l);
  708. if (reg == NULL)
  709. return 0;
  710. endp = reg + (l / sizeof(__be32));
  711. pr_debug("memory scan node %s, reg size %d, data: %x %x %x %x,\n",
  712. uname, l, reg[0], reg[1], reg[2], reg[3]);
  713. while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
  714. u64 base, size;
  715. base = dt_mem_next_cell(dt_root_addr_cells, &reg);
  716. size = dt_mem_next_cell(dt_root_size_cells, &reg);
  717. if (size == 0)
  718. continue;
  719. pr_debug(" - %llx , %llx\n", (unsigned long long)base,
  720. (unsigned long long)size);
  721. early_init_dt_add_memory_arch(base, size);
  722. }
  723. return 0;
  724. }
  725. int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
  726. int depth, void *data)
  727. {
  728. int l;
  729. const char *p;
  730. pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
  731. if (depth != 1 || !data ||
  732. (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
  733. return 0;
  734. early_init_dt_check_for_initrd(node);
  735. /* Retrieve command line */
  736. p = of_get_flat_dt_prop(node, "bootargs", &l);
  737. if (p != NULL && l > 0)
  738. strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));
  739. /*
  740. * CONFIG_CMDLINE is meant to be a default in case nothing else
  741. * managed to set the command line, unless CONFIG_CMDLINE_FORCE
  742. * is set in which case we override whatever was found earlier.
  743. */
  744. #ifdef CONFIG_CMDLINE
  745. #ifndef CONFIG_CMDLINE_FORCE
  746. if (!((char *)data)[0])
  747. #endif
  748. strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
  749. #endif /* CONFIG_CMDLINE */
  750. pr_debug("Command line is: %s\n", (char*)data);
  751. /* break now */
  752. return 1;
  753. }
  754. #ifdef CONFIG_HAVE_MEMBLOCK
  755. void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
  756. {
  757. const u64 phys_offset = __pa(PAGE_OFFSET);
  758. base &= PAGE_MASK;
  759. size &= PAGE_MASK;
  760. if (base + size < phys_offset) {
  761. pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
  762. base, base + size);
  763. return;
  764. }
  765. if (base < phys_offset) {
  766. pr_warning("Ignoring memory range 0x%llx - 0x%llx\n",
  767. base, phys_offset);
  768. size -= phys_offset - base;
  769. base = phys_offset;
  770. }
  771. memblock_add(base, size);
  772. }
  773. int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
  774. phys_addr_t size, bool nomap)
  775. {
  776. if (memblock_is_region_reserved(base, size))
  777. return -EBUSY;
  778. if (nomap)
  779. return memblock_remove(base, size);
  780. return memblock_reserve(base, size);
  781. }
  782. /*
  783. * called from unflatten_device_tree() to bootstrap devicetree itself
  784. * Architectures can override this definition if memblock isn't used
  785. */
  786. void * __init __weak early_init_dt_alloc_memory_arch(u64 size, u64 align)
  787. {
  788. return __va(memblock_alloc(size, align));
  789. }
  790. #else
  791. int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
  792. phys_addr_t size, bool nomap)
  793. {
  794. pr_err("Reserved memory not supported, ignoring range 0x%pa - 0x%pa%s\n",
  795. &base, &size, nomap ? " (nomap)" : "");
  796. return -ENOSYS;
  797. }
  798. #endif
  799. bool __init early_init_dt_scan(void *params)
  800. {
  801. if (!params)
  802. return false;
  803. /* Setup flat device-tree pointer */
  804. initial_boot_params = params;
  805. /* check device tree validity */
  806. if (fdt_check_header(params)) {
  807. initial_boot_params = NULL;
  808. return false;
  809. }
  810. /* Retrieve various information from the /chosen node */
  811. of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
  812. /* Initialize {size,address}-cells info */
  813. of_scan_flat_dt(early_init_dt_scan_root, NULL);
  814. /* Setup memory, calling early_init_dt_add_memory_arch */
  815. of_scan_flat_dt(early_init_dt_scan_memory, NULL);
  816. return true;
  817. }
  818. /**
  819. * unflatten_device_tree - create tree of device_nodes from flat blob
  820. *
  821. * unflattens the device-tree passed by the firmware, creating the
  822. * tree of struct device_node. It also fills the "name" and "type"
  823. * pointers of the nodes so the normal device-tree walking functions
  824. * can be used.
  825. */
  826. void __init unflatten_device_tree(void)
  827. {
  828. __unflatten_device_tree(initial_boot_params, &of_allnodes,
  829. early_init_dt_alloc_memory_arch);
  830. /* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */
  831. of_alias_scan(early_init_dt_alloc_memory_arch);
  832. }
  833. /**
  834. * unflatten_and_copy_device_tree - copy and create tree of device_nodes from flat blob
  835. *
  836. * Copies and unflattens the device-tree passed by the firmware, creating the
  837. * tree of struct device_node. It also fills the "name" and "type"
  838. * pointers of the nodes so the normal device-tree walking functions
  839. * can be used. This should only be used when the FDT memory has not been
  840. * reserved such is the case when the FDT is built-in to the kernel init
  841. * section. If the FDT memory is reserved already then unflatten_device_tree
  842. * should be used instead.
  843. */
  844. void __init unflatten_and_copy_device_tree(void)
  845. {
  846. int size;
  847. void *dt;
  848. if (!initial_boot_params) {
  849. pr_warn("No valid device tree found, continuing without\n");
  850. return;
  851. }
  852. size = fdt_totalsize(initial_boot_params);
  853. dt = early_init_dt_alloc_memory_arch(size,
  854. roundup_pow_of_two(FDT_V17_SIZE));
  855. if (dt) {
  856. memcpy(dt, initial_boot_params, size);
  857. initial_boot_params = dt;
  858. }
  859. unflatten_device_tree();
  860. }
  861. #if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
  862. static struct debugfs_blob_wrapper flat_dt_blob;
  863. static int __init of_flat_dt_debugfs_export_fdt(void)
  864. {
  865. struct dentry *d = debugfs_create_dir("device-tree", NULL);
  866. if (!d)
  867. return -ENOENT;
  868. flat_dt_blob.data = initial_boot_params;
  869. flat_dt_blob.size = fdt_totalsize(initial_boot_params);
  870. d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
  871. d, &flat_dt_blob);
  872. if (!d)
  873. return -ENOENT;
  874. return 0;
  875. }
  876. module_init(of_flat_dt_debugfs_export_fdt);
  877. #endif
  878. #endif /* CONFIG_OF_EARLY_FLATTREE */