1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2016 Google, Inc 4 * Written by Simon Glass <sjg@chromium.org> 5 */ 6 7#include <common.h> 8#include <errno.h> 9#include <fpga.h> 10#include <gzip.h> 11#include <image.h> 12#include <log.h> 13#include <memalign.h> 14#include <mapmem.h> 15#include <spl.h> 16#include <sysinfo.h> 17#include <asm/global_data.h> 18#include <asm/io.h> 19#include <linux/libfdt.h> 20#include <linux/printk.h> 21 22DECLARE_GLOBAL_DATA_PTR; 23 24struct spl_fit_info { 25 const void *fit; /* Pointer to a valid FIT blob */ 26 size_t ext_data_offset; /* Offset to FIT external data (end of FIT) */ 27 int images_node; /* FDT offset to "/images" node */ 28 int conf_node; /* FDT offset to selected configuration node */ 29}; 30 31__weak ulong board_spl_fit_size_align(ulong size) 32{ 33 return size; 34} 35 36static int find_node_from_desc(const void *fit, int node, const char *str) 37{ 38 int child; 39 40 if (node < 0) 41 return -EINVAL; 42 43 /* iterate the FIT nodes and find a matching description */ 44 for (child = fdt_first_subnode(fit, node); child >= 0; 45 child = fdt_next_subnode(fit, child)) { 46 int len; 47 const char *desc = fdt_getprop(fit, child, FIT_DESC_PROP, &len); 48 49 if (!desc) 50 continue; 51 52 if (!strcmp(desc, str)) 53 return child; 54 } 55 56 return -ENOENT; 57} 58 59/** 60 * spl_fit_get_image_name(): By using the matching configuration subnode, 61 * retrieve the name of an image, specified by a property name and an index 62 * into that. 63 * @fit: Pointer to the FDT blob. 64 * @images: Offset of the /images subnode. 65 * @type: Name of the property within the configuration subnode. 66 * @index: Index into the list of strings in this property. 67 * @outname: Name of the image 68 * 69 * Return: 0 on success, or a negative error number 70 */ 71static int spl_fit_get_image_name(const struct spl_fit_info *ctx, 72 const char *type, int index, 73 const char **outname) 74{ 75 struct udevice *sysinfo; 76 const char *name, *str; 77 __maybe_unused int node; 78 int len, i; 79 bool found = true; 80 81 name = fdt_getprop(ctx->fit, ctx->conf_node, type, &len); 82 if (!name) { 83 debug("cannot find property '%s': %d\n", type, len); 84 return -EINVAL; 85 } 86 87 str = name; 88 for (i = 0; i < index; i++) { 89 str = strchr(str, '\0') + 1; 90 if (!str || (str - name >= len)) { 91 found = false; 92 break; 93 } 94 } 95 96 if (!found && CONFIG_IS_ENABLED(SYSINFO) && !sysinfo_get(&sysinfo)) { 97 int rc; 98 /* 99 * no string in the property for this index. Check if the 100 * sysinfo-level code can supply one. 101 */ 102 rc = sysinfo_detect(sysinfo); 103 if (rc) 104 return rc; 105 106 rc = sysinfo_get_fit_loadable(sysinfo, index - i - 1, type, 107 &str); 108 if (rc && rc != -ENOENT) 109 return rc; 110 111 if (!rc) { 112 /* 113 * The sysinfo provided a name for a loadable. 114 * Try to match it against the description properties 115 * first. If no matching node is found, use it as a 116 * node name. 117 */ 118 int node; 119 int images = fdt_path_offset(ctx->fit, FIT_IMAGES_PATH); 120 121 node = find_node_from_desc(ctx->fit, images, str); 122 if (node > 0) 123 str = fdt_get_name(ctx->fit, node, NULL); 124 125 found = true; 126 } 127 } 128 129 if (!found) { 130 debug("no string for index %d\n", index); 131 return -E2BIG; 132 } 133 134 *outname = str; 135 return 0; 136} 137 138/** 139 * spl_fit_get_image_node(): By using the matching configuration subnode, 140 * retrieve the name of an image, specified by a property name and an index 141 * into that. 142 * @fit: Pointer to the FDT blob. 143 * @images: Offset of the /images subnode. 144 * @type: Name of the property within the configuration subnode. 145 * @index: Index into the list of strings in this property. 146 * 147 * Return: the node offset of the respective image node or a negative 148 * error number. 149 */ 150static int spl_fit_get_image_node(const struct spl_fit_info *ctx, 151 const char *type, int index) 152{ 153 const char *str; 154 int err; 155 int node; 156 157 err = spl_fit_get_image_name(ctx, type, index, &str); 158 if (err) 159 return err; 160 161 debug("%s: '%s'\n", type, str); 162 163 node = fdt_subnode_offset(ctx->fit, ctx->images_node, str); 164 if (node < 0) { 165 pr_err("cannot find image node '%s': %d\n", str, node); 166 return -EINVAL; 167 } 168 169 return node; 170} 171 172static int get_aligned_image_offset(struct spl_load_info *info, int offset) 173{ 174 return ALIGN_DOWN(offset, spl_get_bl_len(info)); 175} 176 177static int get_aligned_image_overhead(struct spl_load_info *info, int offset) 178{ 179 return offset & (spl_get_bl_len(info) - 1); 180} 181 182static int get_aligned_image_size(struct spl_load_info *info, int data_size, 183 int offset) 184{ 185 data_size = data_size + get_aligned_image_overhead(info, offset); 186 187 return ALIGN(data_size, spl_get_bl_len(info)); 188} 189 190/** 191 * load_simple_fit(): load the image described in a certain FIT node 192 * @info: points to information about the device to load data from 193 * @sector: the start sector of the FIT image on the device 194 * @ctx: points to the FIT context structure 195 * @node: offset of the DT node describing the image to load (relative 196 * to @fit) 197 * @image_info: will be filled with information about the loaded image 198 * If the FIT node does not contain a "load" (address) property, 199 * the image gets loaded to the address pointed to by the 200 * load_addr member in this struct, if load_addr is not 0 201 * 202 * Return: 0 on success or a negative error number. 203 */ 204static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, 205 const struct spl_fit_info *ctx, int node, 206 struct spl_image_info *image_info) 207{ 208 int offset; 209 size_t length; 210 int len; 211 ulong size; 212 ulong load_addr; 213 void *load_ptr; 214 void *src; 215 ulong overhead; 216 uint8_t image_comp = -1, type = -1; 217 const void *data; 218 const void *fit = ctx->fit; 219 bool external_data = false; 220 221 if (IS_ENABLED(CONFIG_SPL_FPGA) || 222 (IS_ENABLED(CONFIG_SPL_OS_BOOT) && spl_decompression_enabled())) { 223 if (fit_image_get_type(fit, node, &type)) 224 puts("Cannot get image type.\n"); 225 else 226 debug("%s ", genimg_get_type_name(type)); 227 } 228 229 if (spl_decompression_enabled()) { 230 fit_image_get_comp(fit, node, &image_comp); 231 debug("%s ", genimg_get_comp_name(image_comp)); 232 } 233 234 if (fit_image_get_load(fit, node, &load_addr)) { 235 if (!image_info->load_addr) { 236 printf("Can't load %s: No load address and no buffer\n", 237 fit_get_name(fit, node, NULL)); 238 return -ENOBUFS; 239 } 240 load_addr = image_info->load_addr; 241 } 242 243 if (!fit_image_get_data_position(fit, node, &offset)) { 244 external_data = true; 245 } else if (!fit_image_get_data_offset(fit, node, &offset)) { 246 offset += ctx->ext_data_offset; 247 external_data = true; 248 } 249 250 if (external_data) { 251 void *src_ptr; 252 253 /* External data */ 254 if (fit_image_get_data_size(fit, node, &len)) 255 return -ENOENT; 256 257 /* Dont bother to copy 0 byte data, but warn, though */ 258 if (!len) { 259 log_warning("%s: Skip load '%s': image size is 0!\n", 260 __func__, fit_get_name(fit, node, NULL)); 261 return 0; 262 } 263 264 if (spl_decompression_enabled() && 265 (image_comp == IH_COMP_GZIP || image_comp == IH_COMP_LZMA)) 266 src_ptr = map_sysmem(ALIGN(CONFIG_SYS_LOAD_ADDR, ARCH_DMA_MINALIGN), len); 267 else 268 src_ptr = map_sysmem(ALIGN(load_addr, ARCH_DMA_MINALIGN), len); 269 length = len; 270 271 overhead = get_aligned_image_overhead(info, offset); 272 size = get_aligned_image_size(info, length, offset); 273 274 if (info->read(info, 275 fit_offset + 276 get_aligned_image_offset(info, offset), size, 277 src_ptr) < length) 278 return -EIO; 279 280 debug("External data: dst=%p, offset=%x, size=%lx\n", 281 src_ptr, offset, (unsigned long)length); 282 src = src_ptr + overhead; 283 } else { 284 /* Embedded data */ 285 if (fit_image_get_data(fit, node, &data, &length)) { 286 puts("Cannot get image data/size\n"); 287 return -ENOENT; 288 } 289 debug("Embedded data: dst=%lx, size=%lx\n", load_addr, 290 (unsigned long)length); 291 src = (void *)data; /* cast away const */ 292 } 293 294 if (CONFIG_IS_ENABLED(FIT_SIGNATURE)) { 295 printf("## Checking hash(es) for Image %s ... ", 296 fit_get_name(fit, node, NULL)); 297 if (!fit_image_verify_with_data(fit, node, gd_fdt_blob(), src, 298 length)) 299 return -EPERM; 300 puts("OK\n"); 301 } 302 303 if (CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS)) 304 board_fit_image_post_process(fit, node, &src, &length); 305 306 load_ptr = map_sysmem(load_addr, length); 307 if (IS_ENABLED(CONFIG_SPL_GZIP) && image_comp == IH_COMP_GZIP) { 308 size = length; 309 if (gunzip(load_ptr, CONFIG_SYS_BOOTM_LEN, src, &size)) { 310 puts("Uncompressing error\n"); 311 return -EIO; 312 } 313 length = size; 314 } else if (IS_ENABLED(CONFIG_SPL_LZMA) && image_comp == IH_COMP_LZMA) { 315 size = CONFIG_SYS_BOOTM_LEN; 316 ulong loadEnd; 317 318 if (image_decomp(IH_COMP_LZMA, CONFIG_SYS_LOAD_ADDR, 0, 0, 319 load_ptr, src, length, size, &loadEnd)) { 320 puts("Uncompressing error\n"); 321 return -EIO; 322 } 323 length = loadEnd - CONFIG_SYS_LOAD_ADDR; 324 } else { 325 memcpy(load_ptr, src, length); 326 } 327 328 if (image_info) { 329 ulong entry_point; 330 331 image_info->load_addr = load_addr; 332 image_info->size = length; 333 334 if (!fit_image_get_entry(fit, node, &entry_point)) 335 image_info->entry_point = entry_point; 336 else 337 image_info->entry_point = FDT_ERROR; 338 } 339 340 return 0; 341} 342 343static bool os_takes_devicetree(uint8_t os) 344{ 345 switch (os) { 346 case IH_OS_U_BOOT: 347 return true; 348 case IH_OS_LINUX: 349 return IS_ENABLED(CONFIG_SPL_OS_BOOT) || 350 IS_ENABLED(CONFIG_SPL_OPENSBI); 351 default: 352 return false; 353 } 354} 355 356__weak int board_spl_fit_append_fdt_skip(const char *name) 357{ 358 return 0; /* Do not skip */ 359} 360 361static int spl_fit_append_fdt(struct spl_image_info *spl_image, 362 struct spl_load_info *info, ulong offset, 363 const struct spl_fit_info *ctx) 364{ 365 struct spl_image_info image_info; 366 int node, ret = 0, index = 0; 367 368 /* 369 * Use the address following the image as target address for the 370 * device tree. 371 */ 372 image_info.load_addr = spl_image->load_addr + spl_image->size; 373 374 /* Figure out which device tree the board wants to use */ 375 node = spl_fit_get_image_node(ctx, FIT_FDT_PROP, index++); 376 if (node < 0) { 377 size_t size; 378 379 debug("%s: cannot find FDT node\n", __func__); 380 381 /* 382 * U-Boot did not find a device tree inside the FIT image. Use 383 * the U-Boot device tree instead. 384 */ 385 if (!gd->fdt_blob) 386 return node; 387 388 /* 389 * Make the load-address of the FDT available for the SPL 390 * framework 391 */ 392 size = fdt_totalsize(gd->fdt_blob); 393 spl_image->fdt_addr = map_sysmem(image_info.load_addr, size); 394 memcpy(spl_image->fdt_addr, gd->fdt_blob, size); 395 } else { 396 ret = load_simple_fit(info, offset, ctx, node, &image_info); 397 if (ret < 0) 398 return ret; 399 400 spl_image->fdt_addr = phys_to_virt(image_info.load_addr); 401 } 402 403 if (CONFIG_IS_ENABLED(FIT_IMAGE_TINY)) 404 return 0; 405 406#if CONFIG_IS_ENABLED(LOAD_FIT_APPLY_OVERLAY) 407 void *tmpbuffer = NULL; 408 409 for (; ; index++) { 410 const char *str; 411 412 ret = spl_fit_get_image_name(ctx, FIT_FDT_PROP, index, &str); 413 if (ret == -E2BIG) { 414 debug("%s: No additional FDT node\n", __func__); 415 ret = 0; 416 break; 417 } else if (ret < 0) { 418 continue; 419 } 420 421 ret = board_spl_fit_append_fdt_skip(str); 422 if (ret) 423 continue; 424 425 node = fdt_subnode_offset(ctx->fit, ctx->images_node, str); 426 if (node < 0) { 427 debug("%s: unable to find FDT node %d\n", 428 __func__, index); 429 continue; 430 } 431 432 if (!tmpbuffer) { 433 /* 434 * allocate memory to store the DT overlay 435 * before it is applied. It may not be used 436 * depending on how the overlay is stored, so 437 * don't fail yet if the allocation failed. 438 */ 439 size_t size = CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ; 440 441 tmpbuffer = malloc_cache_aligned(size); 442 if (!tmpbuffer) 443 debug("%s: unable to allocate space for overlays\n", 444 __func__); 445 } 446 image_info.load_addr = (ulong)tmpbuffer; 447 ret = load_simple_fit(info, offset, ctx, node, 448 &image_info); 449 if (ret < 0) 450 break; 451 452 /* Make room in FDT for changes from the overlay */ 453 ret = fdt_increase_size(spl_image->fdt_addr, 454 image_info.size); 455 if (ret < 0) 456 break; 457 458 ret = fdt_overlay_apply_verbose(spl_image->fdt_addr, 459 (void *)image_info.load_addr); 460 if (ret) { 461 pr_err("failed to apply DT overlay %s\n", 462 fit_get_name(ctx->fit, node, NULL)); 463 break; 464 } 465 466 debug("%s: DT overlay %s applied\n", __func__, 467 fit_get_name(ctx->fit, node, NULL)); 468 } 469 free(tmpbuffer); 470 if (ret) 471 return ret; 472#endif 473 /* Try to make space, so we can inject details on the loadables */ 474 ret = fdt_shrink_to_minimum(spl_image->fdt_addr, 8192); 475 if (ret < 0) 476 return ret; 477 478 return ret; 479} 480 481static int spl_fit_record_loadable(const struct spl_fit_info *ctx, int index, 482 void *blob, struct spl_image_info *image) 483{ 484 int ret = 0; 485 const char *name; 486 int node; 487 488 if (CONFIG_IS_ENABLED(FIT_IMAGE_TINY)) 489 return 0; 490 491 ret = spl_fit_get_image_name(ctx, "loadables", index, &name); 492 if (ret < 0) 493 return ret; 494 495 node = spl_fit_get_image_node(ctx, "loadables", index); 496 497 ret = fdt_record_loadable(blob, index, name, image->load_addr, 498 image->size, image->entry_point, 499 fdt_getprop(ctx->fit, node, FIT_TYPE_PROP, NULL), 500 fdt_getprop(ctx->fit, node, FIT_OS_PROP, NULL), 501 fdt_getprop(ctx->fit, node, FIT_ARCH_PROP, NULL)); 502 503 return ret; 504} 505 506static int spl_fit_image_is_fpga(const void *fit, int node) 507{ 508 const char *type; 509 510 if (!IS_ENABLED(CONFIG_SPL_FPGA)) 511 return 0; 512 513 type = fdt_getprop(fit, node, FIT_TYPE_PROP, NULL); 514 if (!type) 515 return 0; 516 517 return !strcmp(type, "fpga"); 518} 519 520static int spl_fit_image_get_os(const void *fit, int noffset, uint8_t *os) 521{ 522 if (!CONFIG_IS_ENABLED(FIT_IMAGE_TINY) || CONFIG_IS_ENABLED(OS_BOOT)) 523 return fit_image_get_os(fit, noffset, os); 524 525 const char *name = fdt_getprop(fit, noffset, FIT_OS_PROP, NULL); 526 if (!name) 527 return -ENOENT; 528 529 /* 530 * We don't care what the type of the image actually is, 531 * only whether or not it is U-Boot. This saves some 532 * space by omitting the large table of OS types. 533 */ 534 if (!strcmp(name, "u-boot")) 535 *os = IH_OS_U_BOOT; 536 else 537 *os = IH_OS_INVALID; 538 539 return 0; 540} 541 542/* 543 * The purpose of the FIT load buffer is to provide a memory location that is 544 * independent of the load address of any FIT component. 545 */ 546static void *spl_get_fit_load_buffer(size_t size) 547{ 548 void *buf; 549 550 buf = malloc_cache_aligned(size); 551 if (!buf) { 552 pr_err("Could not get FIT buffer of %lu bytes\n", (ulong)size); 553 554 if (IS_ENABLED(CONFIG_SPL_SYS_MALLOC)) 555 pr_err("\tcheck CONFIG_SPL_SYS_MALLOC_SIZE\n"); 556 else 557 pr_err("\tcheck CONFIG_SPL_SYS_MALLOC_F_LEN\n"); 558 559 buf = spl_get_load_buffer(0, size); 560 } 561 return buf; 562} 563 564__weak void *board_spl_fit_buffer_addr(ulong fit_size, int sectors, int bl_len) 565{ 566 return spl_get_fit_load_buffer(sectors * bl_len); 567} 568 569/* 570 * Weak default function to allow customizing SPL fit loading for load-only 571 * use cases by allowing to skip the parsing/processing of the FIT contents 572 * (so that this can be done separately in a more customized fashion) 573 */ 574__weak bool spl_load_simple_fit_skip_processing(void) 575{ 576 return false; 577} 578 579/* 580 * Weak default function to allow fixes after fit header 581 * is loaded. 582 */ 583__weak void *spl_load_simple_fit_fix_load(const void *fit) 584{ 585 return (void *)fit; 586} 587 588static void warn_deprecated(const char *msg) 589{ 590 printf("DEPRECATED: %s\n", msg); 591 printf("\tSee doc/uImage.FIT/source_file_format.txt\n"); 592} 593 594static int spl_fit_upload_fpga(struct spl_fit_info *ctx, int node, 595 struct spl_image_info *fpga_image) 596{ 597 const char *compatible; 598 int ret; 599 int devnum = 0; 600 int flags = 0; 601 602 debug("FPGA bitstream at: %x, size: %x\n", 603 (u32)fpga_image->load_addr, fpga_image->size); 604 605 compatible = fdt_getprop(ctx->fit, node, "compatible", NULL); 606 if (!compatible) { 607 warn_deprecated("'fpga' image without 'compatible' property"); 608 } else { 609 if (CONFIG_IS_ENABLED(FPGA_LOAD_SECURE)) 610 flags = fpga_compatible2flag(devnum, compatible); 611 if (strcmp(compatible, "u-boot,fpga-legacy")) 612 debug("Ignoring compatible = %s property\n", 613 compatible); 614 } 615 616 ret = fpga_load(devnum, (void *)fpga_image->load_addr, 617 fpga_image->size, BIT_FULL, flags); 618 if (ret) { 619 printf("%s: Cannot load the image to the FPGA\n", __func__); 620 return ret; 621 } 622 623 puts("FPGA image loaded from FIT\n"); 624 625 return 0; 626} 627 628static int spl_fit_load_fpga(struct spl_fit_info *ctx, 629 struct spl_load_info *info, ulong offset) 630{ 631 int node, ret; 632 633 struct spl_image_info fpga_image = { 634 .load_addr = 0, 635 }; 636 637 node = spl_fit_get_image_node(ctx, "fpga", 0); 638 if (node < 0) 639 return node; 640 641 warn_deprecated("'fpga' property in config node. Use 'loadables'"); 642 643 /* Load the image and set up the fpga_image structure */ 644 ret = load_simple_fit(info, offset, ctx, node, &fpga_image); 645 if (ret) { 646 printf("%s: Cannot load the FPGA: %i\n", __func__, ret); 647 return ret; 648 } 649 650 return spl_fit_upload_fpga(ctx, node, &fpga_image); 651} 652 653static int spl_simple_fit_read(struct spl_fit_info *ctx, 654 struct spl_load_info *info, ulong offset, 655 const void *fit_header) 656{ 657 unsigned long count, size; 658 void *buf; 659 660 /* 661 * For FIT with external data, figure out where the external images 662 * start. This is the base for the data-offset properties in each 663 * image. 664 */ 665 size = ALIGN(fdt_totalsize(fit_header), 4); 666 size = board_spl_fit_size_align(size); 667 ctx->ext_data_offset = ALIGN(size, 4); 668 669 /* 670 * So far we only have one block of data from the FIT. Read the entire 671 * thing, including that first block. 672 * 673 * For FIT with data embedded, data is loaded as part of FIT image. 674 * For FIT with external data, data is not loaded in this step. 675 */ 676 size = get_aligned_image_size(info, size, 0); 677 buf = board_spl_fit_buffer_addr(size, size, 1); 678 679 count = info->read(info, offset, size, buf); 680 ctx->fit = buf; 681 debug("fit read offset %lx, size=%lu, dst=%p, count=%lu\n", 682 offset, size, buf, count); 683 684 return (count == 0) ? -EIO : 0; 685} 686 687static int spl_simple_fit_parse(struct spl_fit_info *ctx) 688{ 689 /* Find the correct subnode under "/configurations" */ 690 ctx->conf_node = fit_find_config_node(ctx->fit); 691 if (ctx->conf_node < 0) 692 return -EINVAL; 693 694 if (IS_ENABLED(CONFIG_SPL_FIT_SIGNATURE)) { 695 printf("## Checking hash(es) for config %s ... ", 696 fit_get_name(ctx->fit, ctx->conf_node, NULL)); 697 if (fit_config_verify(ctx->fit, ctx->conf_node)) 698 return -EPERM; 699 puts("OK\n"); 700 } 701 702 /* find the node holding the images information */ 703 ctx->images_node = fdt_path_offset(ctx->fit, FIT_IMAGES_PATH); 704 if (ctx->images_node < 0) { 705 debug("%s: Cannot find /images node: %d\n", __func__, 706 ctx->images_node); 707 return -EINVAL; 708 } 709 710 return 0; 711} 712 713int spl_load_simple_fit(struct spl_image_info *spl_image, 714 struct spl_load_info *info, ulong offset, void *fit) 715{ 716 struct spl_image_info image_info; 717 struct spl_fit_info ctx; 718 int node = -1; 719 int ret; 720 int index = 0; 721 int firmware_node; 722 723 ret = spl_simple_fit_read(&ctx, info, offset, fit); 724 if (ret < 0) 725 return ret; 726 727 /* skip further processing if requested to enable load-only use cases */ 728 if (spl_load_simple_fit_skip_processing()) 729 return 0; 730 731 ctx.fit = spl_load_simple_fit_fix_load(ctx.fit); 732 733 ret = spl_simple_fit_parse(&ctx); 734 if (ret < 0) 735 return ret; 736 737 if (IS_ENABLED(CONFIG_SPL_FPGA)) 738 spl_fit_load_fpga(&ctx, info, offset); 739 740 /* 741 * Find the U-Boot image using the following search order: 742 * - start at 'firmware' (e.g. an ARM Trusted Firmware) 743 * - fall back 'kernel' (e.g. a Falcon-mode OS boot 744 * - fall back to using the first 'loadables' entry 745 */ 746 if (node < 0) 747 node = spl_fit_get_image_node(&ctx, FIT_FIRMWARE_PROP, 0); 748 749 if (node < 0 && IS_ENABLED(CONFIG_SPL_OS_BOOT)) 750 node = spl_fit_get_image_node(&ctx, FIT_KERNEL_PROP, 0); 751 752 if (node < 0) { 753 debug("could not find firmware image, trying loadables...\n"); 754 node = spl_fit_get_image_node(&ctx, "loadables", 0); 755 /* 756 * If we pick the U-Boot image from "loadables", start at 757 * the second image when later loading additional images. 758 */ 759 index = 1; 760 } 761 if (node < 0) { 762 debug("%s: Cannot find u-boot image node: %d\n", 763 __func__, node); 764 return -1; 765 } 766 767 /* Load the image and set up the spl_image structure */ 768 ret = load_simple_fit(info, offset, &ctx, node, spl_image); 769 if (ret) 770 return ret; 771 772 /* 773 * For backward compatibility, we treat the first node that is 774 * as a U-Boot image, if no OS-type has been declared. 775 */ 776 if (!spl_fit_image_get_os(ctx.fit, node, &spl_image->os)) 777 debug("Image OS is %s\n", genimg_get_os_name(spl_image->os)); 778 else if (!IS_ENABLED(CONFIG_SPL_OS_BOOT)) 779 spl_image->os = IH_OS_U_BOOT; 780 781 /* 782 * Booting a next-stage U-Boot may require us to append the FDT. 783 * We allow this to fail, as the U-Boot image might embed its FDT. 784 */ 785 if (os_takes_devicetree(spl_image->os)) { 786 ret = spl_fit_append_fdt(spl_image, info, offset, &ctx); 787 if (ret < 0 && spl_image->os != IH_OS_U_BOOT) 788 return ret; 789 } 790 791 firmware_node = node; 792 /* Now check if there are more images for us to load */ 793 for (; ; index++) { 794 uint8_t os_type = IH_OS_INVALID; 795 796 node = spl_fit_get_image_node(&ctx, "loadables", index); 797 if (node < 0) 798 break; 799 800 /* 801 * if the firmware is also a loadable, skip it because 802 * it already has been loaded. This is typically the case with 803 * u-boot.img generated by mkimage. 804 */ 805 if (firmware_node == node) 806 continue; 807 808 image_info.load_addr = 0; 809 ret = load_simple_fit(info, offset, &ctx, node, &image_info); 810 if (ret < 0) { 811 printf("%s: can't load image loadables index %d (ret = %d)\n", 812 __func__, index, ret); 813 return ret; 814 } 815 816 if (spl_fit_image_is_fpga(ctx.fit, node)) 817 spl_fit_upload_fpga(&ctx, node, &image_info); 818 819 if (!spl_fit_image_get_os(ctx.fit, node, &os_type)) 820 debug("Loadable is %s\n", genimg_get_os_name(os_type)); 821 822 if (os_takes_devicetree(os_type)) { 823 spl_fit_append_fdt(&image_info, info, offset, &ctx); 824 spl_image->fdt_addr = image_info.fdt_addr; 825 } 826 827 /* 828 * If the "firmware" image did not provide an entry point, 829 * use the first valid entry point from the loadables. 830 */ 831 if (spl_image->entry_point == FDT_ERROR && 832 image_info.entry_point != FDT_ERROR) 833 spl_image->entry_point = image_info.entry_point; 834 835 /* Record our loadables into the FDT */ 836 if (spl_image->fdt_addr) 837 spl_fit_record_loadable(&ctx, index, 838 spl_image->fdt_addr, 839 &image_info); 840 } 841 842 /* 843 * If a platform does not provide CONFIG_SYS_UBOOT_START, U-Boot's 844 * Makefile will set it to 0 and it will end up as the entry point 845 * here. What it actually means is: use the load address. 846 */ 847 if (spl_image->entry_point == FDT_ERROR || spl_image->entry_point == 0) 848 spl_image->entry_point = spl_image->load_addr; 849 850 spl_image->flags |= SPL_FIT_FOUND; 851 852 return 0; 853} 854 855/* Parse and load full fitImage in SPL */ 856int spl_load_fit_image(struct spl_image_info *spl_image, 857 const struct legacy_img_hdr *header) 858{ 859 struct bootm_headers images; 860 const char *fit_uname_config = NULL; 861 uintptr_t fdt_hack; 862 const char *uname; 863 ulong fw_data = 0, dt_data = 0, img_data = 0; 864 ulong fw_len = 0, dt_len = 0, img_len = 0; 865 int idx, conf_noffset; 866 int ret; 867 868#ifdef CONFIG_SPL_FIT_SIGNATURE 869 images.verify = 1; 870#endif 871 ret = fit_image_load(&images, virt_to_phys((void *)header), 872 NULL, &fit_uname_config, 873 IH_ARCH_DEFAULT, IH_TYPE_STANDALONE, -1, 874 FIT_LOAD_OPTIONAL, &fw_data, &fw_len); 875 if (ret >= 0) { 876 printf("DEPRECATED: 'standalone = ' property."); 877 printf("Please use either 'firmware =' or 'kernel ='\n"); 878 } else { 879 ret = fit_image_load(&images, virt_to_phys((void *)header), 880 NULL, &fit_uname_config, IH_ARCH_DEFAULT, 881 IH_TYPE_FIRMWARE, -1, FIT_LOAD_OPTIONAL, 882 &fw_data, &fw_len); 883 } 884 885 if (ret < 0) { 886 ret = fit_image_load(&images, virt_to_phys((void *)header), 887 NULL, &fit_uname_config, IH_ARCH_DEFAULT, 888 IH_TYPE_KERNEL, -1, FIT_LOAD_OPTIONAL, 889 &fw_data, &fw_len); 890 } 891 892 if (ret < 0) 893 return ret; 894 895 spl_image->size = fw_len; 896 spl_image->load_addr = fw_data; 897 if (fit_image_get_entry(header, ret, &spl_image->entry_point)) 898 spl_image->entry_point = fw_data; 899 if (fit_image_get_os(header, ret, &spl_image->os)) 900 spl_image->os = IH_OS_INVALID; 901 spl_image->name = genimg_get_os_name(spl_image->os); 902 903 debug(SPL_TPL_PROMPT "payload image: %32s load addr: 0x%lx size: %d\n", 904 spl_image->name, spl_image->load_addr, spl_image->size); 905 906#ifdef CONFIG_SPL_FIT_SIGNATURE 907 images.verify = 1; 908#endif 909 ret = fit_image_load(&images, virt_to_phys((void *)header), NULL, 910 &fit_uname_config, IH_ARCH_DEFAULT, IH_TYPE_FLATDT, 911 -1, FIT_LOAD_OPTIONAL, &dt_data, &dt_len); 912 if (ret >= 0) { 913 spl_image->fdt_addr = (void *)dt_data; 914 915 if (spl_image->os == IH_OS_U_BOOT) { 916 /* HACK: U-Boot expects FDT at a specific address */ 917 fdt_hack = spl_image->load_addr + spl_image->size; 918 fdt_hack = (fdt_hack + 3) & ~3; 919 debug("Relocating FDT to %p\n", spl_image->fdt_addr); 920 memcpy((void *)fdt_hack, spl_image->fdt_addr, dt_len); 921 } 922 } 923 924 conf_noffset = fit_conf_get_node((const void *)header, 925 fit_uname_config); 926 if (conf_noffset < 0) 927 return 0; 928 929 for (idx = 0; 930 uname = fdt_stringlist_get((const void *)header, conf_noffset, 931 FIT_LOADABLE_PROP, idx, 932 NULL), uname; 933 idx++) { 934#ifdef CONFIG_SPL_FIT_SIGNATURE 935 images.verify = 1; 936#endif 937 ret = fit_image_load(&images, (ulong)header, 938 &uname, &fit_uname_config, 939 IH_ARCH_DEFAULT, IH_TYPE_LOADABLE, -1, 940 FIT_LOAD_OPTIONAL_NON_ZERO, 941 &img_data, &img_len); 942 if (ret < 0) 943 return ret; 944 } 945 946 return 0; 947} 948