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