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