]> git.sur5r.net Git - u-boot/blob - common/image.c
Add MD5 support to the new uImage format
[u-boot] / common / image.c
1 /*
2  * (C) Copyright 2008 Semihalf
3  *
4  * (C) Copyright 2000-2006
5  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
6  *
7  * See file CREDITS for list of people who contributed to this
8  * project.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23  * MA 02111-1307 USA
24  */
25
26 #define DEBUG
27
28 #ifndef USE_HOSTCC
29 #include <common.h>
30 #include <watchdog.h>
31
32 #ifdef CONFIG_SHOW_BOOT_PROGRESS
33 #include <status_led.h>
34 #endif
35
36 #ifdef CONFIG_HAS_DATAFLASH
37 #include <dataflash.h>
38 #endif
39
40 #ifdef CONFIG_LOGBUFFER
41 #include <logbuff.h>
42 #endif
43
44 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE)
45 #include <rtc.h>
46 #endif
47
48 #include <image.h>
49
50 #if defined(CONFIG_FIT) || defined (CONFIG_OF_LIBFDT)
51 #include <fdt.h>
52 #include <libfdt.h>
53 #include <fdt_support.h>
54 #endif
55
56 #if defined(CONFIG_FIT)
57 #include <md5.h>
58 #include <sha1.h>
59
60 static int fit_check_ramdisk (const void *fit, int os_noffset,
61                 uint8_t arch, int verify);
62 #endif
63
64 #ifdef CONFIG_CMD_BDI
65 extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
66 #endif
67
68 DECLARE_GLOBAL_DATA_PTR;
69
70 static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
71                                                 int verify);
72 #else
73 #include "mkimage.h"
74 #include <md5.h>
75 #include <time.h>
76 #include <image.h>
77 #endif /* !USE_HOSTCC*/
78
79 typedef struct table_entry {
80         int     id;             /* as defined in image.h        */
81         char    *sname;         /* short (input) name           */
82         char    *lname;         /* long (output) name           */
83 } table_entry_t;
84
85 static table_entry_t uimage_arch[] = {
86         {       IH_ARCH_INVALID,        NULL,           "Invalid ARCH", },
87         {       IH_ARCH_ALPHA,          "alpha",        "Alpha",        },
88         {       IH_ARCH_ARM,            "arm",          "ARM",          },
89         {       IH_ARCH_I386,           "x86",          "Intel x86",    },
90         {       IH_ARCH_IA64,           "ia64",         "IA64",         },
91         {       IH_ARCH_M68K,           "m68k",         "M68K",         },
92         {       IH_ARCH_MICROBLAZE,     "microblaze",   "MicroBlaze",   },
93         {       IH_ARCH_MIPS,           "mips",         "MIPS",         },
94         {       IH_ARCH_MIPS64,         "mips64",       "MIPS 64 Bit",  },
95         {       IH_ARCH_NIOS,           "nios",         "NIOS",         },
96         {       IH_ARCH_NIOS2,          "nios2",        "NIOS II",      },
97         {       IH_ARCH_PPC,            "ppc",          "PowerPC",      },
98         {       IH_ARCH_S390,           "s390",         "IBM S390",     },
99         {       IH_ARCH_SH,             "sh",           "SuperH",       },
100         {       IH_ARCH_SPARC,          "sparc",        "SPARC",        },
101         {       IH_ARCH_SPARC64,        "sparc64",      "SPARC 64 Bit", },
102         {       IH_ARCH_BLACKFIN,       "blackfin",     "Blackfin",     },
103         {       IH_ARCH_AVR32,          "avr32",        "AVR32",        },
104         {       -1,                     "",             "",             },
105 };
106
107 static table_entry_t uimage_os[] = {
108         {       IH_OS_INVALID,  NULL,           "Invalid OS",           },
109 #if defined(CONFIG_ARTOS) || defined(USE_HOSTCC)
110         {       IH_OS_ARTOS,    "artos",        "ARTOS",                },
111 #endif
112         {       IH_OS_LINUX,    "linux",        "Linux",                },
113 #if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC)
114         {       IH_OS_LYNXOS,   "lynxos",       "LynxOS",               },
115 #endif
116         {       IH_OS_NETBSD,   "netbsd",       "NetBSD",               },
117         {       IH_OS_RTEMS,    "rtems",        "RTEMS",                },
118         {       IH_OS_U_BOOT,   "u-boot",       "U-Boot",               },
119 #if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)
120         {       IH_OS_QNX,      "qnx",          "QNX",                  },
121         {       IH_OS_VXWORKS,  "vxworks",      "VxWorks",              },
122 #endif
123 #ifdef USE_HOSTCC
124         {       IH_OS_4_4BSD,   "4_4bsd",       "4_4BSD",               },
125         {       IH_OS_DELL,     "dell",         "Dell",                 },
126         {       IH_OS_ESIX,     "esix",         "Esix",                 },
127         {       IH_OS_FREEBSD,  "freebsd",      "FreeBSD",              },
128         {       IH_OS_IRIX,     "irix",         "Irix",                 },
129         {       IH_OS_NCR,      "ncr",          "NCR",                  },
130         {       IH_OS_OPENBSD,  "openbsd",      "OpenBSD",              },
131         {       IH_OS_PSOS,     "psos",         "pSOS",                 },
132         {       IH_OS_SCO,      "sco",          "SCO",                  },
133         {       IH_OS_SOLARIS,  "solaris",      "Solaris",              },
134         {       IH_OS_SVR4,     "svr4",         "SVR4",                 },
135 #endif
136         {       -1,             "",             "",                     },
137 };
138
139 static table_entry_t uimage_type[] = {
140         {       IH_TYPE_INVALID,    NULL,         "Invalid Image",      },
141         {       IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image",   },
142         {       IH_TYPE_FIRMWARE,   "firmware",   "Firmware",           },
143         {       IH_TYPE_KERNEL,     "kernel",     "Kernel Image",       },
144         {       IH_TYPE_MULTI,      "multi",      "Multi-File Image",   },
145         {       IH_TYPE_RAMDISK,    "ramdisk",    "RAMDisk Image",      },
146         {       IH_TYPE_SCRIPT,     "script",     "Script",             },
147         {       IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
148         {       IH_TYPE_FLATDT,     "flat_dt",    "Flat Device Tree",   },
149         {       -1,                 "",           "",                   },
150 };
151
152 static table_entry_t uimage_comp[] = {
153         {       IH_COMP_NONE,   "none",         "uncompressed",         },
154         {       IH_COMP_BZIP2,  "bzip2",        "bzip2 compressed",     },
155         {       IH_COMP_GZIP,   "gzip",         "gzip compressed",      },
156         {       -1,             "",             "",                     },
157 };
158
159 unsigned long crc32 (unsigned long, const unsigned char *, unsigned int);
160 static void genimg_print_size (uint32_t size);
161 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
162 static void genimg_print_time (time_t timestamp);
163 #endif
164
165 /*****************************************************************************/
166 /* Legacy format routines */
167 /*****************************************************************************/
168 int image_check_hcrc (image_header_t *hdr)
169 {
170         ulong hcrc;
171         ulong len = image_get_header_size ();
172         image_header_t header;
173
174         /* Copy header so we can blank CRC field for re-calculation */
175         memmove (&header, (char *)hdr, image_get_header_size ());
176         image_set_hcrc (&header, 0);
177
178         hcrc = crc32 (0, (unsigned char *)&header, len);
179
180         return (hcrc == image_get_hcrc (hdr));
181 }
182
183 int image_check_dcrc (image_header_t *hdr)
184 {
185         ulong data = image_get_data (hdr);
186         ulong len = image_get_data_size (hdr);
187         ulong dcrc = crc32 (0, (unsigned char *)data, len);
188
189         return (dcrc == image_get_dcrc (hdr));
190 }
191
192 #ifndef USE_HOSTCC
193 int image_check_dcrc_wd (image_header_t *hdr, ulong chunksz)
194 {
195         ulong dcrc = 0;
196         ulong len = image_get_data_size (hdr);
197         ulong data = image_get_data (hdr);
198
199 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
200         ulong cdata = data;
201         ulong edata = cdata + len;
202
203         while (cdata < edata) {
204                 ulong chunk = edata - cdata;
205
206                 if (chunk > chunksz)
207                         chunk = chunksz;
208                 dcrc = crc32 (dcrc, (unsigned char *)cdata, chunk);
209                 cdata += chunk;
210
211                 WATCHDOG_RESET ();
212         }
213 #else
214         dcrc = crc32 (0, (unsigned char *)data, len);
215 #endif
216
217         return (dcrc == image_get_dcrc (hdr));
218 }
219 #endif /* !USE_HOSTCC */
220
221 /**
222  * image_multi_count - get component (sub-image) count
223  * @hdr: pointer to the header of the multi component image
224  *
225  * image_multi_count() returns number of components in a multi
226  * component image.
227  *
228  * Note: no checking of the image type is done, caller must pass
229  * a valid multi component image.
230  *
231  * returns:
232  *     number of components
233  */
234 ulong image_multi_count (image_header_t *hdr)
235 {
236         ulong i, count = 0;
237         uint32_t *size;
238
239         /* get start of the image payload, which in case of multi
240          * component images that points to a table of component sizes */
241         size = (uint32_t *)image_get_data (hdr);
242
243         /* count non empty slots */
244         for (i = 0; size[i]; ++i)
245                 count++;
246
247         return count;
248 }
249
250 /**
251  * image_multi_getimg - get component data address and size
252  * @hdr: pointer to the header of the multi component image
253  * @idx: index of the requested component
254  * @data: pointer to a ulong variable, will hold component data address
255  * @len: pointer to a ulong variable, will hold component size
256  *
257  * image_multi_getimg() returns size and data address for the requested
258  * component in a multi component image.
259  *
260  * Note: no checking of the image type is done, caller must pass
261  * a valid multi component image.
262  *
263  * returns:
264  *     data address and size of the component, if idx is valid
265  *     0 in data and len, if idx is out of range
266  */
267 void image_multi_getimg (image_header_t *hdr, ulong idx,
268                         ulong *data, ulong *len)
269 {
270         int i;
271         uint32_t *size;
272         ulong offset, tail, count, img_data;
273
274         /* get number of component */
275         count = image_multi_count (hdr);
276
277         /* get start of the image payload, which in case of multi
278          * component images that points to a table of component sizes */
279         size = (uint32_t *)image_get_data (hdr);
280
281         /* get address of the proper component data start, which means
282          * skipping sizes table (add 1 for last, null entry) */
283         img_data = image_get_data (hdr) + (count + 1) * sizeof (uint32_t);
284
285         if (idx < count) {
286                 *len = uimage_to_cpu (size[idx]);
287                 offset = 0;
288                 tail = 0;
289
290                 /* go over all indices preceding requested component idx */
291                 for (i = 0; i < idx; i++) {
292                         /* add up i-th component size */
293                         offset += uimage_to_cpu (size[i]);
294
295                         /* add up alignment for i-th component */
296                         tail += (4 - uimage_to_cpu (size[i]) % 4);
297                 }
298
299                 /* calculate idx-th component data address */
300                 *data = img_data + offset + tail;
301         } else {
302                 *len = 0;
303                 *data = 0;
304         }
305 }
306
307 static void image_print_type (image_header_t *hdr)
308 {
309         const char *os, *arch, *type, *comp;
310
311         os = genimg_get_os_name (image_get_os (hdr));
312         arch = genimg_get_arch_name (image_get_arch (hdr));
313         type = genimg_get_type_name (image_get_type (hdr));
314         comp = genimg_get_comp_name (image_get_comp (hdr));
315
316         printf ("%s %s %s (%s)\n", arch, os, type, comp);
317 }
318
319 /**
320  * __image_print_contents - prints out the contents of the legacy format image
321  * @hdr: pointer to the legacy format image header
322  * @p: pointer to prefix string
323  *
324  * __image_print_contents() formats a multi line legacy image contents description.
325  * The routine prints out all header fields followed by the size/offset data
326  * for MULTI/SCRIPT images.
327  *
328  * returns:
329  *     no returned results
330  */
331 static void __image_print_contents (image_header_t *hdr, const char *p)
332 {
333         printf ("%sImage Name:   %.*s\n", p, IH_NMLEN, image_get_name (hdr));
334 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
335         printf ("%sCreated:      ", p);
336         genimg_print_time ((time_t)image_get_time (hdr));
337 #endif
338         printf ("%sImage Type:   ", p);
339         image_print_type (hdr);
340         printf ("%sData Size:    ", p);
341         genimg_print_size (image_get_data_size (hdr));
342         printf ("%sLoad Address: %08x\n", p, image_get_load (hdr));
343         printf ("%sEntry Point:  %08x\n", p, image_get_ep (hdr));
344
345         if (image_check_type (hdr, IH_TYPE_MULTI) ||
346                         image_check_type (hdr, IH_TYPE_SCRIPT)) {
347                 int i;
348                 ulong data, len;
349                 ulong count = image_multi_count (hdr);
350
351                 printf ("%sContents:\n", p);
352                 for (i = 0; i < count; i++) {
353                         image_multi_getimg (hdr, i, &data, &len);
354
355                         printf ("%s   Image %d: ", p, i);
356                         genimg_print_size (len);
357
358                         if (image_check_type (hdr, IH_TYPE_SCRIPT) && i > 0) {
359                                 /*
360                                  * the user may need to know offsets
361                                  * if planning to do something with
362                                  * multiple files
363                                  */
364                                 printf ("%s    Offset = 0x%08lx\n", p, data);
365                         }
366                 }
367         }
368 }
369
370 inline void image_print_contents (image_header_t *hdr)
371 {
372         __image_print_contents (hdr, "   ");
373 }
374
375 inline void image_print_contents_noindent (image_header_t *hdr)
376 {
377         __image_print_contents (hdr, "");
378 }
379
380 #ifndef USE_HOSTCC
381 /**
382  * image_get_ramdisk - get and verify ramdisk image
383  * @rd_addr: ramdisk image start address
384  * @arch: expected ramdisk architecture
385  * @verify: checksum verification flag
386  *
387  * image_get_ramdisk() returns a pointer to the verified ramdisk image
388  * header. Routine receives image start address and expected architecture
389  * flag. Verification done covers data and header integrity and os/type/arch
390  * fields checking.
391  *
392  * If dataflash support is enabled routine checks for dataflash addresses
393  * and handles required dataflash reads.
394  *
395  * returns:
396  *     pointer to a ramdisk image header, if image was found and valid
397  *     otherwise, return NULL
398  */
399 static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
400                                                 int verify)
401 {
402         image_header_t *rd_hdr = (image_header_t *)rd_addr;
403
404         if (!image_check_magic (rd_hdr)) {
405                 puts ("Bad Magic Number\n");
406                 show_boot_progress (-10);
407                 return NULL;
408         }
409
410         if (!image_check_hcrc (rd_hdr)) {
411                 puts ("Bad Header Checksum\n");
412                 show_boot_progress (-11);
413                 return NULL;
414         }
415
416         show_boot_progress (10);
417         image_print_contents (rd_hdr);
418
419         if (verify) {
420                 puts("   Verifying Checksum ... ");
421                 if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) {
422                         puts ("Bad Data CRC\n");
423                         show_boot_progress (-12);
424                         return NULL;
425                 }
426                 puts("OK\n");
427         }
428
429         show_boot_progress (11);
430
431         if (!image_check_os (rd_hdr, IH_OS_LINUX) ||
432             !image_check_arch (rd_hdr, arch) ||
433             !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {
434                 printf ("No Linux %s Ramdisk Image\n",
435                                 genimg_get_arch_name(arch));
436                 show_boot_progress (-13);
437                 return NULL;
438         }
439
440         return rd_hdr;
441 }
442 #endif /* !USE_HOSTCC */
443
444 /*****************************************************************************/
445 /* Shared dual-format routines */
446 /*****************************************************************************/
447 #ifndef USE_HOSTCC
448 int getenv_verify (void)
449 {
450         char *s = getenv ("verify");
451         return (s && (*s == 'n')) ? 0 : 1;
452 }
453
454 int getenv_autostart (void)
455 {
456         char *s = getenv ("autostart");
457         return (s && (*s == 'n')) ? 0 : 1;
458 }
459
460 ulong getenv_bootm_low(void)
461 {
462         char *s = getenv ("bootm_low");
463         if (s) {
464                 ulong tmp = simple_strtoul (s, NULL, 16);
465                 return tmp;
466         }
467
468 #if defined(CFG_SDRAM_BASE)
469         return CFG_SDRAM_BASE;
470 #elif defined(CONFIG_ARM)
471         return gd->bd->bi_dram[0].start;
472 #else
473         return 0;
474 #endif
475 }
476
477 ulong getenv_bootm_size(void)
478 {
479         char *s = getenv ("bootm_size");
480         if (s) {
481                 ulong tmp = simple_strtoul (s, NULL, 16);
482                 return tmp;
483         }
484
485 #if defined(CONFIG_ARM)
486         return gd->bd->bi_dram[0].size;
487 #else
488         return gd->bd->bi_memsize;
489 #endif
490 }
491
492 void memmove_wd (void *to, void *from, size_t len, ulong chunksz)
493 {
494 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
495         while (len > 0) {
496                 size_t tail = (len > chunksz) ? chunksz : len;
497                 WATCHDOG_RESET ();
498                 memmove (to, from, tail);
499                 to += tail;
500                 from += tail;
501                 len -= tail;
502         }
503 #else   /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
504         memmove (to, from, len);
505 #endif  /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
506 }
507 #endif /* !USE_HOSTCC */
508
509 static void genimg_print_size (uint32_t size)
510 {
511 #ifndef USE_HOSTCC
512         printf ("%d Bytes = ", size);
513         print_size (size, "\n");
514 #else
515         printf ("%d Bytes = %.2f kB = %.2f MB\n",
516                         size, (double)size / 1.024e3,
517                         (double)size / 1.048576e6);
518 #endif
519 }
520
521 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
522 static void genimg_print_time (time_t timestamp)
523 {
524 #ifndef USE_HOSTCC
525         struct rtc_time tm;
526
527         to_tm (timestamp, &tm);
528         printf ("%4d-%02d-%02d  %2d:%02d:%02d UTC\n",
529                         tm.tm_year, tm.tm_mon, tm.tm_mday,
530                         tm.tm_hour, tm.tm_min, tm.tm_sec);
531 #else
532         printf ("%s", ctime(&timestamp));
533 #endif
534 }
535 #endif /* CONFIG_TIMESTAMP || CONFIG_CMD_DATE || USE_HOSTCC */
536
537 /**
538  * get_table_entry_name - translate entry id to long name
539  * @table: pointer to a translation table for entries of a specific type
540  * @msg: message to be returned when translation fails
541  * @id: entry id to be translated
542  *
543  * get_table_entry_name() will go over translation table trying to find
544  * entry that matches given id. If matching entry is found, its long
545  * name is returned to the caller.
546  *
547  * returns:
548  *     long entry name if translation succeeds
549  *     msg otherwise
550  */
551 static char *get_table_entry_name (table_entry_t *table, char *msg, int id)
552 {
553         for (; table->id >= 0; ++table) {
554                 if (table->id == id)
555                         return (table->lname);
556         }
557         return (msg);
558 }
559
560 const char *genimg_get_os_name (uint8_t os)
561 {
562         return (get_table_entry_name (uimage_os, "Unknown OS", os));
563 }
564
565 const char *genimg_get_arch_name (uint8_t arch)
566 {
567         return (get_table_entry_name (uimage_arch, "Unknown Architecture", arch));
568 }
569
570 const char *genimg_get_type_name (uint8_t type)
571 {
572         return (get_table_entry_name (uimage_type, "Unknown Image", type));
573 }
574
575 const char *genimg_get_comp_name (uint8_t comp)
576 {
577         return (get_table_entry_name (uimage_comp, "Unknown Compression", comp));
578 }
579
580 /**
581  * get_table_entry_id - translate short entry name to id
582  * @table: pointer to a translation table for entries of a specific type
583  * @table_name: to be used in case of error
584  * @name: entry short name to be translated
585  *
586  * get_table_entry_id() will go over translation table trying to find
587  * entry that matches given short name. If matching entry is found,
588  * its id returned to the caller.
589  *
590  * returns:
591  *     entry id if translation succeeds
592  *     -1 otherwise
593  */
594 static int get_table_entry_id (table_entry_t *table,
595                 const char *table_name, const char *name)
596 {
597         table_entry_t *t;
598 #ifdef USE_HOSTCC
599         int first = 1;
600
601         for (t = table; t->id >= 0; ++t) {
602                 if (t->sname && strcasecmp(t->sname, name) == 0)
603                         return (t->id);
604         }
605
606         fprintf (stderr, "\nInvalid %s Type - valid names are", table_name);
607         for (t = table; t->id >= 0; ++t) {
608                 if (t->sname == NULL)
609                         continue;
610                 fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname);
611                 first = 0;
612         }
613         fprintf (stderr, "\n");
614 #else
615         for (t = table; t->id >= 0; ++t) {
616                 if (t->sname && strcmp(t->sname, name) == 0)
617                         return (t->id);
618         }
619         debug ("Invalid %s Type: %s\n", table_name, name);
620 #endif /* USE_HOSTCC */
621         return (-1);
622 }
623
624 int genimg_get_os_id (const char *name)
625 {
626         return (get_table_entry_id (uimage_os, "OS", name));
627 }
628
629 int genimg_get_arch_id (const char *name)
630 {
631         return (get_table_entry_id (uimage_arch, "CPU", name));
632 }
633
634 int genimg_get_type_id (const char *name)
635 {
636         return (get_table_entry_id (uimage_type, "Image", name));
637 }
638
639 int genimg_get_comp_id (const char *name)
640 {
641         return (get_table_entry_id (uimage_comp, "Compression", name));
642 }
643
644 #ifndef USE_HOSTCC
645 /**
646  * genimg_get_format - get image format type
647  * @img_addr: image start address
648  *
649  * genimg_get_format() checks whether provided address points to a valid
650  * legacy or FIT image.
651  *
652  * New uImage format and FDT blob are based on a libfdt. FDT blob
653  * may be passed directly or embedded in a FIT image. In both situations
654  * genimg_get_format() must be able to dectect libfdt header.
655  *
656  * returns:
657  *     image format type or IMAGE_FORMAT_INVALID if no image is present
658  */
659 int genimg_get_format (void *img_addr)
660 {
661         ulong           format = IMAGE_FORMAT_INVALID;
662         image_header_t  *hdr;
663 #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
664         char            *fit_hdr;
665 #endif
666
667         hdr = (image_header_t *)img_addr;
668         if (image_check_magic(hdr))
669                 format = IMAGE_FORMAT_LEGACY;
670 #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
671         else {
672                 fit_hdr = (char *)img_addr;
673                 if (fdt_check_header (fit_hdr) == 0)
674                         format = IMAGE_FORMAT_FIT;
675         }
676 #endif
677
678         return format;
679 }
680
681 /**
682  * genimg_get_image - get image from special storage (if necessary)
683  * @img_addr: image start address
684  *
685  * genimg_get_image() checks if provided image start adddress is located
686  * in a dataflash storage. If so, image is moved to a system RAM memory.
687  *
688  * returns:
689  *     image start address after possible relocation from special storage
690  */
691 ulong genimg_get_image (ulong img_addr)
692 {
693         ulong ram_addr = img_addr;
694
695 #ifdef CONFIG_HAS_DATAFLASH
696         ulong h_size, d_size;
697
698         if (addr_dataflash (img_addr)){
699                 /* ger RAM address */
700                 ram_addr = CFG_LOAD_ADDR;
701
702                 /* get header size */
703                 h_size = image_get_header_size ();
704 #if defined(CONFIG_FIT)
705                 if (sizeof(struct fdt_header) > h_size)
706                         h_size = sizeof(struct fdt_header);
707 #endif
708
709                 /* read in header */
710                 debug ("   Reading image header from dataflash address "
711                         "%08lx to RAM address %08lx\n", img_addr, ram_addr);
712
713                 read_dataflash (img_addr, h_size, (char *)ram_addr);
714
715                 /* get data size */
716                 switch (genimg_get_format ((void *)ram_addr)) {
717                 case IMAGE_FORMAT_LEGACY:
718                         d_size = image_get_data_size ((image_header_t *)ram_addr);
719                         debug ("   Legacy format image found at 0x%08lx, size 0x%08lx\n",
720                                         ram_addr, d_size);
721                         break;
722 #if defined(CONFIG_FIT)
723                 case IMAGE_FORMAT_FIT:
724                         d_size = fit_get_size ((const void *)ram_addr) - h_size;
725                         debug ("   FIT/FDT format image found at 0x%08lx, size 0x%08lx\n",
726                                         ram_addr, d_size);
727                         break;
728 #endif
729                 default:
730                         printf ("   No valid image found at 0x%08lx\n", img_addr);
731                         return ram_addr;
732                 }
733
734                 /* read in image data */
735                 debug ("   Reading image remaining data from dataflash address "
736                         "%08lx to RAM address %08lx\n", img_addr + h_size,
737                         ram_addr + h_size);
738
739                 read_dataflash (img_addr + h_size, d_size,
740                                 (char *)(ram_addr + h_size));
741
742         }
743 #endif /* CONFIG_HAS_DATAFLASH */
744
745         return ram_addr;
746 }
747
748 /**
749  * fit_has_config - check if there is a valid FIT configuration
750  * @images: pointer to the bootm command headers structure
751  *
752  * fit_has_config() checks if there is a FIT configuration in use
753  * (if FTI support is present).
754  *
755  * returns:
756  *     0, no FIT support or no configuration found
757  *     1, configuration found
758  */
759 int genimg_has_config (bootm_headers_t *images)
760 {
761 #if defined(CONFIG_FIT)
762         if (images->fit_uname_cfg)
763                 return 1;
764 #endif
765         return 0;
766 }
767
768 /**
769  * boot_get_ramdisk - main ramdisk handling routine
770  * @argc: command argument count
771  * @argv: command argument list
772  * @images: pointer to the bootm images structure
773  * @arch: expected ramdisk architecture
774  * @rd_start: pointer to a ulong variable, will hold ramdisk start address
775  * @rd_end: pointer to a ulong variable, will hold ramdisk end
776  *
777  * boot_get_ramdisk() is responsible for finding a valid ramdisk image.
778  * Curently supported are the following ramdisk sources:
779  *      - multicomponent kernel/ramdisk image,
780  *      - commandline provided address of decicated ramdisk image.
781  *
782  * returns:
783  *     0, if ramdisk image was found and valid, or skiped
784  *     rd_start and rd_end are set to ramdisk start/end addresses if
785  *     ramdisk image is found and valid
786  *
787  *     1, if ramdisk image is found but corrupted
788  *     rd_start and rd_end are set to 0 if no ramdisk exists
789  */
790 int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
791                 uint8_t arch, ulong *rd_start, ulong *rd_end)
792 {
793         ulong rd_addr, rd_load;
794         ulong rd_data, rd_len;
795         image_header_t *rd_hdr;
796 #if defined(CONFIG_FIT)
797         void            *fit_hdr;
798         const char      *fit_uname_config = NULL;
799         const char      *fit_uname_ramdisk = NULL;
800         ulong           default_addr;
801         int             rd_noffset;
802         int             cfg_noffset;
803         const void      *data;
804         size_t          size;
805 #endif
806
807         *rd_start = 0;
808         *rd_end = 0;
809
810         /*
811          * Look for a '-' which indicates to ignore the
812          * ramdisk argument
813          */
814         if ((argc >= 3) && (strcmp(argv[2], "-") ==  0)) {
815                 debug ("## Skipping init Ramdisk\n");
816                 rd_len = rd_data = 0;
817         } else if (argc >= 3 || genimg_has_config (images)) {
818 #if defined(CONFIG_FIT)
819                 if (argc >= 3) {
820                         /*
821                          * If the init ramdisk comes from the FIT image and
822                          * the FIT image address is omitted in the command
823                          * line argument, try to use os FIT image address or
824                          * default load address.
825                          */
826                         if (images->fit_uname_os)
827                                 default_addr = (ulong)images->fit_hdr_os;
828                         else
829                                 default_addr = load_addr;
830
831                         if (fit_parse_conf (argv[2], default_addr,
832                                                 &rd_addr, &fit_uname_config)) {
833                                 debug ("*  ramdisk: config '%s' from image at 0x%08lx\n",
834                                                 fit_uname_config, rd_addr);
835                         } else if (fit_parse_subimage (argv[2], default_addr,
836                                                 &rd_addr, &fit_uname_ramdisk)) {
837                                 debug ("*  ramdisk: subimage '%s' from image at 0x%08lx\n",
838                                                 fit_uname_ramdisk, rd_addr);
839                         } else
840 #endif
841                         {
842                                 rd_addr = simple_strtoul(argv[2], NULL, 16);
843                                 debug ("*  ramdisk: cmdline image address = 0x%08lx\n",
844                                                 rd_addr);
845                         }
846 #if defined(CONFIG_FIT)
847                 } else {
848                         /* use FIT configuration provided in first bootm
849                          * command argument
850                          */
851                         rd_addr = (ulong)images->fit_hdr_os;
852                         fit_uname_config = images->fit_uname_cfg;
853                         debug ("*  ramdisk: using config '%s' from image at 0x%08lx\n",
854                                         fit_uname_config, rd_addr);
855
856                         /*
857                          * Check whether configuration has ramdisk defined,
858                          * if not, don't try to use it, quit silently.
859                          */
860                         fit_hdr = (void *)rd_addr;
861                         cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
862                         if (cfg_noffset < 0) {
863                                 debug ("*  ramdisk: no such config\n");
864                                 return 0;
865                         }
866
867                         rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset);
868                         if (rd_noffset < 0) {
869                                 debug ("*  ramdisk: no ramdisk in config\n");
870                                 return 0;
871                         }
872                 }
873 #endif
874
875                 /* copy from dataflash if needed */
876                 rd_addr = genimg_get_image (rd_addr);
877
878                 /*
879                  * Check if there is an initrd image at the
880                  * address provided in the second bootm argument
881                  * check image type, for FIT images get FIT node.
882                  */
883                 switch (genimg_get_format ((void *)rd_addr)) {
884                 case IMAGE_FORMAT_LEGACY:
885                         printf ("## Loading init Ramdisk from Legacy "
886                                         "Image at %08lx ...\n", rd_addr);
887
888                         show_boot_progress (9);
889                         rd_hdr = image_get_ramdisk (rd_addr, arch,
890                                                         images->verify);
891
892                         if (rd_hdr == NULL)
893                                 return 1;
894
895                         rd_data = image_get_data (rd_hdr);
896                         rd_len = image_get_data_size (rd_hdr);
897                         rd_load = image_get_load (rd_hdr);
898                         break;
899 #if defined(CONFIG_FIT)
900                 case IMAGE_FORMAT_FIT:
901                         fit_hdr = (void *)rd_addr;
902                         printf ("## Loading init Ramdisk from FIT "
903                                         "Image at %08lx ...\n", rd_addr);
904
905                         show_boot_progress (120);
906                         if (!fit_check_format (fit_hdr)) {
907                                 puts ("Bad FIT ramdisk image format!\n");
908                                 show_boot_progress (-120);
909                                 return 0;
910                         }
911                         show_boot_progress (121);
912
913                         if (!fit_uname_ramdisk) {
914                                 /*
915                                  * no ramdisk image node unit name, try to get config
916                                  * node first. If config unit node name is NULL
917                                  * fit_conf_get_node() will try to find default config node
918                                  */
919                                 show_boot_progress (122);
920                                 cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
921                                 if (cfg_noffset < 0) {
922                                         puts ("Could not find configuration node\n");
923                                         show_boot_progress (-122);
924                                         return 0;
925                                 }
926                                 fit_uname_config = fdt_get_name (fit_hdr, cfg_noffset, NULL);
927                                 printf ("   Using '%s' configuration\n", fit_uname_config);
928
929                                 rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset);
930                                 fit_uname_ramdisk = fit_get_name (fit_hdr, rd_noffset, NULL);
931                         } else {
932                                 /* get ramdisk component image node offset */
933                                 show_boot_progress (123);
934                                 rd_noffset = fit_image_get_node (fit_hdr, fit_uname_ramdisk);
935                         }
936                         if (rd_noffset < 0) {
937                                 puts ("Could not find subimage node\n");
938                                 show_boot_progress (-124);
939                                 return 0;
940                         }
941
942                         printf ("   Trying '%s' ramdisk subimage\n", fit_uname_ramdisk);
943
944                         show_boot_progress (125);
945                         if (!fit_check_ramdisk (fit_hdr, rd_noffset, arch, images->verify))
946                                 return 0;
947
948                         /* get ramdisk image data address and length */
949                         if (fit_image_get_data (fit_hdr, rd_noffset, &data, &size)) {
950                                 puts ("Could not find ramdisk subimage data!\n");
951                                 show_boot_progress (-127);
952                                 return 0;
953                         }
954                         show_boot_progress (128);
955
956                         rd_data = (ulong)data;
957                         rd_len = size;
958
959                         if (fit_image_get_load (fit_hdr, rd_noffset, &rd_load)) {
960                                 puts ("Can't get ramdisk subimage load address!\n");
961                                 show_boot_progress (-129);
962                                 return 0;
963                         }
964                         show_boot_progress (129);
965
966                         images->fit_hdr_rd = fit_hdr;
967                         images->fit_uname_rd = fit_uname_ramdisk;
968                         images->fit_noffset_rd = rd_noffset;
969                         break;
970 #endif
971                 default:
972                         puts ("Wrong Ramdisk Image Format\n");
973                         rd_data = rd_len = rd_load = 0;
974                 }
975
976 #if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO)
977                 /*
978                  * We need to copy the ramdisk to SRAM to let Linux boot
979                  */
980                 if (rd_data) {
981                         memmove ((void *)rd_load, (uchar *)rd_data, rd_len);
982                         rd_data = rd_load;
983                 }
984 #endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */
985
986         } else if (images->legacy_hdr_valid &&
987                         image_check_type (images->legacy_hdr_os, IH_TYPE_MULTI)) {
988                 /*
989                  * Now check if we have a legacy mult-component image,
990                  * get second entry data start address and len.
991                  */
992                 show_boot_progress (13);
993                 printf ("## Loading init Ramdisk from multi component "
994                                 "Legacy Image at %08lx ...\n",
995                                 (ulong)images->legacy_hdr_os);
996
997                 image_multi_getimg (images->legacy_hdr_os, 1, &rd_data, &rd_len);
998         } else {
999                 /*
1000                  * no initrd image
1001                  */
1002                 show_boot_progress (14);
1003                 rd_len = rd_data = 0;
1004         }
1005
1006         if (!rd_data) {
1007                 debug ("## No init Ramdisk\n");
1008         } else {
1009                 *rd_start = rd_data;
1010                 *rd_end = rd_data + rd_len;
1011         }
1012         debug ("   ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n",
1013                         *rd_start, *rd_end);
1014
1015         return 0;
1016 }
1017
1018 #if defined(CONFIG_PPC) || defined(CONFIG_M68K)
1019 /**
1020  * boot_ramdisk_high - relocate init ramdisk
1021  * @lmb: pointer to lmb handle, will be used for memory mgmt
1022  * @rd_data: ramdisk data start address
1023  * @rd_len: ramdisk data length
1024  * @initrd_start: pointer to a ulong variable, will hold final init ramdisk
1025  *      start address (after possible relocation)
1026  * @initrd_end: pointer to a ulong variable, will hold final init ramdisk
1027  *      end address (after possible relocation)
1028  *
1029  * boot_ramdisk_high() takes a relocation hint from "initrd_high" environement
1030  * variable and if requested ramdisk data is moved to a specified location.
1031  *
1032  * Initrd_start and initrd_end are set to final (after relocation) ramdisk
1033  * start/end addresses if ramdisk image start and len were provided,
1034  * otherwise set initrd_start and initrd_end set to zeros.
1035  *
1036  * returns:
1037  *      0 - success
1038  *     -1 - failure
1039  */
1040 int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
1041                   ulong *initrd_start, ulong *initrd_end)
1042 {
1043         char    *s;
1044         ulong   initrd_high;
1045         int     initrd_copy_to_ram = 1;
1046
1047         if ((s = getenv ("initrd_high")) != NULL) {
1048                 /* a value of "no" or a similar string will act like 0,
1049                  * turning the "load high" feature off. This is intentional.
1050                  */
1051                 initrd_high = simple_strtoul (s, NULL, 16);
1052                 if (initrd_high == ~0)
1053                         initrd_copy_to_ram = 0;
1054         } else {
1055                 /* not set, no restrictions to load high */
1056                 initrd_high = ~0;
1057         }
1058
1059         debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
1060                         initrd_high, initrd_copy_to_ram);
1061
1062         if (rd_data) {
1063                 if (!initrd_copy_to_ram) {      /* zero-copy ramdisk support */
1064                         debug ("   in-place initrd\n");
1065                         *initrd_start = rd_data;
1066                         *initrd_end = rd_data + rd_len;
1067                         lmb_reserve(lmb, rd_data, rd_len);
1068                 } else {
1069                         if (initrd_high)
1070                                 *initrd_start = lmb_alloc_base (lmb, rd_len, 0x1000, initrd_high);
1071                         else
1072                                 *initrd_start = lmb_alloc (lmb, rd_len, 0x1000);
1073
1074                         if (*initrd_start == 0) {
1075                                 puts ("ramdisk - allocation error\n");
1076                                 goto error;
1077                         }
1078                         show_boot_progress (12);
1079
1080                         *initrd_end = *initrd_start + rd_len;
1081                         printf ("   Loading Ramdisk to %08lx, end %08lx ... ",
1082                                         *initrd_start, *initrd_end);
1083
1084                         memmove_wd ((void *)*initrd_start,
1085                                         (void *)rd_data, rd_len, CHUNKSZ);
1086
1087                         puts ("OK\n");
1088                 }
1089         } else {
1090                 *initrd_start = 0;
1091                 *initrd_end = 0;
1092         }
1093         debug ("   ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
1094                         *initrd_start, *initrd_end);
1095
1096         return 0;
1097
1098 error:
1099         return -1;
1100 }
1101
1102 /**
1103  * boot_get_cmdline - allocate and initialize kernel cmdline
1104  * @lmb: pointer to lmb handle, will be used for memory mgmt
1105  * @cmd_start: pointer to a ulong variable, will hold cmdline start
1106  * @cmd_end: pointer to a ulong variable, will hold cmdline end
1107  * @bootmap_base: ulong variable, holds offset in physical memory to
1108  * base of bootmap
1109  *
1110  * boot_get_cmdline() allocates space for kernel command line below
1111  * BOOTMAPSZ + bootmap_base address. If "bootargs" U-boot environemnt
1112  * variable is present its contents is copied to allocated kernel
1113  * command line.
1114  *
1115  * returns:
1116  *      0 - success
1117  *     -1 - failure
1118  */
1119 int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
1120                         ulong bootmap_base)
1121 {
1122         char *cmdline;
1123         char *s;
1124
1125         cmdline = (char *)lmb_alloc_base(lmb, CFG_BARGSIZE, 0xf,
1126                                          CFG_BOOTMAPSZ + bootmap_base);
1127
1128         if (cmdline == NULL)
1129                 return -1;
1130
1131         if ((s = getenv("bootargs")) == NULL)
1132                 s = "";
1133
1134         strcpy(cmdline, s);
1135
1136         *cmd_start = (ulong) & cmdline[0];
1137         *cmd_end = *cmd_start + strlen(cmdline);
1138
1139         debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);
1140
1141         return 0;
1142 }
1143
1144 /**
1145  * boot_get_kbd - allocate and initialize kernel copy of board info
1146  * @lmb: pointer to lmb handle, will be used for memory mgmt
1147  * @kbd: double pointer to board info data
1148  * @bootmap_base: ulong variable, holds offset in physical memory to
1149  * base of bootmap
1150  *
1151  * boot_get_kbd() allocates space for kernel copy of board info data below
1152  * BOOTMAPSZ + bootmap_base address and kernel board info is initialized with
1153  * the current u-boot board info data.
1154  *
1155  * returns:
1156  *      0 - success
1157  *     -1 - failure
1158  */
1159 int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base)
1160 {
1161         *kbd = (bd_t *)lmb_alloc_base(lmb, sizeof(bd_t), 0xf,
1162                                       CFG_BOOTMAPSZ + bootmap_base);
1163         if (*kbd == NULL)
1164                 return -1;
1165
1166         **kbd = *(gd->bd);
1167
1168         debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd);
1169
1170 #if defined(DEBUG) && defined(CONFIG_CMD_BDI)
1171         do_bdinfo(NULL, 0, 0, NULL);
1172 #endif
1173
1174         return 0;
1175 }
1176 #endif /* CONFIG_PPC || CONFIG_M68K */
1177 #endif /* !USE_HOSTCC */
1178
1179 #if defined(CONFIG_FIT)
1180 /*****************************************************************************/
1181 /* New uImage format routines */
1182 /*****************************************************************************/
1183 #ifndef USE_HOSTCC
1184 static int fit_parse_spec (const char *spec, char sepc, ulong addr_curr,
1185                 ulong *addr, const char **name)
1186 {
1187         const char *sep;
1188
1189         *addr = addr_curr;
1190         *name = NULL;
1191
1192         sep = strchr (spec, sepc);
1193         if (sep) {
1194                 if (sep - spec > 0)
1195                         *addr = simple_strtoul (spec, NULL, 16);
1196
1197                 *name = sep + 1;
1198                 return 1;
1199         }
1200
1201         return 0;
1202 }
1203
1204 /**
1205  * fit_parse_conf - parse FIT configuration spec
1206  * @spec: input string, containing configuration spec
1207  * @add_curr: current image address (to be used as a possible default)
1208  * @addr: pointer to a ulong variable, will hold FIT image address of a given
1209  * configuration
1210  * @conf_name double pointer to a char, will hold pointer to a configuration
1211  * unit name
1212  *
1213  * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>,
1214  * where <addr> is a FIT image address that contains configuration
1215  * with a <conf> unit name.
1216  *
1217  * Address part is optional, and if omitted default add_curr will
1218  * be used instead.
1219  *
1220  * returns:
1221  *     1 if spec is a valid configuration string,
1222  *     addr and conf_name are set accordingly
1223  *     0 otherwise
1224  */
1225 inline int fit_parse_conf (const char *spec, ulong addr_curr,
1226                 ulong *addr, const char **conf_name)
1227 {
1228         return fit_parse_spec (spec, '#', addr_curr, addr, conf_name);
1229 }
1230
1231 /**
1232  * fit_parse_subimage - parse FIT subimage spec
1233  * @spec: input string, containing subimage spec
1234  * @add_curr: current image address (to be used as a possible default)
1235  * @addr: pointer to a ulong variable, will hold FIT image address of a given
1236  * subimage
1237  * @image_name: double pointer to a char, will hold pointer to a subimage name
1238  *
1239  * fit_parse_subimage() expects subimage spec in the for of
1240  * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
1241  * subimage with a <subimg> unit name.
1242  *
1243  * Address part is optional, and if omitted default add_curr will
1244  * be used instead.
1245  *
1246  * returns:
1247  *     1 if spec is a valid subimage string,
1248  *     addr and image_name are set accordingly
1249  *     0 otherwise
1250  */
1251 inline int fit_parse_subimage (const char *spec, ulong addr_curr,
1252                 ulong *addr, const char **image_name)
1253 {
1254         return fit_parse_spec (spec, ':', addr_curr, addr, image_name);
1255 }
1256 #endif /* !USE_HOSTCC */
1257
1258 static void fit_get_debug (const void *fit, int noffset,
1259                 char *prop_name, int err)
1260 {
1261         debug ("Can't get '%s' property from FIT 0x%08lx, "
1262                 "node: offset %d, name %s (%s)\n",
1263                 prop_name, (ulong)fit, noffset,
1264                 fit_get_name (fit, noffset, NULL),
1265                 fdt_strerror (err));
1266 }
1267
1268 /**
1269  * __fit_print_contents - prints out the contents of the FIT format image
1270  * @fit: pointer to the FIT format image header
1271  * @p: pointer to prefix string
1272  *
1273  * __fit_print_contents() formats a multi line FIT image contents description.
1274  * The routine prints out FIT image properties (root node level) follwed by
1275  * the details of each component image.
1276  *
1277  * returns:
1278  *     no returned results
1279  */
1280 static void __fit_print_contents (const void *fit, const char *p)
1281 {
1282         char *desc;
1283         char *uname;
1284         int images_noffset;
1285         int confs_noffset;
1286         int noffset;
1287         int ndepth;
1288         int count = 0;
1289         int ret;
1290 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
1291         time_t timestamp;
1292 #endif
1293
1294         /* Root node properties */
1295         ret = fit_get_desc (fit, 0, &desc);
1296         printf ("%sFIT description: ", p);
1297         if (ret)
1298                 printf ("unavailable\n");
1299         else
1300                 printf ("%s\n", desc);
1301
1302 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
1303         ret = fit_get_timestamp (fit, 0, &timestamp);
1304         printf ("%sCreated:         ", p);
1305         if (ret)
1306                 printf ("unavailable\n");
1307         else
1308                 genimg_print_time (timestamp);
1309 #endif
1310
1311         /* Find images parent node offset */
1312         images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
1313         if (images_noffset < 0) {
1314                 printf ("Can't find images parent node '%s' (%s)\n",
1315                         FIT_IMAGES_PATH, fdt_strerror (images_noffset));
1316                 return;
1317         }
1318
1319         /* Process its subnodes, print out component images details */
1320         for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth);
1321              (noffset >= 0) && (ndepth > 0);
1322              noffset = fdt_next_node (fit, noffset, &ndepth)) {
1323                 if (ndepth == 1) {
1324                         /*
1325                          * Direct child node of the images parent node,
1326                          * i.e. component image node.
1327                          */
1328                         printf ("%s Image %u (%s)\n", p, count++,
1329                                         fit_get_name(fit, noffset, NULL));
1330
1331                         fit_image_print (fit, noffset, p);
1332                 }
1333         }
1334
1335         /* Find configurations parent node offset */
1336         confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH);
1337         if (confs_noffset < 0) {
1338                 debug ("Can't get configurations parent node '%s' (%s)\n",
1339                         FIT_CONFS_PATH, fdt_strerror (confs_noffset));
1340                 return;
1341         }
1342
1343         /* get default configuration unit name from default property */
1344         uname = (char *)fdt_getprop (fit, noffset, FIT_DEFAULT_PROP, NULL);
1345         if (uname)
1346                 printf ("%s Default Configuration: '%s'\n", p, uname);
1347
1348         /* Process its subnodes, print out configurations details */
1349         for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, confs_noffset, &ndepth);
1350              (noffset >= 0) && (ndepth > 0);
1351              noffset = fdt_next_node (fit, noffset, &ndepth)) {
1352                 if (ndepth == 1) {
1353                         /*
1354                          * Direct child node of the configurations parent node,
1355                          * i.e. configuration node.
1356                          */
1357                         printf ("%s Configuration %u (%s)\n", p, count++,
1358                                         fit_get_name(fit, noffset, NULL));
1359
1360                         fit_conf_print (fit, noffset, p);
1361                 }
1362         }
1363 }
1364
1365 inline void fit_print_contents (const void *fit)
1366 {
1367         __fit_print_contents (fit, "   ");
1368 }
1369
1370 inline void fit_print_contents_noindent (const void *fit)
1371 {
1372         __fit_print_contents (fit, "");
1373 }
1374
1375 /**
1376  * fit_image_print - prints out the FIT component image details
1377  * @fit: pointer to the FIT format image header
1378  * @image_noffset: offset of the component image node
1379  * @p: pointer to prefix string
1380  *
1381  * fit_image_print() lists all mandatory properies for the processed component
1382  * image. If present, hash nodes are printed out as well.
1383  *
1384  * returns:
1385  *     no returned results
1386  */
1387 void fit_image_print (const void *fit, int image_noffset, const char *p)
1388 {
1389         char *desc;
1390         uint8_t type, arch, os, comp;
1391         size_t size;
1392         ulong load, entry;
1393         const void *data;
1394         int noffset;
1395         int ndepth;
1396         int ret;
1397
1398         /* Mandatory properties */
1399         ret = fit_get_desc (fit, image_noffset, &desc);
1400         printf ("%s  Description:  ", p);
1401         if (ret)
1402                 printf ("unavailable\n");
1403         else
1404                 printf ("%s\n", desc);
1405
1406         fit_image_get_type (fit, image_noffset, &type);
1407         printf ("%s  Type:         %s\n", p, genimg_get_type_name (type));
1408
1409         fit_image_get_comp (fit, image_noffset, &comp);
1410         printf ("%s  Compression:  %s\n", p, genimg_get_comp_name (comp));
1411
1412         ret = fit_image_get_data (fit, image_noffset, &data, &size);
1413
1414 #ifndef USE_HOSTCC
1415         printf ("%s  Data Start:   ", p);
1416         if (ret)
1417                 printf ("unavailable\n");
1418         else
1419                 printf ("0x%08lx\n", (ulong)data);
1420 #endif
1421
1422         printf ("%s  Data Size:    ", p);
1423         if (ret)
1424                 printf ("unavailable\n");
1425         else
1426                 genimg_print_size (size);
1427
1428         /* Remaining, type dependent properties */
1429         if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
1430             (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
1431             (type == IH_TYPE_FLATDT)) {
1432                 fit_image_get_arch (fit, image_noffset, &arch);
1433                 printf ("%s  Architecture: %s\n", p, genimg_get_arch_name (arch));
1434         }
1435
1436         if (type == IH_TYPE_KERNEL) {
1437                 fit_image_get_os (fit, image_noffset, &os);
1438                 printf ("%s  OS:           %s\n", p, genimg_get_os_name (os));
1439         }
1440
1441         if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE)) {
1442                 ret = fit_image_get_load (fit, image_noffset, &load);
1443                 printf ("%s  Load Address: ", p);
1444                 if (ret)
1445                         printf ("unavailable\n");
1446                 else
1447                         printf ("0x%08lx\n", load);
1448
1449                 fit_image_get_entry (fit, image_noffset, &entry);
1450                 printf ("%s  Entry Point:  ", p);
1451                 if (ret)
1452                         printf ("unavailable\n");
1453                 else
1454                         printf ("0x%08lx\n", entry);
1455         }
1456
1457         /* Process all hash subnodes of the component image node */
1458         for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
1459              (noffset >= 0) && (ndepth > 0);
1460              noffset = fdt_next_node (fit, noffset, &ndepth)) {
1461                 if (ndepth == 1) {
1462                         /* Direct child node of the component image node */
1463                         fit_image_print_hash (fit, noffset, p);
1464                 }
1465         }
1466 }
1467
1468 /**
1469  * fit_image_print_hash - prints out the hash node details
1470  * @fit: pointer to the FIT format image header
1471  * @noffset: offset of the hash node
1472  * @p: pointer to prefix string
1473  *
1474  * fit_image_print_hash() lists properies for the processed hash node
1475  *
1476  * returns:
1477  *     no returned results
1478  */
1479 void fit_image_print_hash (const void *fit, int noffset, const char *p)
1480 {
1481         char *algo;
1482         uint8_t *value;
1483         int value_len;
1484         int i, ret;
1485
1486         /*
1487          * Check subnode name, must be equal to "hash".
1488          * Multiple hash nodes require unique unit node
1489          * names, e.g. hash@1, hash@2, etc.
1490          */
1491         if (strncmp (fit_get_name(fit, noffset, NULL),
1492                         FIT_HASH_NODENAME,
1493                         strlen(FIT_HASH_NODENAME)) != 0)
1494                 return;
1495
1496         debug ("%s  Hash node:    '%s'\n", p,
1497                         fit_get_name (fit, noffset, NULL));
1498
1499         printf ("%s  Hash algo:    ", p);
1500         if (fit_image_hash_get_algo (fit, noffset, &algo)) {
1501                 printf ("invalid/unsupported\n");
1502                 return;
1503         }
1504         printf ("%s\n", algo);
1505
1506         ret = fit_image_hash_get_value (fit, noffset, &value,
1507                                         &value_len);
1508         printf ("%s  Hash value:   ", p);
1509         if (ret) {
1510                 printf ("unavailable\n");
1511         } else {
1512                 for (i = 0; i < value_len; i++)
1513                         printf ("%02x", value[i]);
1514                 printf ("\n");
1515         }
1516
1517         debug  ("%s  Hash len:     %d\n", p, value_len);
1518 }
1519
1520 /**
1521  * fit_get_desc - get node description property
1522  * @fit: pointer to the FIT format image header
1523  * @noffset: node offset
1524  * @desc: double pointer to the char, will hold pointer to the descrption
1525  *
1526  * fit_get_desc() reads description property from a given node, if
1527  * description is found pointer to it is returened in third call argument.
1528  *
1529  * returns:
1530  *     0, on success
1531  *     -1, on failure
1532  */
1533 int fit_get_desc (const void *fit, int noffset, char **desc)
1534 {
1535         int len;
1536
1537         *desc = (char *)fdt_getprop (fit, noffset, FIT_DESC_PROP, &len);
1538         if (*desc == NULL) {
1539                 fit_get_debug (fit, noffset, FIT_DESC_PROP, len);
1540                 return -1;
1541         }
1542
1543         return 0;
1544 }
1545
1546 /**
1547  * fit_get_timestamp - get node timestamp property
1548  * @fit: pointer to the FIT format image header
1549  * @noffset: node offset
1550  * @timestamp: pointer to the time_t, will hold read timestamp
1551  *
1552  * fit_get_timestamp() reads timestamp poperty from given node, if timestamp
1553  * is found and has a correct size its value is retured in third call
1554  * argument.
1555  *
1556  * returns:
1557  *     0, on success
1558  *     -1, on property read failure
1559  *     -2, on wrong timestamp size
1560  */
1561 int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp)
1562 {
1563         int len;
1564         const void *data;
1565
1566         data = fdt_getprop (fit, noffset, FIT_TIMESTAMP_PROP, &len);
1567         if (data == NULL) {
1568                 fit_get_debug (fit, noffset, FIT_TIMESTAMP_PROP, len);
1569                 return -1;
1570         }
1571         if (len != sizeof (uint32_t)) {
1572                 debug ("FIT timestamp with incorrect size of (%u)\n", len);
1573                 return -2;
1574         }
1575
1576         *timestamp = uimage_to_cpu (*((uint32_t *)data));
1577         return 0;
1578 }
1579
1580 /**
1581  * fit_image_get_node - get node offset for component image of a given unit name
1582  * @fit: pointer to the FIT format image header
1583  * @image_uname: component image node unit name
1584  *
1585  * fit_image_get_node() finds a component image (withing the '/images'
1586  * node) of a provided unit name. If image is found its node offset is
1587  * returned to the caller.
1588  *
1589  * returns:
1590  *     image node offset when found (>=0)
1591  *     negative number on failure (FDT_ERR_* code)
1592  */
1593 int fit_image_get_node (const void *fit, const char *image_uname)
1594 {
1595         int noffset, images_noffset;
1596
1597         images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
1598         if (images_noffset < 0) {
1599                 debug ("Can't find images parent node '%s' (%s)\n",
1600                         FIT_IMAGES_PATH, fdt_strerror (images_noffset));
1601                 return images_noffset;
1602         }
1603
1604         noffset = fdt_subnode_offset (fit, images_noffset, image_uname);
1605         if (noffset < 0) {
1606                 debug ("Can't get node offset for image unit name: '%s' (%s)\n",
1607                         image_uname, fdt_strerror (noffset));
1608         }
1609
1610         return noffset;
1611 }
1612
1613 /**
1614  * fit_image_get_os - get os id for a given component image node
1615  * @fit: pointer to the FIT format image header
1616  * @noffset: component image node offset
1617  * @os: pointer to the uint8_t, will hold os numeric id
1618  *
1619  * fit_image_get_os() finds os property in a given component image node.
1620  * If the property is found, its (string) value is translated to the numeric
1621  * id which is returned to the caller.
1622  *
1623  * returns:
1624  *     0, on success
1625  *     -1, on failure
1626  */
1627 int fit_image_get_os (const void *fit, int noffset, uint8_t *os)
1628 {
1629         int len;
1630         const void *data;
1631
1632         /* Get OS name from property data */
1633         data = fdt_getprop (fit, noffset, FIT_OS_PROP, &len);
1634         if (data == NULL) {
1635                 fit_get_debug (fit, noffset, FIT_OS_PROP, len);
1636                 *os = -1;
1637                 return -1;
1638         }
1639
1640         /* Translate OS name to id */
1641         *os = genimg_get_os_id (data);
1642         return 0;
1643 }
1644
1645 /**
1646  * fit_image_get_arch - get arch id for a given component image node
1647  * @fit: pointer to the FIT format image header
1648  * @noffset: component image node offset
1649  * @arch: pointer to the uint8_t, will hold arch numeric id
1650  *
1651  * fit_image_get_arch() finds arch property in a given component image node.
1652  * If the property is found, its (string) value is translated to the numeric
1653  * id which is returned to the caller.
1654  *
1655  * returns:
1656  *     0, on success
1657  *     -1, on failure
1658  */
1659 int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch)
1660 {
1661         int len;
1662         const void *data;
1663
1664         /* Get architecture name from property data */
1665         data = fdt_getprop (fit, noffset, FIT_ARCH_PROP, &len);
1666         if (data == NULL) {
1667                 fit_get_debug (fit, noffset, FIT_ARCH_PROP, len);
1668                 *arch = -1;
1669                 return -1;
1670         }
1671
1672         /* Translate architecture name to id */
1673         *arch = genimg_get_arch_id (data);
1674         return 0;
1675 }
1676
1677 /**
1678  * fit_image_get_type - get type id for a given component image node
1679  * @fit: pointer to the FIT format image header
1680  * @noffset: component image node offset
1681  * @type: pointer to the uint8_t, will hold type numeric id
1682  *
1683  * fit_image_get_type() finds type property in a given component image node.
1684  * If the property is found, its (string) value is translated to the numeric
1685  * id which is returned to the caller.
1686  *
1687  * returns:
1688  *     0, on success
1689  *     -1, on failure
1690  */
1691 int fit_image_get_type (const void *fit, int noffset, uint8_t *type)
1692 {
1693         int len;
1694         const void *data;
1695
1696         /* Get image type name from property data */
1697         data = fdt_getprop (fit, noffset, FIT_TYPE_PROP, &len);
1698         if (data == NULL) {
1699                 fit_get_debug (fit, noffset, FIT_TYPE_PROP, len);
1700                 *type = -1;
1701                 return -1;
1702         }
1703
1704         /* Translate image type name to id */
1705         *type = genimg_get_type_id (data);
1706         return 0;
1707 }
1708
1709 /**
1710  * fit_image_get_comp - get comp id for a given component image node
1711  * @fit: pointer to the FIT format image header
1712  * @noffset: component image node offset
1713  * @comp: pointer to the uint8_t, will hold comp numeric id
1714  *
1715  * fit_image_get_comp() finds comp property in a given component image node.
1716  * If the property is found, its (string) value is translated to the numeric
1717  * id which is returned to the caller.
1718  *
1719  * returns:
1720  *     0, on success
1721  *     -1, on failure
1722  */
1723 int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp)
1724 {
1725         int len;
1726         const void *data;
1727
1728         /* Get compression name from property data */
1729         data = fdt_getprop (fit, noffset, FIT_COMP_PROP, &len);
1730         if (data == NULL) {
1731                 fit_get_debug (fit, noffset, FIT_COMP_PROP, len);
1732                 *comp = -1;
1733                 return -1;
1734         }
1735
1736         /* Translate compression name to id */
1737         *comp = genimg_get_comp_id (data);
1738         return 0;
1739 }
1740
1741 /**
1742  * fit_image_get_load - get load address property for a given component image node
1743  * @fit: pointer to the FIT format image header
1744  * @noffset: component image node offset
1745  * @load: pointer to the uint32_t, will hold load address
1746  *
1747  * fit_image_get_load() finds load address property in a given component image node.
1748  * If the property is found, its value is returned to the caller.
1749  *
1750  * returns:
1751  *     0, on success
1752  *     -1, on failure
1753  */
1754 int fit_image_get_load (const void *fit, int noffset, ulong *load)
1755 {
1756         int len;
1757         const uint32_t *data;
1758
1759         data = fdt_getprop (fit, noffset, FIT_LOAD_PROP, &len);
1760         if (data == NULL) {
1761                 fit_get_debug (fit, noffset, FIT_LOAD_PROP, len);
1762                 return -1;
1763         }
1764
1765         *load = uimage_to_cpu (*data);
1766         return 0;
1767 }
1768
1769 /**
1770  * fit_image_get_entry - get entry point address property for a given component image node
1771  * @fit: pointer to the FIT format image header
1772  * @noffset: component image node offset
1773  * @entry: pointer to the uint32_t, will hold entry point address
1774  *
1775  * fit_image_get_entry() finds entry point address property in a given component image node.
1776  * If the property is found, its value is returned to the caller.
1777  *
1778  * returns:
1779  *     0, on success
1780  *     -1, on failure
1781  */
1782 int fit_image_get_entry (const void *fit, int noffset, ulong *entry)
1783 {
1784         int len;
1785         const uint32_t *data;
1786
1787         data = fdt_getprop (fit, noffset, FIT_ENTRY_PROP, &len);
1788         if (data == NULL) {
1789                 fit_get_debug (fit, noffset, FIT_ENTRY_PROP, len);
1790                 return -1;
1791         }
1792
1793         *entry = uimage_to_cpu (*data);
1794         return 0;
1795 }
1796
1797 /**
1798  * fit_image_get_data - get data property and its size for a given component image node
1799  * @fit: pointer to the FIT format image header
1800  * @noffset: component image node offset
1801  * @data: double pointer to void, will hold data property's data address
1802  * @size: pointer to size_t, will hold data property's data size
1803  *
1804  * fit_image_get_data() finds data property in a given component image node.
1805  * If the property is found its data start address and size are returned to
1806  * the caller.
1807  *
1808  * returns:
1809  *     0, on success
1810  *     -1, on failure
1811  */
1812 int fit_image_get_data (const void *fit, int noffset,
1813                 const void **data, size_t *size)
1814 {
1815         int len;
1816
1817         *data = fdt_getprop (fit, noffset, FIT_DATA_PROP, &len);
1818         if (*data == NULL) {
1819                 fit_get_debug (fit, noffset, FIT_DATA_PROP, len);
1820                 *size = 0;
1821                 return -1;
1822         }
1823
1824         *size = len;
1825         return 0;
1826 }
1827
1828 /**
1829  * fit_image_hash_get_algo - get hash algorithm name
1830  * @fit: pointer to the FIT format image header
1831  * @noffset: hash node offset
1832  * @algo: double pointer to char, will hold pointer to the algorithm name
1833  *
1834  * fit_image_hash_get_algo() finds hash algorithm property in a given hash node.
1835  * If the property is found its data start address is returned to the caller.
1836  *
1837  * returns:
1838  *     0, on success
1839  *     -1, on failure
1840  */
1841 int fit_image_hash_get_algo (const void *fit, int noffset, char **algo)
1842 {
1843         int len;
1844
1845         *algo = (char *)fdt_getprop (fit, noffset, FIT_ALGO_PROP, &len);
1846         if (*algo == NULL) {
1847                 fit_get_debug (fit, noffset, FIT_ALGO_PROP, len);
1848                 return -1;
1849         }
1850
1851         return 0;
1852 }
1853
1854 /**
1855  * fit_image_hash_get_value - get hash value and length
1856  * @fit: pointer to the FIT format image header
1857  * @noffset: hash node offset
1858  * @value: double pointer to uint8_t, will hold address of a hash value data
1859  * @value_len: pointer to an int, will hold hash data length
1860  *
1861  * fit_image_hash_get_value() finds hash value property in a given hash node.
1862  * If the property is found its data start address and size are returned to
1863  * the caller.
1864  *
1865  * returns:
1866  *     0, on success
1867  *     -1, on failure
1868  */
1869 int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value,
1870                                 int *value_len)
1871 {
1872         int len;
1873
1874         *value = (uint8_t *)fdt_getprop (fit, noffset, FIT_VALUE_PROP, &len);
1875         if (*value == NULL) {
1876                 fit_get_debug (fit, noffset, FIT_VALUE_PROP, len);
1877                 *value_len = 0;
1878                 return -1;
1879         }
1880
1881         *value_len = len;
1882         return 0;
1883 }
1884
1885 /**
1886  * fit_set_timestamp - set node timestamp property
1887  * @fit: pointer to the FIT format image header
1888  * @noffset: node offset
1889  * @timestamp: timestamp value to be set
1890  *
1891  * fit_set_timestamp() attempts to set timestamp property in the requested
1892  * node and returns operation status to the caller.
1893  *
1894  * returns:
1895  *     0, on success
1896  *     -1, on property read failure
1897  */
1898 int fit_set_timestamp (void *fit, int noffset, time_t timestamp)
1899 {
1900         uint32_t t;
1901         int ret;
1902
1903         t = cpu_to_uimage (timestamp);
1904         ret = fdt_setprop (fit, noffset, FIT_TIMESTAMP_PROP, &t,
1905                                 sizeof (uint32_t));
1906         if (ret) {
1907                 printf ("Can't set '%s' property for '%s' node (%s)\n",
1908                         FIT_TIMESTAMP_PROP, fit_get_name (fit, noffset, NULL),
1909                         fdt_strerror (ret));
1910                 return -1;
1911         }
1912
1913         return 0;
1914 }
1915
1916 /**
1917  * calculate_hash - calculate and return hash for provided input data
1918  * @data: pointer to the input data
1919  * @data_len: data length
1920  * @algo: requested hash algorithm
1921  * @value: pointer to the char, will hold hash value data (caller must
1922  * allocate enough free space)
1923  * value_len: length of the calculated hash
1924  *
1925  * calculate_hash() computes input data hash according to the requested algorithm.
1926  * Resulting hash value is placed in caller provided 'value' buffer, length
1927  * of the calculated hash is returned via value_len pointer argument.
1928  *
1929  * returns:
1930  *     0, on success
1931  *    -1, when algo is unsupported
1932  */
1933 static int calculate_hash (const void *data, int data_len, const char *algo,
1934                         uint8_t *value, int *value_len)
1935 {
1936         if (strcmp (algo, "crc32") == 0 ) {
1937                 *((uint32_t *)value) = crc32 (0, data, data_len);
1938                 *((uint32_t *)value) = cpu_to_uimage (*((uint32_t *)value));
1939                 *value_len = 4;
1940         } else if (strcmp (algo, "sha1") == 0 ) {
1941                 sha1_csum ((unsigned char *) data, data_len,
1942                                 (unsigned char *) value);
1943                 *value_len = 20;
1944         } else if (strcmp (algo, "md5") == 0 ) {
1945                 md5 ((unsigned char *)data, data_len, value);
1946                 *value_len = 16;
1947         } else {
1948                 debug ("Unsupported hash alogrithm\n");
1949                 return -1;
1950         }
1951         return 0;
1952 }
1953
1954 #ifdef USE_HOSTCC
1955 /**
1956  * fit_set_hashes - process FIT component image nodes and calculate hashes
1957  * @fit: pointer to the FIT format image header
1958  *
1959  * fit_set_hashes() adds hash values for all component images in the FIT blob.
1960  * Hashes are calculated for all component images which have hash subnodes
1961  * with algorithm property set to one of the supported hash algorithms.
1962  *
1963  * returns
1964  *     0, on success
1965  *     libfdt error code, on failure
1966  */
1967 int fit_set_hashes (void *fit)
1968 {
1969         int images_noffset;
1970         int noffset;
1971         int ndepth;
1972         int ret;
1973
1974         /* Find images parent node offset */
1975         images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
1976         if (images_noffset < 0) {
1977                 printf ("Can't find images parent node '%s' (%s)\n",
1978                         FIT_IMAGES_PATH, fdt_strerror (images_noffset));
1979                 return images_noffset;
1980         }
1981
1982         /* Process its subnodes, print out component images details */
1983         for (ndepth = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth);
1984              (noffset >= 0) && (ndepth > 0);
1985              noffset = fdt_next_node (fit, noffset, &ndepth)) {
1986                 if (ndepth == 1) {
1987                         /*
1988                          * Direct child node of the images parent node,
1989                          * i.e. component image node.
1990                          */
1991                         ret = fit_image_set_hashes (fit, noffset);
1992                         if (ret)
1993                                 return ret;
1994                 }
1995         }
1996
1997         return 0;
1998 }
1999
2000 /**
2001  * fit_image_set_hashes - calculate/set hashes for given component image node
2002  * @fit: pointer to the FIT format image header
2003  * @image_noffset: requested component image node
2004  *
2005  * fit_image_set_hashes() adds hash values for an component image node. All
2006  * existing hash subnodes are checked, if algorithm property is set to one of
2007  * the supported hash algorithms, hash value is computed and corresponding
2008  * hash node property is set, for example:
2009  *
2010  * Input component image node structure:
2011  *
2012  * o image@1 (at image_noffset)
2013  *   | - data = [binary data]
2014  *   o hash@1
2015  *     |- algo = "sha1"
2016  *
2017  * Output component image node structure:
2018  *
2019  * o image@1 (at image_noffset)
2020  *   | - data = [binary data]
2021  *   o hash@1
2022  *     |- algo = "sha1"
2023  *     |- value = sha1(data)
2024  *
2025  * returns:
2026  *     0 on sucess
2027  *    <0 on failure
2028  */
2029 int fit_image_set_hashes (void *fit, int image_noffset)
2030 {
2031         const void *data;
2032         size_t size;
2033         char *algo;
2034         uint8_t value[FIT_MAX_HASH_LEN];
2035         int value_len;
2036         int noffset;
2037         int ndepth;
2038
2039         /* Get image data and data length */
2040         if (fit_image_get_data (fit, image_noffset, &data, &size)) {
2041                 printf ("Can't get image data/size\n");
2042                 return -1;
2043         }
2044
2045         /* Process all hash subnodes of the component image node */
2046         for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
2047              (noffset >= 0) && (ndepth > 0);
2048              noffset = fdt_next_node (fit, noffset, &ndepth)) {
2049                 if (ndepth == 1) {
2050                         /* Direct child node of the component image node */
2051
2052                         /*
2053                          * Check subnode name, must be equal to "hash".
2054                          * Multiple hash nodes require unique unit node
2055                          * names, e.g. hash@1, hash@2, etc.
2056                          */
2057                         if (strncmp (fit_get_name(fit, noffset, NULL),
2058                                                 FIT_HASH_NODENAME,
2059                                                 strlen(FIT_HASH_NODENAME)) != 0) {
2060                                 /* Not a hash subnode, skip it */
2061                                 continue;
2062                         }
2063
2064                         if (fit_image_hash_get_algo (fit, noffset, &algo)) {
2065                                 printf ("Can't get hash algo property for "
2066                                         "'%s' hash node in '%s' image node\n",
2067                                         fit_get_name (fit, noffset, NULL),
2068                                         fit_get_name (fit, image_noffset, NULL));
2069                                 return -1;
2070                         }
2071
2072                         if (calculate_hash (data, size, algo, value, &value_len)) {
2073                                 printf ("Unsupported hash algorithm (%s) for "
2074                                         "'%s' hash node in '%s' image node\n",
2075                                         algo, fit_get_name (fit, noffset, NULL),
2076                                         fit_get_name (fit, image_noffset, NULL));
2077                                 return -1;
2078                         }
2079
2080                         if (fit_image_hash_set_value (fit, noffset, value,
2081                                                         value_len)) {
2082                                 printf ("Can't set hash value for "
2083                                         "'%s' hash node in '%s' image node\n",
2084                                         fit_get_name (fit, noffset, NULL),
2085                                         fit_get_name (fit, image_noffset, NULL));
2086                                 return -1;
2087                         }
2088                 }
2089         }
2090
2091         return 0;
2092 }
2093
2094 /**
2095  * fit_image_hash_set_value - set hash value in requested has node
2096  * @fit: pointer to the FIT format image header
2097  * @noffset: hash node offset
2098  * @value: hash value to be set
2099  * @value_len: hash value length
2100  *
2101  * fit_image_hash_set_value() attempts to set hash value in a node at offset
2102  * given and returns operation status to the caller.
2103  *
2104  * returns
2105  *     0, on success
2106  *     -1, on failure
2107  */
2108 int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value,
2109                                 int value_len)
2110 {
2111         int ret;
2112
2113         ret = fdt_setprop (fit, noffset, FIT_VALUE_PROP, value, value_len);
2114         if (ret) {
2115                 printf ("Can't set hash '%s' property for '%s' node (%s)\n",
2116                         FIT_VALUE_PROP, fit_get_name (fit, noffset, NULL),
2117                         fdt_strerror (ret));
2118                 return -1;
2119         }
2120
2121         return 0;
2122 }
2123 #endif /* USE_HOSTCC */
2124
2125 /**
2126  * fit_image_check_hashes - verify data intergity
2127  * @fit: pointer to the FIT format image header
2128  * @image_noffset: component image node offset
2129  *
2130  * fit_image_check_hashes() goes over component image hash nodes,
2131  * re-calculates each data hash and compares with the value stored in hash
2132  * node.
2133  *
2134  * returns:
2135  *     1, if all hashes are valid
2136  *     0, otherwise (or on error)
2137  */
2138 int fit_image_check_hashes (const void *fit, int image_noffset)
2139 {
2140         const void      *data;
2141         size_t          size;
2142         char            *algo;
2143         uint8_t         *fit_value;
2144         int             fit_value_len;
2145         uint8_t         value[FIT_MAX_HASH_LEN];
2146         int             value_len;
2147         int             noffset;
2148         int             ndepth;
2149         char            *err_msg = "";
2150
2151         /* Get image data and data length */
2152         if (fit_image_get_data (fit, image_noffset, &data, &size)) {
2153                 printf ("Can't get image data/size\n");
2154                 return 0;
2155         }
2156
2157         /* Process all hash subnodes of the component image node */
2158         for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
2159              (noffset >= 0) && (ndepth > 0);
2160              noffset = fdt_next_node (fit, noffset, &ndepth)) {
2161                 if (ndepth == 1) {
2162                         /* Direct child node of the component image node */
2163
2164                         /*
2165                          * Check subnode name, must be equal to "hash".
2166                          * Multiple hash nodes require unique unit node
2167                          * names, e.g. hash@1, hash@2, etc.
2168                          */
2169                         if (strncmp (fit_get_name(fit, noffset, NULL),
2170                                         FIT_HASH_NODENAME,
2171                                         strlen(FIT_HASH_NODENAME)) != 0)
2172                                 continue;
2173
2174                         if (fit_image_hash_get_algo (fit, noffset, &algo)) {
2175                                 err_msg = "Can't get hash algo property";
2176                                 goto error;
2177                         }
2178                         printf ("%s", algo);
2179
2180                         if (fit_image_hash_get_value (fit, noffset, &fit_value,
2181                                                         &fit_value_len)) {
2182                                 err_msg = "Can't get hash value property";
2183                                 goto error;
2184                         }
2185
2186                         if (calculate_hash (data, size, algo, value, &value_len)) {
2187                                 err_msg = "Unsupported hash algorithm";
2188                                 goto error;
2189                         }
2190
2191                         if (value_len != fit_value_len) {
2192                                 err_msg = "Bad hash value len";
2193                                 goto error;
2194                         } else if (memcmp (value, fit_value, value_len) != 0) {
2195                                 err_msg = "Bad hash value";
2196                                 goto error;
2197                         }
2198                         printf ("+ ");
2199                 }
2200         }
2201
2202         return 1;
2203
2204 error:
2205         printf ("%s for '%s' hash node in '%s' image node\n",
2206                         err_msg, fit_get_name (fit, noffset, NULL),
2207                         fit_get_name (fit, image_noffset, NULL));
2208         return 0;
2209 }
2210
2211 /**
2212  * fit_image_check_os - check whether image node is of a given os type
2213  * @fit: pointer to the FIT format image header
2214  * @noffset: component image node offset
2215  * @os: requested image os
2216  *
2217  * fit_image_check_os() reads image os property and compares its numeric
2218  * id with the requested os. Comparison result is returned to the caller.
2219  *
2220  * returns:
2221  *     1 if image is of given os type
2222  *     0 otherwise (or on error)
2223  */
2224 int fit_image_check_os (const void *fit, int noffset, uint8_t os)
2225 {
2226         uint8_t image_os;
2227
2228         if (fit_image_get_os (fit, noffset, &image_os))
2229                 return 0;
2230         return (os == image_os);
2231 }
2232
2233 /**
2234  * fit_image_check_arch - check whether image node is of a given arch
2235  * @fit: pointer to the FIT format image header
2236  * @noffset: component image node offset
2237  * @arch: requested imagearch
2238  *
2239  * fit_image_check_arch() reads image arch property and compares its numeric
2240  * id with the requested arch. Comparison result is returned to the caller.
2241  *
2242  * returns:
2243  *     1 if image is of given arch
2244  *     0 otherwise (or on error)
2245  */
2246 int fit_image_check_arch (const void *fit, int noffset, uint8_t arch)
2247 {
2248         uint8_t image_arch;
2249
2250         if (fit_image_get_arch (fit, noffset, &image_arch))
2251                 return 0;
2252         return (arch == image_arch);
2253 }
2254
2255 /**
2256  * fit_image_check_type - check whether image node is of a given type
2257  * @fit: pointer to the FIT format image header
2258  * @noffset: component image node offset
2259  * @type: requested image type
2260  *
2261  * fit_image_check_type() reads image type property and compares its numeric
2262  * id with the requested type. Comparison result is returned to the caller.
2263  *
2264  * returns:
2265  *     1 if image is of given type
2266  *     0 otherwise (or on error)
2267  */
2268 int fit_image_check_type (const void *fit, int noffset, uint8_t type)
2269 {
2270         uint8_t image_type;
2271
2272         if (fit_image_get_type (fit, noffset, &image_type))
2273                 return 0;
2274         return (type == image_type);
2275 }
2276
2277 /**
2278  * fit_image_check_comp - check whether image node uses given compression
2279  * @fit: pointer to the FIT format image header
2280  * @noffset: component image node offset
2281  * @comp: requested image compression type
2282  *
2283  * fit_image_check_comp() reads image compression property and compares its
2284  * numeric id with the requested compression type. Comparison result is
2285  * returned to the caller.
2286  *
2287  * returns:
2288  *     1 if image uses requested compression
2289  *     0 otherwise (or on error)
2290  */
2291 int fit_image_check_comp (const void *fit, int noffset, uint8_t comp)
2292 {
2293         uint8_t image_comp;
2294
2295         if (fit_image_get_comp (fit, noffset, &image_comp))
2296                 return 0;
2297         return (comp == image_comp);
2298 }
2299
2300 /**
2301  * fit_check_format - sanity check FIT image format
2302  * @fit: pointer to the FIT format image header
2303  *
2304  * fit_check_format() runs a basic sanity FIT image verification.
2305  * Routine checks for mandatory properties, nodes, etc.
2306  *
2307  * returns:
2308  *     1, on success
2309  *     0, on failure
2310  */
2311 int fit_check_format (const void *fit)
2312 {
2313         /* mandatory / node 'description' property */
2314         if (fdt_getprop (fit, 0, FIT_DESC_PROP, NULL) == NULL) {
2315                 debug ("Wrong FIT format: no description\n");
2316                 return 0;
2317         }
2318
2319 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
2320         /* mandatory / node 'timestamp' property */
2321         if (fdt_getprop (fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) {
2322                 debug ("Wrong FIT format: no description\n");
2323                 return 0;
2324         }
2325 #endif
2326
2327         /* mandatory subimages parent '/images' node */
2328         if (fdt_path_offset (fit, FIT_IMAGES_PATH) < 0) {
2329                 debug ("Wrong FIT format: no images parent node\n");
2330                 return 0;
2331         }
2332
2333         return 1;
2334 }
2335
2336 /**
2337  * fit_conf_get_node - get node offset for configuration of a given unit name
2338  * @fit: pointer to the FIT format image header
2339  * @conf_uname: configuration node unit name
2340  *
2341  * fit_conf_get_node() finds a configuration (withing the '/configurations'
2342  * parant node) of a provided unit name. If configuration is found its node offset
2343  * is returned to the caller.
2344  *
2345  * When NULL is provided in second argument fit_conf_get_node() will search
2346  * for a default configuration node instead. Default configuration node unit name
2347  * is retrived from FIT_DEFAULT_PROP property of the '/configurations' node.
2348  *
2349  * returns:
2350  *     configuration node offset when found (>=0)
2351  *     negative number on failure (FDT_ERR_* code)
2352  */
2353 int fit_conf_get_node (const void *fit, const char *conf_uname)
2354 {
2355         int noffset, confs_noffset;
2356         int len;
2357
2358         confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH);
2359         if (confs_noffset < 0) {
2360                 debug ("Can't find configurations parent node '%s' (%s)\n",
2361                         FIT_CONFS_PATH, fdt_strerror (confs_noffset));
2362                 return confs_noffset;
2363         }
2364
2365         if (conf_uname == NULL) {
2366                 /* get configuration unit name from the default property */
2367                 debug ("No configuration specified, trying default...\n");
2368                 conf_uname = (char *)fdt_getprop (fit, confs_noffset, FIT_DEFAULT_PROP, &len);
2369                 if (conf_uname == NULL) {
2370                         fit_get_debug (fit, confs_noffset, FIT_DEFAULT_PROP, len);
2371                         return len;
2372                 }
2373                 debug ("Found default configuration: '%s'\n", conf_uname);
2374         }
2375
2376         noffset = fdt_subnode_offset (fit, confs_noffset, conf_uname);
2377         if (noffset < 0) {
2378                 debug ("Can't get node offset for configuration unit name: '%s' (%s)\n",
2379                         conf_uname, fdt_strerror (noffset));
2380         }
2381
2382         return noffset;
2383 }
2384
2385 static int __fit_conf_get_prop_node (const void *fit, int noffset,
2386                 const char *prop_name)
2387 {
2388         char *uname;
2389         int len;
2390
2391         /* get kernel image unit name from configuration kernel property */
2392         uname = (char *)fdt_getprop (fit, noffset, prop_name, &len);
2393         if (uname == NULL)
2394                 return len;
2395
2396         return fit_image_get_node (fit, uname);
2397 }
2398
2399 /**
2400  * fit_conf_get_kernel_node - get kernel image node offset that corresponds to
2401  * a given configuration
2402  * @fit: pointer to the FIT format image header
2403  * @noffset: configuration node offset
2404  *
2405  * fit_conf_get_kernel_node() retrives kernel image node unit name from
2406  * configuration FIT_KERNEL_PROP property and translates it to the node
2407  * offset.
2408  *
2409  * returns:
2410  *     image node offset when found (>=0)
2411  *     negative number on failure (FDT_ERR_* code)
2412  */
2413 int fit_conf_get_kernel_node (const void *fit, int noffset)
2414 {
2415         return __fit_conf_get_prop_node (fit, noffset, FIT_KERNEL_PROP);
2416 }
2417
2418 /**
2419  * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to
2420  * a given configuration
2421  * @fit: pointer to the FIT format image header
2422  * @noffset: configuration node offset
2423  *
2424  * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from
2425  * configuration FIT_KERNEL_PROP property and translates it to the node
2426  * offset.
2427  *
2428  * returns:
2429  *     image node offset when found (>=0)
2430  *     negative number on failure (FDT_ERR_* code)
2431  */
2432 int fit_conf_get_ramdisk_node (const void *fit, int noffset)
2433 {
2434         return __fit_conf_get_prop_node (fit, noffset, FIT_RAMDISK_PROP);
2435 }
2436
2437 /**
2438  * fit_conf_get_fdt_node - get fdt image node offset that corresponds to
2439  * a given configuration
2440  * @fit: pointer to the FIT format image header
2441  * @noffset: configuration node offset
2442  *
2443  * fit_conf_get_fdt_node() retrives fdt image node unit name from
2444  * configuration FIT_KERNEL_PROP property and translates it to the node
2445  * offset.
2446  *
2447  * returns:
2448  *     image node offset when found (>=0)
2449  *     negative number on failure (FDT_ERR_* code)
2450  */
2451 int fit_conf_get_fdt_node (const void *fit, int noffset)
2452 {
2453         return __fit_conf_get_prop_node (fit, noffset, FIT_FDT_PROP);
2454 }
2455
2456 /**
2457  * fit_conf_print - prints out the FIT configuration details
2458  * @fit: pointer to the FIT format image header
2459  * @noffset: offset of the configuration node
2460  * @p: pointer to prefix string
2461  *
2462  * fit_conf_print() lists all mandatory properies for the processed
2463  * configuration node.
2464  *
2465  * returns:
2466  *     no returned results
2467  */
2468 void fit_conf_print (const void *fit, int noffset, const char *p)
2469 {
2470         char *desc;
2471         char *uname;
2472         int ret;
2473
2474         /* Mandatory properties */
2475         ret = fit_get_desc (fit, noffset, &desc);
2476         printf ("%s  Description:  ", p);
2477         if (ret)
2478                 printf ("unavailable\n");
2479         else
2480                 printf ("%s\n", desc);
2481
2482         uname = (char *)fdt_getprop (fit, noffset, FIT_KERNEL_PROP, NULL);
2483         printf ("%s  Kernel:       ", p);
2484         if (uname == NULL)
2485                 printf ("unavailable\n");
2486         else
2487                 printf ("%s\n", uname);
2488
2489         /* Optional properties */
2490         uname = (char *)fdt_getprop (fit, noffset, FIT_RAMDISK_PROP, NULL);
2491         if (uname)
2492                 printf ("%s  Init Ramdisk: %s\n", p, uname);
2493
2494         uname = (char *)fdt_getprop (fit, noffset, FIT_FDT_PROP, NULL);
2495         if (uname)
2496                 printf ("%s  FDT:          %s\n", p, uname);
2497 }
2498
2499 /**
2500  * fit_check_ramdisk - verify FIT format ramdisk subimage
2501  * @fit_hdr: pointer to the FIT ramdisk header
2502  * @rd_noffset: ramdisk subimage node offset within FIT image
2503  * @arch: requested ramdisk image architecture type
2504  * @verify: data CRC verification flag
2505  *
2506  * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from
2507  * specified FIT image.
2508  *
2509  * returns:
2510  *     1, on success
2511  *     0, on failure
2512  */
2513 #ifndef USE_HOSTCC
2514 static int fit_check_ramdisk (const void *fit, int rd_noffset, uint8_t arch, int verify)
2515 {
2516         fit_image_print (fit, rd_noffset, "   ");
2517
2518         if (verify) {
2519                 puts ("   Verifying Hash Integrity ... ");
2520                 if (!fit_image_check_hashes (fit, rd_noffset)) {
2521                         puts ("Bad Data Hash\n");
2522                         show_boot_progress (-125);
2523                         return 0;
2524                 }
2525                 puts ("OK\n");
2526         }
2527
2528         show_boot_progress (126);
2529         if (!fit_image_check_os (fit, rd_noffset, IH_OS_LINUX) ||
2530             !fit_image_check_arch (fit, rd_noffset, arch) ||
2531             !fit_image_check_type (fit, rd_noffset, IH_TYPE_RAMDISK)) {
2532                 printf ("No Linux %s Ramdisk Image\n",
2533                                 genimg_get_arch_name(arch));
2534                 show_boot_progress (-126);
2535                 return 0;
2536         }
2537
2538         show_boot_progress (127);
2539         return 1;
2540 }
2541 #endif /* USE_HOSTCC */
2542 #endif /* CONFIG_FIT */