spl_fit.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2016 Google, Inc
  4. * Written by Simon Glass <sjg@chromium.org>
  5. */
  6. #include <common.h>
  7. #include <errno.h>
  8. #include <fpga.h>
  9. #include <gzip.h>
  10. #include <image.h>
  11. #include <log.h>
  12. #include <memalign.h>
  13. #include <mapmem.h>
  14. #include <spl.h>
  15. #include <sysinfo.h>
  16. #include <asm/cache.h>
  17. #include <asm/global_data.h>
  18. #include <linux/libfdt.h>
  19. DECLARE_GLOBAL_DATA_PTR;
  20. struct spl_fit_info {
  21. const void *fit; /* Pointer to a valid FIT blob */
  22. size_t ext_data_offset; /* Offset to FIT external data (end of FIT) */
  23. int images_node; /* FDT offset to "/images" node */
  24. int conf_node; /* FDT offset to selected configuration node */
  25. };
  26. __weak ulong board_spl_fit_size_align(ulong size)
  27. {
  28. return size;
  29. }
  30. static int find_node_from_desc(const void *fit, int node, const char *str)
  31. {
  32. int child;
  33. if (node < 0)
  34. return -EINVAL;
  35. /* iterate the FIT nodes and find a matching description */
  36. for (child = fdt_first_subnode(fit, node); child >= 0;
  37. child = fdt_next_subnode(fit, child)) {
  38. int len;
  39. const char *desc = fdt_getprop(fit, child, "description", &len);
  40. if (!desc)
  41. continue;
  42. if (!strcmp(desc, str))
  43. return child;
  44. }
  45. return -ENOENT;
  46. }
  47. /**
  48. * spl_fit_get_image_name(): By using the matching configuration subnode,
  49. * retrieve the name of an image, specified by a property name and an index
  50. * into that.
  51. * @fit: Pointer to the FDT blob.
  52. * @images: Offset of the /images subnode.
  53. * @type: Name of the property within the configuration subnode.
  54. * @index: Index into the list of strings in this property.
  55. * @outname: Name of the image
  56. *
  57. * Return: 0 on success, or a negative error number
  58. */
  59. static int spl_fit_get_image_name(const struct spl_fit_info *ctx,
  60. const char *type, int index,
  61. const char **outname)
  62. {
  63. struct udevice *sysinfo;
  64. const char *name, *str;
  65. __maybe_unused int node;
  66. int len, i;
  67. bool found = true;
  68. name = fdt_getprop(ctx->fit, ctx->conf_node, type, &len);
  69. if (!name) {
  70. debug("cannot find property '%s': %d\n", type, len);
  71. return -EINVAL;
  72. }
  73. str = name;
  74. for (i = 0; i < index; i++) {
  75. str = strchr(str, '\0') + 1;
  76. if (!str || (str - name >= len)) {
  77. found = false;
  78. break;
  79. }
  80. }
  81. if (!found && CONFIG_IS_ENABLED(SYSINFO) && !sysinfo_get(&sysinfo)) {
  82. int rc;
  83. /*
  84. * no string in the property for this index. Check if the
  85. * sysinfo-level code can supply one.
  86. */
  87. rc = sysinfo_detect(sysinfo);
  88. if (rc)
  89. return rc;
  90. rc = sysinfo_get_fit_loadable(sysinfo, index - i - 1, type,
  91. &str);
  92. if (rc && rc != -ENOENT)
  93. return rc;
  94. if (!rc) {
  95. /*
  96. * The sysinfo provided a name for a loadable.
  97. * Try to match it against the description properties
  98. * first. If no matching node is found, use it as a
  99. * node name.
  100. */
  101. int node;
  102. int images = fdt_path_offset(ctx->fit, FIT_IMAGES_PATH);
  103. node = find_node_from_desc(ctx->fit, images, str);
  104. if (node > 0)
  105. str = fdt_get_name(ctx->fit, node, NULL);
  106. found = true;
  107. }
  108. }
  109. if (!found) {
  110. debug("no string for index %d\n", index);
  111. return -E2BIG;
  112. }
  113. *outname = str;
  114. return 0;
  115. }
  116. /**
  117. * spl_fit_get_image_node(): By using the matching configuration subnode,
  118. * retrieve the name of an image, specified by a property name and an index
  119. * into that.
  120. * @fit: Pointer to the FDT blob.
  121. * @images: Offset of the /images subnode.
  122. * @type: Name of the property within the configuration subnode.
  123. * @index: Index into the list of strings in this property.
  124. *
  125. * Return: the node offset of the respective image node or a negative
  126. * error number.
  127. */
  128. static int spl_fit_get_image_node(const struct spl_fit_info *ctx,
  129. const char *type, int index)
  130. {
  131. const char *str;
  132. int err;
  133. int node;
  134. err = spl_fit_get_image_name(ctx, type, index, &str);
  135. if (err)
  136. return err;
  137. debug("%s: '%s'\n", type, str);
  138. node = fdt_subnode_offset(ctx->fit, ctx->images_node, str);
  139. if (node < 0) {
  140. pr_err("cannot find image node '%s': %d\n", str, node);
  141. return -EINVAL;
  142. }
  143. return node;
  144. }
  145. static int get_aligned_image_offset(struct spl_load_info *info, int offset)
  146. {
  147. /*
  148. * If it is a FS read, get the first address before offset which is
  149. * aligned to ARCH_DMA_MINALIGN. If it is raw read return the
  150. * block number to which offset belongs.
  151. */
  152. if (info->filename)
  153. return offset & ~(ARCH_DMA_MINALIGN - 1);
  154. return offset / info->bl_len;
  155. }
  156. static int get_aligned_image_overhead(struct spl_load_info *info, int offset)
  157. {
  158. /*
  159. * If it is a FS read, get the difference between the offset and
  160. * the first address before offset which is aligned to
  161. * ARCH_DMA_MINALIGN. If it is raw read return the offset within the
  162. * block.
  163. */
  164. if (info->filename)
  165. return offset & (ARCH_DMA_MINALIGN - 1);
  166. return offset % info->bl_len;
  167. }
  168. static int get_aligned_image_size(struct spl_load_info *info, int data_size,
  169. int offset)
  170. {
  171. data_size = data_size + get_aligned_image_overhead(info, offset);
  172. if (info->filename)
  173. return data_size;
  174. return (data_size + info->bl_len - 1) / info->bl_len;
  175. }
  176. /**
  177. * spl_load_fit_image(): load the image described in a certain FIT node
  178. * @info: points to information about the device to load data from
  179. * @sector: the start sector of the FIT image on the device
  180. * @ctx: points to the FIT context structure
  181. * @node: offset of the DT node describing the image to load (relative
  182. * to @fit)
  183. * @image_info: will be filled with information about the loaded image
  184. * If the FIT node does not contain a "load" (address) property,
  185. * the image gets loaded to the address pointed to by the
  186. * load_addr member in this struct, if load_addr is not 0
  187. *
  188. * Return: 0 on success or a negative error number.
  189. */
  190. static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
  191. const struct spl_fit_info *ctx, int node,
  192. struct spl_image_info *image_info)
  193. {
  194. int offset;
  195. size_t length;
  196. int len;
  197. ulong size;
  198. ulong load_addr;
  199. void *load_ptr;
  200. void *src;
  201. ulong overhead;
  202. int nr_sectors;
  203. uint8_t image_comp = -1, type = -1;
  204. const void *data;
  205. const void *fit = ctx->fit;
  206. bool external_data = false;
  207. if (IS_ENABLED(CONFIG_SPL_FPGA) ||
  208. (IS_ENABLED(CONFIG_SPL_OS_BOOT) && IS_ENABLED(CONFIG_SPL_GZIP))) {
  209. if (fit_image_get_type(fit, node, &type))
  210. puts("Cannot get image type.\n");
  211. else
  212. debug("%s ", genimg_get_type_name(type));
  213. }
  214. if (IS_ENABLED(CONFIG_SPL_GZIP)) {
  215. fit_image_get_comp(fit, node, &image_comp);
  216. debug("%s ", genimg_get_comp_name(image_comp));
  217. }
  218. if (fit_image_get_load(fit, node, &load_addr)) {
  219. if (!image_info->load_addr) {
  220. printf("Can't load %s: No load address and no buffer\n",
  221. fit_get_name(fit, node, NULL));
  222. return -ENOBUFS;
  223. }
  224. load_addr = image_info->load_addr;
  225. }
  226. if (!fit_image_get_data_position(fit, node, &offset)) {
  227. external_data = true;
  228. } else if (!fit_image_get_data_offset(fit, node, &offset)) {
  229. offset += ctx->ext_data_offset;
  230. external_data = true;
  231. }
  232. if (external_data) {
  233. void *src_ptr;
  234. /* External data */
  235. if (fit_image_get_data_size(fit, node, &len))
  236. return -ENOENT;
  237. /* Dont bother to copy 0 byte data, but warn, though */
  238. if (!len) {
  239. log_warning("%s: Skip load '%s': image size is 0!\n",
  240. __func__, fit_get_name(fit, node, NULL));
  241. return 0;
  242. }
  243. src_ptr = map_sysmem(ALIGN(load_addr, ARCH_DMA_MINALIGN), len);
  244. length = len;
  245. overhead = get_aligned_image_overhead(info, offset);
  246. nr_sectors = get_aligned_image_size(info, length, offset);
  247. if (info->read(info,
  248. sector + get_aligned_image_offset(info, offset),
  249. nr_sectors, src_ptr) != nr_sectors)
  250. return -EIO;
  251. debug("External data: dst=%p, offset=%x, size=%lx\n",
  252. src_ptr, offset, (unsigned long)length);
  253. src = src_ptr + overhead;
  254. } else {
  255. /* Embedded data */
  256. if (fit_image_get_data(fit, node, &data, &length)) {
  257. puts("Cannot get image data/size\n");
  258. return -ENOENT;
  259. }
  260. debug("Embedded data: dst=%lx, size=%lx\n", load_addr,
  261. (unsigned long)length);
  262. src = (void *)data; /* cast away const */
  263. }
  264. if (CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
  265. printf("## Checking hash(es) for Image %s ... ",
  266. fit_get_name(fit, node, NULL));
  267. if (!fit_image_verify_with_data(fit, node, gd_fdt_blob(), src,
  268. length))
  269. return -EPERM;
  270. puts("OK\n");
  271. }
  272. if (CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS))
  273. board_fit_image_post_process(fit, node, &src, &length);
  274. load_ptr = map_sysmem(load_addr, length);
  275. if (IS_ENABLED(CONFIG_SPL_GZIP) && image_comp == IH_COMP_GZIP) {
  276. size = length;
  277. if (gunzip(load_ptr, CONFIG_SYS_BOOTM_LEN, src, &size)) {
  278. puts("Uncompressing error\n");
  279. return -EIO;
  280. }
  281. length = size;
  282. } else {
  283. memcpy(load_ptr, src, length);
  284. }
  285. if (image_info) {
  286. ulong entry_point;
  287. image_info->load_addr = load_addr;
  288. image_info->size = length;
  289. if (!fit_image_get_entry(fit, node, &entry_point))
  290. image_info->entry_point = entry_point;
  291. else
  292. image_info->entry_point = FDT_ERROR;
  293. }
  294. return 0;
  295. }
  296. static bool os_takes_devicetree(uint8_t os)
  297. {
  298. switch (os) {
  299. case IH_OS_U_BOOT:
  300. return true;
  301. case IH_OS_LINUX:
  302. return IS_ENABLED(CONFIG_SPL_OS_BOOT);
  303. default:
  304. return false;
  305. }
  306. }
  307. static int spl_fit_append_fdt(struct spl_image_info *spl_image,
  308. struct spl_load_info *info, ulong sector,
  309. const struct spl_fit_info *ctx)
  310. {
  311. struct spl_image_info image_info;
  312. int node, ret = 0, index = 0;
  313. /*
  314. * Use the address following the image as target address for the
  315. * device tree.
  316. */
  317. image_info.load_addr = spl_image->load_addr + spl_image->size;
  318. /* Figure out which device tree the board wants to use */
  319. node = spl_fit_get_image_node(ctx, FIT_FDT_PROP, index++);
  320. if (node < 0) {
  321. debug("%s: cannot find FDT node\n", __func__);
  322. /*
  323. * U-Boot did not find a device tree inside the FIT image. Use
  324. * the U-Boot device tree instead.
  325. */
  326. if (gd->fdt_blob)
  327. memcpy((void *)image_info.load_addr, gd->fdt_blob,
  328. fdt_totalsize(gd->fdt_blob));
  329. else
  330. return node;
  331. } else {
  332. ret = spl_load_fit_image(info, sector, ctx, node,
  333. &image_info);
  334. if (ret < 0)
  335. return ret;
  336. }
  337. /* Make the load-address of the FDT available for the SPL framework */
  338. spl_image->fdt_addr = map_sysmem(image_info.load_addr, 0);
  339. if (CONFIG_IS_ENABLED(FIT_IMAGE_TINY))
  340. return 0;
  341. #if CONFIG_IS_ENABLED(LOAD_FIT_APPLY_OVERLAY)
  342. void *tmpbuffer = NULL;
  343. for (; ; index++) {
  344. node = spl_fit_get_image_node(ctx, FIT_FDT_PROP, index);
  345. if (node == -E2BIG) {
  346. debug("%s: No additional FDT node\n", __func__);
  347. break;
  348. } else if (node < 0) {
  349. debug("%s: unable to find FDT node %d\n",
  350. __func__, index);
  351. continue;
  352. }
  353. if (!tmpbuffer) {
  354. /*
  355. * allocate memory to store the DT overlay
  356. * before it is applied. It may not be used
  357. * depending on how the overlay is stored, so
  358. * don't fail yet if the allocation failed.
  359. */
  360. size_t size = CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ;
  361. tmpbuffer = malloc_cache_aligned(size);
  362. if (!tmpbuffer)
  363. debug("%s: unable to allocate space for overlays\n",
  364. __func__);
  365. }
  366. image_info.load_addr = (ulong)tmpbuffer;
  367. ret = spl_load_fit_image(info, sector, ctx,
  368. node, &image_info);
  369. if (ret < 0)
  370. break;
  371. /* Make room in FDT for changes from the overlay */
  372. ret = fdt_increase_size(spl_image->fdt_addr,
  373. image_info.size);
  374. if (ret < 0)
  375. break;
  376. ret = fdt_overlay_apply_verbose(spl_image->fdt_addr,
  377. (void *)image_info.load_addr);
  378. if (ret) {
  379. pr_err("failed to apply DT overlay %s\n",
  380. fit_get_name(ctx->fit, node, NULL));
  381. break;
  382. }
  383. debug("%s: DT overlay %s applied\n", __func__,
  384. fit_get_name(ctx->fit, node, NULL));
  385. }
  386. free(tmpbuffer);
  387. if (ret)
  388. return ret;
  389. #endif
  390. /* Try to make space, so we can inject details on the loadables */
  391. ret = fdt_shrink_to_minimum(spl_image->fdt_addr, 8192);
  392. if (ret < 0)
  393. return ret;
  394. return ret;
  395. }
  396. static int spl_fit_record_loadable(const struct spl_fit_info *ctx, int index,
  397. void *blob, struct spl_image_info *image)
  398. {
  399. int ret = 0;
  400. const char *name;
  401. int node;
  402. if (CONFIG_IS_ENABLED(FIT_IMAGE_TINY))
  403. return 0;
  404. ret = spl_fit_get_image_name(ctx, "loadables", index, &name);
  405. if (ret < 0)
  406. return ret;
  407. node = spl_fit_get_image_node(ctx, "loadables", index);
  408. ret = fdt_record_loadable(blob, index, name, image->load_addr,
  409. image->size, image->entry_point,
  410. fdt_getprop(ctx->fit, node, "type", NULL),
  411. fdt_getprop(ctx->fit, node, "os", NULL),
  412. fdt_getprop(ctx->fit, node, "arch", NULL));
  413. return ret;
  414. }
  415. static int spl_fit_image_is_fpga(const void *fit, int node)
  416. {
  417. const char *type;
  418. if (!IS_ENABLED(CONFIG_SPL_FPGA))
  419. return 0;
  420. type = fdt_getprop(fit, node, FIT_TYPE_PROP, NULL);
  421. if (!type)
  422. return 0;
  423. return !strcmp(type, "fpga");
  424. }
  425. static int spl_fit_image_get_os(const void *fit, int noffset, uint8_t *os)
  426. {
  427. if (!CONFIG_IS_ENABLED(FIT_IMAGE_TINY) || CONFIG_IS_ENABLED(OS_BOOT))
  428. return fit_image_get_os(fit, noffset, os);
  429. const char *name = fdt_getprop(fit, noffset, FIT_OS_PROP, NULL);
  430. if (!name)
  431. return -ENOENT;
  432. /*
  433. * We don't care what the type of the image actually is,
  434. * only whether or not it is U-Boot. This saves some
  435. * space by omitting the large table of OS types.
  436. */
  437. if (!strcmp(name, "u-boot"))
  438. *os = IH_OS_U_BOOT;
  439. else
  440. *os = IH_OS_INVALID;
  441. return 0;
  442. }
  443. /*
  444. * The purpose of the FIT load buffer is to provide a memory location that is
  445. * independent of the load address of any FIT component.
  446. */
  447. static void *spl_get_fit_load_buffer(size_t size)
  448. {
  449. void *buf;
  450. buf = malloc_cache_aligned(size);
  451. if (!buf) {
  452. pr_err("Could not get FIT buffer of %lu bytes\n", (ulong)size);
  453. pr_err("\tcheck CONFIG_SYS_SPL_MALLOC_SIZE\n");
  454. buf = spl_get_load_buffer(0, size);
  455. }
  456. return buf;
  457. }
  458. __weak void *board_spl_fit_buffer_addr(ulong fit_size, int sectors, int bl_len)
  459. {
  460. return spl_get_fit_load_buffer(sectors * bl_len);
  461. }
  462. /*
  463. * Weak default function to allow customizing SPL fit loading for load-only
  464. * use cases by allowing to skip the parsing/processing of the FIT contents
  465. * (so that this can be done separately in a more customized fashion)
  466. */
  467. __weak bool spl_load_simple_fit_skip_processing(void)
  468. {
  469. return false;
  470. }
  471. /*
  472. * Weak default function to allow fixes after fit header
  473. * is loaded.
  474. */
  475. __weak void *spl_load_simple_fit_fix_load(const void *fit)
  476. {
  477. return (void *)fit;
  478. }
  479. static void warn_deprecated(const char *msg)
  480. {
  481. printf("DEPRECATED: %s\n", msg);
  482. printf("\tSee doc/uImage.FIT/source_file_format.txt\n");
  483. }
  484. static int spl_fit_upload_fpga(struct spl_fit_info *ctx, int node,
  485. struct spl_image_info *fpga_image)
  486. {
  487. const char *compatible;
  488. int ret;
  489. int devnum = 0;
  490. int flags = 0;
  491. debug("FPGA bitstream at: %x, size: %x\n",
  492. (u32)fpga_image->load_addr, fpga_image->size);
  493. compatible = fdt_getprop(ctx->fit, node, "compatible", NULL);
  494. if (!compatible) {
  495. warn_deprecated("'fpga' image without 'compatible' property");
  496. } else {
  497. if (CONFIG_IS_ENABLED(FPGA_LOAD_SECURE))
  498. flags = fpga_compatible2flag(devnum, compatible);
  499. if (strcmp(compatible, "u-boot,fpga-legacy"))
  500. debug("Ignoring compatible = %s property\n",
  501. compatible);
  502. }
  503. ret = fpga_load(devnum, (void *)fpga_image->load_addr,
  504. fpga_image->size, BIT_FULL, flags);
  505. if (ret) {
  506. printf("%s: Cannot load the image to the FPGA\n", __func__);
  507. return ret;
  508. }
  509. puts("FPGA image loaded from FIT\n");
  510. return 0;
  511. }
  512. static int spl_fit_load_fpga(struct spl_fit_info *ctx,
  513. struct spl_load_info *info, ulong sector)
  514. {
  515. int node, ret;
  516. struct spl_image_info fpga_image = {
  517. .load_addr = 0,
  518. };
  519. node = spl_fit_get_image_node(ctx, "fpga", 0);
  520. if (node < 0)
  521. return node;
  522. warn_deprecated("'fpga' property in config node. Use 'loadables'");
  523. /* Load the image and set up the fpga_image structure */
  524. ret = spl_load_fit_image(info, sector, ctx, node, &fpga_image);
  525. if (ret) {
  526. printf("%s: Cannot load the FPGA: %i\n", __func__, ret);
  527. return ret;
  528. }
  529. return spl_fit_upload_fpga(ctx, node, &fpga_image);
  530. }
  531. static int spl_simple_fit_read(struct spl_fit_info *ctx,
  532. struct spl_load_info *info, ulong sector,
  533. const void *fit_header)
  534. {
  535. unsigned long count, size;
  536. int sectors;
  537. void *buf;
  538. /*
  539. * For FIT with external data, figure out where the external images
  540. * start. This is the base for the data-offset properties in each
  541. * image.
  542. */
  543. size = ALIGN(fdt_totalsize(fit_header), 4);
  544. size = board_spl_fit_size_align(size);
  545. ctx->ext_data_offset = ALIGN(size, 4);
  546. /*
  547. * So far we only have one block of data from the FIT. Read the entire
  548. * thing, including that first block.
  549. *
  550. * For FIT with data embedded, data is loaded as part of FIT image.
  551. * For FIT with external data, data is not loaded in this step.
  552. */
  553. sectors = get_aligned_image_size(info, size, 0);
  554. buf = board_spl_fit_buffer_addr(size, sectors, info->bl_len);
  555. count = info->read(info, sector, sectors, buf);
  556. ctx->fit = buf;
  557. debug("fit read sector %lx, sectors=%d, dst=%p, count=%lu, size=0x%lx\n",
  558. sector, sectors, buf, count, size);
  559. return (count == 0) ? -EIO : 0;
  560. }
  561. static int spl_simple_fit_parse(struct spl_fit_info *ctx)
  562. {
  563. /* Find the correct subnode under "/configurations" */
  564. ctx->conf_node = fit_find_config_node(ctx->fit);
  565. if (ctx->conf_node < 0)
  566. return -EINVAL;
  567. if (IS_ENABLED(CONFIG_SPL_FIT_SIGNATURE)) {
  568. printf("## Checking hash(es) for config %s ... ",
  569. fit_get_name(ctx->fit, ctx->conf_node, NULL));
  570. if (fit_config_verify(ctx->fit, ctx->conf_node))
  571. return -EPERM;
  572. puts("OK\n");
  573. }
  574. /* find the node holding the images information */
  575. ctx->images_node = fdt_path_offset(ctx->fit, FIT_IMAGES_PATH);
  576. if (ctx->images_node < 0) {
  577. debug("%s: Cannot find /images node: %d\n", __func__,
  578. ctx->images_node);
  579. return -EINVAL;
  580. }
  581. return 0;
  582. }
  583. int spl_load_simple_fit(struct spl_image_info *spl_image,
  584. struct spl_load_info *info, ulong sector, void *fit)
  585. {
  586. struct spl_image_info image_info;
  587. struct spl_fit_info ctx;
  588. int node = -1;
  589. int ret;
  590. int index = 0;
  591. int firmware_node;
  592. ret = spl_simple_fit_read(&ctx, info, sector, fit);
  593. if (ret < 0)
  594. return ret;
  595. /* skip further processing if requested to enable load-only use cases */
  596. if (spl_load_simple_fit_skip_processing())
  597. return 0;
  598. ctx.fit = spl_load_simple_fit_fix_load(ctx.fit);
  599. ret = spl_simple_fit_parse(&ctx);
  600. if (ret < 0)
  601. return ret;
  602. if (IS_ENABLED(CONFIG_SPL_FPGA))
  603. spl_fit_load_fpga(&ctx, info, sector);
  604. /*
  605. * Find the U-Boot image using the following search order:
  606. * - start at 'firmware' (e.g. an ARM Trusted Firmware)
  607. * - fall back 'kernel' (e.g. a Falcon-mode OS boot
  608. * - fall back to using the first 'loadables' entry
  609. */
  610. if (node < 0)
  611. node = spl_fit_get_image_node(&ctx, FIT_FIRMWARE_PROP, 0);
  612. if (node < 0 && IS_ENABLED(CONFIG_SPL_OS_BOOT))
  613. node = spl_fit_get_image_node(&ctx, FIT_KERNEL_PROP, 0);
  614. if (node < 0) {
  615. debug("could not find firmware image, trying loadables...\n");
  616. node = spl_fit_get_image_node(&ctx, "loadables", 0);
  617. /*
  618. * If we pick the U-Boot image from "loadables", start at
  619. * the second image when later loading additional images.
  620. */
  621. index = 1;
  622. }
  623. if (node < 0) {
  624. debug("%s: Cannot find u-boot image node: %d\n",
  625. __func__, node);
  626. return -1;
  627. }
  628. /* Load the image and set up the spl_image structure */
  629. ret = spl_load_fit_image(info, sector, &ctx, node, spl_image);
  630. if (ret)
  631. return ret;
  632. /*
  633. * For backward compatibility, we treat the first node that is
  634. * as a U-Boot image, if no OS-type has been declared.
  635. */
  636. if (!spl_fit_image_get_os(ctx.fit, node, &spl_image->os))
  637. debug("Image OS is %s\n", genimg_get_os_name(spl_image->os));
  638. else if (!IS_ENABLED(CONFIG_SPL_OS_BOOT))
  639. spl_image->os = IH_OS_U_BOOT;
  640. /*
  641. * Booting a next-stage U-Boot may require us to append the FDT.
  642. * We allow this to fail, as the U-Boot image might embed its FDT.
  643. */
  644. if (os_takes_devicetree(spl_image->os)) {
  645. ret = spl_fit_append_fdt(spl_image, info, sector, &ctx);
  646. if (ret < 0 && spl_image->os != IH_OS_U_BOOT)
  647. return ret;
  648. }
  649. firmware_node = node;
  650. /* Now check if there are more images for us to load */
  651. for (; ; index++) {
  652. uint8_t os_type = IH_OS_INVALID;
  653. node = spl_fit_get_image_node(&ctx, "loadables", index);
  654. if (node < 0)
  655. break;
  656. /*
  657. * if the firmware is also a loadable, skip it because
  658. * it already has been loaded. This is typically the case with
  659. * u-boot.img generated by mkimage.
  660. */
  661. if (firmware_node == node)
  662. continue;
  663. image_info.load_addr = 0;
  664. ret = spl_load_fit_image(info, sector, &ctx, node, &image_info);
  665. if (ret < 0) {
  666. printf("%s: can't load image loadables index %d (ret = %d)\n",
  667. __func__, index, ret);
  668. return ret;
  669. }
  670. if (spl_fit_image_is_fpga(ctx.fit, node))
  671. spl_fit_upload_fpga(&ctx, node, &image_info);
  672. if (!spl_fit_image_get_os(ctx.fit, node, &os_type))
  673. debug("Loadable is %s\n", genimg_get_os_name(os_type));
  674. if (os_takes_devicetree(os_type)) {
  675. spl_fit_append_fdt(&image_info, info, sector, &ctx);
  676. spl_image->fdt_addr = image_info.fdt_addr;
  677. }
  678. /*
  679. * If the "firmware" image did not provide an entry point,
  680. * use the first valid entry point from the loadables.
  681. */
  682. if (spl_image->entry_point == FDT_ERROR &&
  683. image_info.entry_point != FDT_ERROR)
  684. spl_image->entry_point = image_info.entry_point;
  685. /* Record our loadables into the FDT */
  686. if (spl_image->fdt_addr)
  687. spl_fit_record_loadable(&ctx, index,
  688. spl_image->fdt_addr,
  689. &image_info);
  690. }
  691. /*
  692. * If a platform does not provide CFG_SYS_UBOOT_START, U-Boot's
  693. * Makefile will set it to 0 and it will end up as the entry point
  694. * here. What it actually means is: use the load address.
  695. */
  696. if (spl_image->entry_point == FDT_ERROR || spl_image->entry_point == 0)
  697. spl_image->entry_point = spl_image->load_addr;
  698. spl_image->flags |= SPL_FIT_FOUND;
  699. return 0;
  700. }