uboot/common/image-fit.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2013, Google Inc.
   3 *
   4 * (C) Copyright 2008 Semihalf
   5 *
   6 * (C) Copyright 2000-2006
   7 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   8 *
   9 * SPDX-License-Identifier:     GPL-2.0+
  10 */
  11
  12#ifdef USE_HOSTCC
  13#include "mkimage.h"
  14#include <time.h>
  15#else
  16#include <linux/compiler.h>
  17#include <linux/kconfig.h>
  18#include <common.h>
  19#include <errno.h>
  20#include <mapmem.h>
  21#include <asm/io.h>
  22#include <malloc.h>
  23DECLARE_GLOBAL_DATA_PTR;
  24#endif /* !USE_HOSTCC*/
  25
  26#include <image.h>
  27#include <bootstage.h>
  28#include <u-boot/crc.h>
  29#include <u-boot/md5.h>
  30#include <u-boot/sha1.h>
  31#include <u-boot/sha256.h>
  32
  33/*****************************************************************************/
  34/* New uImage format routines */
  35/*****************************************************************************/
  36#ifndef USE_HOSTCC
  37static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr,
  38                ulong *addr, const char **name)
  39{
  40        const char *sep;
  41
  42        *addr = addr_curr;
  43        *name = NULL;
  44
  45        sep = strchr(spec, sepc);
  46        if (sep) {
  47                if (sep - spec > 0)
  48                        *addr = simple_strtoul(spec, NULL, 16);
  49
  50                *name = sep + 1;
  51                return 1;
  52        }
  53
  54        return 0;
  55}
  56
  57/**
  58 * fit_parse_conf - parse FIT configuration spec
  59 * @spec: input string, containing configuration spec
  60 * @add_curr: current image address (to be used as a possible default)
  61 * @addr: pointer to a ulong variable, will hold FIT image address of a given
  62 * configuration
  63 * @conf_name double pointer to a char, will hold pointer to a configuration
  64 * unit name
  65 *
  66 * fit_parse_conf() expects configuration spec in the form of [<addr>]#<conf>,
  67 * where <addr> is a FIT image address that contains configuration
  68 * with a <conf> unit name.
  69 *
  70 * Address part is optional, and if omitted default add_curr will
  71 * be used instead.
  72 *
  73 * returns:
  74 *     1 if spec is a valid configuration string,
  75 *     addr and conf_name are set accordingly
  76 *     0 otherwise
  77 */
  78int fit_parse_conf(const char *spec, ulong addr_curr,
  79                ulong *addr, const char **conf_name)
  80{
  81        return fit_parse_spec(spec, '#', addr_curr, addr, conf_name);
  82}
  83
  84/**
  85 * fit_parse_subimage - parse FIT subimage spec
  86 * @spec: input string, containing subimage spec
  87 * @add_curr: current image address (to be used as a possible default)
  88 * @addr: pointer to a ulong variable, will hold FIT image address of a given
  89 * subimage
  90 * @image_name: double pointer to a char, will hold pointer to a subimage name
  91 *
  92 * fit_parse_subimage() expects subimage spec in the form of
  93 * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
  94 * subimage with a <subimg> unit name.
  95 *
  96 * Address part is optional, and if omitted default add_curr will
  97 * be used instead.
  98 *
  99 * returns:
 100 *     1 if spec is a valid subimage string,
 101 *     addr and image_name are set accordingly
 102 *     0 otherwise
 103 */
 104int fit_parse_subimage(const char *spec, ulong addr_curr,
 105                ulong *addr, const char **image_name)
 106{
 107        return fit_parse_spec(spec, ':', addr_curr, addr, image_name);
 108}
 109#endif /* !USE_HOSTCC */
 110
 111static void fit_get_debug(const void *fit, int noffset,
 112                char *prop_name, int err)
 113{
 114        debug("Can't get '%s' property from FIT 0x%08lx, node: offset %d, name %s (%s)\n",
 115              prop_name, (ulong)fit, noffset, fit_get_name(fit, noffset, NULL),
 116              fdt_strerror(err));
 117}
 118
 119/**
 120 * fit_get_subimage_count - get component (sub-image) count
 121 * @fit: pointer to the FIT format image header
 122 * @images_noffset: offset of images node
 123 *
 124 * returns:
 125 *     number of image components
 126 */
 127int fit_get_subimage_count(const void *fit, int images_noffset)
 128{
 129        int noffset;
 130        int ndepth;
 131        int count = 0;
 132
 133        /* Process its subnodes, print out component images details */
 134        for (ndepth = 0, count = 0,
 135                noffset = fdt_next_node(fit, images_noffset, &ndepth);
 136             (noffset >= 0) && (ndepth > 0);
 137             noffset = fdt_next_node(fit, noffset, &ndepth)) {
 138                if (ndepth == 1) {
 139                        count++;
 140                }
 141        }
 142
 143        return count;
 144}
 145
 146#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT)
 147/**
 148 * fit_print_contents - prints out the contents of the FIT format image
 149 * @fit: pointer to the FIT format image header
 150 * @p: pointer to prefix string
 151 *
 152 * fit_print_contents() formats a multi line FIT image contents description.
 153 * The routine prints out FIT image properties (root node level) followed by
 154 * the details of each component image.
 155 *
 156 * returns:
 157 *     no returned results
 158 */
 159void fit_print_contents(const void *fit)
 160{
 161        char *desc;
 162        char *uname;
 163        int images_noffset;
 164        int confs_noffset;
 165        int noffset;
 166        int ndepth;
 167        int count = 0;
 168        int ret;
 169        const char *p;
 170        time_t timestamp;
 171
 172        /* Indent string is defined in header image.h */
 173        p = IMAGE_INDENT_STRING;
 174
 175        /* Root node properties */
 176        ret = fit_get_desc(fit, 0, &desc);
 177        printf("%sFIT description: ", p);
 178        if (ret)
 179                printf("unavailable\n");
 180        else
 181                printf("%s\n", desc);
 182
 183        if (IMAGE_ENABLE_TIMESTAMP) {
 184                ret = fit_get_timestamp(fit, 0, &timestamp);
 185                printf("%sCreated:         ", p);
 186                if (ret)
 187                        printf("unavailable\n");
 188                else
 189                        genimg_print_time(timestamp);
 190        }
 191
 192        /* Find images parent node offset */
 193        images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
 194        if (images_noffset < 0) {
 195                printf("Can't find images parent node '%s' (%s)\n",
 196                       FIT_IMAGES_PATH, fdt_strerror(images_noffset));
 197                return;
 198        }
 199
 200        /* Process its subnodes, print out component images details */
 201        for (ndepth = 0, count = 0,
 202                noffset = fdt_next_node(fit, images_noffset, &ndepth);
 203             (noffset >= 0) && (ndepth > 0);
 204             noffset = fdt_next_node(fit, noffset, &ndepth)) {
 205                if (ndepth == 1) {
 206                        /*
 207                         * Direct child node of the images parent node,
 208                         * i.e. component image node.
 209                         */
 210                        printf("%s Image %u (%s)\n", p, count++,
 211                               fit_get_name(fit, noffset, NULL));
 212
 213                        fit_image_print(fit, noffset, p);
 214                }
 215        }
 216
 217        /* Find configurations parent node offset */
 218        confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
 219        if (confs_noffset < 0) {
 220                debug("Can't get configurations parent node '%s' (%s)\n",
 221                      FIT_CONFS_PATH, fdt_strerror(confs_noffset));
 222                return;
 223        }
 224
 225        /* get default configuration unit name from default property */
 226        uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL);
 227        if (uname)
 228                printf("%s Default Configuration: '%s'\n", p, uname);
 229
 230        /* Process its subnodes, print out configurations details */
 231        for (ndepth = 0, count = 0,
 232                noffset = fdt_next_node(fit, confs_noffset, &ndepth);
 233             (noffset >= 0) && (ndepth > 0);
 234             noffset = fdt_next_node(fit, noffset, &ndepth)) {
 235                if (ndepth == 1) {
 236                        /*
 237                         * Direct child node of the configurations parent node,
 238                         * i.e. configuration node.
 239                         */
 240                        printf("%s Configuration %u (%s)\n", p, count++,
 241                               fit_get_name(fit, noffset, NULL));
 242
 243                        fit_conf_print(fit, noffset, p);
 244                }
 245        }
 246}
 247
 248/**
 249 * fit_image_print_data() - prints out the hash node details
 250 * @fit: pointer to the FIT format image header
 251 * @noffset: offset of the hash node
 252 * @p: pointer to prefix string
 253 * @type: Type of information to print ("hash" or "sign")
 254 *
 255 * fit_image_print_data() lists properties for the processed hash node
 256 *
 257 * This function avoid using puts() since it prints a newline on the host
 258 * but does not in U-Boot.
 259 *
 260 * returns:
 261 *     no returned results
 262 */
 263static void fit_image_print_data(const void *fit, int noffset, const char *p,
 264                                 const char *type)
 265{
 266        const char *keyname;
 267        uint8_t *value;
 268        int value_len;
 269        char *algo;
 270        int required;
 271        int ret, i;
 272
 273        debug("%s  %s node:    '%s'\n", p, type,
 274              fit_get_name(fit, noffset, NULL));
 275        printf("%s  %s algo:    ", p, type);
 276        if (fit_image_hash_get_algo(fit, noffset, &algo)) {
 277                printf("invalid/unsupported\n");
 278                return;
 279        }
 280        printf("%s", algo);
 281        keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
 282        required = fdt_getprop(fit, noffset, "required", NULL) != NULL;
 283        if (keyname)
 284                printf(":%s", keyname);
 285        if (required)
 286                printf(" (required)");
 287        printf("\n");
 288
 289        ret = fit_image_hash_get_value(fit, noffset, &value,
 290                                        &value_len);
 291        printf("%s  %s value:   ", p, type);
 292        if (ret) {
 293                printf("unavailable\n");
 294        } else {
 295                for (i = 0; i < value_len; i++)
 296                        printf("%02x", value[i]);
 297                printf("\n");
 298        }
 299
 300        debug("%s  %s len:     %d\n", p, type, value_len);
 301
 302        /* Signatures have a time stamp */
 303        if (IMAGE_ENABLE_TIMESTAMP && keyname) {
 304                time_t timestamp;
 305
 306                printf("%s  Timestamp:    ", p);
 307                if (fit_get_timestamp(fit, noffset, &timestamp))
 308                        printf("unavailable\n");
 309                else
 310                        genimg_print_time(timestamp);
 311        }
 312}
 313
 314/**
 315 * fit_image_print_verification_data() - prints out the hash/signature details
 316 * @fit: pointer to the FIT format image header
 317 * @noffset: offset of the hash or signature node
 318 * @p: pointer to prefix string
 319 *
 320 * This lists properties for the processed hash node
 321 *
 322 * returns:
 323 *     no returned results
 324 */
 325static void fit_image_print_verification_data(const void *fit, int noffset,
 326                                       const char *p)
 327{
 328        const char *name;
 329
 330        /*
 331         * Check subnode name, must be equal to "hash" or "signature".
 332         * Multiple hash/signature nodes require unique unit node
 333         * names, e.g. hash-1, hash-2, signature-1, signature-2, etc.
 334         */
 335        name = fit_get_name(fit, noffset, NULL);
 336        if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) {
 337                fit_image_print_data(fit, noffset, p, "Hash");
 338        } else if (!strncmp(name, FIT_SIG_NODENAME,
 339                                strlen(FIT_SIG_NODENAME))) {
 340                fit_image_print_data(fit, noffset, p, "Sign");
 341        }
 342}
 343
 344/**
 345 * fit_image_print - prints out the FIT component image details
 346 * @fit: pointer to the FIT format image header
 347 * @image_noffset: offset of the component image node
 348 * @p: pointer to prefix string
 349 *
 350 * fit_image_print() lists all mandatory properties for the processed component
 351 * image. If present, hash nodes are printed out as well. Load
 352 * address for images of type firmware is also printed out. Since the load
 353 * address is not mandatory for firmware images, it will be output as
 354 * "unavailable" when not present.
 355 *
 356 * returns:
 357 *     no returned results
 358 */
 359void fit_image_print(const void *fit, int image_noffset, const char *p)
 360{
 361        char *desc;
 362        uint8_t type, arch, os, comp;
 363        size_t size;
 364        ulong load, entry;
 365        const void *data;
 366        int noffset;
 367        int ndepth;
 368        int ret;
 369
 370        /* Mandatory properties */
 371        ret = fit_get_desc(fit, image_noffset, &desc);
 372        printf("%s  Description:  ", p);
 373        if (ret)
 374                printf("unavailable\n");
 375        else
 376                printf("%s\n", desc);
 377
 378        if (IMAGE_ENABLE_TIMESTAMP) {
 379                time_t timestamp;
 380
 381                ret = fit_get_timestamp(fit, 0, &timestamp);
 382                printf("%s  Created:      ", p);
 383                if (ret)
 384                        printf("unavailable\n");
 385                else
 386                        genimg_print_time(timestamp);
 387        }
 388
 389        fit_image_get_type(fit, image_noffset, &type);
 390        printf("%s  Type:         %s\n", p, genimg_get_type_name(type));
 391
 392        fit_image_get_comp(fit, image_noffset, &comp);
 393        printf("%s  Compression:  %s\n", p, genimg_get_comp_name(comp));
 394
 395        ret = fit_image_get_data(fit, image_noffset, &data, &size);
 396
 397#ifndef USE_HOSTCC
 398        printf("%s  Data Start:   ", p);
 399        if (ret) {
 400                printf("unavailable\n");
 401        } else {
 402                void *vdata = (void *)data;
 403
 404                printf("0x%08lx\n", (ulong)map_to_sysmem(vdata));
 405        }
 406#endif
 407
 408        printf("%s  Data Size:    ", p);
 409        if (ret)
 410                printf("unavailable\n");
 411        else
 412                genimg_print_size(size);
 413
 414        /* Remaining, type dependent properties */
 415        if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
 416            (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
 417            (type == IH_TYPE_FLATDT)) {
 418                fit_image_get_arch(fit, image_noffset, &arch);
 419                printf("%s  Architecture: %s\n", p, genimg_get_arch_name(arch));
 420        }
 421
 422        if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK)) {
 423                fit_image_get_os(fit, image_noffset, &os);
 424                printf("%s  OS:           %s\n", p, genimg_get_os_name(os));
 425        }
 426
 427        if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
 428            (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK) ||
 429            (type == IH_TYPE_FPGA)) {
 430                ret = fit_image_get_load(fit, image_noffset, &load);
 431                printf("%s  Load Address: ", p);
 432                if (ret)
 433                        printf("unavailable\n");
 434                else
 435                        printf("0x%08lx\n", load);
 436        }
 437
 438        /* optional load address for FDT */
 439        if (type == IH_TYPE_FLATDT && !fit_image_get_load(fit, image_noffset, &load))
 440                printf("%s  Load Address: 0x%08lx\n", p, load);
 441
 442        if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
 443            (type == IH_TYPE_RAMDISK)) {
 444                ret = fit_image_get_entry(fit, image_noffset, &entry);
 445                printf("%s  Entry Point:  ", p);
 446                if (ret)
 447                        printf("unavailable\n");
 448                else
 449                        printf("0x%08lx\n", entry);
 450        }
 451
 452        /* Process all hash subnodes of the component image node */
 453        for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth);
 454             (noffset >= 0) && (ndepth > 0);
 455             noffset = fdt_next_node(fit, noffset, &ndepth)) {
 456                if (ndepth == 1) {
 457                        /* Direct child node of the component image node */
 458                        fit_image_print_verification_data(fit, noffset, p);
 459                }
 460        }
 461}
 462
 463#endif /* !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT) */
 464
 465/**
 466 * fit_get_desc - get node description property
 467 * @fit: pointer to the FIT format image header
 468 * @noffset: node offset
 469 * @desc: double pointer to the char, will hold pointer to the description
 470 *
 471 * fit_get_desc() reads description property from a given node, if
 472 * description is found pointer to it is returned in third call argument.
 473 *
 474 * returns:
 475 *     0, on success
 476 *     -1, on failure
 477 */
 478int fit_get_desc(const void *fit, int noffset, char **desc)
 479{
 480        int len;
 481
 482        *desc = (char *)fdt_getprop(fit, noffset, FIT_DESC_PROP, &len);
 483        if (*desc == NULL) {
 484                fit_get_debug(fit, noffset, FIT_DESC_PROP, len);
 485                return -1;
 486        }
 487
 488        return 0;
 489}
 490
 491/**
 492 * fit_get_timestamp - get node timestamp property
 493 * @fit: pointer to the FIT format image header
 494 * @noffset: node offset
 495 * @timestamp: pointer to the time_t, will hold read timestamp
 496 *
 497 * fit_get_timestamp() reads timestamp property from given node, if timestamp
 498 * is found and has a correct size its value is returned in third call
 499 * argument.
 500 *
 501 * returns:
 502 *     0, on success
 503 *     -1, on property read failure
 504 *     -2, on wrong timestamp size
 505 */
 506int fit_get_timestamp(const void *fit, int noffset, time_t *timestamp)
 507{
 508        int len;
 509        const void *data;
 510
 511        data = fdt_getprop(fit, noffset, FIT_TIMESTAMP_PROP, &len);
 512        if (data == NULL) {
 513                fit_get_debug(fit, noffset, FIT_TIMESTAMP_PROP, len);
 514                return -1;
 515        }
 516        if (len != sizeof(uint32_t)) {
 517                debug("FIT timestamp with incorrect size of (%u)\n", len);
 518                return -2;
 519        }
 520
 521        *timestamp = uimage_to_cpu(*((uint32_t *)data));
 522        return 0;
 523}
 524
 525/**
 526 * fit_image_get_node - get node offset for component image of a given unit name
 527 * @fit: pointer to the FIT format image header
 528 * @image_uname: component image node unit name
 529 *
 530 * fit_image_get_node() finds a component image (within the '/images'
 531 * node) of a provided unit name. If image is found its node offset is
 532 * returned to the caller.
 533 *
 534 * returns:
 535 *     image node offset when found (>=0)
 536 *     negative number on failure (FDT_ERR_* code)
 537 */
 538int fit_image_get_node(const void *fit, const char *image_uname)
 539{
 540        int noffset, images_noffset;
 541
 542        images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
 543        if (images_noffset < 0) {
 544                debug("Can't find images parent node '%s' (%s)\n",
 545                      FIT_IMAGES_PATH, fdt_strerror(images_noffset));
 546                return images_noffset;
 547        }
 548
 549        noffset = fdt_subnode_offset(fit, images_noffset, image_uname);
 550        if (noffset < 0) {
 551                debug("Can't get node offset for image unit name: '%s' (%s)\n",
 552                      image_uname, fdt_strerror(noffset));
 553        }
 554
 555        return noffset;
 556}
 557
 558/**
 559 * fit_image_get_os - get os id for a given component image node
 560 * @fit: pointer to the FIT format image header
 561 * @noffset: component image node offset
 562 * @os: pointer to the uint8_t, will hold os numeric id
 563 *
 564 * fit_image_get_os() finds os property in a given component image node.
 565 * If the property is found, its (string) value is translated to the numeric
 566 * id which is returned to the caller.
 567 *
 568 * returns:
 569 *     0, on success
 570 *     -1, on failure
 571 */
 572int fit_image_get_os(const void *fit, int noffset, uint8_t *os)
 573{
 574        int len;
 575        const void *data;
 576
 577        /* Get OS name from property data */
 578        data = fdt_getprop(fit, noffset, FIT_OS_PROP, &len);
 579        if (data == NULL) {
 580                fit_get_debug(fit, noffset, FIT_OS_PROP, len);
 581                *os = -1;
 582                return -1;
 583        }
 584
 585        /* Translate OS name to id */
 586        *os = genimg_get_os_id(data);
 587        return 0;
 588}
 589
 590/**
 591 * fit_image_get_arch - get arch id for a given component image node
 592 * @fit: pointer to the FIT format image header
 593 * @noffset: component image node offset
 594 * @arch: pointer to the uint8_t, will hold arch numeric id
 595 *
 596 * fit_image_get_arch() finds arch property in a given component image node.
 597 * If the property is found, its (string) value is translated to the numeric
 598 * id which is returned to the caller.
 599 *
 600 * returns:
 601 *     0, on success
 602 *     -1, on failure
 603 */
 604int fit_image_get_arch(const void *fit, int noffset, uint8_t *arch)
 605{
 606        int len;
 607        const void *data;
 608
 609        /* Get architecture name from property data */
 610        data = fdt_getprop(fit, noffset, FIT_ARCH_PROP, &len);
 611        if (data == NULL) {
 612                fit_get_debug(fit, noffset, FIT_ARCH_PROP, len);
 613                *arch = -1;
 614                return -1;
 615        }
 616
 617        /* Translate architecture name to id */
 618        *arch = genimg_get_arch_id(data);
 619        return 0;
 620}
 621
 622/**
 623 * fit_image_get_type - get type id for a given component image node
 624 * @fit: pointer to the FIT format image header
 625 * @noffset: component image node offset
 626 * @type: pointer to the uint8_t, will hold type numeric id
 627 *
 628 * fit_image_get_type() finds type property in a given component image node.
 629 * If the property is found, its (string) value is translated to the numeric
 630 * id which is returned to the caller.
 631 *
 632 * returns:
 633 *     0, on success
 634 *     -1, on failure
 635 */
 636int fit_image_get_type(const void *fit, int noffset, uint8_t *type)
 637{
 638        int len;
 639        const void *data;
 640
 641        /* Get image type name from property data */
 642        data = fdt_getprop(fit, noffset, FIT_TYPE_PROP, &len);
 643        if (data == NULL) {
 644                fit_get_debug(fit, noffset, FIT_TYPE_PROP, len);
 645                *type = -1;
 646                return -1;
 647        }
 648
 649        /* Translate image type name to id */
 650        *type = genimg_get_type_id(data);
 651        return 0;
 652}
 653
 654/**
 655 * fit_image_get_comp - get comp id for a given component image node
 656 * @fit: pointer to the FIT format image header
 657 * @noffset: component image node offset
 658 * @comp: pointer to the uint8_t, will hold comp numeric id
 659 *
 660 * fit_image_get_comp() finds comp property in a given component image node.
 661 * If the property is found, its (string) value is translated to the numeric
 662 * id which is returned to the caller.
 663 *
 664 * returns:
 665 *     0, on success
 666 *     -1, on failure
 667 */
 668int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp)
 669{
 670        int len;
 671        const void *data;
 672
 673        /* Get compression name from property data */
 674        data = fdt_getprop(fit, noffset, FIT_COMP_PROP, &len);
 675        if (data == NULL) {
 676                fit_get_debug(fit, noffset, FIT_COMP_PROP, len);
 677                *comp = -1;
 678                return -1;
 679        }
 680
 681        /* Translate compression name to id */
 682        *comp = genimg_get_comp_id(data);
 683        return 0;
 684}
 685
 686static int fit_image_get_address(const void *fit, int noffset, char *name,
 687                          ulong *load)
 688{
 689        int len, cell_len;
 690        const fdt32_t *cell;
 691        uint64_t load64 = 0;
 692
 693        cell = fdt_getprop(fit, noffset, name, &len);
 694        if (cell == NULL) {
 695                fit_get_debug(fit, noffset, name, len);
 696                return -1;
 697        }
 698
 699        if (len > sizeof(ulong)) {
 700                printf("Unsupported %s address size\n", name);
 701                return -1;
 702        }
 703
 704        cell_len = len >> 2;
 705        /* Use load64 to avoid compiling warning for 32-bit target */
 706        while (cell_len--) {
 707                load64 = (load64 << 32) | uimage_to_cpu(*cell);
 708                cell++;
 709        }
 710        *load = (ulong)load64;
 711
 712        return 0;
 713}
 714/**
 715 * fit_image_get_load() - get load addr property for given component image node
 716 * @fit: pointer to the FIT format image header
 717 * @noffset: component image node offset
 718 * @load: pointer to the uint32_t, will hold load address
 719 *
 720 * fit_image_get_load() finds load address property in a given component
 721 * image node. If the property is found, its value is returned to the caller.
 722 *
 723 * returns:
 724 *     0, on success
 725 *     -1, on failure
 726 */
 727int fit_image_get_load(const void *fit, int noffset, ulong *load)
 728{
 729        return fit_image_get_address(fit, noffset, FIT_LOAD_PROP, load);
 730}
 731
 732/**
 733 * fit_image_get_entry() - get entry point address property
 734 * @fit: pointer to the FIT format image header
 735 * @noffset: component image node offset
 736 * @entry: pointer to the uint32_t, will hold entry point address
 737 *
 738 * This gets the entry point address property for a given component image
 739 * node.
 740 *
 741 * fit_image_get_entry() finds entry point address property in a given
 742 * component image node.  If the property is found, its value is returned
 743 * to the caller.
 744 *
 745 * returns:
 746 *     0, on success
 747 *     -1, on failure
 748 */
 749int fit_image_get_entry(const void *fit, int noffset, ulong *entry)
 750{
 751        return fit_image_get_address(fit, noffset, FIT_ENTRY_PROP, entry);
 752}
 753
 754/**
 755 * fit_image_get_data - get data property and its size for a given component image node
 756 * @fit: pointer to the FIT format image header
 757 * @noffset: component image node offset
 758 * @data: double pointer to void, will hold data property's data address
 759 * @size: pointer to size_t, will hold data property's data size
 760 *
 761 * fit_image_get_data() finds data property in a given component image node.
 762 * If the property is found its data start address and size are returned to
 763 * the caller.
 764 *
 765 * returns:
 766 *     0, on success
 767 *     -1, on failure
 768 */
 769int fit_image_get_data(const void *fit, int noffset,
 770                const void **data, size_t *size)
 771{
 772        int len;
 773
 774        *data = fdt_getprop(fit, noffset, FIT_DATA_PROP, &len);
 775        if (*data == NULL) {
 776                fit_get_debug(fit, noffset, FIT_DATA_PROP, len);
 777                *size = 0;
 778                return -1;
 779        }
 780
 781        *size = len;
 782        return 0;
 783}
 784
 785/**
 786 * Get 'data-offset' property from a given image node.
 787 *
 788 * @fit: pointer to the FIT image header
 789 * @noffset: component image node offset
 790 * @data_offset: holds the data-offset property
 791 *
 792 * returns:
 793 *     0, on success
 794 *     -ENOENT if the property could not be found
 795 */
 796int fit_image_get_data_offset(const void *fit, int noffset, int *data_offset)
 797{
 798        const fdt32_t *val;
 799
 800        val = fdt_getprop(fit, noffset, FIT_DATA_OFFSET_PROP, NULL);
 801        if (!val)
 802                return -ENOENT;
 803
 804        *data_offset = fdt32_to_cpu(*val);
 805
 806        return 0;
 807}
 808
 809/**
 810 * Get 'data-position' property from a given image node.
 811 *
 812 * @fit: pointer to the FIT image header
 813 * @noffset: component image node offset
 814 * @data_position: holds the data-position property
 815 *
 816 * returns:
 817 *     0, on success
 818 *     -ENOENT if the property could not be found
 819 */
 820int fit_image_get_data_position(const void *fit, int noffset,
 821                                int *data_position)
 822{
 823        const fdt32_t *val;
 824
 825        val = fdt_getprop(fit, noffset, FIT_DATA_POSITION_PROP, NULL);
 826        if (!val)
 827                return -ENOENT;
 828
 829        *data_position = fdt32_to_cpu(*val);
 830
 831        return 0;
 832}
 833
 834/**
 835 * Get 'data-size' property from a given image node.
 836 *
 837 * @fit: pointer to the FIT image header
 838 * @noffset: component image node offset
 839 * @data_size: holds the data-size property
 840 *
 841 * returns:
 842 *     0, on success
 843 *     -ENOENT if the property could not be found
 844 */
 845int fit_image_get_data_size(const void *fit, int noffset, int *data_size)
 846{
 847        const fdt32_t *val;
 848
 849        val = fdt_getprop(fit, noffset, FIT_DATA_SIZE_PROP, NULL);
 850        if (!val)
 851                return -ENOENT;
 852
 853        *data_size = fdt32_to_cpu(*val);
 854
 855        return 0;
 856}
 857
 858/**
 859 * fit_image_hash_get_algo - get hash algorithm name
 860 * @fit: pointer to the FIT format image header
 861 * @noffset: hash node offset
 862 * @algo: double pointer to char, will hold pointer to the algorithm name
 863 *
 864 * fit_image_hash_get_algo() finds hash algorithm property in a given hash node.
 865 * If the property is found its data start address is returned to the caller.
 866 *
 867 * returns:
 868 *     0, on success
 869 *     -1, on failure
 870 */
 871int fit_image_hash_get_algo(const void *fit, int noffset, char **algo)
 872{
 873        int len;
 874
 875        *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
 876        if (*algo == NULL) {
 877                fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
 878                return -1;
 879        }
 880
 881        return 0;
 882}
 883
 884/**
 885 * fit_image_hash_get_value - get hash value and length
 886 * @fit: pointer to the FIT format image header
 887 * @noffset: hash node offset
 888 * @value: double pointer to uint8_t, will hold address of a hash value data
 889 * @value_len: pointer to an int, will hold hash data length
 890 *
 891 * fit_image_hash_get_value() finds hash value property in a given hash node.
 892 * If the property is found its data start address and size are returned to
 893 * the caller.
 894 *
 895 * returns:
 896 *     0, on success
 897 *     -1, on failure
 898 */
 899int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value,
 900                                int *value_len)
 901{
 902        int len;
 903
 904        *value = (uint8_t *)fdt_getprop(fit, noffset, FIT_VALUE_PROP, &len);
 905        if (*value == NULL) {
 906                fit_get_debug(fit, noffset, FIT_VALUE_PROP, len);
 907                *value_len = 0;
 908                return -1;
 909        }
 910
 911        *value_len = len;
 912        return 0;
 913}
 914
 915/**
 916 * fit_image_hash_get_ignore - get hash ignore flag
 917 * @fit: pointer to the FIT format image header
 918 * @noffset: hash node offset
 919 * @ignore: pointer to an int, will hold hash ignore flag
 920 *
 921 * fit_image_hash_get_ignore() finds hash ignore property in a given hash node.
 922 * If the property is found and non-zero, the hash algorithm is not verified by
 923 * u-boot automatically.
 924 *
 925 * returns:
 926 *     0, on ignore not found
 927 *     value, on ignore found
 928 */
 929static int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore)
 930{
 931        int len;
 932        int *value;
 933
 934        value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len);
 935        if (value == NULL || len != sizeof(int))
 936                *ignore = 0;
 937        else
 938                *ignore = *value;
 939
 940        return 0;
 941}
 942
 943ulong fit_get_end(const void *fit)
 944{
 945        return map_to_sysmem((void *)(fit + fdt_totalsize(fit)));
 946}
 947
 948/**
 949 * fit_set_timestamp - set node timestamp property
 950 * @fit: pointer to the FIT format image header
 951 * @noffset: node offset
 952 * @timestamp: timestamp value to be set
 953 *
 954 * fit_set_timestamp() attempts to set timestamp property in the requested
 955 * node and returns operation status to the caller.
 956 *
 957 * returns:
 958 *     0, on success
 959 *     -ENOSPC if no space in device tree, -1 for other error
 960 */
 961int fit_set_timestamp(void *fit, int noffset, time_t timestamp)
 962{
 963        uint32_t t;
 964        int ret;
 965
 966        t = cpu_to_uimage(timestamp);
 967        ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t,
 968                                sizeof(uint32_t));
 969        if (ret) {
 970                debug("Can't set '%s' property for '%s' node (%s)\n",
 971                      FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL),
 972                      fdt_strerror(ret));
 973                return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -1;
 974        }
 975
 976        return 0;
 977}
 978
 979/**
 980 * calculate_hash - calculate and return hash for provided input data
 981 * @data: pointer to the input data
 982 * @data_len: data length
 983 * @algo: requested hash algorithm
 984 * @value: pointer to the char, will hold hash value data (caller must
 985 * allocate enough free space)
 986 * value_len: length of the calculated hash
 987 *
 988 * calculate_hash() computes input data hash according to the requested
 989 * algorithm.
 990 * Resulting hash value is placed in caller provided 'value' buffer, length
 991 * of the calculated hash is returned via value_len pointer argument.
 992 *
 993 * returns:
 994 *     0, on success
 995 *    -1, when algo is unsupported
 996 */
 997int calculate_hash(const void *data, int data_len, const char *algo,
 998                        uint8_t *value, int *value_len)
 999{
1000        if (IMAGE_ENABLE_CRC32 && strcmp(algo, "crc32") == 0) {
1001                *((uint32_t *)value) = crc32_wd(0, data, data_len,
1002                                                        CHUNKSZ_CRC32);
1003                *((uint32_t *)value) = cpu_to_uimage(*((uint32_t *)value));
1004                *value_len = 4;
1005        } else if (IMAGE_ENABLE_SHA1 && strcmp(algo, "sha1") == 0) {
1006                sha1_csum_wd((unsigned char *)data, data_len,
1007                             (unsigned char *)value, CHUNKSZ_SHA1);
1008                *value_len = 20;
1009        } else if (IMAGE_ENABLE_SHA256 && strcmp(algo, "sha256") == 0) {
1010                sha256_csum_wd((unsigned char *)data, data_len,
1011                               (unsigned char *)value, CHUNKSZ_SHA256);
1012                *value_len = SHA256_SUM_LEN;
1013        } else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) {
1014                md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
1015                *value_len = 16;
1016        } else {
1017                debug("Unsupported hash alogrithm\n");
1018                return -1;
1019        }
1020        return 0;
1021}
1022
1023static int fit_image_check_hash(const void *fit, int noffset, const void *data,
1024                                size_t size, char **err_msgp)
1025{
1026        uint8_t value[FIT_MAX_HASH_LEN];
1027        int value_len;
1028        char *algo;
1029        uint8_t *fit_value;
1030        int fit_value_len;
1031        int ignore;
1032
1033        *err_msgp = NULL;
1034
1035        if (fit_image_hash_get_algo(fit, noffset, &algo)) {
1036                *err_msgp = "Can't get hash algo property";
1037                return -1;
1038        }
1039        printf("%s", algo);
1040
1041        if (IMAGE_ENABLE_IGNORE) {
1042                fit_image_hash_get_ignore(fit, noffset, &ignore);
1043                if (ignore) {
1044                        printf("-skipped ");
1045                        return 0;
1046                }
1047        }
1048
1049        if (fit_image_hash_get_value(fit, noffset, &fit_value,
1050                                     &fit_value_len)) {
1051                *err_msgp = "Can't get hash value property";
1052                return -1;
1053        }
1054
1055        if (calculate_hash(data, size, algo, value, &value_len)) {
1056                *err_msgp = "Unsupported hash algorithm";
1057                return -1;
1058        }
1059
1060        if (value_len != fit_value_len) {
1061                *err_msgp = "Bad hash value len";
1062                return -1;
1063        } else if (memcmp(value, fit_value, value_len) != 0) {
1064                *err_msgp = "Bad hash value";
1065                return -1;
1066        }
1067
1068        return 0;
1069}
1070
1071/**
1072 * fit_image_verify - verify data integrity
1073 * @fit: pointer to the FIT format image header
1074 * @image_noffset: component image node offset
1075 *
1076 * fit_image_verify() goes over component image hash nodes,
1077 * re-calculates each data hash and compares with the value stored in hash
1078 * node.
1079 *
1080 * returns:
1081 *     1, if all hashes are valid
1082 *     0, otherwise (or on error)
1083 */
1084int fit_image_verify(const void *fit, int image_noffset)
1085{
1086        const void      *data;
1087        size_t          size;
1088        int             noffset = 0;
1089        char            *err_msg = "";
1090        int verify_all = 1;
1091        int ret;
1092
1093        /* Get image data and data length */
1094        if (fit_image_get_data(fit, image_noffset, &data, &size)) {
1095                err_msg = "Can't get image data/size";
1096                goto error;
1097        }
1098
1099        /* Verify all required signatures */
1100        if (IMAGE_ENABLE_VERIFY &&
1101            fit_image_verify_required_sigs(fit, image_noffset, data, size,
1102                                           gd_fdt_blob(), &verify_all)) {
1103                err_msg = "Unable to verify required signature";
1104                goto error;
1105        }
1106
1107        /* Process all hash subnodes of the component image node */
1108        fdt_for_each_subnode(noffset, fit, image_noffset) {
1109                const char *name = fit_get_name(fit, noffset, NULL);
1110
1111                /*
1112                 * Check subnode name, must be equal to "hash".
1113                 * Multiple hash nodes require unique unit node
1114                 * names, e.g. hash-1, hash-2, etc.
1115                 */
1116                if (!strncmp(name, FIT_HASH_NODENAME,
1117                             strlen(FIT_HASH_NODENAME))) {
1118                        if (fit_image_check_hash(fit, noffset, data, size,
1119                                                 &err_msg))
1120                                goto error;
1121                        puts("+ ");
1122                } else if (IMAGE_ENABLE_VERIFY && verify_all &&
1123                                !strncmp(name, FIT_SIG_NODENAME,
1124                                        strlen(FIT_SIG_NODENAME))) {
1125                        ret = fit_image_check_sig(fit, noffset, data,
1126                                                        size, -1, &err_msg);
1127
1128                        /*
1129                         * Show an indication on failure, but do not return
1130                         * an error. Only keys marked 'required' can cause
1131                         * an image validation failure. See the call to
1132                         * fit_image_verify_required_sigs() above.
1133                         */
1134                        if (ret)
1135                                puts("- ");
1136                        else
1137                                puts("+ ");
1138                }
1139        }
1140
1141        if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
1142                err_msg = "Corrupted or truncated tree";
1143                goto error;
1144        }
1145
1146        return 1;
1147
1148error:
1149        printf(" error!\n%s for '%s' hash node in '%s' image node\n",
1150               err_msg, fit_get_name(fit, noffset, NULL),
1151               fit_get_name(fit, image_noffset, NULL));
1152        return 0;
1153}
1154
1155/**
1156 * fit_all_image_verify - verify data integrity for all images
1157 * @fit: pointer to the FIT format image header
1158 *
1159 * fit_all_image_verify() goes over all images in the FIT and
1160 * for every images checks if all it's hashes are valid.
1161 *
1162 * returns:
1163 *     1, if all hashes of all images are valid
1164 *     0, otherwise (or on error)
1165 */
1166int fit_all_image_verify(const void *fit)
1167{
1168        int images_noffset;
1169        int noffset;
1170        int ndepth;
1171        int count;
1172
1173        /* Find images parent node offset */
1174        images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1175        if (images_noffset < 0) {
1176                printf("Can't find images parent node '%s' (%s)\n",
1177                       FIT_IMAGES_PATH, fdt_strerror(images_noffset));
1178                return 0;
1179        }
1180
1181        /* Process all image subnodes, check hashes for each */
1182        printf("## Checking hash(es) for FIT Image at %08lx ...\n",
1183               (ulong)fit);
1184        for (ndepth = 0, count = 0,
1185             noffset = fdt_next_node(fit, images_noffset, &ndepth);
1186                        (noffset >= 0) && (ndepth > 0);
1187                        noffset = fdt_next_node(fit, noffset, &ndepth)) {
1188                if (ndepth == 1) {
1189                        /*
1190                         * Direct child node of the images parent node,
1191                         * i.e. component image node.
1192                         */
1193                        printf("   Hash(es) for Image %u (%s): ", count,
1194                               fit_get_name(fit, noffset, NULL));
1195                        count++;
1196
1197                        if (!fit_image_verify(fit, noffset))
1198                                return 0;
1199                        printf("\n");
1200                }
1201        }
1202        return 1;
1203}
1204
1205/**
1206 * fit_image_check_os - check whether image node is of a given os type
1207 * @fit: pointer to the FIT format image header
1208 * @noffset: component image node offset
1209 * @os: requested image os
1210 *
1211 * fit_image_check_os() reads image os property and compares its numeric
1212 * id with the requested os. Comparison result is returned to the caller.
1213 *
1214 * returns:
1215 *     1 if image is of given os type
1216 *     0 otherwise (or on error)
1217 */
1218int fit_image_check_os(const void *fit, int noffset, uint8_t os)
1219{
1220        uint8_t image_os;
1221
1222        if (fit_image_get_os(fit, noffset, &image_os))
1223                return 0;
1224        return (os == image_os);
1225}
1226
1227/**
1228 * fit_image_check_arch - check whether image node is of a given arch
1229 * @fit: pointer to the FIT format image header
1230 * @noffset: component image node offset
1231 * @arch: requested imagearch
1232 *
1233 * fit_image_check_arch() reads image arch property and compares its numeric
1234 * id with the requested arch. Comparison result is returned to the caller.
1235 *
1236 * returns:
1237 *     1 if image is of given arch
1238 *     0 otherwise (or on error)
1239 */
1240int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)
1241{
1242        uint8_t image_arch;
1243        int aarch32_support = 0;
1244
1245#ifdef CONFIG_ARM64_SUPPORT_AARCH32
1246        aarch32_support = 1;
1247#endif
1248
1249        if (fit_image_get_arch(fit, noffset, &image_arch))
1250                return 0;
1251        return (arch == image_arch) ||
1252                (arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
1253                (arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&
1254                 aarch32_support);
1255}
1256
1257/**
1258 * fit_image_check_type - check whether image node is of a given type
1259 * @fit: pointer to the FIT format image header
1260 * @noffset: component image node offset
1261 * @type: requested image type
1262 *
1263 * fit_image_check_type() reads image type property and compares its numeric
1264 * id with the requested type. Comparison result is returned to the caller.
1265 *
1266 * returns:
1267 *     1 if image is of given type
1268 *     0 otherwise (or on error)
1269 */
1270int fit_image_check_type(const void *fit, int noffset, uint8_t type)
1271{
1272        uint8_t image_type;
1273
1274        if (fit_image_get_type(fit, noffset, &image_type))
1275                return 0;
1276        return (type == image_type);
1277}
1278
1279/**
1280 * fit_image_check_comp - check whether image node uses given compression
1281 * @fit: pointer to the FIT format image header
1282 * @noffset: component image node offset
1283 * @comp: requested image compression type
1284 *
1285 * fit_image_check_comp() reads image compression property and compares its
1286 * numeric id with the requested compression type. Comparison result is
1287 * returned to the caller.
1288 *
1289 * returns:
1290 *     1 if image uses requested compression
1291 *     0 otherwise (or on error)
1292 */
1293int fit_image_check_comp(const void *fit, int noffset, uint8_t comp)
1294{
1295        uint8_t image_comp;
1296
1297        if (fit_image_get_comp(fit, noffset, &image_comp))
1298                return 0;
1299        return (comp == image_comp);
1300}
1301
1302/**
1303 * fit_check_format - sanity check FIT image format
1304 * @fit: pointer to the FIT format image header
1305 *
1306 * fit_check_format() runs a basic sanity FIT image verification.
1307 * Routine checks for mandatory properties, nodes, etc.
1308 *
1309 * returns:
1310 *     1, on success
1311 *     0, on failure
1312 */
1313int fit_check_format(const void *fit)
1314{
1315        /* mandatory / node 'description' property */
1316        if (fdt_getprop(fit, 0, FIT_DESC_PROP, NULL) == NULL) {
1317                debug("Wrong FIT format: no description\n");
1318                return 0;
1319        }
1320
1321        if (IMAGE_ENABLE_TIMESTAMP) {
1322                /* mandatory / node 'timestamp' property */
1323                if (fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) {
1324                        debug("Wrong FIT format: no timestamp\n");
1325                        return 0;
1326                }
1327        }
1328
1329        /* mandatory subimages parent '/images' node */
1330        if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) {
1331                debug("Wrong FIT format: no images parent node\n");
1332                return 0;
1333        }
1334
1335        return 1;
1336}
1337
1338
1339/**
1340 * fit_conf_find_compat
1341 * @fit: pointer to the FIT format image header
1342 * @fdt: pointer to the device tree to compare against
1343 *
1344 * fit_conf_find_compat() attempts to find the configuration whose fdt is the
1345 * most compatible with the passed in device tree.
1346 *
1347 * Example:
1348 *
1349 * / o image-tree
1350 *   |-o images
1351 *   | |-o fdt-1
1352 *   | |-o fdt-2
1353 *   |
1354 *   |-o configurations
1355 *     |-o config-1
1356 *     | |-fdt = fdt-1
1357 *     |
1358 *     |-o config-2
1359 *       |-fdt = fdt-2
1360 *
1361 * / o U-Boot fdt
1362 *   |-compatible = "foo,bar", "bim,bam"
1363 *
1364 * / o kernel fdt1
1365 *   |-compatible = "foo,bar",
1366 *
1367 * / o kernel fdt2
1368 *   |-compatible = "bim,bam", "baz,biz"
1369 *
1370 * Configuration 1 would be picked because the first string in U-Boot's
1371 * compatible list, "foo,bar", matches a compatible string in the root of fdt1.
1372 * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1.
1373 *
1374 * returns:
1375 *     offset to the configuration to use if one was found
1376 *     -1 otherwise
1377 */
1378int fit_conf_find_compat(const void *fit, const void *fdt)
1379{
1380        int ndepth = 0;
1381        int noffset, confs_noffset, images_noffset;
1382        const void *fdt_compat;
1383        int fdt_compat_len;
1384        int best_match_offset = 0;
1385        int best_match_pos = 0;
1386
1387        confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1388        images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1389        if (confs_noffset < 0 || images_noffset < 0) {
1390                debug("Can't find configurations or images nodes.\n");
1391                return -1;
1392        }
1393
1394        fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
1395        if (!fdt_compat) {
1396                debug("Fdt for comparison has no \"compatible\" property.\n");
1397                return -1;
1398        }
1399
1400        /*
1401         * Loop over the configurations in the FIT image.
1402         */
1403        for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
1404                        (noffset >= 0) && (ndepth > 0);
1405                        noffset = fdt_next_node(fit, noffset, &ndepth)) {
1406                const void *kfdt;
1407                const char *kfdt_name;
1408                int kfdt_noffset;
1409                const char *cur_fdt_compat;
1410                int len;
1411                size_t size;
1412                int i;
1413
1414                if (ndepth > 1)
1415                        continue;
1416
1417                kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
1418                if (!kfdt_name) {
1419                        debug("No fdt property found.\n");
1420                        continue;
1421                }
1422                kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
1423                                                  kfdt_name);
1424                if (kfdt_noffset < 0) {
1425                        debug("No image node named \"%s\" found.\n",
1426                              kfdt_name);
1427                        continue;
1428                }
1429                /*
1430                 * Get a pointer to this configuration's fdt.
1431                 */
1432                if (fit_image_get_data(fit, kfdt_noffset, &kfdt, &size)) {
1433                        debug("Failed to get fdt \"%s\".\n", kfdt_name);
1434                        continue;
1435                }
1436
1437                len = fdt_compat_len;
1438                cur_fdt_compat = fdt_compat;
1439                /*
1440                 * Look for a match for each U-Boot compatibility string in
1441                 * turn in this configuration's fdt.
1442                 */
1443                for (i = 0; len > 0 &&
1444                     (!best_match_offset || best_match_pos > i); i++) {
1445                        int cur_len = strlen(cur_fdt_compat) + 1;
1446
1447                        if (!fdt_node_check_compatible(kfdt, 0,
1448                                                       cur_fdt_compat)) {
1449                                best_match_offset = noffset;
1450                                best_match_pos = i;
1451                                break;
1452                        }
1453                        len -= cur_len;
1454                        cur_fdt_compat += cur_len;
1455                }
1456        }
1457        if (!best_match_offset) {
1458                debug("No match found.\n");
1459                return -1;
1460        }
1461
1462        return best_match_offset;
1463}
1464
1465/**
1466 * fit_conf_get_node - get node offset for configuration of a given unit name
1467 * @fit: pointer to the FIT format image header
1468 * @conf_uname: configuration node unit name
1469 *
1470 * fit_conf_get_node() finds a configuration (within the '/configurations'
1471 * parent node) of a provided unit name. If configuration is found its node
1472 * offset is returned to the caller.
1473 *
1474 * When NULL is provided in second argument fit_conf_get_node() will search
1475 * for a default configuration node instead. Default configuration node unit
1476 * name is retrieved from FIT_DEFAULT_PROP property of the '/configurations'
1477 * node.
1478 *
1479 * returns:
1480 *     configuration node offset when found (>=0)
1481 *     negative number on failure (FDT_ERR_* code)
1482 */
1483int fit_conf_get_node(const void *fit, const char *conf_uname)
1484{
1485        int noffset, confs_noffset;
1486        int len;
1487        const char *s;
1488        char *conf_uname_copy = NULL;
1489
1490        confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1491        if (confs_noffset < 0) {
1492                debug("Can't find configurations parent node '%s' (%s)\n",
1493                      FIT_CONFS_PATH, fdt_strerror(confs_noffset));
1494                return confs_noffset;
1495        }
1496
1497        if (conf_uname == NULL) {
1498                /* get configuration unit name from the default property */
1499                debug("No configuration specified, trying default...\n");
1500                conf_uname = (char *)fdt_getprop(fit, confs_noffset,
1501                                                 FIT_DEFAULT_PROP, &len);
1502                if (conf_uname == NULL) {
1503                        fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP,
1504                                      len);
1505                        return len;
1506                }
1507                debug("Found default configuration: '%s'\n", conf_uname);
1508        }
1509
1510        s = strchr(conf_uname, '#');
1511        if (s) {
1512                len = s - conf_uname;
1513                conf_uname_copy = malloc(len + 1);
1514                if (!conf_uname_copy) {
1515                        debug("Can't allocate uname copy: '%s'\n",
1516                                        conf_uname);
1517                        return -ENOMEM;
1518                }
1519                memcpy(conf_uname_copy, conf_uname, len);
1520                conf_uname_copy[len] = '\0';
1521                conf_uname = conf_uname_copy;
1522        }
1523
1524        noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname);
1525        if (noffset < 0) {
1526                debug("Can't get node offset for configuration unit name: '%s' (%s)\n",
1527                      conf_uname, fdt_strerror(noffset));
1528        }
1529
1530        if (conf_uname_copy)
1531                free(conf_uname_copy);
1532
1533        return noffset;
1534}
1535
1536int fit_conf_get_prop_node_count(const void *fit, int noffset,
1537                const char *prop_name)
1538{
1539        return fdt_stringlist_count(fit, noffset, prop_name);
1540}
1541
1542int fit_conf_get_prop_node_index(const void *fit, int noffset,
1543                const char *prop_name, int index)
1544{
1545        const char *uname;
1546        int len;
1547
1548        /* get kernel image unit name from configuration kernel property */
1549        uname = fdt_stringlist_get(fit, noffset, prop_name, index, &len);
1550        if (uname == NULL)
1551                return len;
1552
1553        return fit_image_get_node(fit, uname);
1554}
1555
1556int fit_conf_get_prop_node(const void *fit, int noffset,
1557                const char *prop_name)
1558{
1559        return fit_conf_get_prop_node_index(fit, noffset, prop_name, 0);
1560}
1561
1562/**
1563 * fit_conf_print - prints out the FIT configuration details
1564 * @fit: pointer to the FIT format image header
1565 * @noffset: offset of the configuration node
1566 * @p: pointer to prefix string
1567 *
1568 * fit_conf_print() lists all mandatory properties for the processed
1569 * configuration node.
1570 *
1571 * returns:
1572 *     no returned results
1573 */
1574void fit_conf_print(const void *fit, int noffset, const char *p)
1575{
1576        char *desc;
1577        const char *uname;
1578        int ret;
1579        int fdt_index, loadables_index;
1580
1581        /* Mandatory properties */
1582        ret = fit_get_desc(fit, noffset, &desc);
1583        printf("%s  Description:  ", p);
1584        if (ret)
1585                printf("unavailable\n");
1586        else
1587                printf("%s\n", desc);
1588
1589        uname = fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL);
1590        printf("%s  Kernel:       ", p);
1591        if (uname == NULL)
1592                printf("unavailable\n");
1593        else
1594                printf("%s\n", uname);
1595
1596        /* Optional properties */
1597        uname = fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL);
1598        if (uname)
1599                printf("%s  Init Ramdisk: %s\n", p, uname);
1600
1601        for (fdt_index = 0;
1602             uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP,
1603                                        fdt_index, NULL), uname;
1604             fdt_index++) {
1605
1606                if (fdt_index == 0)
1607                        printf("%s  FDT:          ", p);
1608                else
1609                        printf("%s                ", p);
1610                printf("%s\n", uname);
1611        }
1612
1613        uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL);
1614        if (uname)
1615                printf("%s  FPGA:         %s\n", p, uname);
1616
1617        /* Print out all of the specified loadables */
1618        for (loadables_index = 0;
1619             uname = fdt_stringlist_get(fit, noffset, FIT_LOADABLE_PROP,
1620                                        loadables_index, NULL), uname;
1621             loadables_index++) {
1622                if (loadables_index == 0) {
1623                        printf("%s  Loadables:    ", p);
1624                } else {
1625                        printf("%s                ", p);
1626                }
1627                printf("%s\n", uname);
1628        }
1629}
1630
1631static int fit_image_select(const void *fit, int rd_noffset, int verify)
1632{
1633        fit_image_print(fit, rd_noffset, "   ");
1634
1635        if (verify) {
1636                puts("   Verifying Hash Integrity ... ");
1637                if (!fit_image_verify(fit, rd_noffset)) {
1638                        puts("Bad Data Hash\n");
1639                        return -EACCES;
1640                }
1641                puts("OK\n");
1642        }
1643
1644        return 0;
1645}
1646
1647int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
1648                        ulong addr)
1649{
1650        int cfg_noffset;
1651        void *fit_hdr;
1652        int noffset;
1653
1654        debug("*  %s: using config '%s' from image at 0x%08lx\n",
1655              prop_name, images->fit_uname_cfg, addr);
1656
1657        /* Check whether configuration has this property defined */
1658        fit_hdr = map_sysmem(addr, 0);
1659        cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg);
1660        if (cfg_noffset < 0) {
1661                debug("*  %s: no such config\n", prop_name);
1662                return -EINVAL;
1663        }
1664
1665        noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name);
1666        if (noffset < 0) {
1667                debug("*  %s: no '%s' in config\n", prop_name, prop_name);
1668                return -ENOENT;
1669        }
1670
1671        return noffset;
1672}
1673
1674/**
1675 * fit_get_image_type_property() - get property name for IH_TYPE_...
1676 *
1677 * @return the properly name where we expect to find the image in the
1678 * config node
1679 */
1680static const char *fit_get_image_type_property(int type)
1681{
1682        /*
1683         * This is sort-of available in the uimage_type[] table in image.c
1684         * but we don't have access to the short name, and "fdt" is different
1685         * anyway. So let's just keep it here.
1686         */
1687        switch (type) {
1688        case IH_TYPE_FLATDT:
1689                return FIT_FDT_PROP;
1690        case IH_TYPE_KERNEL:
1691                return FIT_KERNEL_PROP;
1692        case IH_TYPE_RAMDISK:
1693                return FIT_RAMDISK_PROP;
1694        case IH_TYPE_X86_SETUP:
1695                return FIT_SETUP_PROP;
1696        case IH_TYPE_LOADABLE:
1697                return FIT_LOADABLE_PROP;
1698        case IH_TYPE_FPGA:
1699                return FIT_FPGA_PROP;
1700        }
1701
1702        return "unknown";
1703}
1704
1705int fit_image_load(bootm_headers_t *images, ulong addr,
1706                   const char **fit_unamep, const char **fit_uname_configp,
1707                   int arch, int image_type, int bootstage_id,
1708                   enum fit_load_op load_op, ulong *datap, ulong *lenp)
1709{
1710        int cfg_noffset, noffset;
1711        const char *fit_uname;
1712        const char *fit_uname_config;
1713        const char *fit_base_uname_config;
1714        const void *fit;
1715        const void *buf;
1716        size_t size;
1717        int type_ok, os_ok;
1718        ulong load, data, len;
1719        uint8_t os;
1720#ifndef USE_HOSTCC
1721        uint8_t os_arch;
1722#endif
1723        const char *prop_name;
1724        int ret;
1725
1726        fit = map_sysmem(addr, 0);
1727        fit_uname = fit_unamep ? *fit_unamep : NULL;
1728        fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL;
1729        fit_base_uname_config = NULL;
1730        prop_name = fit_get_image_type_property(image_type);
1731        printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);
1732
1733        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
1734        if (!fit_check_format(fit)) {
1735                printf("Bad FIT %s image format!\n", prop_name);
1736                bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
1737                return -ENOEXEC;
1738        }
1739        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
1740        if (fit_uname) {
1741                /* get FIT component image node offset */
1742                bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME);
1743                noffset = fit_image_get_node(fit, fit_uname);
1744        } else {
1745                /*
1746                 * no image node unit name, try to get config
1747                 * node first. If config unit node name is NULL
1748                 * fit_conf_get_node() will try to find default config node
1749                 */
1750                bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
1751                if (IMAGE_ENABLE_BEST_MATCH && !fit_uname_config) {
1752                        cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
1753                } else {
1754                        cfg_noffset = fit_conf_get_node(fit,
1755                                                        fit_uname_config);
1756                }
1757                if (cfg_noffset < 0) {
1758                        puts("Could not find configuration node\n");
1759                        bootstage_error(bootstage_id +
1760                                        BOOTSTAGE_SUB_NO_UNIT_NAME);
1761                        return -ENOENT;
1762                }
1763                fit_base_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
1764                printf("   Using '%s' configuration\n", fit_base_uname_config);
1765                if (image_type == IH_TYPE_KERNEL) {
1766                        /* Remember (and possibly verify) this config */
1767                        images->fit_uname_cfg = fit_base_uname_config;
1768                        if (IMAGE_ENABLE_VERIFY && images->verify) {
1769                                puts("   Verifying Hash Integrity ... ");
1770                                if (fit_config_verify(fit, cfg_noffset)) {
1771                                        puts("Bad Data Hash\n");
1772                                        bootstage_error(bootstage_id +
1773                                                BOOTSTAGE_SUB_HASH);
1774                                        return -EACCES;
1775                                }
1776                                puts("OK\n");
1777                        }
1778                        bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
1779                }
1780
1781                noffset = fit_conf_get_prop_node(fit, cfg_noffset,
1782                                                 prop_name);
1783                fit_uname = fit_get_name(fit, noffset, NULL);
1784        }
1785        if (noffset < 0) {
1786                puts("Could not find subimage node\n");
1787                bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
1788                return -ENOENT;
1789        }
1790
1791        printf("   Trying '%s' %s subimage\n", fit_uname, prop_name);
1792
1793        ret = fit_image_select(fit, noffset, images->verify);
1794        if (ret) {
1795                bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH);
1796                return ret;
1797        }
1798
1799        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
1800#if !defined(USE_HOSTCC) && !defined(CONFIG_SANDBOX)
1801        if (!fit_image_check_target_arch(fit, noffset)) {
1802                puts("Unsupported Architecture\n");
1803                bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
1804                return -ENOEXEC;
1805        }
1806#endif
1807
1808#ifndef USE_HOSTCC
1809        fit_image_get_arch(fit, noffset, &os_arch);
1810        images->os.arch = os_arch;
1811#endif
1812
1813        if (image_type == IH_TYPE_FLATDT &&
1814            !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) {
1815                puts("FDT image is compressed");
1816                return -EPROTONOSUPPORT;
1817        }
1818
1819        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
1820        type_ok = fit_image_check_type(fit, noffset, image_type) ||
1821                  fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE) ||
1822                  (image_type == IH_TYPE_KERNEL &&
1823                   fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD));
1824
1825        os_ok = image_type == IH_TYPE_FLATDT ||
1826                image_type == IH_TYPE_FPGA ||
1827                fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
1828                fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
1829                fit_image_check_os(fit, noffset, IH_OS_OPENRTOS);
1830
1831        /*
1832         * If either of the checks fail, we should report an error, but
1833         * if the image type is coming from the "loadables" field, we
1834         * don't care what it is
1835         */
1836        if ((!type_ok || !os_ok) && image_type != IH_TYPE_LOADABLE) {
1837                fit_image_get_os(fit, noffset, &os);
1838                printf("No %s %s %s Image\n",
1839                       genimg_get_os_name(os),
1840                       genimg_get_arch_name(arch),
1841                       genimg_get_type_name(image_type));
1842                bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
1843                return -EIO;
1844        }
1845
1846        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
1847
1848        /* get image data address and length */
1849        if (fit_image_get_data(fit, noffset, &buf, &size)) {
1850                printf("Could not find %s subimage data!\n", prop_name);
1851                bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
1852                return -ENOENT;
1853        }
1854
1855#if !defined(USE_HOSTCC) && defined(CONFIG_FIT_IMAGE_POST_PROCESS)
1856        /* perform any post-processing on the image data */
1857        board_fit_image_post_process((void **)&buf, &size);
1858#endif
1859
1860        len = (ulong)size;
1861
1862        /* verify that image data is a proper FDT blob */
1863        if (image_type == IH_TYPE_FLATDT && fdt_check_header(buf)) {
1864                puts("Subimage data is not a FDT");
1865                return -ENOEXEC;
1866        }
1867
1868        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);
1869
1870        /*
1871         * Work-around for eldk-4.2 which gives this warning if we try to
1872         * cast in the unmap_sysmem() call:
1873         * warning: initialization discards qualifiers from pointer target type
1874         */
1875        {
1876                void *vbuf = (void *)buf;
1877
1878                data = map_to_sysmem(vbuf);
1879        }
1880
1881        if (load_op == FIT_LOAD_IGNORED) {
1882                /* Don't load */
1883        } else if (fit_image_get_load(fit, noffset, &load)) {
1884                if (load_op == FIT_LOAD_REQUIRED) {
1885                        printf("Can't get %s subimage load address!\n",
1886                               prop_name);
1887                        bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD);
1888                        return -EBADF;
1889                }
1890        } else if (load_op != FIT_LOAD_OPTIONAL_NON_ZERO || load) {
1891                ulong image_start, image_end;
1892                ulong load_end;
1893                void *dst;
1894
1895                /*
1896                 * move image data to the load address,
1897                 * make sure we don't overwrite initial image
1898                 */
1899                image_start = addr;
1900                image_end = addr + fit_get_size(fit);
1901
1902                load_end = load + len;
1903                if (image_type != IH_TYPE_KERNEL &&
1904                    load < image_end && load_end > image_start) {
1905                        printf("Error: %s overwritten\n", prop_name);
1906                        return -EXDEV;
1907                }
1908
1909                printf("   Loading %s from 0x%08lx to 0x%08lx\n",
1910                       prop_name, data, load);
1911
1912                dst = map_sysmem(load, len);
1913                memmove(dst, buf, len);
1914                data = load;
1915        }
1916        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
1917
1918        *datap = data;
1919        *lenp = len;
1920        if (fit_unamep)
1921                *fit_unamep = (char *)fit_uname;
1922        if (fit_uname_configp)
1923                *fit_uname_configp = (char *)(fit_uname_config ? :
1924                                              fit_base_uname_config);
1925
1926        return noffset;
1927}
1928
1929int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
1930                        ulong *setup_start, ulong *setup_len)
1931{
1932        int noffset;
1933        ulong addr;
1934        ulong len;
1935        int ret;
1936
1937        addr = map_to_sysmem(images->fit_hdr_os);
1938        noffset = fit_get_node_from_config(images, FIT_SETUP_PROP, addr);
1939        if (noffset < 0)
1940                return noffset;
1941
1942        ret = fit_image_load(images, addr, NULL, NULL, arch,
1943                             IH_TYPE_X86_SETUP, BOOTSTAGE_ID_FIT_SETUP_START,
1944                             FIT_LOAD_REQUIRED, setup_start, &len);
1945
1946        return ret;
1947}
1948
1949#ifndef USE_HOSTCC
1950int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
1951                   const char **fit_unamep, const char **fit_uname_configp,
1952                   int arch, ulong *datap, ulong *lenp)
1953{
1954        int fdt_noffset, cfg_noffset, count;
1955        const void *fit;
1956        const char *fit_uname = NULL;
1957        const char *fit_uname_config = NULL;
1958        char *fit_uname_config_copy = NULL;
1959        char *next_config = NULL;
1960        ulong load, len;
1961#ifdef CONFIG_OF_LIBFDT_OVERLAY
1962        ulong image_start, image_end;
1963        ulong ovload, ovlen;
1964        const char *uconfig;
1965        const char *uname;
1966        void *base, *ov;
1967        int i, err, noffset, ov_noffset;
1968#endif
1969
1970        fit_uname = fit_unamep ? *fit_unamep : NULL;
1971
1972        if (fit_uname_configp && *fit_uname_configp) {
1973                fit_uname_config_copy = strdup(*fit_uname_configp);
1974                if (!fit_uname_config_copy)
1975                        return -ENOMEM;
1976
1977                next_config = strchr(fit_uname_config_copy, '#');
1978                if (next_config)
1979                        *next_config++ = '\0';
1980                if (next_config - 1 > fit_uname_config_copy)
1981                        fit_uname_config = fit_uname_config_copy;
1982        }
1983
1984        fdt_noffset = fit_image_load(images,
1985                addr, &fit_uname, &fit_uname_config,
1986                arch, IH_TYPE_FLATDT,
1987                BOOTSTAGE_ID_FIT_FDT_START,
1988                FIT_LOAD_OPTIONAL, &load, &len);
1989
1990        if (fdt_noffset < 0)
1991                goto out;
1992
1993        debug("fit_uname=%s, fit_uname_config=%s\n",
1994                        fit_uname ? fit_uname : "<NULL>",
1995                        fit_uname_config ? fit_uname_config : "<NULL>");
1996
1997        fit = map_sysmem(addr, 0);
1998
1999        cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
2000
2001        /* single blob, or error just return as well */
2002        count = fit_conf_get_prop_node_count(fit, cfg_noffset, FIT_FDT_PROP);
2003        if (count <= 1 && !next_config)
2004                goto out;
2005
2006        /* we need to apply overlays */
2007
2008#ifdef CONFIG_OF_LIBFDT_OVERLAY
2009        image_start = addr;
2010        image_end = addr + fit_get_size(fit);
2011        /* verify that relocation took place by load address not being in fit */
2012        if (load >= image_start && load < image_end) {
2013                /* check is simplified; fit load checks for overlaps */
2014                printf("Overlayed FDT requires relocation\n");
2015                fdt_noffset = -EBADF;
2016                goto out;
2017        }
2018
2019        base = map_sysmem(load, len);
2020
2021        /* apply extra configs in FIT first, followed by args */
2022        for (i = 1; ; i++) {
2023                if (i < count) {
2024                        noffset = fit_conf_get_prop_node_index(fit, cfg_noffset,
2025                                                               FIT_FDT_PROP, i);
2026                        uname = fit_get_name(fit, noffset, NULL);
2027                        uconfig = NULL;
2028                } else {
2029                        if (!next_config)
2030                                break;
2031                        uconfig = next_config;
2032                        next_config = strchr(next_config, '#');
2033                        if (next_config)
2034                                *next_config++ = '\0';
2035                        uname = NULL;
2036                }
2037
2038                debug("%d: using uname=%s uconfig=%s\n", i, uname, uconfig);
2039
2040                ov_noffset = fit_image_load(images,
2041                        addr, &uname, &uconfig,
2042                        arch, IH_TYPE_FLATDT,
2043                        BOOTSTAGE_ID_FIT_FDT_START,
2044                        FIT_LOAD_REQUIRED, &ovload, &ovlen);
2045                if (ov_noffset < 0) {
2046                        printf("load of %s failed\n", uname);
2047                        continue;
2048                }
2049                debug("%s loaded at 0x%08lx len=0x%08lx\n",
2050                                uname, ovload, ovlen);
2051                ov = map_sysmem(ovload, ovlen);
2052
2053                base = map_sysmem(load, len + ovlen);
2054                err = fdt_open_into(base, base, len + ovlen);
2055                if (err < 0) {
2056                        printf("failed on fdt_open_into\n");
2057                        fdt_noffset = err;
2058                        goto out;
2059                }
2060                /* the verbose method prints out messages on error */
2061                err = fdt_overlay_apply_verbose(base, ov);
2062                if (err < 0) {
2063                        fdt_noffset = err;
2064                        goto out;
2065                }
2066                fdt_pack(base);
2067                len = fdt_totalsize(base);
2068        }
2069#else
2070        printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
2071        fdt_noffset = -EBADF;
2072#endif
2073
2074out:
2075        if (datap)
2076                *datap = load;
2077        if (lenp)
2078                *lenp = len;
2079        if (fit_unamep)
2080                *fit_unamep = fit_uname;
2081        if (fit_uname_configp)
2082                *fit_uname_configp = fit_uname_config;
2083
2084        if (fit_uname_config_copy)
2085                free(fit_uname_config_copy);
2086        return fdt_noffset;
2087}
2088#endif
2089