nds32: common bdinfo, bootm, image support
[kernel/u-boot.git] / 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 #ifndef USE_HOSTCC
27 #include <common.h>
28 #include <watchdog.h>
29
30 #ifdef CONFIG_SHOW_BOOT_PROGRESS
31 #include <status_led.h>
32 #endif
33
34 #ifdef CONFIG_HAS_DATAFLASH
35 #include <dataflash.h>
36 #endif
37
38 #ifdef CONFIG_LOGBUFFER
39 #include <logbuff.h>
40 #endif
41
42 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE)
43 #include <rtc.h>
44 #endif
45
46 #include <image.h>
47
48 #if defined(CONFIG_FIT) || defined (CONFIG_OF_LIBFDT)
49 #include <fdt.h>
50 #include <libfdt.h>
51 #include <fdt_support.h>
52 #endif
53
54 #if defined(CONFIG_FIT)
55 #include <u-boot/md5.h>
56 #include <sha1.h>
57
58 static int fit_check_ramdisk (const void *fit, int os_noffset,
59                 uint8_t arch, int verify);
60 #endif
61
62 #ifdef CONFIG_CMD_BDI
63 extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
64 #endif
65
66 DECLARE_GLOBAL_DATA_PTR;
67
68 static const image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
69                                                 int verify);
70 #else
71 #include "mkimage.h"
72 #include <u-boot/md5.h>
73 #include <time.h>
74 #include <image.h>
75 #endif /* !USE_HOSTCC*/
76
77 static const table_entry_t uimage_arch[] = {
78         {       IH_ARCH_INVALID,        NULL,           "Invalid ARCH", },
79         {       IH_ARCH_ALPHA,          "alpha",        "Alpha",        },
80         {       IH_ARCH_ARM,            "arm",          "ARM",          },
81         {       IH_ARCH_I386,           "x86",          "Intel x86",    },
82         {       IH_ARCH_IA64,           "ia64",         "IA64",         },
83         {       IH_ARCH_M68K,           "m68k",         "M68K",         },
84         {       IH_ARCH_MICROBLAZE,     "microblaze",   "MicroBlaze",   },
85         {       IH_ARCH_MIPS,           "mips",         "MIPS",         },
86         {       IH_ARCH_MIPS64,         "mips64",       "MIPS 64 Bit",  },
87         {       IH_ARCH_NIOS2,          "nios2",        "NIOS II",      },
88         {       IH_ARCH_PPC,            "powerpc",      "PowerPC",      },
89         {       IH_ARCH_PPC,            "ppc",          "PowerPC",      },
90         {       IH_ARCH_S390,           "s390",         "IBM S390",     },
91         {       IH_ARCH_SH,             "sh",           "SuperH",       },
92         {       IH_ARCH_SPARC,          "sparc",        "SPARC",        },
93         {       IH_ARCH_SPARC64,        "sparc64",      "SPARC 64 Bit", },
94         {       IH_ARCH_BLACKFIN,       "blackfin",     "Blackfin",     },
95         {       IH_ARCH_AVR32,          "avr32",        "AVR32",        },
96         {       IH_ARCH_NDS32,          "nds32",        "NDS32",        },
97         {       -1,                     "",             "",             },
98 };
99
100 static const table_entry_t uimage_os[] = {
101         {       IH_OS_INVALID,  NULL,           "Invalid OS",           },
102         {       IH_OS_LINUX,    "linux",        "Linux",                },
103 #if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC)
104         {       IH_OS_LYNXOS,   "lynxos",       "LynxOS",               },
105 #endif
106         {       IH_OS_NETBSD,   "netbsd",       "NetBSD",               },
107         {       IH_OS_OSE,      "ose",          "Enea OSE",             },
108         {       IH_OS_RTEMS,    "rtems",        "RTEMS",                },
109         {       IH_OS_U_BOOT,   "u-boot",       "U-Boot",               },
110 #if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)
111         {       IH_OS_QNX,      "qnx",          "QNX",                  },
112         {       IH_OS_VXWORKS,  "vxworks",      "VxWorks",              },
113 #endif
114 #if defined(CONFIG_INTEGRITY) || defined(USE_HOSTCC)
115         {       IH_OS_INTEGRITY,"integrity",    "INTEGRITY",            },
116 #endif
117 #ifdef USE_HOSTCC
118         {       IH_OS_4_4BSD,   "4_4bsd",       "4_4BSD",               },
119         {       IH_OS_DELL,     "dell",         "Dell",                 },
120         {       IH_OS_ESIX,     "esix",         "Esix",                 },
121         {       IH_OS_FREEBSD,  "freebsd",      "FreeBSD",              },
122         {       IH_OS_IRIX,     "irix",         "Irix",                 },
123         {       IH_OS_NCR,      "ncr",          "NCR",                  },
124         {       IH_OS_OPENBSD,  "openbsd",      "OpenBSD",              },
125         {       IH_OS_PSOS,     "psos",         "pSOS",                 },
126         {       IH_OS_SCO,      "sco",          "SCO",                  },
127         {       IH_OS_SOLARIS,  "solaris",      "Solaris",              },
128         {       IH_OS_SVR4,     "svr4",         "SVR4",                 },
129 #endif
130         {       -1,             "",             "",                     },
131 };
132
133 static const table_entry_t uimage_type[] = {
134         {       IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image",   },
135         {       IH_TYPE_FIRMWARE,   "firmware",   "Firmware",           },
136         {       IH_TYPE_FLATDT,     "flat_dt",    "Flat Device Tree",   },
137         {       IH_TYPE_KERNEL,     "kernel",     "Kernel Image",       },
138         {       IH_TYPE_MULTI,      "multi",      "Multi-File Image",   },
139         {       IH_TYPE_RAMDISK,    "ramdisk",    "RAMDisk Image",      },
140         {       IH_TYPE_SCRIPT,     "script",     "Script",             },
141         {       IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
142         {       IH_TYPE_IMXIMAGE,   "imximage",   "Freescale i.MX Boot Image",},
143         {       IH_TYPE_KWBIMAGE,   "kwbimage",   "Kirkwood Boot Image",},
144         {       IH_TYPE_OMAPIMAGE,  "omapimage",  "TI OMAP SPL With GP CH",},
145         {       IH_TYPE_UBLIMAGE,   "ublimage",   "Davinci UBL image",},
146         {       IH_TYPE_INVALID,    NULL,         "Invalid Image",      },
147         {       -1,                 "",           "",                   },
148 };
149
150 static const table_entry_t uimage_comp[] = {
151         {       IH_COMP_NONE,   "none",         "uncompressed",         },
152         {       IH_COMP_BZIP2,  "bzip2",        "bzip2 compressed",     },
153         {       IH_COMP_GZIP,   "gzip",         "gzip compressed",      },
154         {       IH_COMP_LZMA,   "lzma",         "lzma compressed",      },
155         {       IH_COMP_LZO,    "lzo",          "lzo compressed",       },
156         {       -1,             "",             "",                     },
157 };
158
159 uint32_t crc32 (uint32_t, const unsigned char *, uint);
160 uint32_t crc32_wd (uint32_t, const unsigned char *, uint, uint);
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 (const 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 (const image_header_t *hdr)
184 {
185         ulong data = image_get_data (hdr);
186         ulong len = image_get_data_size (hdr);
187         ulong dcrc = crc32_wd (0, (unsigned char *)data, len, CHUNKSZ_CRC32);
188
189         return (dcrc == image_get_dcrc (hdr));
190 }
191
192 /**
193  * image_multi_count - get component (sub-image) count
194  * @hdr: pointer to the header of the multi component image
195  *
196  * image_multi_count() returns number of components in a multi
197  * component image.
198  *
199  * Note: no checking of the image type is done, caller must pass
200  * a valid multi component image.
201  *
202  * returns:
203  *     number of components
204  */
205 ulong image_multi_count (const image_header_t *hdr)
206 {
207         ulong i, count = 0;
208         uint32_t *size;
209
210         /* get start of the image payload, which in case of multi
211          * component images that points to a table of component sizes */
212         size = (uint32_t *)image_get_data (hdr);
213
214         /* count non empty slots */
215         for (i = 0; size[i]; ++i)
216                 count++;
217
218         return count;
219 }
220
221 /**
222  * image_multi_getimg - get component data address and size
223  * @hdr: pointer to the header of the multi component image
224  * @idx: index of the requested component
225  * @data: pointer to a ulong variable, will hold component data address
226  * @len: pointer to a ulong variable, will hold component size
227  *
228  * image_multi_getimg() returns size and data address for the requested
229  * component in a multi component image.
230  *
231  * Note: no checking of the image type is done, caller must pass
232  * a valid multi component image.
233  *
234  * returns:
235  *     data address and size of the component, if idx is valid
236  *     0 in data and len, if idx is out of range
237  */
238 void image_multi_getimg (const image_header_t *hdr, ulong idx,
239                         ulong *data, ulong *len)
240 {
241         int i;
242         uint32_t *size;
243         ulong offset, count, img_data;
244
245         /* get number of component */
246         count = image_multi_count (hdr);
247
248         /* get start of the image payload, which in case of multi
249          * component images that points to a table of component sizes */
250         size = (uint32_t *)image_get_data (hdr);
251
252         /* get address of the proper component data start, which means
253          * skipping sizes table (add 1 for last, null entry) */
254         img_data = image_get_data (hdr) + (count + 1) * sizeof (uint32_t);
255
256         if (idx < count) {
257                 *len = uimage_to_cpu (size[idx]);
258                 offset = 0;
259
260                 /* go over all indices preceding requested component idx */
261                 for (i = 0; i < idx; i++) {
262                         /* add up i-th component size, rounding up to 4 bytes */
263                         offset += (uimage_to_cpu (size[i]) + 3) & ~3 ;
264                 }
265
266                 /* calculate idx-th component data address */
267                 *data = img_data + offset;
268         } else {
269                 *len = 0;
270                 *data = 0;
271         }
272 }
273
274 static void image_print_type (const image_header_t *hdr)
275 {
276         const char *os, *arch, *type, *comp;
277
278         os = genimg_get_os_name (image_get_os (hdr));
279         arch = genimg_get_arch_name (image_get_arch (hdr));
280         type = genimg_get_type_name (image_get_type (hdr));
281         comp = genimg_get_comp_name (image_get_comp (hdr));
282
283         printf ("%s %s %s (%s)\n", arch, os, type, comp);
284 }
285
286 /**
287  * image_print_contents - prints out the contents of the legacy format image
288  * @ptr: pointer to the legacy format image header
289  * @p: pointer to prefix string
290  *
291  * image_print_contents() formats a multi line legacy image contents description.
292  * The routine prints out all header fields followed by the size/offset data
293  * for MULTI/SCRIPT images.
294  *
295  * returns:
296  *     no returned results
297  */
298 void image_print_contents (const void *ptr)
299 {
300         const image_header_t *hdr = (const image_header_t *)ptr;
301         const char *p;
302
303 #ifdef USE_HOSTCC
304         p = "";
305 #else
306         p = "   ";
307 #endif
308
309         printf ("%sImage Name:   %.*s\n", p, IH_NMLEN, image_get_name (hdr));
310 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
311         printf ("%sCreated:      ", p);
312         genimg_print_time ((time_t)image_get_time (hdr));
313 #endif
314         printf ("%sImage Type:   ", p);
315         image_print_type (hdr);
316         printf ("%sData Size:    ", p);
317         genimg_print_size (image_get_data_size (hdr));
318         printf ("%sLoad Address: %08x\n", p, image_get_load (hdr));
319         printf ("%sEntry Point:  %08x\n", p, image_get_ep (hdr));
320
321         if (image_check_type (hdr, IH_TYPE_MULTI) ||
322                         image_check_type (hdr, IH_TYPE_SCRIPT)) {
323                 int i;
324                 ulong data, len;
325                 ulong count = image_multi_count (hdr);
326
327                 printf ("%sContents:\n", p);
328                 for (i = 0; i < count; i++) {
329                         image_multi_getimg (hdr, i, &data, &len);
330
331                         printf ("%s   Image %d: ", p, i);
332                         genimg_print_size (len);
333
334                         if (image_check_type (hdr, IH_TYPE_SCRIPT) && i > 0) {
335                                 /*
336                                  * the user may need to know offsets
337                                  * if planning to do something with
338                                  * multiple files
339                                  */
340                                 printf ("%s    Offset = 0x%08lx\n", p, data);
341                         }
342                 }
343         }
344 }
345
346
347 #ifndef USE_HOSTCC
348 /**
349  * image_get_ramdisk - get and verify ramdisk image
350  * @rd_addr: ramdisk image start address
351  * @arch: expected ramdisk architecture
352  * @verify: checksum verification flag
353  *
354  * image_get_ramdisk() returns a pointer to the verified ramdisk image
355  * header. Routine receives image start address and expected architecture
356  * flag. Verification done covers data and header integrity and os/type/arch
357  * fields checking.
358  *
359  * If dataflash support is enabled routine checks for dataflash addresses
360  * and handles required dataflash reads.
361  *
362  * returns:
363  *     pointer to a ramdisk image header, if image was found and valid
364  *     otherwise, return NULL
365  */
366 static const image_header_t *image_get_ramdisk (ulong rd_addr, uint8_t arch,
367                                                 int verify)
368 {
369         const image_header_t *rd_hdr = (const image_header_t *)rd_addr;
370
371         if (!image_check_magic (rd_hdr)) {
372                 puts ("Bad Magic Number\n");
373                 show_boot_progress (-10);
374                 return NULL;
375         }
376
377         if (!image_check_hcrc (rd_hdr)) {
378                 puts ("Bad Header Checksum\n");
379                 show_boot_progress (-11);
380                 return NULL;
381         }
382
383         show_boot_progress (10);
384         image_print_contents (rd_hdr);
385
386         if (verify) {
387                 puts("   Verifying Checksum ... ");
388                 if (!image_check_dcrc (rd_hdr)) {
389                         puts ("Bad Data CRC\n");
390                         show_boot_progress (-12);
391                         return NULL;
392                 }
393                 puts("OK\n");
394         }
395
396         show_boot_progress (11);
397
398         if (!image_check_os (rd_hdr, IH_OS_LINUX) ||
399             !image_check_arch (rd_hdr, arch) ||
400             !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {
401                 printf ("No Linux %s Ramdisk Image\n",
402                                 genimg_get_arch_name(arch));
403                 show_boot_progress (-13);
404                 return NULL;
405         }
406
407         return rd_hdr;
408 }
409 #endif /* !USE_HOSTCC */
410
411 /*****************************************************************************/
412 /* Shared dual-format routines */
413 /*****************************************************************************/
414 #ifndef USE_HOSTCC
415 int getenv_yesno (char *var)
416 {
417         char *s = getenv (var);
418         return (s && (*s == 'n')) ? 0 : 1;
419 }
420
421 ulong getenv_bootm_low(void)
422 {
423         char *s = getenv ("bootm_low");
424         if (s) {
425                 ulong tmp = simple_strtoul (s, NULL, 16);
426                 return tmp;
427         }
428
429 #if defined(CONFIG_SYS_SDRAM_BASE)
430         return CONFIG_SYS_SDRAM_BASE;
431 #elif defined(CONFIG_ARM)
432         return gd->bd->bi_dram[0].start;
433 #else
434         return 0;
435 #endif
436 }
437
438 phys_size_t getenv_bootm_size(void)
439 {
440         phys_size_t tmp;
441         char *s = getenv ("bootm_size");
442         if (s) {
443                 tmp = (phys_size_t)simple_strtoull (s, NULL, 16);
444                 return tmp;
445         }
446         s = getenv("bootm_low");
447         if (s)
448                 tmp = (phys_size_t)simple_strtoull (s, NULL, 16);
449         else
450                 tmp = 0;
451
452
453 #if defined(CONFIG_ARM)
454         return gd->bd->bi_dram[0].size - tmp;
455 #else
456         return gd->bd->bi_memsize - tmp;
457 #endif
458 }
459
460 phys_size_t getenv_bootm_mapsize(void)
461 {
462         phys_size_t tmp;
463         char *s = getenv ("bootm_mapsize");
464         if (s) {
465                 tmp = (phys_size_t)simple_strtoull (s, NULL, 16);
466                 return tmp;
467         }
468
469 #if defined(CONFIG_SYS_BOOTMAPSZ)
470         return CONFIG_SYS_BOOTMAPSZ;
471 #else
472         return getenv_bootm_size();
473 #endif
474 }
475
476 void memmove_wd (void *to, void *from, size_t len, ulong chunksz)
477 {
478         if (to == from)
479                 return;
480
481 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
482         while (len > 0) {
483                 size_t tail = (len > chunksz) ? chunksz : len;
484                 WATCHDOG_RESET ();
485                 memmove (to, from, tail);
486                 to += tail;
487                 from += tail;
488                 len -= tail;
489         }
490 #else   /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
491         memmove (to, from, len);
492 #endif  /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
493 }
494 #endif /* !USE_HOSTCC */
495
496 void genimg_print_size (uint32_t size)
497 {
498 #ifndef USE_HOSTCC
499         printf ("%d Bytes = ", size);
500         print_size (size, "\n");
501 #else
502         printf ("%d Bytes = %.2f kB = %.2f MB\n",
503                         size, (double)size / 1.024e3,
504                         (double)size / 1.048576e6);
505 #endif
506 }
507
508 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
509 static void genimg_print_time (time_t timestamp)
510 {
511 #ifndef USE_HOSTCC
512         struct rtc_time tm;
513
514         to_tm (timestamp, &tm);
515         printf ("%4d-%02d-%02d  %2d:%02d:%02d UTC\n",
516                         tm.tm_year, tm.tm_mon, tm.tm_mday,
517                         tm.tm_hour, tm.tm_min, tm.tm_sec);
518 #else
519         printf ("%s", ctime(&timestamp));
520 #endif
521 }
522 #endif /* CONFIG_TIMESTAMP || CONFIG_CMD_DATE || USE_HOSTCC */
523
524 /**
525  * get_table_entry_name - translate entry id to long name
526  * @table: pointer to a translation table for entries of a specific type
527  * @msg: message to be returned when translation fails
528  * @id: entry id to be translated
529  *
530  * get_table_entry_name() will go over translation table trying to find
531  * entry that matches given id. If matching entry is found, its long
532  * name is returned to the caller.
533  *
534  * returns:
535  *     long entry name if translation succeeds
536  *     msg otherwise
537  */
538 char *get_table_entry_name(const table_entry_t *table, char *msg, int id)
539 {
540         for (; table->id >= 0; ++table) {
541                 if (table->id == id)
542 #if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
543                         return table->lname;
544 #else
545                         return table->lname + gd->reloc_off;
546 #endif
547         }
548         return (msg);
549 }
550
551 const char *genimg_get_os_name (uint8_t os)
552 {
553         return (get_table_entry_name (uimage_os, "Unknown OS", os));
554 }
555
556 const char *genimg_get_arch_name (uint8_t arch)
557 {
558         return (get_table_entry_name (uimage_arch, "Unknown Architecture", arch));
559 }
560
561 const char *genimg_get_type_name (uint8_t type)
562 {
563         return (get_table_entry_name (uimage_type, "Unknown Image", type));
564 }
565
566 const char *genimg_get_comp_name (uint8_t comp)
567 {
568         return (get_table_entry_name (uimage_comp, "Unknown Compression", comp));
569 }
570
571 /**
572  * get_table_entry_id - translate short entry name to id
573  * @table: pointer to a translation table for entries of a specific type
574  * @table_name: to be used in case of error
575  * @name: entry short name to be translated
576  *
577  * get_table_entry_id() will go over translation table trying to find
578  * entry that matches given short name. If matching entry is found,
579  * its id returned to the caller.
580  *
581  * returns:
582  *     entry id if translation succeeds
583  *     -1 otherwise
584  */
585 int get_table_entry_id(const table_entry_t *table,
586                 const char *table_name, const char *name)
587 {
588         const table_entry_t *t;
589 #ifdef USE_HOSTCC
590         int first = 1;
591
592         for (t = table; t->id >= 0; ++t) {
593                 if (t->sname && strcasecmp(t->sname, name) == 0)
594                         return (t->id);
595         }
596
597         fprintf (stderr, "\nInvalid %s Type - valid names are", table_name);
598         for (t = table; t->id >= 0; ++t) {
599                 if (t->sname == NULL)
600                         continue;
601                 fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname);
602                 first = 0;
603         }
604         fprintf (stderr, "\n");
605 #else
606         for (t = table; t->id >= 0; ++t) {
607 #ifdef CONFIG_NEEDS_MANUAL_RELOC
608                 if (t->sname && strcmp(t->sname + gd->reloc_off, name) == 0)
609 #else
610                 if (t->sname && strcmp(t->sname, name) == 0)
611 #endif
612                         return (t->id);
613         }
614         debug ("Invalid %s Type: %s\n", table_name, name);
615 #endif /* USE_HOSTCC */
616         return (-1);
617 }
618
619 int genimg_get_os_id (const char *name)
620 {
621         return (get_table_entry_id (uimage_os, "OS", name));
622 }
623
624 int genimg_get_arch_id (const char *name)
625 {
626         return (get_table_entry_id (uimage_arch, "CPU", name));
627 }
628
629 int genimg_get_type_id (const char *name)
630 {
631         return (get_table_entry_id (uimage_type, "Image", name));
632 }
633
634 int genimg_get_comp_id (const char *name)
635 {
636         return (get_table_entry_id (uimage_comp, "Compression", name));
637 }
638
639 #ifndef USE_HOSTCC
640 /**
641  * genimg_get_format - get image format type
642  * @img_addr: image start address
643  *
644  * genimg_get_format() checks whether provided address points to a valid
645  * legacy or FIT image.
646  *
647  * New uImage format and FDT blob are based on a libfdt. FDT blob
648  * may be passed directly or embedded in a FIT image. In both situations
649  * genimg_get_format() must be able to dectect libfdt header.
650  *
651  * returns:
652  *     image format type or IMAGE_FORMAT_INVALID if no image is present
653  */
654 int genimg_get_format (void *img_addr)
655 {
656         ulong format = IMAGE_FORMAT_INVALID;
657         const image_header_t *hdr;
658 #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
659         char *fit_hdr;
660 #endif
661
662         hdr = (const image_header_t *)img_addr;
663         if (image_check_magic(hdr))
664                 format = IMAGE_FORMAT_LEGACY;
665 #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
666         else {
667                 fit_hdr = (char *)img_addr;
668                 if (fdt_check_header (fit_hdr) == 0)
669                         format = IMAGE_FORMAT_FIT;
670         }
671 #endif
672
673         return format;
674 }
675
676 /**
677  * genimg_get_image - get image from special storage (if necessary)
678  * @img_addr: image start address
679  *
680  * genimg_get_image() checks if provided image start adddress is located
681  * in a dataflash storage. If so, image is moved to a system RAM memory.
682  *
683  * returns:
684  *     image start address after possible relocation from special storage
685  */
686 ulong genimg_get_image (ulong img_addr)
687 {
688         ulong ram_addr = img_addr;
689
690 #ifdef CONFIG_HAS_DATAFLASH
691         ulong h_size, d_size;
692
693         if (addr_dataflash (img_addr)){
694                 /* ger RAM address */
695                 ram_addr = CONFIG_SYS_LOAD_ADDR;
696
697                 /* get header size */
698                 h_size = image_get_header_size ();
699 #if defined(CONFIG_FIT)
700                 if (sizeof(struct fdt_header) > h_size)
701                         h_size = sizeof(struct fdt_header);
702 #endif
703
704                 /* read in header */
705                 debug ("   Reading image header from dataflash address "
706                         "%08lx to RAM address %08lx\n", img_addr, ram_addr);
707
708                 read_dataflash (img_addr, h_size, (char *)ram_addr);
709
710                 /* get data size */
711                 switch (genimg_get_format ((void *)ram_addr)) {
712                 case IMAGE_FORMAT_LEGACY:
713                         d_size = image_get_data_size ((const image_header_t *)ram_addr);
714                         debug ("   Legacy format image found at 0x%08lx, size 0x%08lx\n",
715                                         ram_addr, d_size);
716                         break;
717 #if defined(CONFIG_FIT)
718                 case IMAGE_FORMAT_FIT:
719                         d_size = fit_get_size ((const void *)ram_addr) - h_size;
720                         debug ("   FIT/FDT format image found at 0x%08lx, size 0x%08lx\n",
721                                         ram_addr, d_size);
722                         break;
723 #endif
724                 default:
725                         printf ("   No valid image found at 0x%08lx\n", img_addr);
726                         return ram_addr;
727                 }
728
729                 /* read in image data */
730                 debug ("   Reading image remaining data from dataflash address "
731                         "%08lx to RAM address %08lx\n", img_addr + h_size,
732                         ram_addr + h_size);
733
734                 read_dataflash (img_addr + h_size, d_size,
735                                 (char *)(ram_addr + h_size));
736
737         }
738 #endif /* CONFIG_HAS_DATAFLASH */
739
740         return ram_addr;
741 }
742
743 /**
744  * fit_has_config - check if there is a valid FIT configuration
745  * @images: pointer to the bootm command headers structure
746  *
747  * fit_has_config() checks if there is a FIT configuration in use
748  * (if FTI support is present).
749  *
750  * returns:
751  *     0, no FIT support or no configuration found
752  *     1, configuration found
753  */
754 int genimg_has_config (bootm_headers_t *images)
755 {
756 #if defined(CONFIG_FIT)
757         if (images->fit_uname_cfg)
758                 return 1;
759 #endif
760         return 0;
761 }
762
763 /**
764  * boot_get_ramdisk - main ramdisk handling routine
765  * @argc: command argument count
766  * @argv: command argument list
767  * @images: pointer to the bootm images structure
768  * @arch: expected ramdisk architecture
769  * @rd_start: pointer to a ulong variable, will hold ramdisk start address
770  * @rd_end: pointer to a ulong variable, will hold ramdisk end
771  *
772  * boot_get_ramdisk() is responsible for finding a valid ramdisk image.
773  * Curently supported are the following ramdisk sources:
774  *      - multicomponent kernel/ramdisk image,
775  *      - commandline provided address of decicated ramdisk image.
776  *
777  * returns:
778  *     0, if ramdisk image was found and valid, or skiped
779  *     rd_start and rd_end are set to ramdisk start/end addresses if
780  *     ramdisk image is found and valid
781  *
782  *     1, if ramdisk image is found but corrupted, or invalid
783  *     rd_start and rd_end are set to 0 if no ramdisk exists
784  */
785 int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images,
786                 uint8_t arch, ulong *rd_start, ulong *rd_end)
787 {
788         ulong rd_addr, rd_load;
789         ulong rd_data, rd_len;
790         const image_header_t *rd_hdr;
791 #if defined(CONFIG_FIT)
792         void            *fit_hdr;
793         const char      *fit_uname_config = NULL;
794         const char      *fit_uname_ramdisk = NULL;
795         ulong           default_addr;
796         int             rd_noffset;
797         int             cfg_noffset;
798         const void      *data;
799         size_t          size;
800 #endif
801
802         *rd_start = 0;
803         *rd_end = 0;
804
805         /*
806          * Look for a '-' which indicates to ignore the
807          * ramdisk argument
808          */
809         if ((argc >= 3) && (strcmp(argv[2], "-") ==  0)) {
810                 debug ("## Skipping init Ramdisk\n");
811                 rd_len = rd_data = 0;
812         } else if (argc >= 3 || genimg_has_config (images)) {
813 #if defined(CONFIG_FIT)
814                 if (argc >= 3) {
815                         /*
816                          * If the init ramdisk comes from the FIT image and
817                          * the FIT image address is omitted in the command
818                          * line argument, try to use os FIT image address or
819                          * default load address.
820                          */
821                         if (images->fit_uname_os)
822                                 default_addr = (ulong)images->fit_hdr_os;
823                         else
824                                 default_addr = load_addr;
825
826                         if (fit_parse_conf (argv[2], default_addr,
827                                                 &rd_addr, &fit_uname_config)) {
828                                 debug ("*  ramdisk: config '%s' from image at 0x%08lx\n",
829                                                 fit_uname_config, rd_addr);
830                         } else if (fit_parse_subimage (argv[2], default_addr,
831                                                 &rd_addr, &fit_uname_ramdisk)) {
832                                 debug ("*  ramdisk: subimage '%s' from image at 0x%08lx\n",
833                                                 fit_uname_ramdisk, rd_addr);
834                         } else
835 #endif
836                         {
837                                 rd_addr = simple_strtoul(argv[2], NULL, 16);
838                                 debug ("*  ramdisk: cmdline image address = 0x%08lx\n",
839                                                 rd_addr);
840                         }
841 #if defined(CONFIG_FIT)
842                 } else {
843                         /* use FIT configuration provided in first bootm
844                          * command argument
845                          */
846                         rd_addr = (ulong)images->fit_hdr_os;
847                         fit_uname_config = images->fit_uname_cfg;
848                         debug ("*  ramdisk: using config '%s' from image at 0x%08lx\n",
849                                         fit_uname_config, rd_addr);
850
851                         /*
852                          * Check whether configuration has ramdisk defined,
853                          * if not, don't try to use it, quit silently.
854                          */
855                         fit_hdr = (void *)rd_addr;
856                         cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
857                         if (cfg_noffset < 0) {
858                                 debug ("*  ramdisk: no such config\n");
859                                 return 1;
860                         }
861
862                         rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset);
863                         if (rd_noffset < 0) {
864                                 debug ("*  ramdisk: no ramdisk in config\n");
865                                 return 0;
866                         }
867                 }
868 #endif
869
870                 /* copy from dataflash if needed */
871                 rd_addr = genimg_get_image (rd_addr);
872
873                 /*
874                  * Check if there is an initrd image at the
875                  * address provided in the second bootm argument
876                  * check image type, for FIT images get FIT node.
877                  */
878                 switch (genimg_get_format ((void *)rd_addr)) {
879                 case IMAGE_FORMAT_LEGACY:
880                         printf ("## Loading init Ramdisk from Legacy "
881                                         "Image at %08lx ...\n", rd_addr);
882
883                         show_boot_progress (9);
884                         rd_hdr = image_get_ramdisk (rd_addr, arch,
885                                                         images->verify);
886
887                         if (rd_hdr == NULL)
888                                 return 1;
889
890                         rd_data = image_get_data (rd_hdr);
891                         rd_len = image_get_data_size (rd_hdr);
892                         rd_load = image_get_load (rd_hdr);
893                         break;
894 #if defined(CONFIG_FIT)
895                 case IMAGE_FORMAT_FIT:
896                         fit_hdr = (void *)rd_addr;
897                         printf ("## Loading init Ramdisk from FIT "
898                                         "Image at %08lx ...\n", rd_addr);
899
900                         show_boot_progress (120);
901                         if (!fit_check_format (fit_hdr)) {
902                                 puts ("Bad FIT ramdisk image format!\n");
903                                 show_boot_progress (-120);
904                                 return 1;
905                         }
906                         show_boot_progress (121);
907
908                         if (!fit_uname_ramdisk) {
909                                 /*
910                                  * no ramdisk image node unit name, try to get config
911                                  * node first. If config unit node name is NULL
912                                  * fit_conf_get_node() will try to find default config node
913                                  */
914                                 show_boot_progress (122);
915                                 cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
916                                 if (cfg_noffset < 0) {
917                                         puts ("Could not find configuration node\n");
918                                         show_boot_progress (-122);
919                                         return 1;
920                                 }
921                                 fit_uname_config = fdt_get_name (fit_hdr, cfg_noffset, NULL);
922                                 printf ("   Using '%s' configuration\n", fit_uname_config);
923
924                                 rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset);
925                                 fit_uname_ramdisk = fit_get_name (fit_hdr, rd_noffset, NULL);
926                         } else {
927                                 /* get ramdisk component image node offset */
928                                 show_boot_progress (123);
929                                 rd_noffset = fit_image_get_node (fit_hdr, fit_uname_ramdisk);
930                         }
931                         if (rd_noffset < 0) {
932                                 puts ("Could not find subimage node\n");
933                                 show_boot_progress (-124);
934                                 return 1;
935                         }
936
937                         printf ("   Trying '%s' ramdisk subimage\n", fit_uname_ramdisk);
938
939                         show_boot_progress (125);
940                         if (!fit_check_ramdisk (fit_hdr, rd_noffset, arch, images->verify))
941                                 return 1;
942
943                         /* get ramdisk image data address and length */
944                         if (fit_image_get_data (fit_hdr, rd_noffset, &data, &size)) {
945                                 puts ("Could not find ramdisk subimage data!\n");
946                                 show_boot_progress (-127);
947                                 return 1;
948                         }
949                         show_boot_progress (128);
950
951                         rd_data = (ulong)data;
952                         rd_len = size;
953
954                         if (fit_image_get_load (fit_hdr, rd_noffset, &rd_load)) {
955                                 puts ("Can't get ramdisk subimage load address!\n");
956                                 show_boot_progress (-129);
957                                 return 1;
958                         }
959                         show_boot_progress (129);
960
961                         images->fit_hdr_rd = fit_hdr;
962                         images->fit_uname_rd = fit_uname_ramdisk;
963                         images->fit_noffset_rd = rd_noffset;
964                         break;
965 #endif
966                 default:
967                         puts ("Wrong Ramdisk Image Format\n");
968                         rd_data = rd_len = rd_load = 0;
969                         return 1;
970                 }
971         } else if (images->legacy_hdr_valid &&
972                         image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
973                 /*
974                  * Now check if we have a legacy mult-component image,
975                  * get second entry data start address and len.
976                  */
977                 show_boot_progress (13);
978                 printf ("## Loading init Ramdisk from multi component "
979                                 "Legacy Image at %08lx ...\n",
980                                 (ulong)images->legacy_hdr_os);
981
982                 image_multi_getimg (images->legacy_hdr_os, 1, &rd_data, &rd_len);
983         } else {
984                 /*
985                  * no initrd image
986                  */
987                 show_boot_progress (14);
988                 rd_len = rd_data = 0;
989         }
990
991         if (!rd_data) {
992                 debug ("## No init Ramdisk\n");
993         } else {
994                 *rd_start = rd_data;
995                 *rd_end = rd_data + rd_len;
996         }
997         debug ("   ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n",
998                         *rd_start, *rd_end);
999
1000         return 0;
1001 }
1002
1003 #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
1004 /**
1005  * boot_ramdisk_high - relocate init ramdisk
1006  * @lmb: pointer to lmb handle, will be used for memory mgmt
1007  * @rd_data: ramdisk data start address
1008  * @rd_len: ramdisk data length
1009  * @initrd_start: pointer to a ulong variable, will hold final init ramdisk
1010  *      start address (after possible relocation)
1011  * @initrd_end: pointer to a ulong variable, will hold final init ramdisk
1012  *      end address (after possible relocation)
1013  *
1014  * boot_ramdisk_high() takes a relocation hint from "initrd_high" environement
1015  * variable and if requested ramdisk data is moved to a specified location.
1016  *
1017  * Initrd_start and initrd_end are set to final (after relocation) ramdisk
1018  * start/end addresses if ramdisk image start and len were provided,
1019  * otherwise set initrd_start and initrd_end set to zeros.
1020  *
1021  * returns:
1022  *      0 - success
1023  *     -1 - failure
1024  */
1025 int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
1026                   ulong *initrd_start, ulong *initrd_end)
1027 {
1028         char    *s;
1029         ulong   initrd_high;
1030         int     initrd_copy_to_ram = 1;
1031
1032         if ((s = getenv ("initrd_high")) != NULL) {
1033                 /* a value of "no" or a similar string will act like 0,
1034                  * turning the "load high" feature off. This is intentional.
1035                  */
1036                 initrd_high = simple_strtoul (s, NULL, 16);
1037                 if (initrd_high == ~0)
1038                         initrd_copy_to_ram = 0;
1039         } else {
1040                 /* not set, no restrictions to load high */
1041                 initrd_high = ~0;
1042         }
1043
1044
1045 #ifdef CONFIG_LOGBUFFER
1046         /* Prevent initrd from overwriting logbuffer */
1047         lmb_reserve(lmb, logbuffer_base() - LOGBUFF_OVERHEAD, LOGBUFF_RESERVE);
1048 #endif
1049
1050         debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
1051                         initrd_high, initrd_copy_to_ram);
1052
1053         if (rd_data) {
1054                 if (!initrd_copy_to_ram) {      /* zero-copy ramdisk support */
1055                         debug ("   in-place initrd\n");
1056                         *initrd_start = rd_data;
1057                         *initrd_end = rd_data + rd_len;
1058                         lmb_reserve(lmb, rd_data, rd_len);
1059                 } else {
1060                         if (initrd_high)
1061                                 *initrd_start = (ulong)lmb_alloc_base (lmb, rd_len, 0x1000, initrd_high);
1062                         else
1063                                 *initrd_start = (ulong)lmb_alloc (lmb, rd_len, 0x1000);
1064
1065                         if (*initrd_start == 0) {
1066                                 puts ("ramdisk - allocation error\n");
1067                                 goto error;
1068                         }
1069                         show_boot_progress (12);
1070
1071                         *initrd_end = *initrd_start + rd_len;
1072                         printf ("   Loading Ramdisk to %08lx, end %08lx ... ",
1073                                         *initrd_start, *initrd_end);
1074
1075                         memmove_wd ((void *)*initrd_start,
1076                                         (void *)rd_data, rd_len, CHUNKSZ);
1077
1078                         puts ("OK\n");
1079                 }
1080         } else {
1081                 *initrd_start = 0;
1082                 *initrd_end = 0;
1083         }
1084         debug ("   ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
1085                         *initrd_start, *initrd_end);
1086
1087         return 0;
1088
1089 error:
1090         return -1;
1091 }
1092 #endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */
1093
1094 #ifdef CONFIG_OF_LIBFDT
1095 static void fdt_error (const char *msg)
1096 {
1097         puts ("ERROR: ");
1098         puts (msg);
1099         puts (" - must RESET the board to recover.\n");
1100 }
1101
1102 static const image_header_t *image_get_fdt (ulong fdt_addr)
1103 {
1104         const image_header_t *fdt_hdr = (const image_header_t *)fdt_addr;
1105
1106         image_print_contents (fdt_hdr);
1107
1108         puts ("   Verifying Checksum ... ");
1109         if (!image_check_hcrc (fdt_hdr)) {
1110                 fdt_error ("fdt header checksum invalid");
1111                 return NULL;
1112         }
1113
1114         if (!image_check_dcrc (fdt_hdr)) {
1115                 fdt_error ("fdt checksum invalid");
1116                 return NULL;
1117         }
1118         puts ("OK\n");
1119
1120         if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) {
1121                 fdt_error ("uImage is not a fdt");
1122                 return NULL;
1123         }
1124         if (image_get_comp (fdt_hdr) != IH_COMP_NONE) {
1125                 fdt_error ("uImage is compressed");
1126                 return NULL;
1127         }
1128         if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) {
1129                 fdt_error ("uImage data is not a fdt");
1130                 return NULL;
1131         }
1132         return fdt_hdr;
1133 }
1134
1135 /**
1136  * fit_check_fdt - verify FIT format FDT subimage
1137  * @fit_hdr: pointer to the FIT  header
1138  * fdt_noffset: FDT subimage node offset within FIT image
1139  * @verify: data CRC verification flag
1140  *
1141  * fit_check_fdt() verifies integrity of the FDT subimage and from
1142  * specified FIT image.
1143  *
1144  * returns:
1145  *     1, on success
1146  *     0, on failure
1147  */
1148 #if defined(CONFIG_FIT)
1149 static int fit_check_fdt (const void *fit, int fdt_noffset, int verify)
1150 {
1151         fit_image_print (fit, fdt_noffset, "   ");
1152
1153         if (verify) {
1154                 puts ("   Verifying Hash Integrity ... ");
1155                 if (!fit_image_check_hashes (fit, fdt_noffset)) {
1156                         fdt_error ("Bad Data Hash");
1157                         return 0;
1158                 }
1159                 puts ("OK\n");
1160         }
1161
1162         if (!fit_image_check_type (fit, fdt_noffset, IH_TYPE_FLATDT)) {
1163                 fdt_error ("Not a FDT image");
1164                 return 0;
1165         }
1166
1167         if (!fit_image_check_comp (fit, fdt_noffset, IH_COMP_NONE)) {
1168                 fdt_error ("FDT image is compressed");
1169                 return 0;
1170         }
1171
1172         return 1;
1173 }
1174 #endif /* CONFIG_FIT */
1175
1176 #ifndef CONFIG_SYS_FDT_PAD
1177 #define CONFIG_SYS_FDT_PAD 0x3000
1178 #endif
1179
1180 #if defined(CONFIG_OF_LIBFDT)
1181 /**
1182  * boot_fdt_add_mem_rsv_regions - Mark the memreserve sections as unusable
1183  * @lmb: pointer to lmb handle, will be used for memory mgmt
1184  * @fdt_blob: pointer to fdt blob base address
1185  *
1186  * Adds the memreserve regions in the dtb to the lmb block.  Adding the
1187  * memreserve regions prevents u-boot from using them to store the initrd
1188  * or the fdt blob.
1189  */
1190 void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
1191 {
1192         uint64_t addr, size;
1193         int i, total;
1194
1195         if (fdt_check_header (fdt_blob) != 0)
1196                 return;
1197
1198         total = fdt_num_mem_rsv(fdt_blob);
1199         for (i = 0; i < total; i++) {
1200                 if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0)
1201                         continue;
1202                 printf("   reserving fdt memory region: addr=%llx size=%llx\n",
1203                         (unsigned long long)addr, (unsigned long long)size);
1204                 lmb_reserve(lmb, addr, size);
1205         }
1206 }
1207
1208 /**
1209  * boot_relocate_fdt - relocate flat device tree
1210  * @lmb: pointer to lmb handle, will be used for memory mgmt
1211  * @of_flat_tree: pointer to a char* variable, will hold fdt start address
1212  * @of_size: pointer to a ulong variable, will hold fdt length
1213  *
1214  * boot_relocate_fdt() allocates a region of memory within the bootmap and
1215  * relocates the of_flat_tree into that region, even if the fdt is already in
1216  * the bootmap.  It also expands the size of the fdt by CONFIG_SYS_FDT_PAD
1217  * bytes.
1218  *
1219  * of_flat_tree and of_size are set to final (after relocation) values
1220  *
1221  * returns:
1222  *      0 - success
1223  *      1 - failure
1224  */
1225 int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size)
1226 {
1227         void    *fdt_blob = *of_flat_tree;
1228         void    *of_start = 0;
1229         char    *fdt_high;
1230         ulong   of_len = 0;
1231         int     err;
1232         int     disable_relocation = 0;
1233
1234         /* nothing to do */
1235         if (*of_size == 0)
1236                 return 0;
1237
1238         if (fdt_check_header (fdt_blob) != 0) {
1239                 fdt_error ("image is not a fdt");
1240                 goto error;
1241         }
1242
1243         /* position on a 4K boundary before the alloc_current */
1244         /* Pad the FDT by a specified amount */
1245         of_len = *of_size + CONFIG_SYS_FDT_PAD;
1246
1247         /* If fdt_high is set use it to select the relocation address */
1248         fdt_high = getenv("fdt_high");
1249         if (fdt_high) {
1250                 void *desired_addr = (void *)simple_strtoul(fdt_high, NULL, 16);
1251
1252                 if (((ulong) desired_addr) == ~0UL) {
1253                         /* All ones means use fdt in place */
1254                         desired_addr = fdt_blob;
1255                         disable_relocation = 1;
1256                 }
1257                 if (desired_addr) {
1258                         of_start =
1259                             (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000,
1260                                                            ((ulong)
1261                                                             desired_addr)
1262                                                            + of_len);
1263                         if (desired_addr && of_start != desired_addr) {
1264                                 puts("Failed using fdt_high value for Device Tree");
1265                                 goto error;
1266                         }
1267                 } else {
1268                         of_start =
1269                             (void *)(ulong) lmb_alloc(lmb, of_len, 0x1000);
1270                 }
1271         } else {
1272                 of_start =
1273                     (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000,
1274                                                    getenv_bootm_mapsize()
1275                                                    + getenv_bootm_low());
1276         }
1277
1278         if (of_start == 0) {
1279                 puts("device tree - allocation error\n");
1280                 goto error;
1281         }
1282
1283         if (disable_relocation) {
1284                 /* We assume there is space after the existing fdt to use for padding */
1285                 fdt_set_totalsize(of_start, of_len);
1286                 printf("   Using Device Tree in place at %p, end %p\n",
1287                        of_start, of_start + of_len - 1);
1288         } else {
1289                 debug ("## device tree at %p ... %p (len=%ld [0x%lX])\n",
1290                         fdt_blob, fdt_blob + *of_size - 1, of_len, of_len);
1291
1292                 printf ("   Loading Device Tree to %p, end %p ... ",
1293                         of_start, of_start + of_len - 1);
1294
1295                 err = fdt_open_into (fdt_blob, of_start, of_len);
1296                 if (err != 0) {
1297                         fdt_error ("fdt move failed");
1298                         goto error;
1299                 }
1300                 puts ("OK\n");
1301         }
1302
1303         *of_flat_tree = of_start;
1304         *of_size = of_len;
1305
1306         set_working_fdt_addr(*of_flat_tree);
1307         return 0;
1308
1309 error:
1310         return 1;
1311 }
1312 #endif /* CONFIG_OF_LIBFDT */
1313
1314 /**
1315  * boot_get_fdt - main fdt handling routine
1316  * @argc: command argument count
1317  * @argv: command argument list
1318  * @images: pointer to the bootm images structure
1319  * @of_flat_tree: pointer to a char* variable, will hold fdt start address
1320  * @of_size: pointer to a ulong variable, will hold fdt length
1321  *
1322  * boot_get_fdt() is responsible for finding a valid flat device tree image.
1323  * Curently supported are the following ramdisk sources:
1324  *      - multicomponent kernel/ramdisk image,
1325  *      - commandline provided address of decicated ramdisk image.
1326  *
1327  * returns:
1328  *     0, if fdt image was found and valid, or skipped
1329  *     of_flat_tree and of_size are set to fdt start address and length if
1330  *     fdt image is found and valid
1331  *
1332  *     1, if fdt image is found but corrupted
1333  *     of_flat_tree and of_size are set to 0 if no fdt exists
1334  */
1335 int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *images,
1336                 char **of_flat_tree, ulong *of_size)
1337 {
1338         const image_header_t *fdt_hdr;
1339         ulong           fdt_addr;
1340         char            *fdt_blob = NULL;
1341         ulong           image_start, image_end;
1342         ulong           load_start, load_end;
1343 #if defined(CONFIG_FIT)
1344         void            *fit_hdr;
1345         const char      *fit_uname_config = NULL;
1346         const char      *fit_uname_fdt = NULL;
1347         ulong           default_addr;
1348         int             cfg_noffset;
1349         int             fdt_noffset;
1350         const void      *data;
1351         size_t          size;
1352 #endif
1353
1354         *of_flat_tree = NULL;
1355         *of_size = 0;
1356
1357         if (argc > 3 || genimg_has_config (images)) {
1358 #if defined(CONFIG_FIT)
1359                 if (argc > 3) {
1360                         /*
1361                          * If the FDT blob comes from the FIT image and the
1362                          * FIT image address is omitted in the command line
1363                          * argument, try to use ramdisk or os FIT image
1364                          * address or default load address.
1365                          */
1366                         if (images->fit_uname_rd)
1367                                 default_addr = (ulong)images->fit_hdr_rd;
1368                         else if (images->fit_uname_os)
1369                                 default_addr = (ulong)images->fit_hdr_os;
1370                         else
1371                                 default_addr = load_addr;
1372
1373                         if (fit_parse_conf (argv[3], default_addr,
1374                                                 &fdt_addr, &fit_uname_config)) {
1375                                 debug ("*  fdt: config '%s' from image at 0x%08lx\n",
1376                                                 fit_uname_config, fdt_addr);
1377                         } else if (fit_parse_subimage (argv[3], default_addr,
1378                                                 &fdt_addr, &fit_uname_fdt)) {
1379                                 debug ("*  fdt: subimage '%s' from image at 0x%08lx\n",
1380                                                 fit_uname_fdt, fdt_addr);
1381                         } else
1382 #endif
1383                         {
1384                                 fdt_addr = simple_strtoul(argv[3], NULL, 16);
1385                                 debug ("*  fdt: cmdline image address = 0x%08lx\n",
1386                                                 fdt_addr);
1387                         }
1388 #if defined(CONFIG_FIT)
1389                 } else {
1390                         /* use FIT configuration provided in first bootm
1391                          * command argument
1392                          */
1393                         fdt_addr = (ulong)images->fit_hdr_os;
1394                         fit_uname_config = images->fit_uname_cfg;
1395                         debug ("*  fdt: using config '%s' from image at 0x%08lx\n",
1396                                         fit_uname_config, fdt_addr);
1397
1398                         /*
1399                          * Check whether configuration has FDT blob defined,
1400                          * if not quit silently.
1401                          */
1402                         fit_hdr = (void *)fdt_addr;
1403                         cfg_noffset = fit_conf_get_node (fit_hdr,
1404                                         fit_uname_config);
1405                         if (cfg_noffset < 0) {
1406                                 debug ("*  fdt: no such config\n");
1407                                 return 0;
1408                         }
1409
1410                         fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
1411                                         cfg_noffset);
1412                         if (fdt_noffset < 0) {
1413                                 debug ("*  fdt: no fdt in config\n");
1414                                 return 0;
1415                         }
1416                 }
1417 #endif
1418
1419                 debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n",
1420                                 fdt_addr);
1421
1422                 /* copy from dataflash if needed */
1423                 fdt_addr = genimg_get_image (fdt_addr);
1424
1425                 /*
1426                  * Check if there is an FDT image at the
1427                  * address provided in the second bootm argument
1428                  * check image type, for FIT images get a FIT node.
1429                  */
1430                 switch (genimg_get_format ((void *)fdt_addr)) {
1431                 case IMAGE_FORMAT_LEGACY:
1432                         /* verify fdt_addr points to a valid image header */
1433                         printf ("## Flattened Device Tree from Legacy Image at %08lx\n",
1434                                         fdt_addr);
1435                         fdt_hdr = image_get_fdt (fdt_addr);
1436                         if (!fdt_hdr)
1437                                 goto error;
1438
1439                         /*
1440                          * move image data to the load address,
1441                          * make sure we don't overwrite initial image
1442                          */
1443                         image_start = (ulong)fdt_hdr;
1444                         image_end = image_get_image_end (fdt_hdr);
1445
1446                         load_start = image_get_load (fdt_hdr);
1447                         load_end = load_start + image_get_data_size (fdt_hdr);
1448
1449                         if ((load_start < image_end) && (load_end > image_start)) {
1450                                 fdt_error ("fdt overwritten");
1451                                 goto error;
1452                         }
1453
1454                         debug ("   Loading FDT from 0x%08lx to 0x%08lx\n",
1455                                         image_get_data (fdt_hdr), load_start);
1456
1457                         memmove ((void *)load_start,
1458                                         (void *)image_get_data (fdt_hdr),
1459                                         image_get_data_size (fdt_hdr));
1460
1461                         fdt_blob = (char *)load_start;
1462                         break;
1463                 case IMAGE_FORMAT_FIT:
1464                         /*
1465                          * This case will catch both: new uImage format
1466                          * (libfdt based) and raw FDT blob (also libfdt
1467                          * based).
1468                          */
1469 #if defined(CONFIG_FIT)
1470                         /* check FDT blob vs FIT blob */
1471                         if (fit_check_format ((const void *)fdt_addr)) {
1472                                 /*
1473                                  * FIT image
1474                                  */
1475                                 fit_hdr = (void *)fdt_addr;
1476                                 printf ("## Flattened Device Tree from FIT Image at %08lx\n",
1477                                                 fdt_addr);
1478
1479                                 if (!fit_uname_fdt) {
1480                                         /*
1481                                          * no FDT blob image node unit name,
1482                                          * try to get config node first. If
1483                                          * config unit node name is NULL
1484                                          * fit_conf_get_node() will try to
1485                                          * find default config node
1486                                          */
1487                                         cfg_noffset = fit_conf_get_node (fit_hdr,
1488                                                         fit_uname_config);
1489
1490                                         if (cfg_noffset < 0) {
1491                                                 fdt_error ("Could not find configuration node\n");
1492                                                 goto error;
1493                                         }
1494
1495                                         fit_uname_config = fdt_get_name (fit_hdr,
1496                                                         cfg_noffset, NULL);
1497                                         printf ("   Using '%s' configuration\n",
1498                                                         fit_uname_config);
1499
1500                                         fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
1501                                                         cfg_noffset);
1502                                         fit_uname_fdt = fit_get_name (fit_hdr,
1503                                                         fdt_noffset, NULL);
1504                                 } else {
1505                                         /* get FDT component image node offset */
1506                                         fdt_noffset = fit_image_get_node (fit_hdr,
1507                                                         fit_uname_fdt);
1508                                 }
1509                                 if (fdt_noffset < 0) {
1510                                         fdt_error ("Could not find subimage node\n");
1511                                         goto error;
1512                                 }
1513
1514                                 printf ("   Trying '%s' FDT blob subimage\n",
1515                                                 fit_uname_fdt);
1516
1517                                 if (!fit_check_fdt (fit_hdr, fdt_noffset,
1518                                                         images->verify))
1519                                         goto error;
1520
1521                                 /* get ramdisk image data address and length */
1522                                 if (fit_image_get_data (fit_hdr, fdt_noffset,
1523                                                         &data, &size)) {
1524                                         fdt_error ("Could not find FDT subimage data");
1525                                         goto error;
1526                                 }
1527
1528                                 /* verift that image data is a proper FDT blob */
1529                                 if (fdt_check_header ((char *)data) != 0) {
1530                                         fdt_error ("Subimage data is not a FTD");
1531                                         goto error;
1532                                 }
1533
1534                                 /*
1535                                  * move image data to the load address,
1536                                  * make sure we don't overwrite initial image
1537                                  */
1538                                 image_start = (ulong)fit_hdr;
1539                                 image_end = fit_get_end (fit_hdr);
1540
1541                                 if (fit_image_get_load (fit_hdr, fdt_noffset,
1542                                                         &load_start) == 0) {
1543                                         load_end = load_start + size;
1544
1545                                         if ((load_start < image_end) &&
1546                                                         (load_end > image_start)) {
1547                                                 fdt_error ("FDT overwritten");
1548                                                 goto error;
1549                                         }
1550
1551                                         printf ("   Loading FDT from 0x%08lx to 0x%08lx\n",
1552                                                         (ulong)data, load_start);
1553
1554                                         memmove ((void *)load_start,
1555                                                         (void *)data, size);
1556
1557                                         fdt_blob = (char *)load_start;
1558                                 } else {
1559                                         fdt_blob = (char *)data;
1560                                 }
1561
1562                                 images->fit_hdr_fdt = fit_hdr;
1563                                 images->fit_uname_fdt = fit_uname_fdt;
1564                                 images->fit_noffset_fdt = fdt_noffset;
1565                                 break;
1566                         } else
1567 #endif
1568                         {
1569                                 /*
1570                                  * FDT blob
1571                                  */
1572                                 fdt_blob = (char *)fdt_addr;
1573                                 debug ("*  fdt: raw FDT blob\n");
1574                                 printf ("## Flattened Device Tree blob at %08lx\n", (long)fdt_blob);
1575                         }
1576                         break;
1577                 default:
1578                         puts ("ERROR: Did not find a cmdline Flattened Device Tree\n");
1579                         goto error;
1580                 }
1581
1582                 printf("   Booting using the fdt blob at 0x%p\n", fdt_blob);
1583
1584         } else if (images->legacy_hdr_valid &&
1585                         image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
1586
1587                 ulong fdt_data, fdt_len;
1588
1589                 /*
1590                  * Now check if we have a legacy multi-component image,
1591                  * get second entry data start address and len.
1592                  */
1593                 printf ("## Flattened Device Tree from multi "
1594                         "component Image at %08lX\n",
1595                         (ulong)images->legacy_hdr_os);
1596
1597                 image_multi_getimg (images->legacy_hdr_os, 2, &fdt_data, &fdt_len);
1598                 if (fdt_len) {
1599
1600                         fdt_blob = (char *)fdt_data;
1601                         printf("   Booting using the fdt at 0x%p\n", fdt_blob);
1602
1603                         if (fdt_check_header (fdt_blob) != 0) {
1604                                 fdt_error ("image is not a fdt");
1605                                 goto error;
1606                         }
1607
1608                         if (fdt_totalsize(fdt_blob) != fdt_len) {
1609                                 fdt_error ("fdt size != image size");
1610                                 goto error;
1611                         }
1612                 } else {
1613                         debug ("## No Flattened Device Tree\n");
1614                         return 0;
1615                 }
1616         } else {
1617                 debug ("## No Flattened Device Tree\n");
1618                 return 0;
1619         }
1620
1621         *of_flat_tree = fdt_blob;
1622         *of_size = fdt_totalsize(fdt_blob);
1623         debug ("   of_flat_tree at 0x%08lx size 0x%08lx\n",
1624                         (ulong)*of_flat_tree, *of_size);
1625
1626         return 0;
1627
1628 error:
1629         *of_flat_tree = 0;
1630         *of_size = 0;
1631         return 1;
1632 }
1633 #endif /* CONFIG_OF_LIBFDT */
1634
1635 #ifdef CONFIG_SYS_BOOT_GET_CMDLINE
1636 /**
1637  * boot_get_cmdline - allocate and initialize kernel cmdline
1638  * @lmb: pointer to lmb handle, will be used for memory mgmt
1639  * @cmd_start: pointer to a ulong variable, will hold cmdline start
1640  * @cmd_end: pointer to a ulong variable, will hold cmdline end
1641  *
1642  * boot_get_cmdline() allocates space for kernel command line below
1643  * BOOTMAPSZ + getenv_bootm_low() address. If "bootargs" U-boot environemnt
1644  * variable is present its contents is copied to allocated kernel
1645  * command line.
1646  *
1647  * returns:
1648  *      0 - success
1649  *     -1 - failure
1650  */
1651 int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end)
1652 {
1653         char *cmdline;
1654         char *s;
1655
1656         cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf,
1657                                 getenv_bootm_mapsize() + getenv_bootm_low());
1658
1659         if (cmdline == NULL)
1660                 return -1;
1661
1662         if ((s = getenv("bootargs")) == NULL)
1663                 s = "";
1664
1665         strcpy(cmdline, s);
1666
1667         *cmd_start = (ulong) & cmdline[0];
1668         *cmd_end = *cmd_start + strlen(cmdline);
1669
1670         debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);
1671
1672         return 0;
1673 }
1674 #endif /* CONFIG_SYS_BOOT_GET_CMDLINE */
1675
1676 #ifdef CONFIG_SYS_BOOT_GET_KBD
1677 /**
1678  * boot_get_kbd - allocate and initialize kernel copy of board info
1679  * @lmb: pointer to lmb handle, will be used for memory mgmt
1680  * @kbd: double pointer to board info data
1681  *
1682  * boot_get_kbd() allocates space for kernel copy of board info data below
1683  * BOOTMAPSZ + getenv_bootm_low() address and kernel board info is initialized
1684  * with the current u-boot board info data.
1685  *
1686  * returns:
1687  *      0 - success
1688  *     -1 - failure
1689  */
1690 int boot_get_kbd (struct lmb *lmb, bd_t **kbd)
1691 {
1692         *kbd = (bd_t *)(ulong)lmb_alloc_base(lmb, sizeof(bd_t), 0xf,
1693                                 getenv_bootm_mapsize() + getenv_bootm_low());
1694         if (*kbd == NULL)
1695                 return -1;
1696
1697         **kbd = *(gd->bd);
1698
1699         debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd);
1700
1701 #if defined(DEBUG) && defined(CONFIG_CMD_BDI)
1702         do_bdinfo(NULL, 0, 0, NULL);
1703 #endif
1704
1705         return 0;
1706 }
1707 #endif /* CONFIG_SYS_BOOT_GET_KBD */
1708 #endif /* !USE_HOSTCC */
1709
1710 #if defined(CONFIG_FIT)
1711 /*****************************************************************************/
1712 /* New uImage format routines */
1713 /*****************************************************************************/
1714 #ifndef USE_HOSTCC
1715 static int fit_parse_spec (const char *spec, char sepc, ulong addr_curr,
1716                 ulong *addr, const char **name)
1717 {
1718         const char *sep;
1719
1720         *addr = addr_curr;
1721         *name = NULL;
1722
1723         sep = strchr (spec, sepc);
1724         if (sep) {
1725                 if (sep - spec > 0)
1726                         *addr = simple_strtoul (spec, NULL, 16);
1727
1728                 *name = sep + 1;
1729                 return 1;
1730         }
1731
1732         return 0;
1733 }
1734
1735 /**
1736  * fit_parse_conf - parse FIT configuration spec
1737  * @spec: input string, containing configuration spec
1738  * @add_curr: current image address (to be used as a possible default)
1739  * @addr: pointer to a ulong variable, will hold FIT image address of a given
1740  * configuration
1741  * @conf_name double pointer to a char, will hold pointer to a configuration
1742  * unit name
1743  *
1744  * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>,
1745  * where <addr> is a FIT image address that contains configuration
1746  * with a <conf> unit name.
1747  *
1748  * Address part is optional, and if omitted default add_curr will
1749  * be used instead.
1750  *
1751  * returns:
1752  *     1 if spec is a valid configuration string,
1753  *     addr and conf_name are set accordingly
1754  *     0 otherwise
1755  */
1756 inline int fit_parse_conf (const char *spec, ulong addr_curr,
1757                 ulong *addr, const char **conf_name)
1758 {
1759         return fit_parse_spec (spec, '#', addr_curr, addr, conf_name);
1760 }
1761
1762 /**
1763  * fit_parse_subimage - parse FIT subimage spec
1764  * @spec: input string, containing subimage spec
1765  * @add_curr: current image address (to be used as a possible default)
1766  * @addr: pointer to a ulong variable, will hold FIT image address of a given
1767  * subimage
1768  * @image_name: double pointer to a char, will hold pointer to a subimage name
1769  *
1770  * fit_parse_subimage() expects subimage spec in the for of
1771  * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
1772  * subimage with a <subimg> unit name.
1773  *
1774  * Address part is optional, and if omitted default add_curr will
1775  * be used instead.
1776  *
1777  * returns:
1778  *     1 if spec is a valid subimage string,
1779  *     addr and image_name are set accordingly
1780  *     0 otherwise
1781  */
1782 inline int fit_parse_subimage (const char *spec, ulong addr_curr,
1783                 ulong *addr, const char **image_name)
1784 {
1785         return fit_parse_spec (spec, ':', addr_curr, addr, image_name);
1786 }
1787 #endif /* !USE_HOSTCC */
1788
1789 static void fit_get_debug (const void *fit, int noffset,
1790                 char *prop_name, int err)
1791 {
1792         debug ("Can't get '%s' property from FIT 0x%08lx, "
1793                 "node: offset %d, name %s (%s)\n",
1794                 prop_name, (ulong)fit, noffset,
1795                 fit_get_name (fit, noffset, NULL),
1796                 fdt_strerror (err));
1797 }
1798
1799 /**
1800  * fit_print_contents - prints out the contents of the FIT format image
1801  * @fit: pointer to the FIT format image header
1802  * @p: pointer to prefix string
1803  *
1804  * fit_print_contents() formats a multi line FIT image contents description.
1805  * The routine prints out FIT image properties (root node level) follwed by
1806  * the details of each component image.
1807  *
1808  * returns:
1809  *     no returned results
1810  */
1811 void fit_print_contents (const void *fit)
1812 {
1813         char *desc;
1814         char *uname;
1815         int images_noffset;
1816         int confs_noffset;
1817         int noffset;
1818         int ndepth;
1819         int count = 0;
1820         int ret;
1821         const char *p;
1822 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
1823         time_t timestamp;
1824 #endif
1825
1826 #ifdef USE_HOSTCC
1827         p = "";
1828 #else
1829         p = "   ";
1830 #endif
1831
1832         /* Root node properties */
1833         ret = fit_get_desc (fit, 0, &desc);
1834         printf ("%sFIT description: ", p);
1835         if (ret)
1836                 printf ("unavailable\n");
1837         else
1838                 printf ("%s\n", desc);
1839
1840 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
1841         ret = fit_get_timestamp (fit, 0, &timestamp);
1842         printf ("%sCreated:         ", p);
1843         if (ret)
1844                 printf ("unavailable\n");
1845         else
1846                 genimg_print_time (timestamp);
1847 #endif
1848
1849         /* Find images parent node offset */
1850         images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
1851         if (images_noffset < 0) {
1852                 printf ("Can't find images parent node '%s' (%s)\n",
1853                         FIT_IMAGES_PATH, fdt_strerror (images_noffset));
1854                 return;
1855         }
1856
1857         /* Process its subnodes, print out component images details */
1858         for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth);
1859              (noffset >= 0) && (ndepth > 0);
1860              noffset = fdt_next_node (fit, noffset, &ndepth)) {
1861                 if (ndepth == 1) {
1862                         /*
1863                          * Direct child node of the images parent node,
1864                          * i.e. component image node.
1865                          */
1866                         printf ("%s Image %u (%s)\n", p, count++,
1867                                         fit_get_name(fit, noffset, NULL));
1868
1869                         fit_image_print (fit, noffset, p);
1870                 }
1871         }
1872
1873         /* Find configurations parent node offset */
1874         confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH);
1875         if (confs_noffset < 0) {
1876                 debug ("Can't get configurations parent node '%s' (%s)\n",
1877                         FIT_CONFS_PATH, fdt_strerror (confs_noffset));
1878                 return;
1879         }
1880
1881         /* get default configuration unit name from default property */
1882         uname = (char *)fdt_getprop (fit, noffset, FIT_DEFAULT_PROP, NULL);
1883         if (uname)
1884                 printf ("%s Default Configuration: '%s'\n", p, uname);
1885
1886         /* Process its subnodes, print out configurations details */
1887         for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, confs_noffset, &ndepth);
1888              (noffset >= 0) && (ndepth > 0);
1889              noffset = fdt_next_node (fit, noffset, &ndepth)) {
1890                 if (ndepth == 1) {
1891                         /*
1892                          * Direct child node of the configurations parent node,
1893                          * i.e. configuration node.
1894                          */
1895                         printf ("%s Configuration %u (%s)\n", p, count++,
1896                                         fit_get_name(fit, noffset, NULL));
1897
1898                         fit_conf_print (fit, noffset, p);
1899                 }
1900         }
1901 }
1902
1903 /**
1904  * fit_image_print - prints out the FIT component image details
1905  * @fit: pointer to the FIT format image header
1906  * @image_noffset: offset of the component image node
1907  * @p: pointer to prefix string
1908  *
1909  * fit_image_print() lists all mandatory properies for the processed component
1910  * image. If present, hash nodes are printed out as well. Load
1911  * address for images of type firmware is also printed out. Since the load
1912  * address is not mandatory for firmware images, it will be output as
1913  * "unavailable" when not present.
1914  *
1915  * returns:
1916  *     no returned results
1917  */
1918 void fit_image_print (const void *fit, int image_noffset, const char *p)
1919 {
1920         char *desc;
1921         uint8_t type, arch, os, comp;
1922         size_t size;
1923         ulong load, entry;
1924         const void *data;
1925         int noffset;
1926         int ndepth;
1927         int ret;
1928
1929         /* Mandatory properties */
1930         ret = fit_get_desc (fit, image_noffset, &desc);
1931         printf ("%s  Description:  ", p);
1932         if (ret)
1933                 printf ("unavailable\n");
1934         else
1935                 printf ("%s\n", desc);
1936
1937         fit_image_get_type (fit, image_noffset, &type);
1938         printf ("%s  Type:         %s\n", p, genimg_get_type_name (type));
1939
1940         fit_image_get_comp (fit, image_noffset, &comp);
1941         printf ("%s  Compression:  %s\n", p, genimg_get_comp_name (comp));
1942
1943         ret = fit_image_get_data (fit, image_noffset, &data, &size);
1944
1945 #ifndef USE_HOSTCC
1946         printf ("%s  Data Start:   ", p);
1947         if (ret)
1948                 printf ("unavailable\n");
1949         else
1950                 printf ("0x%08lx\n", (ulong)data);
1951 #endif
1952
1953         printf ("%s  Data Size:    ", p);
1954         if (ret)
1955                 printf ("unavailable\n");
1956         else
1957                 genimg_print_size (size);
1958
1959         /* Remaining, type dependent properties */
1960         if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
1961             (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
1962             (type == IH_TYPE_FLATDT)) {
1963                 fit_image_get_arch (fit, image_noffset, &arch);
1964                 printf ("%s  Architecture: %s\n", p, genimg_get_arch_name (arch));
1965         }
1966
1967         if (type == IH_TYPE_KERNEL) {
1968                 fit_image_get_os (fit, image_noffset, &os);
1969                 printf ("%s  OS:           %s\n", p, genimg_get_os_name (os));
1970         }
1971
1972         if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
1973                 (type == IH_TYPE_FIRMWARE)) {
1974                 ret = fit_image_get_load (fit, image_noffset, &load);
1975                 printf ("%s  Load Address: ", p);
1976                 if (ret)
1977                         printf ("unavailable\n");
1978                 else
1979                         printf ("0x%08lx\n", load);
1980         }
1981
1982         if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE)) {
1983                 fit_image_get_entry (fit, image_noffset, &entry);
1984                 printf ("%s  Entry Point:  ", p);
1985                 if (ret)
1986                         printf ("unavailable\n");
1987                 else
1988                         printf ("0x%08lx\n", entry);
1989         }
1990
1991         /* Process all hash subnodes of the component image node */
1992         for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
1993              (noffset >= 0) && (ndepth > 0);
1994              noffset = fdt_next_node (fit, noffset, &ndepth)) {
1995                 if (ndepth == 1) {
1996                         /* Direct child node of the component image node */
1997                         fit_image_print_hash (fit, noffset, p);
1998                 }
1999         }
2000 }
2001
2002 /**
2003  * fit_image_print_hash - prints out the hash node details
2004  * @fit: pointer to the FIT format image header
2005  * @noffset: offset of the hash node
2006  * @p: pointer to prefix string
2007  *
2008  * fit_image_print_hash() lists properies for the processed hash node
2009  *
2010  * returns:
2011  *     no returned results
2012  */
2013 void fit_image_print_hash (const void *fit, int noffset, const char *p)
2014 {
2015         char *algo;
2016         uint8_t *value;
2017         int value_len;
2018         int i, ret;
2019
2020         /*
2021          * Check subnode name, must be equal to "hash".
2022          * Multiple hash nodes require unique unit node
2023          * names, e.g. hash@1, hash@2, etc.
2024          */
2025         if (strncmp (fit_get_name(fit, noffset, NULL),
2026                         FIT_HASH_NODENAME,
2027                         strlen(FIT_HASH_NODENAME)) != 0)
2028                 return;
2029
2030         debug ("%s  Hash node:    '%s'\n", p,
2031                         fit_get_name (fit, noffset, NULL));
2032
2033         printf ("%s  Hash algo:    ", p);
2034         if (fit_image_hash_get_algo (fit, noffset, &algo)) {
2035                 printf ("invalid/unsupported\n");
2036                 return;
2037         }
2038         printf ("%s\n", algo);
2039
2040         ret = fit_image_hash_get_value (fit, noffset, &value,
2041                                         &value_len);
2042         printf ("%s  Hash value:   ", p);
2043         if (ret) {
2044                 printf ("unavailable\n");
2045         } else {
2046                 for (i = 0; i < value_len; i++)
2047                         printf ("%02x", value[i]);
2048                 printf ("\n");
2049         }
2050
2051         debug  ("%s  Hash len:     %d\n", p, value_len);
2052 }
2053
2054 /**
2055  * fit_get_desc - get node description property
2056  * @fit: pointer to the FIT format image header
2057  * @noffset: node offset
2058  * @desc: double pointer to the char, will hold pointer to the descrption
2059  *
2060  * fit_get_desc() reads description property from a given node, if
2061  * description is found pointer to it is returened in third call argument.
2062  *
2063  * returns:
2064  *     0, on success
2065  *     -1, on failure
2066  */
2067 int fit_get_desc (const void *fit, int noffset, char **desc)
2068 {
2069         int len;
2070
2071         *desc = (char *)fdt_getprop (fit, noffset, FIT_DESC_PROP, &len);
2072         if (*desc == NULL) {
2073                 fit_get_debug (fit, noffset, FIT_DESC_PROP, len);
2074                 return -1;
2075         }
2076
2077         return 0;
2078 }
2079
2080 /**
2081  * fit_get_timestamp - get node timestamp property
2082  * @fit: pointer to the FIT format image header
2083  * @noffset: node offset
2084  * @timestamp: pointer to the time_t, will hold read timestamp
2085  *
2086  * fit_get_timestamp() reads timestamp poperty from given node, if timestamp
2087  * is found and has a correct size its value is retured in third call
2088  * argument.
2089  *
2090  * returns:
2091  *     0, on success
2092  *     -1, on property read failure
2093  *     -2, on wrong timestamp size
2094  */
2095 int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp)
2096 {
2097         int len;
2098         const void *data;
2099
2100         data = fdt_getprop (fit, noffset, FIT_TIMESTAMP_PROP, &len);
2101         if (data == NULL) {
2102                 fit_get_debug (fit, noffset, FIT_TIMESTAMP_PROP, len);
2103                 return -1;
2104         }
2105         if (len != sizeof (uint32_t)) {
2106                 debug ("FIT timestamp with incorrect size of (%u)\n", len);
2107                 return -2;
2108         }
2109
2110         *timestamp = uimage_to_cpu (*((uint32_t *)data));
2111         return 0;
2112 }
2113
2114 /**
2115  * fit_image_get_node - get node offset for component image of a given unit name
2116  * @fit: pointer to the FIT format image header
2117  * @image_uname: component image node unit name
2118  *
2119  * fit_image_get_node() finds a component image (withing the '/images'
2120  * node) of a provided unit name. If image is found its node offset is
2121  * returned to the caller.
2122  *
2123  * returns:
2124  *     image node offset when found (>=0)
2125  *     negative number on failure (FDT_ERR_* code)
2126  */
2127 int fit_image_get_node (const void *fit, const char *image_uname)
2128 {
2129         int noffset, images_noffset;
2130
2131         images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
2132         if (images_noffset < 0) {
2133                 debug ("Can't find images parent node '%s' (%s)\n",
2134                         FIT_IMAGES_PATH, fdt_strerror (images_noffset));
2135                 return images_noffset;
2136         }
2137
2138         noffset = fdt_subnode_offset (fit, images_noffset, image_uname);
2139         if (noffset < 0) {
2140                 debug ("Can't get node offset for image unit name: '%s' (%s)\n",
2141                         image_uname, fdt_strerror (noffset));
2142         }
2143
2144         return noffset;
2145 }
2146
2147 /**
2148  * fit_image_get_os - get os id for a given component image node
2149  * @fit: pointer to the FIT format image header
2150  * @noffset: component image node offset
2151  * @os: pointer to the uint8_t, will hold os numeric id
2152  *
2153  * fit_image_get_os() finds os property in a given component image node.
2154  * If the property is found, its (string) value is translated to the numeric
2155  * id which is returned to the caller.
2156  *
2157  * returns:
2158  *     0, on success
2159  *     -1, on failure
2160  */
2161 int fit_image_get_os (const void *fit, int noffset, uint8_t *os)
2162 {
2163         int len;
2164         const void *data;
2165
2166         /* Get OS name from property data */
2167         data = fdt_getprop (fit, noffset, FIT_OS_PROP, &len);
2168         if (data == NULL) {
2169                 fit_get_debug (fit, noffset, FIT_OS_PROP, len);
2170                 *os = -1;
2171                 return -1;
2172         }
2173
2174         /* Translate OS name to id */
2175         *os = genimg_get_os_id (data);
2176         return 0;
2177 }
2178
2179 /**
2180  * fit_image_get_arch - get arch id for a given component image node
2181  * @fit: pointer to the FIT format image header
2182  * @noffset: component image node offset
2183  * @arch: pointer to the uint8_t, will hold arch numeric id
2184  *
2185  * fit_image_get_arch() finds arch property in a given component image node.
2186  * If the property is found, its (string) value is translated to the numeric
2187  * id which is returned to the caller.
2188  *
2189  * returns:
2190  *     0, on success
2191  *     -1, on failure
2192  */
2193 int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch)
2194 {
2195         int len;
2196         const void *data;
2197
2198         /* Get architecture name from property data */
2199         data = fdt_getprop (fit, noffset, FIT_ARCH_PROP, &len);
2200         if (data == NULL) {
2201                 fit_get_debug (fit, noffset, FIT_ARCH_PROP, len);
2202                 *arch = -1;
2203                 return -1;
2204         }
2205
2206         /* Translate architecture name to id */
2207         *arch = genimg_get_arch_id (data);
2208         return 0;
2209 }
2210
2211 /**
2212  * fit_image_get_type - get type id for a given component image node
2213  * @fit: pointer to the FIT format image header
2214  * @noffset: component image node offset
2215  * @type: pointer to the uint8_t, will hold type numeric id
2216  *
2217  * fit_image_get_type() finds type property in a given component image node.
2218  * If the property is found, its (string) value is translated to the numeric
2219  * id which is returned to the caller.
2220  *
2221  * returns:
2222  *     0, on success
2223  *     -1, on failure
2224  */
2225 int fit_image_get_type (const void *fit, int noffset, uint8_t *type)
2226 {
2227         int len;
2228         const void *data;
2229
2230         /* Get image type name from property data */
2231         data = fdt_getprop (fit, noffset, FIT_TYPE_PROP, &len);
2232         if (data == NULL) {
2233                 fit_get_debug (fit, noffset, FIT_TYPE_PROP, len);
2234                 *type = -1;
2235                 return -1;
2236         }
2237
2238         /* Translate image type name to id */
2239         *type = genimg_get_type_id (data);
2240         return 0;
2241 }
2242
2243 /**
2244  * fit_image_get_comp - get comp id for a given component image node
2245  * @fit: pointer to the FIT format image header
2246  * @noffset: component image node offset
2247  * @comp: pointer to the uint8_t, will hold comp numeric id
2248  *
2249  * fit_image_get_comp() finds comp property in a given component image node.
2250  * If the property is found, its (string) value is translated to the numeric
2251  * id which is returned to the caller.
2252  *
2253  * returns:
2254  *     0, on success
2255  *     -1, on failure
2256  */
2257 int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp)
2258 {
2259         int len;
2260         const void *data;
2261
2262         /* Get compression name from property data */
2263         data = fdt_getprop (fit, noffset, FIT_COMP_PROP, &len);
2264         if (data == NULL) {
2265                 fit_get_debug (fit, noffset, FIT_COMP_PROP, len);
2266                 *comp = -1;
2267                 return -1;
2268         }
2269
2270         /* Translate compression name to id */
2271         *comp = genimg_get_comp_id (data);
2272         return 0;
2273 }
2274
2275 /**
2276  * fit_image_get_load - get load address property for a given component image node
2277  * @fit: pointer to the FIT format image header
2278  * @noffset: component image node offset
2279  * @load: pointer to the uint32_t, will hold load address
2280  *
2281  * fit_image_get_load() finds load address property in a given component image node.
2282  * If the property is found, its value is returned to the caller.
2283  *
2284  * returns:
2285  *     0, on success
2286  *     -1, on failure
2287  */
2288 int fit_image_get_load (const void *fit, int noffset, ulong *load)
2289 {
2290         int len;
2291         const uint32_t *data;
2292
2293         data = fdt_getprop (fit, noffset, FIT_LOAD_PROP, &len);
2294         if (data == NULL) {
2295                 fit_get_debug (fit, noffset, FIT_LOAD_PROP, len);
2296                 return -1;
2297         }
2298
2299         *load = uimage_to_cpu (*data);
2300         return 0;
2301 }
2302
2303 /**
2304  * fit_image_get_entry - get entry point address property for a given component image node
2305  * @fit: pointer to the FIT format image header
2306  * @noffset: component image node offset
2307  * @entry: pointer to the uint32_t, will hold entry point address
2308  *
2309  * fit_image_get_entry() finds entry point address property in a given component image node.
2310  * If the property is found, its value is returned to the caller.
2311  *
2312  * returns:
2313  *     0, on success
2314  *     -1, on failure
2315  */
2316 int fit_image_get_entry (const void *fit, int noffset, ulong *entry)
2317 {
2318         int len;
2319         const uint32_t *data;
2320
2321         data = fdt_getprop (fit, noffset, FIT_ENTRY_PROP, &len);
2322         if (data == NULL) {
2323                 fit_get_debug (fit, noffset, FIT_ENTRY_PROP, len);
2324                 return -1;
2325         }
2326
2327         *entry = uimage_to_cpu (*data);
2328         return 0;
2329 }
2330
2331 /**
2332  * fit_image_get_data - get data property and its size for a given component image node
2333  * @fit: pointer to the FIT format image header
2334  * @noffset: component image node offset
2335  * @data: double pointer to void, will hold data property's data address
2336  * @size: pointer to size_t, will hold data property's data size
2337  *
2338  * fit_image_get_data() finds data property in a given component image node.
2339  * If the property is found its data start address and size are returned to
2340  * the caller.
2341  *
2342  * returns:
2343  *     0, on success
2344  *     -1, on failure
2345  */
2346 int fit_image_get_data (const void *fit, int noffset,
2347                 const void **data, size_t *size)
2348 {
2349         int len;
2350
2351         *data = fdt_getprop (fit, noffset, FIT_DATA_PROP, &len);
2352         if (*data == NULL) {
2353                 fit_get_debug (fit, noffset, FIT_DATA_PROP, len);
2354                 *size = 0;
2355                 return -1;
2356         }
2357
2358         *size = len;
2359         return 0;
2360 }
2361
2362 /**
2363  * fit_image_hash_get_algo - get hash algorithm name
2364  * @fit: pointer to the FIT format image header
2365  * @noffset: hash node offset
2366  * @algo: double pointer to char, will hold pointer to the algorithm name
2367  *
2368  * fit_image_hash_get_algo() finds hash algorithm property in a given hash node.
2369  * If the property is found its data start address is returned to the caller.
2370  *
2371  * returns:
2372  *     0, on success
2373  *     -1, on failure
2374  */
2375 int fit_image_hash_get_algo (const void *fit, int noffset, char **algo)
2376 {
2377         int len;
2378
2379         *algo = (char *)fdt_getprop (fit, noffset, FIT_ALGO_PROP, &len);
2380         if (*algo == NULL) {
2381                 fit_get_debug (fit, noffset, FIT_ALGO_PROP, len);
2382                 return -1;
2383         }
2384
2385         return 0;
2386 }
2387
2388 /**
2389  * fit_image_hash_get_value - get hash value and length
2390  * @fit: pointer to the FIT format image header
2391  * @noffset: hash node offset
2392  * @value: double pointer to uint8_t, will hold address of a hash value data
2393  * @value_len: pointer to an int, will hold hash data length
2394  *
2395  * fit_image_hash_get_value() finds hash value property in a given hash node.
2396  * If the property is found its data start address and size are returned to
2397  * the caller.
2398  *
2399  * returns:
2400  *     0, on success
2401  *     -1, on failure
2402  */
2403 int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value,
2404                                 int *value_len)
2405 {
2406         int len;
2407
2408         *value = (uint8_t *)fdt_getprop (fit, noffset, FIT_VALUE_PROP, &len);
2409         if (*value == NULL) {
2410                 fit_get_debug (fit, noffset, FIT_VALUE_PROP, len);
2411                 *value_len = 0;
2412                 return -1;
2413         }
2414
2415         *value_len = len;
2416         return 0;
2417 }
2418
2419 /**
2420  * fit_set_timestamp - set node timestamp property
2421  * @fit: pointer to the FIT format image header
2422  * @noffset: node offset
2423  * @timestamp: timestamp value to be set
2424  *
2425  * fit_set_timestamp() attempts to set timestamp property in the requested
2426  * node and returns operation status to the caller.
2427  *
2428  * returns:
2429  *     0, on success
2430  *     -1, on property read failure
2431  */
2432 int fit_set_timestamp (void *fit, int noffset, time_t timestamp)
2433 {
2434         uint32_t t;
2435         int ret;
2436
2437         t = cpu_to_uimage (timestamp);
2438         ret = fdt_setprop (fit, noffset, FIT_TIMESTAMP_PROP, &t,
2439                                 sizeof (uint32_t));
2440         if (ret) {
2441                 printf ("Can't set '%s' property for '%s' node (%s)\n",
2442                         FIT_TIMESTAMP_PROP, fit_get_name (fit, noffset, NULL),
2443                         fdt_strerror (ret));
2444                 return -1;
2445         }
2446
2447         return 0;
2448 }
2449
2450 /**
2451  * calculate_hash - calculate and return hash for provided input data
2452  * @data: pointer to the input data
2453  * @data_len: data length
2454  * @algo: requested hash algorithm
2455  * @value: pointer to the char, will hold hash value data (caller must
2456  * allocate enough free space)
2457  * value_len: length of the calculated hash
2458  *
2459  * calculate_hash() computes input data hash according to the requested algorithm.
2460  * Resulting hash value is placed in caller provided 'value' buffer, length
2461  * of the calculated hash is returned via value_len pointer argument.
2462  *
2463  * returns:
2464  *     0, on success
2465  *    -1, when algo is unsupported
2466  */
2467 static int calculate_hash (const void *data, int data_len, const char *algo,
2468                         uint8_t *value, int *value_len)
2469 {
2470         if (strcmp (algo, "crc32") == 0 ) {
2471                 *((uint32_t *)value) = crc32_wd (0, data, data_len,
2472                                                         CHUNKSZ_CRC32);
2473                 *((uint32_t *)value) = cpu_to_uimage (*((uint32_t *)value));
2474                 *value_len = 4;
2475         } else if (strcmp (algo, "sha1") == 0 ) {
2476                 sha1_csum_wd ((unsigned char *) data, data_len,
2477                                 (unsigned char *) value, CHUNKSZ_SHA1);
2478                 *value_len = 20;
2479         } else if (strcmp (algo, "md5") == 0 ) {
2480                 md5_wd ((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
2481                 *value_len = 16;
2482         } else {
2483                 debug ("Unsupported hash alogrithm\n");
2484                 return -1;
2485         }
2486         return 0;
2487 }
2488
2489 #ifdef USE_HOSTCC
2490 /**
2491  * fit_set_hashes - process FIT component image nodes and calculate hashes
2492  * @fit: pointer to the FIT format image header
2493  *
2494  * fit_set_hashes() adds hash values for all component images in the FIT blob.
2495  * Hashes are calculated for all component images which have hash subnodes
2496  * with algorithm property set to one of the supported hash algorithms.
2497  *
2498  * returns
2499  *     0, on success
2500  *     libfdt error code, on failure
2501  */
2502 int fit_set_hashes (void *fit)
2503 {
2504         int images_noffset;
2505         int noffset;
2506         int ndepth;
2507         int ret;
2508
2509         /* Find images parent node offset */
2510         images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
2511         if (images_noffset < 0) {
2512                 printf ("Can't find images parent node '%s' (%s)\n",
2513                         FIT_IMAGES_PATH, fdt_strerror (images_noffset));
2514                 return images_noffset;
2515         }
2516
2517         /* Process its subnodes, print out component images details */
2518         for (ndepth = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth);
2519              (noffset >= 0) && (ndepth > 0);
2520              noffset = fdt_next_node (fit, noffset, &ndepth)) {
2521                 if (ndepth == 1) {
2522                         /*
2523                          * Direct child node of the images parent node,
2524                          * i.e. component image node.
2525                          */
2526                         ret = fit_image_set_hashes (fit, noffset);
2527                         if (ret)
2528                                 return ret;
2529                 }
2530         }
2531
2532         return 0;
2533 }
2534
2535 /**
2536  * fit_image_set_hashes - calculate/set hashes for given component image node
2537  * @fit: pointer to the FIT format image header
2538  * @image_noffset: requested component image node
2539  *
2540  * fit_image_set_hashes() adds hash values for an component image node. All
2541  * existing hash subnodes are checked, if algorithm property is set to one of
2542  * the supported hash algorithms, hash value is computed and corresponding
2543  * hash node property is set, for example:
2544  *
2545  * Input component image node structure:
2546  *
2547  * o image@1 (at image_noffset)
2548  *   | - data = [binary data]
2549  *   o hash@1
2550  *     |- algo = "sha1"
2551  *
2552  * Output component image node structure:
2553  *
2554  * o image@1 (at image_noffset)
2555  *   | - data = [binary data]
2556  *   o hash@1
2557  *     |- algo = "sha1"
2558  *     |- value = sha1(data)
2559  *
2560  * returns:
2561  *     0 on sucess
2562  *    <0 on failure
2563  */
2564 int fit_image_set_hashes (void *fit, int image_noffset)
2565 {
2566         const void *data;
2567         size_t size;
2568         char *algo;
2569         uint8_t value[FIT_MAX_HASH_LEN];
2570         int value_len;
2571         int noffset;
2572         int ndepth;
2573
2574         /* Get image data and data length */
2575         if (fit_image_get_data (fit, image_noffset, &data, &size)) {
2576                 printf ("Can't get image data/size\n");
2577                 return -1;
2578         }
2579
2580         /* Process all hash subnodes of the component image node */
2581         for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
2582              (noffset >= 0) && (ndepth > 0);
2583              noffset = fdt_next_node (fit, noffset, &ndepth)) {
2584                 if (ndepth == 1) {
2585                         /* Direct child node of the component image node */
2586
2587                         /*
2588                          * Check subnode name, must be equal to "hash".
2589                          * Multiple hash nodes require unique unit node
2590                          * names, e.g. hash@1, hash@2, etc.
2591                          */
2592                         if (strncmp (fit_get_name(fit, noffset, NULL),
2593                                                 FIT_HASH_NODENAME,
2594                                                 strlen(FIT_HASH_NODENAME)) != 0) {
2595                                 /* Not a hash subnode, skip it */
2596                                 continue;
2597                         }
2598
2599                         if (fit_image_hash_get_algo (fit, noffset, &algo)) {
2600                                 printf ("Can't get hash algo property for "
2601                                         "'%s' hash node in '%s' image node\n",
2602                                         fit_get_name (fit, noffset, NULL),
2603                                         fit_get_name (fit, image_noffset, NULL));
2604                                 return -1;
2605                         }
2606
2607                         if (calculate_hash (data, size, algo, value, &value_len)) {
2608                                 printf ("Unsupported hash algorithm (%s) for "
2609                                         "'%s' hash node in '%s' image node\n",
2610                                         algo, fit_get_name (fit, noffset, NULL),
2611                                         fit_get_name (fit, image_noffset, NULL));
2612                                 return -1;
2613                         }
2614
2615                         if (fit_image_hash_set_value (fit, noffset, value,
2616                                                         value_len)) {
2617                                 printf ("Can't set hash value for "
2618                                         "'%s' hash node in '%s' image node\n",
2619                                         fit_get_name (fit, noffset, NULL),
2620                                         fit_get_name (fit, image_noffset, NULL));
2621                                 return -1;
2622                         }
2623                 }
2624         }
2625
2626         return 0;
2627 }
2628
2629 /**
2630  * fit_image_hash_set_value - set hash value in requested has node
2631  * @fit: pointer to the FIT format image header
2632  * @noffset: hash node offset
2633  * @value: hash value to be set
2634  * @value_len: hash value length
2635  *
2636  * fit_image_hash_set_value() attempts to set hash value in a node at offset
2637  * given and returns operation status to the caller.
2638  *
2639  * returns
2640  *     0, on success
2641  *     -1, on failure
2642  */
2643 int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value,
2644                                 int value_len)
2645 {
2646         int ret;
2647
2648         ret = fdt_setprop (fit, noffset, FIT_VALUE_PROP, value, value_len);
2649         if (ret) {
2650                 printf ("Can't set hash '%s' property for '%s' node (%s)\n",
2651                         FIT_VALUE_PROP, fit_get_name (fit, noffset, NULL),
2652                         fdt_strerror (ret));
2653                 return -1;
2654         }
2655
2656         return 0;
2657 }
2658 #endif /* USE_HOSTCC */
2659
2660 /**
2661  * fit_image_check_hashes - verify data intergity
2662  * @fit: pointer to the FIT format image header
2663  * @image_noffset: component image node offset
2664  *
2665  * fit_image_check_hashes() goes over component image hash nodes,
2666  * re-calculates each data hash and compares with the value stored in hash
2667  * node.
2668  *
2669  * returns:
2670  *     1, if all hashes are valid
2671  *     0, otherwise (or on error)
2672  */
2673 int fit_image_check_hashes (const void *fit, int image_noffset)
2674 {
2675         const void      *data;
2676         size_t          size;
2677         char            *algo;
2678         uint8_t         *fit_value;
2679         int             fit_value_len;
2680         uint8_t         value[FIT_MAX_HASH_LEN];
2681         int             value_len;
2682         int             noffset;
2683         int             ndepth;
2684         char            *err_msg = "";
2685
2686         /* Get image data and data length */
2687         if (fit_image_get_data (fit, image_noffset, &data, &size)) {
2688                 printf ("Can't get image data/size\n");
2689                 return 0;
2690         }
2691
2692         /* Process all hash subnodes of the component image node */
2693         for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
2694              (noffset >= 0) && (ndepth > 0);
2695              noffset = fdt_next_node (fit, noffset, &ndepth)) {
2696                 if (ndepth == 1) {
2697                         /* Direct child node of the component image node */
2698
2699                         /*
2700                          * Check subnode name, must be equal to "hash".
2701                          * Multiple hash nodes require unique unit node
2702                          * names, e.g. hash@1, hash@2, etc.
2703                          */
2704                         if (strncmp (fit_get_name(fit, noffset, NULL),
2705                                         FIT_HASH_NODENAME,
2706                                         strlen(FIT_HASH_NODENAME)) != 0)
2707                                 continue;
2708
2709                         if (fit_image_hash_get_algo (fit, noffset, &algo)) {
2710                                 err_msg = " error!\nCan't get hash algo "
2711                                                 "property";
2712                                 goto error;
2713                         }
2714                         printf ("%s", algo);
2715
2716                         if (fit_image_hash_get_value (fit, noffset, &fit_value,
2717                                                         &fit_value_len)) {
2718                                 err_msg = " error!\nCan't get hash value "
2719                                                 "property";
2720                                 goto error;
2721                         }
2722
2723                         if (calculate_hash (data, size, algo, value, &value_len)) {
2724                                 err_msg = " error!\nUnsupported hash algorithm";
2725                                 goto error;
2726                         }
2727
2728                         if (value_len != fit_value_len) {
2729                                 err_msg = " error !\nBad hash value len";
2730                                 goto error;
2731                         } else if (memcmp (value, fit_value, value_len) != 0) {
2732                                 err_msg = " error!\nBad hash value";
2733                                 goto error;
2734                         }
2735                         printf ("+ ");
2736                 }
2737         }
2738
2739         return 1;
2740
2741 error:
2742         printf ("%s for '%s' hash node in '%s' image node\n",
2743                         err_msg, fit_get_name (fit, noffset, NULL),
2744                         fit_get_name (fit, image_noffset, NULL));
2745         return 0;
2746 }
2747
2748 /**
2749  * fit_all_image_check_hashes - verify data intergity for all images
2750  * @fit: pointer to the FIT format image header
2751  *
2752  * fit_all_image_check_hashes() goes over all images in the FIT and
2753  * for every images checks if all it's hashes are valid.
2754  *
2755  * returns:
2756  *     1, if all hashes of all images are valid
2757  *     0, otherwise (or on error)
2758  */
2759 int fit_all_image_check_hashes (const void *fit)
2760 {
2761         int images_noffset;
2762         int noffset;
2763         int ndepth;
2764         int count;
2765
2766         /* Find images parent node offset */
2767         images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
2768         if (images_noffset < 0) {
2769                 printf ("Can't find images parent node '%s' (%s)\n",
2770                         FIT_IMAGES_PATH, fdt_strerror (images_noffset));
2771                 return 0;
2772         }
2773
2774         /* Process all image subnodes, check hashes for each */
2775         printf ("## Checking hash(es) for FIT Image at %08lx ...\n",
2776                 (ulong)fit);
2777         for (ndepth = 0, count = 0,
2778                 noffset = fdt_next_node (fit, images_noffset, &ndepth);
2779                 (noffset >= 0) && (ndepth > 0);
2780                 noffset = fdt_next_node (fit, noffset, &ndepth)) {
2781                 if (ndepth == 1) {
2782                         /*
2783                          * Direct child node of the images parent node,
2784                          * i.e. component image node.
2785                          */
2786                         printf ("   Hash(es) for Image %u (%s): ", count++,
2787                                         fit_get_name (fit, noffset, NULL));
2788
2789                         if (!fit_image_check_hashes (fit, noffset))
2790                                 return 0;
2791                         printf ("\n");
2792                 }
2793         }
2794         return 1;
2795 }
2796
2797 /**
2798  * fit_image_check_os - check whether image node is of a given os type
2799  * @fit: pointer to the FIT format image header
2800  * @noffset: component image node offset
2801  * @os: requested image os
2802  *
2803  * fit_image_check_os() reads image os property and compares its numeric
2804  * id with the requested os. Comparison result is returned to the caller.
2805  *
2806  * returns:
2807  *     1 if image is of given os type
2808  *     0 otherwise (or on error)
2809  */
2810 int fit_image_check_os (const void *fit, int noffset, uint8_t os)
2811 {
2812         uint8_t image_os;
2813
2814         if (fit_image_get_os (fit, noffset, &image_os))
2815                 return 0;
2816         return (os == image_os);
2817 }
2818
2819 /**
2820  * fit_image_check_arch - check whether image node is of a given arch
2821  * @fit: pointer to the FIT format image header
2822  * @noffset: component image node offset
2823  * @arch: requested imagearch
2824  *
2825  * fit_image_check_arch() reads image arch property and compares its numeric
2826  * id with the requested arch. Comparison result is returned to the caller.
2827  *
2828  * returns:
2829  *     1 if image is of given arch
2830  *     0 otherwise (or on error)
2831  */
2832 int fit_image_check_arch (const void *fit, int noffset, uint8_t arch)
2833 {
2834         uint8_t image_arch;
2835
2836         if (fit_image_get_arch (fit, noffset, &image_arch))
2837                 return 0;
2838         return (arch == image_arch);
2839 }
2840
2841 /**
2842  * fit_image_check_type - check whether image node is of a given type
2843  * @fit: pointer to the FIT format image header
2844  * @noffset: component image node offset
2845  * @type: requested image type
2846  *
2847  * fit_image_check_type() reads image type property and compares its numeric
2848  * id with the requested type. Comparison result is returned to the caller.
2849  *
2850  * returns:
2851  *     1 if image is of given type
2852  *     0 otherwise (or on error)
2853  */
2854 int fit_image_check_type (const void *fit, int noffset, uint8_t type)
2855 {
2856         uint8_t image_type;
2857
2858         if (fit_image_get_type (fit, noffset, &image_type))
2859                 return 0;
2860         return (type == image_type);
2861 }
2862
2863 /**
2864  * fit_image_check_comp - check whether image node uses given compression
2865  * @fit: pointer to the FIT format image header
2866  * @noffset: component image node offset
2867  * @comp: requested image compression type
2868  *
2869  * fit_image_check_comp() reads image compression property and compares its
2870  * numeric id with the requested compression type. Comparison result is
2871  * returned to the caller.
2872  *
2873  * returns:
2874  *     1 if image uses requested compression
2875  *     0 otherwise (or on error)
2876  */
2877 int fit_image_check_comp (const void *fit, int noffset, uint8_t comp)
2878 {
2879         uint8_t image_comp;
2880
2881         if (fit_image_get_comp (fit, noffset, &image_comp))
2882                 return 0;
2883         return (comp == image_comp);
2884 }
2885
2886 /**
2887  * fit_check_format - sanity check FIT image format
2888  * @fit: pointer to the FIT format image header
2889  *
2890  * fit_check_format() runs a basic sanity FIT image verification.
2891  * Routine checks for mandatory properties, nodes, etc.
2892  *
2893  * returns:
2894  *     1, on success
2895  *     0, on failure
2896  */
2897 int fit_check_format (const void *fit)
2898 {
2899         /* mandatory / node 'description' property */
2900         if (fdt_getprop (fit, 0, FIT_DESC_PROP, NULL) == NULL) {
2901                 debug ("Wrong FIT format: no description\n");
2902                 return 0;
2903         }
2904
2905 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
2906         /* mandatory / node 'timestamp' property */
2907         if (fdt_getprop (fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) {
2908                 debug ("Wrong FIT format: no timestamp\n");
2909                 return 0;
2910         }
2911 #endif
2912
2913         /* mandatory subimages parent '/images' node */
2914         if (fdt_path_offset (fit, FIT_IMAGES_PATH) < 0) {
2915                 debug ("Wrong FIT format: no images parent node\n");
2916                 return 0;
2917         }
2918
2919         return 1;
2920 }
2921
2922 /**
2923  * fit_conf_get_node - get node offset for configuration of a given unit name
2924  * @fit: pointer to the FIT format image header
2925  * @conf_uname: configuration node unit name
2926  *
2927  * fit_conf_get_node() finds a configuration (withing the '/configurations'
2928  * parant node) of a provided unit name. If configuration is found its node offset
2929  * is returned to the caller.
2930  *
2931  * When NULL is provided in second argument fit_conf_get_node() will search
2932  * for a default configuration node instead. Default configuration node unit name
2933  * is retrived from FIT_DEFAULT_PROP property of the '/configurations' node.
2934  *
2935  * returns:
2936  *     configuration node offset when found (>=0)
2937  *     negative number on failure (FDT_ERR_* code)
2938  */
2939 int fit_conf_get_node (const void *fit, const char *conf_uname)
2940 {
2941         int noffset, confs_noffset;
2942         int len;
2943
2944         confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH);
2945         if (confs_noffset < 0) {
2946                 debug ("Can't find configurations parent node '%s' (%s)\n",
2947                         FIT_CONFS_PATH, fdt_strerror (confs_noffset));
2948                 return confs_noffset;
2949         }
2950
2951         if (conf_uname == NULL) {
2952                 /* get configuration unit name from the default property */
2953                 debug ("No configuration specified, trying default...\n");
2954                 conf_uname = (char *)fdt_getprop (fit, confs_noffset, FIT_DEFAULT_PROP, &len);
2955                 if (conf_uname == NULL) {
2956                         fit_get_debug (fit, confs_noffset, FIT_DEFAULT_PROP, len);
2957                         return len;
2958                 }
2959                 debug ("Found default configuration: '%s'\n", conf_uname);
2960         }
2961
2962         noffset = fdt_subnode_offset (fit, confs_noffset, conf_uname);
2963         if (noffset < 0) {
2964                 debug ("Can't get node offset for configuration unit name: '%s' (%s)\n",
2965                         conf_uname, fdt_strerror (noffset));
2966         }
2967
2968         return noffset;
2969 }
2970
2971 static int __fit_conf_get_prop_node (const void *fit, int noffset,
2972                 const char *prop_name)
2973 {
2974         char *uname;
2975         int len;
2976
2977         /* get kernel image unit name from configuration kernel property */
2978         uname = (char *)fdt_getprop (fit, noffset, prop_name, &len);
2979         if (uname == NULL)
2980                 return len;
2981
2982         return fit_image_get_node (fit, uname);
2983 }
2984
2985 /**
2986  * fit_conf_get_kernel_node - get kernel image node offset that corresponds to
2987  * a given configuration
2988  * @fit: pointer to the FIT format image header
2989  * @noffset: configuration node offset
2990  *
2991  * fit_conf_get_kernel_node() retrives kernel image node unit name from
2992  * configuration FIT_KERNEL_PROP property and translates it to the node
2993  * offset.
2994  *
2995  * returns:
2996  *     image node offset when found (>=0)
2997  *     negative number on failure (FDT_ERR_* code)
2998  */
2999 int fit_conf_get_kernel_node (const void *fit, int noffset)
3000 {
3001         return __fit_conf_get_prop_node (fit, noffset, FIT_KERNEL_PROP);
3002 }
3003
3004 /**
3005  * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to
3006  * a given configuration
3007  * @fit: pointer to the FIT format image header
3008  * @noffset: configuration node offset
3009  *
3010  * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from
3011  * configuration FIT_KERNEL_PROP property and translates it to the node
3012  * offset.
3013  *
3014  * returns:
3015  *     image node offset when found (>=0)
3016  *     negative number on failure (FDT_ERR_* code)
3017  */
3018 int fit_conf_get_ramdisk_node (const void *fit, int noffset)
3019 {
3020         return __fit_conf_get_prop_node (fit, noffset, FIT_RAMDISK_PROP);
3021 }
3022
3023 /**
3024  * fit_conf_get_fdt_node - get fdt image node offset that corresponds to
3025  * a given configuration
3026  * @fit: pointer to the FIT format image header
3027  * @noffset: configuration node offset
3028  *
3029  * fit_conf_get_fdt_node() retrives fdt image node unit name from
3030  * configuration FIT_KERNEL_PROP property and translates it to the node
3031  * offset.
3032  *
3033  * returns:
3034  *     image node offset when found (>=0)
3035  *     negative number on failure (FDT_ERR_* code)
3036  */
3037 int fit_conf_get_fdt_node (const void *fit, int noffset)
3038 {
3039         return __fit_conf_get_prop_node (fit, noffset, FIT_FDT_PROP);
3040 }
3041
3042 /**
3043  * fit_conf_print - prints out the FIT configuration details
3044  * @fit: pointer to the FIT format image header
3045  * @noffset: offset of the configuration node
3046  * @p: pointer to prefix string
3047  *
3048  * fit_conf_print() lists all mandatory properies for the processed
3049  * configuration node.
3050  *
3051  * returns:
3052  *     no returned results
3053  */
3054 void fit_conf_print (const void *fit, int noffset, const char *p)
3055 {
3056         char *desc;
3057         char *uname;
3058         int ret;
3059
3060         /* Mandatory properties */
3061         ret = fit_get_desc (fit, noffset, &desc);
3062         printf ("%s  Description:  ", p);
3063         if (ret)
3064                 printf ("unavailable\n");
3065         else
3066                 printf ("%s\n", desc);
3067
3068         uname = (char *)fdt_getprop (fit, noffset, FIT_KERNEL_PROP, NULL);
3069         printf ("%s  Kernel:       ", p);
3070         if (uname == NULL)
3071                 printf ("unavailable\n");
3072         else
3073                 printf ("%s\n", uname);
3074
3075         /* Optional properties */
3076         uname = (char *)fdt_getprop (fit, noffset, FIT_RAMDISK_PROP, NULL);
3077         if (uname)
3078                 printf ("%s  Init Ramdisk: %s\n", p, uname);
3079
3080         uname = (char *)fdt_getprop (fit, noffset, FIT_FDT_PROP, NULL);
3081         if (uname)
3082                 printf ("%s  FDT:          %s\n", p, uname);
3083 }
3084
3085 /**
3086  * fit_check_ramdisk - verify FIT format ramdisk subimage
3087  * @fit_hdr: pointer to the FIT ramdisk header
3088  * @rd_noffset: ramdisk subimage node offset within FIT image
3089  * @arch: requested ramdisk image architecture type
3090  * @verify: data CRC verification flag
3091  *
3092  * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from
3093  * specified FIT image.
3094  *
3095  * returns:
3096  *     1, on success
3097  *     0, on failure
3098  */
3099 #ifndef USE_HOSTCC
3100 static int fit_check_ramdisk (const void *fit, int rd_noffset, uint8_t arch, int verify)
3101 {
3102         fit_image_print (fit, rd_noffset, "   ");
3103
3104         if (verify) {
3105                 puts ("   Verifying Hash Integrity ... ");
3106                 if (!fit_image_check_hashes (fit, rd_noffset)) {
3107                         puts ("Bad Data Hash\n");
3108                         show_boot_progress (-125);
3109                         return 0;
3110                 }
3111                 puts ("OK\n");
3112         }
3113
3114         show_boot_progress (126);
3115         if (!fit_image_check_os (fit, rd_noffset, IH_OS_LINUX) ||
3116             !fit_image_check_arch (fit, rd_noffset, arch) ||
3117             !fit_image_check_type (fit, rd_noffset, IH_TYPE_RAMDISK)) {
3118                 printf ("No Linux %s Ramdisk Image\n",
3119                                 genimg_get_arch_name(arch));
3120                 show_boot_progress (-126);
3121                 return 0;
3122         }
3123
3124         show_boot_progress (127);
3125         return 1;
3126 }
3127 #endif /* USE_HOSTCC */
3128 #endif /* CONFIG_FIT */