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