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