xref: /openbmc/u-boot/common/image.c (revision 3dfe1101)
1b97a2a0aSMarian Balakowicz /*
2b97a2a0aSMarian Balakowicz  * (C) Copyright 2008 Semihalf
3b97a2a0aSMarian Balakowicz  *
4b97a2a0aSMarian Balakowicz  * (C) Copyright 2000-2006
5b97a2a0aSMarian Balakowicz  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
6b97a2a0aSMarian Balakowicz  *
7b97a2a0aSMarian Balakowicz  * See file CREDITS for list of people who contributed to this
8b97a2a0aSMarian Balakowicz  * project.
9b97a2a0aSMarian Balakowicz  *
10b97a2a0aSMarian Balakowicz  * This program is free software; you can redistribute it and/or
11b97a2a0aSMarian Balakowicz  * modify it under the terms of the GNU General Public License as
12b97a2a0aSMarian Balakowicz  * published by the Free Software Foundation; either version 2 of
13b97a2a0aSMarian Balakowicz  * the License, or (at your option) any later version.
14b97a2a0aSMarian Balakowicz  *
15b97a2a0aSMarian Balakowicz  * This program is distributed in the hope that it will be useful,
16b97a2a0aSMarian Balakowicz  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17b97a2a0aSMarian Balakowicz  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18b97a2a0aSMarian Balakowicz  * GNU General Public License for more details.
19b97a2a0aSMarian Balakowicz  *
20b97a2a0aSMarian Balakowicz  * You should have received a copy of the GNU General Public License
21b97a2a0aSMarian Balakowicz  * along with this program; if not, write to the Free Software
22b97a2a0aSMarian Balakowicz  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23b97a2a0aSMarian Balakowicz  * MA 02111-1307 USA
24b97a2a0aSMarian Balakowicz  */
25ceaed2b1SMarian Balakowicz 
26ceaed2b1SMarian Balakowicz #define DEBUG
27ceaed2b1SMarian Balakowicz 
28b97a2a0aSMarian Balakowicz #ifndef USE_HOSTCC
29b97a2a0aSMarian Balakowicz #include <common.h>
30b97a2a0aSMarian Balakowicz #include <watchdog.h>
315ad03eb3SMarian Balakowicz 
325ad03eb3SMarian Balakowicz #ifdef CONFIG_SHOW_BOOT_PROGRESS
335ad03eb3SMarian Balakowicz #include <status_led.h>
345ad03eb3SMarian Balakowicz #endif
355ad03eb3SMarian Balakowicz 
365ad03eb3SMarian Balakowicz #ifdef CONFIG_HAS_DATAFLASH
375ad03eb3SMarian Balakowicz #include <dataflash.h>
385ad03eb3SMarian Balakowicz #endif
395ad03eb3SMarian Balakowicz 
40ceaed2b1SMarian Balakowicz #ifdef CONFIG_LOGBUFFER
41ceaed2b1SMarian Balakowicz #include <logbuff.h>
42ceaed2b1SMarian Balakowicz #endif
43ceaed2b1SMarian Balakowicz 
442242f536SMarian Balakowicz #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE)
452242f536SMarian Balakowicz #include <rtc.h>
462242f536SMarian Balakowicz #endif
472242f536SMarian Balakowicz 
485dfb5213SMarian Balakowicz #include <image.h>
495dfb5213SMarian Balakowicz 
50c8779648SMarian Balakowicz #if defined(CONFIG_FIT) || defined (CONFIG_OF_LIBFDT)
51fff888a1SMarian Balakowicz #include <fdt.h>
52fff888a1SMarian Balakowicz #include <libfdt.h>
53fff888a1SMarian Balakowicz #include <fdt_support.h>
54c8779648SMarian Balakowicz #endif
55c8779648SMarian Balakowicz 
56c8779648SMarian Balakowicz #if defined(CONFIG_FIT)
575dfb5213SMarian Balakowicz #include <sha1.h>
58c8779648SMarian Balakowicz 
59c8779648SMarian Balakowicz static int fit_check_ramdisk (const void *fit, int os_noffset,
60c8779648SMarian Balakowicz 		uint8_t arch, int verify);
61fff888a1SMarian Balakowicz #endif
62fff888a1SMarian Balakowicz 
63b6b0fe64SMarian Balakowicz #ifdef CONFIG_CMD_BDI
64b6b0fe64SMarian Balakowicz extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
65b6b0fe64SMarian Balakowicz #endif
66b6b0fe64SMarian Balakowicz 
67b6b0fe64SMarian Balakowicz DECLARE_GLOBAL_DATA_PTR;
688a5ea3e6SMarian Balakowicz 
69d985c849SMarian Balakowicz static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
70d985c849SMarian Balakowicz 						int verify);
71b97a2a0aSMarian Balakowicz #else
72b97a2a0aSMarian Balakowicz #include "mkimage.h"
735dfb5213SMarian Balakowicz #include <time.h>
74b97a2a0aSMarian Balakowicz #include <image.h>
755dfb5213SMarian Balakowicz #endif /* !USE_HOSTCC*/
76b97a2a0aSMarian Balakowicz 
77570abb0aSMarian Balakowicz typedef struct table_entry {
78570abb0aSMarian Balakowicz 	int	id;		/* as defined in image.h	*/
79570abb0aSMarian Balakowicz 	char	*sname;		/* short (input) name		*/
80570abb0aSMarian Balakowicz 	char	*lname;		/* long (output) name		*/
81570abb0aSMarian Balakowicz } table_entry_t;
82570abb0aSMarian Balakowicz 
83570abb0aSMarian Balakowicz static table_entry_t uimage_arch[] = {
84570abb0aSMarian Balakowicz 	{	IH_ARCH_INVALID,	NULL,		"Invalid ARCH",	},
85570abb0aSMarian Balakowicz 	{	IH_ARCH_ALPHA,		"alpha",	"Alpha",	},
86570abb0aSMarian Balakowicz 	{	IH_ARCH_ARM,		"arm",		"ARM",		},
87570abb0aSMarian Balakowicz 	{	IH_ARCH_I386,		"x86",		"Intel x86",	},
88570abb0aSMarian Balakowicz 	{	IH_ARCH_IA64,		"ia64",		"IA64",		},
89570abb0aSMarian Balakowicz 	{	IH_ARCH_M68K,		"m68k",		"M68K",		},
90570abb0aSMarian Balakowicz 	{	IH_ARCH_MICROBLAZE,	"microblaze",	"MicroBlaze",	},
91570abb0aSMarian Balakowicz 	{	IH_ARCH_MIPS,		"mips",		"MIPS",		},
92570abb0aSMarian Balakowicz 	{	IH_ARCH_MIPS64,		"mips64",	"MIPS 64 Bit",	},
93570abb0aSMarian Balakowicz 	{	IH_ARCH_NIOS,		"nios",		"NIOS",		},
94570abb0aSMarian Balakowicz 	{	IH_ARCH_NIOS2,		"nios2",	"NIOS II",	},
95570abb0aSMarian Balakowicz 	{	IH_ARCH_PPC,		"ppc",		"PowerPC",	},
96570abb0aSMarian Balakowicz 	{	IH_ARCH_S390,		"s390",		"IBM S390",	},
97570abb0aSMarian Balakowicz 	{	IH_ARCH_SH,		"sh",		"SuperH",	},
98570abb0aSMarian Balakowicz 	{	IH_ARCH_SPARC,		"sparc",	"SPARC",	},
99570abb0aSMarian Balakowicz 	{	IH_ARCH_SPARC64,	"sparc64",	"SPARC 64 Bit",	},
100570abb0aSMarian Balakowicz 	{	IH_ARCH_BLACKFIN,	"blackfin",	"Blackfin",	},
101570abb0aSMarian Balakowicz 	{	IH_ARCH_AVR32,		"avr32",	"AVR32",	},
102570abb0aSMarian Balakowicz 	{	-1,			"",		"",		},
103570abb0aSMarian Balakowicz };
104570abb0aSMarian Balakowicz 
105570abb0aSMarian Balakowicz static table_entry_t uimage_os[] = {
106570abb0aSMarian Balakowicz 	{	IH_OS_INVALID,	NULL,		"Invalid OS",		},
107570abb0aSMarian Balakowicz #if defined(CONFIG_ARTOS) || defined(USE_HOSTCC)
108570abb0aSMarian Balakowicz 	{	IH_OS_ARTOS,	"artos",	"ARTOS",		},
109570abb0aSMarian Balakowicz #endif
110570abb0aSMarian Balakowicz 	{	IH_OS_LINUX,	"linux",	"Linux",		},
111570abb0aSMarian Balakowicz #if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC)
112570abb0aSMarian Balakowicz 	{	IH_OS_LYNXOS,	"lynxos",	"LynxOS",		},
113570abb0aSMarian Balakowicz #endif
114570abb0aSMarian Balakowicz 	{	IH_OS_NETBSD,	"netbsd",	"NetBSD",		},
115570abb0aSMarian Balakowicz 	{	IH_OS_RTEMS,	"rtems",	"RTEMS",		},
116570abb0aSMarian Balakowicz 	{	IH_OS_U_BOOT,	"u-boot",	"U-Boot",		},
117570abb0aSMarian Balakowicz #if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)
118570abb0aSMarian Balakowicz 	{	IH_OS_QNX,	"qnx",		"QNX",			},
119570abb0aSMarian Balakowicz 	{	IH_OS_VXWORKS,	"vxworks",	"VxWorks",		},
120570abb0aSMarian Balakowicz #endif
121570abb0aSMarian Balakowicz #ifdef USE_HOSTCC
122570abb0aSMarian Balakowicz 	{	IH_OS_4_4BSD,	"4_4bsd",	"4_4BSD",		},
123570abb0aSMarian Balakowicz 	{	IH_OS_DELL,	"dell",		"Dell",			},
124570abb0aSMarian Balakowicz 	{	IH_OS_ESIX,	"esix",		"Esix",			},
125570abb0aSMarian Balakowicz 	{	IH_OS_FREEBSD,	"freebsd",	"FreeBSD",		},
126570abb0aSMarian Balakowicz 	{	IH_OS_IRIX,	"irix",		"Irix",			},
127570abb0aSMarian Balakowicz 	{	IH_OS_NCR,	"ncr",		"NCR",			},
128570abb0aSMarian Balakowicz 	{	IH_OS_OPENBSD,	"openbsd",	"OpenBSD",		},
129570abb0aSMarian Balakowicz 	{	IH_OS_PSOS,	"psos",		"pSOS",			},
130570abb0aSMarian Balakowicz 	{	IH_OS_SCO,	"sco",		"SCO",			},
131570abb0aSMarian Balakowicz 	{	IH_OS_SOLARIS,	"solaris",	"Solaris",		},
132570abb0aSMarian Balakowicz 	{	IH_OS_SVR4,	"svr4",		"SVR4",			},
133570abb0aSMarian Balakowicz #endif
134570abb0aSMarian Balakowicz 	{	-1,		"",		"",			},
135570abb0aSMarian Balakowicz };
136570abb0aSMarian Balakowicz 
137570abb0aSMarian Balakowicz static table_entry_t uimage_type[] = {
138570abb0aSMarian Balakowicz 	{	IH_TYPE_INVALID,    NULL,	  "Invalid Image",	},
139570abb0aSMarian Balakowicz 	{	IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image",	},
140570abb0aSMarian Balakowicz 	{	IH_TYPE_FIRMWARE,   "firmware",	  "Firmware",		},
141570abb0aSMarian Balakowicz 	{	IH_TYPE_KERNEL,	    "kernel",	  "Kernel Image",	},
142570abb0aSMarian Balakowicz 	{	IH_TYPE_MULTI,	    "multi",	  "Multi-File Image",	},
143570abb0aSMarian Balakowicz 	{	IH_TYPE_RAMDISK,    "ramdisk",	  "RAMDisk Image",	},
144570abb0aSMarian Balakowicz 	{	IH_TYPE_SCRIPT,     "script",	  "Script",		},
145570abb0aSMarian Balakowicz 	{	IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
146570abb0aSMarian Balakowicz 	{	IH_TYPE_FLATDT,     "flat_dt",    "Flat Device Tree",	},
147570abb0aSMarian Balakowicz 	{	-1,		    "",		  "",			},
148570abb0aSMarian Balakowicz };
149570abb0aSMarian Balakowicz 
150570abb0aSMarian Balakowicz static table_entry_t uimage_comp[] = {
151570abb0aSMarian Balakowicz 	{	IH_COMP_NONE,	"none",		"uncompressed",		},
152570abb0aSMarian Balakowicz 	{	IH_COMP_BZIP2,	"bzip2",	"bzip2 compressed",	},
153570abb0aSMarian Balakowicz 	{	IH_COMP_GZIP,	"gzip",		"gzip compressed",	},
154570abb0aSMarian Balakowicz 	{	-1,		"",		"",			},
155570abb0aSMarian Balakowicz };
156570abb0aSMarian Balakowicz 
157b97a2a0aSMarian Balakowicz unsigned long crc32 (unsigned long, const unsigned char *, unsigned int);
158570abb0aSMarian Balakowicz static void genimg_print_size (uint32_t size);
159570abb0aSMarian Balakowicz #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
160570abb0aSMarian Balakowicz static void genimg_print_time (time_t timestamp);
161570abb0aSMarian Balakowicz #endif
162b97a2a0aSMarian Balakowicz 
1639a4daad0SMarian Balakowicz /*****************************************************************************/
1649a4daad0SMarian Balakowicz /* Legacy format routines */
1659a4daad0SMarian Balakowicz /*****************************************************************************/
166b97a2a0aSMarian Balakowicz int image_check_hcrc (image_header_t *hdr)
167b97a2a0aSMarian Balakowicz {
168b97a2a0aSMarian Balakowicz 	ulong hcrc;
169b97a2a0aSMarian Balakowicz 	ulong len = image_get_header_size ();
170b97a2a0aSMarian Balakowicz 	image_header_t header;
171b97a2a0aSMarian Balakowicz 
172b97a2a0aSMarian Balakowicz 	/* Copy header so we can blank CRC field for re-calculation */
173b97a2a0aSMarian Balakowicz 	memmove (&header, (char *)hdr, image_get_header_size ());
174b97a2a0aSMarian Balakowicz 	image_set_hcrc (&header, 0);
175b97a2a0aSMarian Balakowicz 
176b97a2a0aSMarian Balakowicz 	hcrc = crc32 (0, (unsigned char *)&header, len);
177b97a2a0aSMarian Balakowicz 
178b97a2a0aSMarian Balakowicz 	return (hcrc == image_get_hcrc (hdr));
179b97a2a0aSMarian Balakowicz }
180b97a2a0aSMarian Balakowicz 
181b97a2a0aSMarian Balakowicz int image_check_dcrc (image_header_t *hdr)
182b97a2a0aSMarian Balakowicz {
183b97a2a0aSMarian Balakowicz 	ulong data = image_get_data (hdr);
184b97a2a0aSMarian Balakowicz 	ulong len = image_get_data_size (hdr);
185b97a2a0aSMarian Balakowicz 	ulong dcrc = crc32 (0, (unsigned char *)data, len);
186b97a2a0aSMarian Balakowicz 
187b97a2a0aSMarian Balakowicz 	return (dcrc == image_get_dcrc (hdr));
188b97a2a0aSMarian Balakowicz }
189b97a2a0aSMarian Balakowicz 
190af13cdbcSMarian Balakowicz #ifndef USE_HOSTCC
191b97a2a0aSMarian Balakowicz int image_check_dcrc_wd (image_header_t *hdr, ulong chunksz)
192b97a2a0aSMarian Balakowicz {
193b97a2a0aSMarian Balakowicz 	ulong dcrc = 0;
194b97a2a0aSMarian Balakowicz 	ulong len = image_get_data_size (hdr);
195b97a2a0aSMarian Balakowicz 	ulong data = image_get_data (hdr);
196b97a2a0aSMarian Balakowicz 
197b97a2a0aSMarian Balakowicz #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
198b97a2a0aSMarian Balakowicz 	ulong cdata = data;
199b97a2a0aSMarian Balakowicz 	ulong edata = cdata + len;
200b97a2a0aSMarian Balakowicz 
201b97a2a0aSMarian Balakowicz 	while (cdata < edata) {
202b97a2a0aSMarian Balakowicz 		ulong chunk = edata - cdata;
203b97a2a0aSMarian Balakowicz 
204b97a2a0aSMarian Balakowicz 		if (chunk > chunksz)
205b97a2a0aSMarian Balakowicz 			chunk = chunksz;
206b97a2a0aSMarian Balakowicz 		dcrc = crc32 (dcrc, (unsigned char *)cdata, chunk);
207b97a2a0aSMarian Balakowicz 		cdata += chunk;
208b97a2a0aSMarian Balakowicz 
209b97a2a0aSMarian Balakowicz 		WATCHDOG_RESET ();
210b97a2a0aSMarian Balakowicz 	}
211b97a2a0aSMarian Balakowicz #else
212b97a2a0aSMarian Balakowicz 	dcrc = crc32 (0, (unsigned char *)data, len);
213b97a2a0aSMarian Balakowicz #endif
214b97a2a0aSMarian Balakowicz 
215b97a2a0aSMarian Balakowicz 	return (dcrc == image_get_dcrc (hdr));
216b97a2a0aSMarian Balakowicz }
217570abb0aSMarian Balakowicz #endif /* !USE_HOSTCC */
218b97a2a0aSMarian Balakowicz 
219f13e7b2eSMarian Balakowicz /**
220f13e7b2eSMarian Balakowicz  * image_multi_count - get component (sub-image) count
221f13e7b2eSMarian Balakowicz  * @hdr: pointer to the header of the multi component image
222f13e7b2eSMarian Balakowicz  *
223f13e7b2eSMarian Balakowicz  * image_multi_count() returns number of components in a multi
224f13e7b2eSMarian Balakowicz  * component image.
225f13e7b2eSMarian Balakowicz  *
226f13e7b2eSMarian Balakowicz  * Note: no checking of the image type is done, caller must pass
227f13e7b2eSMarian Balakowicz  * a valid multi component image.
228f13e7b2eSMarian Balakowicz  *
229f13e7b2eSMarian Balakowicz  * returns:
230f13e7b2eSMarian Balakowicz  *     number of components
231f13e7b2eSMarian Balakowicz  */
232f13e7b2eSMarian Balakowicz ulong image_multi_count (image_header_t *hdr)
233f13e7b2eSMarian Balakowicz {
234f13e7b2eSMarian Balakowicz 	ulong i, count = 0;
235df6f1b89SMarian Balakowicz 	uint32_t *size;
236f13e7b2eSMarian Balakowicz 
237f13e7b2eSMarian Balakowicz 	/* get start of the image payload, which in case of multi
238f13e7b2eSMarian Balakowicz 	 * component images that points to a table of component sizes */
239df6f1b89SMarian Balakowicz 	size = (uint32_t *)image_get_data (hdr);
240f13e7b2eSMarian Balakowicz 
241f13e7b2eSMarian Balakowicz 	/* count non empty slots */
242f13e7b2eSMarian Balakowicz 	for (i = 0; size[i]; ++i)
243f13e7b2eSMarian Balakowicz 		count++;
244f13e7b2eSMarian Balakowicz 
245f13e7b2eSMarian Balakowicz 	return count;
246f13e7b2eSMarian Balakowicz }
247f13e7b2eSMarian Balakowicz 
248f13e7b2eSMarian Balakowicz /**
249f13e7b2eSMarian Balakowicz  * image_multi_getimg - get component data address and size
250f13e7b2eSMarian Balakowicz  * @hdr: pointer to the header of the multi component image
251f13e7b2eSMarian Balakowicz  * @idx: index of the requested component
252f13e7b2eSMarian Balakowicz  * @data: pointer to a ulong variable, will hold component data address
253f13e7b2eSMarian Balakowicz  * @len: pointer to a ulong variable, will hold component size
254f13e7b2eSMarian Balakowicz  *
255f13e7b2eSMarian Balakowicz  * image_multi_getimg() returns size and data address for the requested
256f13e7b2eSMarian Balakowicz  * component in a multi component image.
257f13e7b2eSMarian Balakowicz  *
258f13e7b2eSMarian Balakowicz  * Note: no checking of the image type is done, caller must pass
259f13e7b2eSMarian Balakowicz  * a valid multi component image.
260f13e7b2eSMarian Balakowicz  *
261f13e7b2eSMarian Balakowicz  * returns:
262f13e7b2eSMarian Balakowicz  *     data address and size of the component, if idx is valid
263f13e7b2eSMarian Balakowicz  *     0 in data and len, if idx is out of range
264f13e7b2eSMarian Balakowicz  */
265f13e7b2eSMarian Balakowicz void image_multi_getimg (image_header_t *hdr, ulong idx,
266f13e7b2eSMarian Balakowicz 			ulong *data, ulong *len)
267f13e7b2eSMarian Balakowicz {
268f13e7b2eSMarian Balakowicz 	int i;
269df6f1b89SMarian Balakowicz 	uint32_t *size;
270f13e7b2eSMarian Balakowicz 	ulong offset, tail, count, img_data;
271f13e7b2eSMarian Balakowicz 
272f13e7b2eSMarian Balakowicz 	/* get number of component */
273f13e7b2eSMarian Balakowicz 	count = image_multi_count (hdr);
274f13e7b2eSMarian Balakowicz 
275f13e7b2eSMarian Balakowicz 	/* get start of the image payload, which in case of multi
276f13e7b2eSMarian Balakowicz 	 * component images that points to a table of component sizes */
277df6f1b89SMarian Balakowicz 	size = (uint32_t *)image_get_data (hdr);
278f13e7b2eSMarian Balakowicz 
279f13e7b2eSMarian Balakowicz 	/* get address of the proper component data start, which means
280f13e7b2eSMarian Balakowicz 	 * skipping sizes table (add 1 for last, null entry) */
281df6f1b89SMarian Balakowicz 	img_data = image_get_data (hdr) + (count + 1) * sizeof (uint32_t);
282f13e7b2eSMarian Balakowicz 
283f13e7b2eSMarian Balakowicz 	if (idx < count) {
284df6f1b89SMarian Balakowicz 		*len = uimage_to_cpu (size[idx]);
285f13e7b2eSMarian Balakowicz 		offset = 0;
286f13e7b2eSMarian Balakowicz 		tail = 0;
287f13e7b2eSMarian Balakowicz 
288f13e7b2eSMarian Balakowicz 		/* go over all indices preceding requested component idx */
289f13e7b2eSMarian Balakowicz 		for (i = 0; i < idx; i++) {
290f13e7b2eSMarian Balakowicz 			/* add up i-th component size */
291df6f1b89SMarian Balakowicz 			offset += uimage_to_cpu (size[i]);
292f13e7b2eSMarian Balakowicz 
293f13e7b2eSMarian Balakowicz 			/* add up alignment for i-th component */
294df6f1b89SMarian Balakowicz 			tail += (4 - uimage_to_cpu (size[i]) % 4);
295f13e7b2eSMarian Balakowicz 		}
296f13e7b2eSMarian Balakowicz 
297f13e7b2eSMarian Balakowicz 		/* calculate idx-th component data address */
298f13e7b2eSMarian Balakowicz 		*data = img_data + offset + tail;
299f13e7b2eSMarian Balakowicz 	} else {
300f13e7b2eSMarian Balakowicz 		*len = 0;
301f13e7b2eSMarian Balakowicz 		*data = 0;
302f13e7b2eSMarian Balakowicz 	}
303f13e7b2eSMarian Balakowicz }
30442b73e8eSMarian Balakowicz 
3052242f536SMarian Balakowicz static void image_print_type (image_header_t *hdr)
3062242f536SMarian Balakowicz {
3072242f536SMarian Balakowicz 	const char *os, *arch, *type, *comp;
3082242f536SMarian Balakowicz 
3099a4daad0SMarian Balakowicz 	os = genimg_get_os_name (image_get_os (hdr));
3109a4daad0SMarian Balakowicz 	arch = genimg_get_arch_name (image_get_arch (hdr));
3119a4daad0SMarian Balakowicz 	type = genimg_get_type_name (image_get_type (hdr));
3129a4daad0SMarian Balakowicz 	comp = genimg_get_comp_name (image_get_comp (hdr));
3132242f536SMarian Balakowicz 
314570abb0aSMarian Balakowicz 	printf ("%s %s %s (%s)\n", arch, os, type, comp);
3152242f536SMarian Balakowicz }
3162242f536SMarian Balakowicz 
3175dfb5213SMarian Balakowicz /**
3185dfb5213SMarian Balakowicz  * __image_print_contents - prints out the contents of the legacy format image
3195dfb5213SMarian Balakowicz  * @hdr: pointer to the legacy format image header
3205dfb5213SMarian Balakowicz  * @p: pointer to prefix string
3215dfb5213SMarian Balakowicz  *
3225dfb5213SMarian Balakowicz  * __image_print_contents() formats a multi line legacy image contents description.
3235dfb5213SMarian Balakowicz  * The routine prints out all header fields followed by the size/offset data
3245dfb5213SMarian Balakowicz  * for MULTI/SCRIPT images.
3255dfb5213SMarian Balakowicz  *
3265dfb5213SMarian Balakowicz  * returns:
3275dfb5213SMarian Balakowicz  *     no returned results
3285dfb5213SMarian Balakowicz  */
329570abb0aSMarian Balakowicz static void __image_print_contents (image_header_t *hdr, const char *p)
3302242f536SMarian Balakowicz {
331570abb0aSMarian Balakowicz 	printf ("%sImage Name:   %.*s\n", p, IH_NMLEN, image_get_name (hdr));
332570abb0aSMarian Balakowicz #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
333570abb0aSMarian Balakowicz 	printf ("%sCreated:      ", p);
334570abb0aSMarian Balakowicz 	genimg_print_time ((time_t)image_get_time (hdr));
3352242f536SMarian Balakowicz #endif
336570abb0aSMarian Balakowicz 	printf ("%sImage Type:   ", p);
3372242f536SMarian Balakowicz 	image_print_type (hdr);
338570abb0aSMarian Balakowicz 	printf ("%sData Size:    ", p);
339570abb0aSMarian Balakowicz 	genimg_print_size (image_get_data_size (hdr));
340570abb0aSMarian Balakowicz 	printf ("%sLoad Address: %08x\n", p, image_get_load (hdr));
341570abb0aSMarian Balakowicz 	printf ("%sEntry Point:  %08x\n", p, image_get_ep (hdr));
3422242f536SMarian Balakowicz 
343570abb0aSMarian Balakowicz 	if (image_check_type (hdr, IH_TYPE_MULTI) ||
344570abb0aSMarian Balakowicz 			image_check_type (hdr, IH_TYPE_SCRIPT)) {
3452242f536SMarian Balakowicz 		int i;
3462242f536SMarian Balakowicz 		ulong data, len;
3472242f536SMarian Balakowicz 		ulong count = image_multi_count (hdr);
3482242f536SMarian Balakowicz 
349570abb0aSMarian Balakowicz 		printf ("%sContents:\n", p);
3502242f536SMarian Balakowicz 		for (i = 0; i < count; i++) {
3512242f536SMarian Balakowicz 			image_multi_getimg (hdr, i, &data, &len);
352570abb0aSMarian Balakowicz 
353570abb0aSMarian Balakowicz 			printf ("%s   Image %d: ", p, i);
354570abb0aSMarian Balakowicz 			genimg_print_size (len);
355570abb0aSMarian Balakowicz 
356570abb0aSMarian Balakowicz 			if (image_check_type (hdr, IH_TYPE_SCRIPT) && i > 0) {
357570abb0aSMarian Balakowicz 				/*
358570abb0aSMarian Balakowicz 				 * the user may need to know offsets
359570abb0aSMarian Balakowicz 				 * if planning to do something with
360570abb0aSMarian Balakowicz 				 * multiple files
361570abb0aSMarian Balakowicz 				 */
362570abb0aSMarian Balakowicz 				printf ("%s    Offset = 0x%08lx\n", p, data);
363570abb0aSMarian Balakowicz 			}
3642242f536SMarian Balakowicz 		}
3652242f536SMarian Balakowicz 	}
3662242f536SMarian Balakowicz }
3672242f536SMarian Balakowicz 
368570abb0aSMarian Balakowicz inline void image_print_contents (image_header_t *hdr)
369570abb0aSMarian Balakowicz {
370570abb0aSMarian Balakowicz 	__image_print_contents (hdr, "   ");
371570abb0aSMarian Balakowicz }
372570abb0aSMarian Balakowicz 
373570abb0aSMarian Balakowicz inline void image_print_contents_noindent (image_header_t *hdr)
374570abb0aSMarian Balakowicz {
375570abb0aSMarian Balakowicz 	__image_print_contents (hdr, "");
376570abb0aSMarian Balakowicz }
377570abb0aSMarian Balakowicz 
378570abb0aSMarian Balakowicz #ifndef USE_HOSTCC
3795ad03eb3SMarian Balakowicz /**
3805ad03eb3SMarian Balakowicz  * image_get_ramdisk - get and verify ramdisk image
3815ad03eb3SMarian Balakowicz  * @rd_addr: ramdisk image start address
3825ad03eb3SMarian Balakowicz  * @arch: expected ramdisk architecture
3835ad03eb3SMarian Balakowicz  * @verify: checksum verification flag
3845ad03eb3SMarian Balakowicz  *
3855ad03eb3SMarian Balakowicz  * image_get_ramdisk() returns a pointer to the verified ramdisk image
3865ad03eb3SMarian Balakowicz  * header. Routine receives image start address and expected architecture
3875ad03eb3SMarian Balakowicz  * flag. Verification done covers data and header integrity and os/type/arch
3885ad03eb3SMarian Balakowicz  * fields checking.
3895ad03eb3SMarian Balakowicz  *
3905ad03eb3SMarian Balakowicz  * If dataflash support is enabled routine checks for dataflash addresses
3915ad03eb3SMarian Balakowicz  * and handles required dataflash reads.
3925ad03eb3SMarian Balakowicz  *
3935ad03eb3SMarian Balakowicz  * returns:
3945ad03eb3SMarian Balakowicz  *     pointer to a ramdisk image header, if image was found and valid
395274cea2bSKumar Gala  *     otherwise, return NULL
3965ad03eb3SMarian Balakowicz  */
397d985c849SMarian Balakowicz static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
398d985c849SMarian Balakowicz 						int verify)
3995ad03eb3SMarian Balakowicz {
4005ad03eb3SMarian Balakowicz 	image_header_t *rd_hdr;
4015ad03eb3SMarian Balakowicz 
4025ad03eb3SMarian Balakowicz 	show_boot_progress (9);
4035ad03eb3SMarian Balakowicz 	rd_hdr = (image_header_t *)rd_addr;
4045ad03eb3SMarian Balakowicz 
4055ad03eb3SMarian Balakowicz 	if (!image_check_magic (rd_hdr)) {
4065ad03eb3SMarian Balakowicz 		puts ("Bad Magic Number\n");
4075ad03eb3SMarian Balakowicz 		show_boot_progress (-10);
408274cea2bSKumar Gala 		return NULL;
4095ad03eb3SMarian Balakowicz 	}
4105ad03eb3SMarian Balakowicz 
4115ad03eb3SMarian Balakowicz 	if (!image_check_hcrc (rd_hdr)) {
4125ad03eb3SMarian Balakowicz 		puts ("Bad Header Checksum\n");
4135ad03eb3SMarian Balakowicz 		show_boot_progress (-11);
414274cea2bSKumar Gala 		return NULL;
4155ad03eb3SMarian Balakowicz 	}
4165ad03eb3SMarian Balakowicz 
4175ad03eb3SMarian Balakowicz 	show_boot_progress (10);
4182242f536SMarian Balakowicz 	image_print_contents (rd_hdr);
4195ad03eb3SMarian Balakowicz 
4205ad03eb3SMarian Balakowicz 	if (verify) {
4215ad03eb3SMarian Balakowicz 		puts("   Verifying Checksum ... ");
4225ad03eb3SMarian Balakowicz 		if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) {
4235ad03eb3SMarian Balakowicz 			puts ("Bad Data CRC\n");
4245ad03eb3SMarian Balakowicz 			show_boot_progress (-12);
425274cea2bSKumar Gala 			return NULL;
4265ad03eb3SMarian Balakowicz 		}
4275ad03eb3SMarian Balakowicz 		puts("OK\n");
4285ad03eb3SMarian Balakowicz 	}
4295ad03eb3SMarian Balakowicz 
4305ad03eb3SMarian Balakowicz 	show_boot_progress (11);
4315ad03eb3SMarian Balakowicz 
4325ad03eb3SMarian Balakowicz 	if (!image_check_os (rd_hdr, IH_OS_LINUX) ||
4335ad03eb3SMarian Balakowicz 	    !image_check_arch (rd_hdr, arch) ||
4345ad03eb3SMarian Balakowicz 	    !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {
4355ad03eb3SMarian Balakowicz 		printf ("No Linux %s Ramdisk Image\n",
4369a4daad0SMarian Balakowicz 				genimg_get_arch_name(arch));
4375ad03eb3SMarian Balakowicz 		show_boot_progress (-13);
438274cea2bSKumar Gala 		return NULL;
4395ad03eb3SMarian Balakowicz 	}
4405ad03eb3SMarian Balakowicz 
4415ad03eb3SMarian Balakowicz 	return rd_hdr;
4425ad03eb3SMarian Balakowicz }
443570abb0aSMarian Balakowicz #endif /* !USE_HOSTCC */
4445ad03eb3SMarian Balakowicz 
4459a4daad0SMarian Balakowicz /*****************************************************************************/
4469a4daad0SMarian Balakowicz /* Shared dual-format routines */
4479a4daad0SMarian Balakowicz /*****************************************************************************/
448570abb0aSMarian Balakowicz #ifndef USE_HOSTCC
4499a4daad0SMarian Balakowicz int getenv_verify (void)
4509a4daad0SMarian Balakowicz {
4519a4daad0SMarian Balakowicz 	char *s = getenv ("verify");
4529a4daad0SMarian Balakowicz 	return (s && (*s == 'n')) ? 0 : 1;
4539a4daad0SMarian Balakowicz }
4549a4daad0SMarian Balakowicz 
4559a4daad0SMarian Balakowicz int getenv_autostart (void)
4569a4daad0SMarian Balakowicz {
4579a4daad0SMarian Balakowicz 	char *s = getenv ("autostart");
4589a4daad0SMarian Balakowicz 	return (s && (*s == 'n')) ? 0 : 1;
4599a4daad0SMarian Balakowicz }
4609a4daad0SMarian Balakowicz 
4619a4daad0SMarian Balakowicz ulong getenv_bootm_low(void)
4629a4daad0SMarian Balakowicz {
4639a4daad0SMarian Balakowicz 	char *s = getenv ("bootm_low");
4649a4daad0SMarian Balakowicz 	if (s) {
4659a4daad0SMarian Balakowicz 		ulong tmp = simple_strtoul (s, NULL, 16);
4669a4daad0SMarian Balakowicz 		return tmp;
4679a4daad0SMarian Balakowicz 	}
4689a4daad0SMarian Balakowicz 
4699a4daad0SMarian Balakowicz #ifdef CFG_SDRAM_BASE
4709a4daad0SMarian Balakowicz 	return CFG_SDRAM_BASE;
4719a4daad0SMarian Balakowicz #else
4729a4daad0SMarian Balakowicz 	return 0;
4739a4daad0SMarian Balakowicz #endif
4749a4daad0SMarian Balakowicz }
4759a4daad0SMarian Balakowicz 
4769a4daad0SMarian Balakowicz ulong getenv_bootm_size(void)
4779a4daad0SMarian Balakowicz {
4789a4daad0SMarian Balakowicz 	char *s = getenv ("bootm_size");
4799a4daad0SMarian Balakowicz 	if (s) {
4809a4daad0SMarian Balakowicz 		ulong tmp = simple_strtoul (s, NULL, 16);
4819a4daad0SMarian Balakowicz 		return tmp;
4829a4daad0SMarian Balakowicz 	}
4839a4daad0SMarian Balakowicz 
4849a4daad0SMarian Balakowicz 	return gd->bd->bi_memsize;
4859a4daad0SMarian Balakowicz }
4869a4daad0SMarian Balakowicz 
4879a4daad0SMarian Balakowicz void memmove_wd (void *to, void *from, size_t len, ulong chunksz)
4889a4daad0SMarian Balakowicz {
4899a4daad0SMarian Balakowicz #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
4909a4daad0SMarian Balakowicz 	while (len > 0) {
4919a4daad0SMarian Balakowicz 		size_t tail = (len > chunksz) ? chunksz : len;
4929a4daad0SMarian Balakowicz 		WATCHDOG_RESET ();
4939a4daad0SMarian Balakowicz 		memmove (to, from, tail);
4949a4daad0SMarian Balakowicz 		to += tail;
4959a4daad0SMarian Balakowicz 		from += tail;
4969a4daad0SMarian Balakowicz 		len -= tail;
4979a4daad0SMarian Balakowicz 	}
4989a4daad0SMarian Balakowicz #else	/* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
4999a4daad0SMarian Balakowicz 	memmove (to, from, len);
5009a4daad0SMarian Balakowicz #endif	/* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
5019a4daad0SMarian Balakowicz }
502570abb0aSMarian Balakowicz #endif /* !USE_HOSTCC */
503570abb0aSMarian Balakowicz 
504570abb0aSMarian Balakowicz static void genimg_print_size (uint32_t size)
505570abb0aSMarian Balakowicz {
506570abb0aSMarian Balakowicz #ifndef USE_HOSTCC
507570abb0aSMarian Balakowicz 	printf ("%d Bytes = ", size);
508570abb0aSMarian Balakowicz 	print_size (size, "\n");
509570abb0aSMarian Balakowicz #else
510570abb0aSMarian Balakowicz 	printf ("%d Bytes = %.2f kB = %.2f MB\n",
511570abb0aSMarian Balakowicz 			size, (double)size / 1.024e3,
512570abb0aSMarian Balakowicz 			(double)size / 1.048576e6);
513570abb0aSMarian Balakowicz #endif
514570abb0aSMarian Balakowicz }
515570abb0aSMarian Balakowicz 
516570abb0aSMarian Balakowicz #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
517570abb0aSMarian Balakowicz static void genimg_print_time (time_t timestamp)
518570abb0aSMarian Balakowicz {
519570abb0aSMarian Balakowicz #ifndef USE_HOSTCC
520570abb0aSMarian Balakowicz 	struct rtc_time tm;
521570abb0aSMarian Balakowicz 
522570abb0aSMarian Balakowicz 	to_tm (timestamp, &tm);
523570abb0aSMarian Balakowicz 	printf ("%4d-%02d-%02d  %2d:%02d:%02d UTC\n",
524570abb0aSMarian Balakowicz 			tm.tm_year, tm.tm_mon, tm.tm_mday,
525570abb0aSMarian Balakowicz 			tm.tm_hour, tm.tm_min, tm.tm_sec);
526570abb0aSMarian Balakowicz #else
527570abb0aSMarian Balakowicz 	printf ("%s", ctime(&timestamp));
528570abb0aSMarian Balakowicz #endif
529570abb0aSMarian Balakowicz }
530570abb0aSMarian Balakowicz #endif /* CONFIG_TIMESTAMP || CONFIG_CMD_DATE || USE_HOSTCC */
531570abb0aSMarian Balakowicz 
532570abb0aSMarian Balakowicz /**
533570abb0aSMarian Balakowicz  * get_table_entry_name - translate entry id to long name
534570abb0aSMarian Balakowicz  * @table: pointer to a translation table for entries of a specific type
535570abb0aSMarian Balakowicz  * @msg: message to be returned when translation fails
536570abb0aSMarian Balakowicz  * @id: entry id to be translated
537570abb0aSMarian Balakowicz  *
538570abb0aSMarian Balakowicz  * get_table_entry_name() will go over translation table trying to find
539570abb0aSMarian Balakowicz  * entry that matches given id. If matching entry is found, its long
540570abb0aSMarian Balakowicz  * name is returned to the caller.
541570abb0aSMarian Balakowicz  *
542570abb0aSMarian Balakowicz  * returns:
543570abb0aSMarian Balakowicz  *     long entry name if translation succeeds
544570abb0aSMarian Balakowicz  *     msg otherwise
545570abb0aSMarian Balakowicz  */
546570abb0aSMarian Balakowicz static char *get_table_entry_name (table_entry_t *table, char *msg, int id)
547570abb0aSMarian Balakowicz {
548570abb0aSMarian Balakowicz 	for (; table->id >= 0; ++table) {
549570abb0aSMarian Balakowicz 		if (table->id == id)
550570abb0aSMarian Balakowicz 			return (table->lname);
551570abb0aSMarian Balakowicz 	}
552570abb0aSMarian Balakowicz 	return (msg);
553570abb0aSMarian Balakowicz }
5549a4daad0SMarian Balakowicz 
5559a4daad0SMarian Balakowicz const char *genimg_get_os_name (uint8_t os)
5569a4daad0SMarian Balakowicz {
557570abb0aSMarian Balakowicz 	return (get_table_entry_name (uimage_os, "Unknown OS", os));
5589a4daad0SMarian Balakowicz }
5599a4daad0SMarian Balakowicz 
5609a4daad0SMarian Balakowicz const char *genimg_get_arch_name (uint8_t arch)
5619a4daad0SMarian Balakowicz {
562570abb0aSMarian Balakowicz 	return (get_table_entry_name (uimage_arch, "Unknown Architecture", arch));
5639a4daad0SMarian Balakowicz }
5649a4daad0SMarian Balakowicz 
5659a4daad0SMarian Balakowicz const char *genimg_get_type_name (uint8_t type)
5669a4daad0SMarian Balakowicz {
567570abb0aSMarian Balakowicz 	return (get_table_entry_name (uimage_type, "Unknown Image", type));
5689a4daad0SMarian Balakowicz }
5699a4daad0SMarian Balakowicz 
5709a4daad0SMarian Balakowicz const char *genimg_get_comp_name (uint8_t comp)
5719a4daad0SMarian Balakowicz {
572570abb0aSMarian Balakowicz 	return (get_table_entry_name (uimage_comp, "Unknown Compression", comp));
5739a4daad0SMarian Balakowicz }
5749a4daad0SMarian Balakowicz 
575570abb0aSMarian Balakowicz /**
576570abb0aSMarian Balakowicz  * get_table_entry_id - translate short entry name to id
577570abb0aSMarian Balakowicz  * @table: pointer to a translation table for entries of a specific type
578570abb0aSMarian Balakowicz  * @table_name: to be used in case of error
579570abb0aSMarian Balakowicz  * @name: entry short name to be translated
580570abb0aSMarian Balakowicz  *
581570abb0aSMarian Balakowicz  * get_table_entry_id() will go over translation table trying to find
582570abb0aSMarian Balakowicz  * entry that matches given short name. If matching entry is found,
583570abb0aSMarian Balakowicz  * its id returned to the caller.
584570abb0aSMarian Balakowicz  *
585570abb0aSMarian Balakowicz  * returns:
586570abb0aSMarian Balakowicz  *     entry id if translation succeeds
587570abb0aSMarian Balakowicz  *     -1 otherwise
588570abb0aSMarian Balakowicz  */
589570abb0aSMarian Balakowicz static int get_table_entry_id (table_entry_t *table,
590570abb0aSMarian Balakowicz 		const char *table_name, const char *name)
591570abb0aSMarian Balakowicz {
592570abb0aSMarian Balakowicz 	table_entry_t *t;
593570abb0aSMarian Balakowicz #ifdef USE_HOSTCC
594570abb0aSMarian Balakowicz 	int first = 1;
595570abb0aSMarian Balakowicz 
596570abb0aSMarian Balakowicz 	for (t = table; t->id >= 0; ++t) {
597570abb0aSMarian Balakowicz 		if (t->sname && strcasecmp(t->sname, name) == 0)
598570abb0aSMarian Balakowicz 			return (t->id);
5999a4daad0SMarian Balakowicz 	}
6009a4daad0SMarian Balakowicz 
601570abb0aSMarian Balakowicz 	fprintf (stderr, "\nInvalid %s Type - valid names are", table_name);
602570abb0aSMarian Balakowicz 	for (t = table; t->id >= 0; ++t) {
603570abb0aSMarian Balakowicz 		if (t->sname == NULL)
604570abb0aSMarian Balakowicz 			continue;
605570abb0aSMarian Balakowicz 		fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname);
606570abb0aSMarian Balakowicz 		first = 0;
607570abb0aSMarian Balakowicz 	}
608570abb0aSMarian Balakowicz 	fprintf (stderr, "\n");
609570abb0aSMarian Balakowicz #else
610570abb0aSMarian Balakowicz 	for (t = table; t->id >= 0; ++t) {
611570abb0aSMarian Balakowicz 		if (t->sname && strcmp(t->sname, name) == 0)
612570abb0aSMarian Balakowicz 			return (t->id);
613570abb0aSMarian Balakowicz 	}
614570abb0aSMarian Balakowicz 	debug ("Invalid %s Type: %s\n", table_name, name);
615570abb0aSMarian Balakowicz #endif /* USE_HOSTCC */
616570abb0aSMarian Balakowicz 	return (-1);
617570abb0aSMarian Balakowicz }
618570abb0aSMarian Balakowicz 
619570abb0aSMarian Balakowicz int genimg_get_os_id (const char *name)
620570abb0aSMarian Balakowicz {
621570abb0aSMarian Balakowicz 	return (get_table_entry_id (uimage_os, "OS", name));
622570abb0aSMarian Balakowicz }
623570abb0aSMarian Balakowicz 
624570abb0aSMarian Balakowicz int genimg_get_arch_id (const char *name)
625570abb0aSMarian Balakowicz {
626570abb0aSMarian Balakowicz 	return (get_table_entry_id (uimage_arch, "CPU", name));
627570abb0aSMarian Balakowicz }
628570abb0aSMarian Balakowicz 
629570abb0aSMarian Balakowicz int genimg_get_type_id (const char *name)
630570abb0aSMarian Balakowicz {
631570abb0aSMarian Balakowicz 	return (get_table_entry_id (uimage_type, "Image", name));
632570abb0aSMarian Balakowicz }
633570abb0aSMarian Balakowicz 
634570abb0aSMarian Balakowicz int genimg_get_comp_id (const char *name)
635570abb0aSMarian Balakowicz {
636570abb0aSMarian Balakowicz 	return (get_table_entry_id (uimage_comp, "Compression", name));
637570abb0aSMarian Balakowicz }
638570abb0aSMarian Balakowicz 
639570abb0aSMarian Balakowicz #ifndef USE_HOSTCC
6405ad03eb3SMarian Balakowicz /**
6419a4daad0SMarian Balakowicz  * genimg_get_format - get image format type
6429a4daad0SMarian Balakowicz  * @img_addr: image start address
6439a4daad0SMarian Balakowicz  *
6449a4daad0SMarian Balakowicz  * genimg_get_format() checks whether provided address points to a valid
6459a4daad0SMarian Balakowicz  * legacy or FIT image.
6469a4daad0SMarian Balakowicz  *
6479a4daad0SMarian Balakowicz  * New uImage format and FDT blob are based on a libfdt. FDT blob
6489a4daad0SMarian Balakowicz  * may be passed directly or embedded in a FIT image. In both situations
6499a4daad0SMarian Balakowicz  * genimg_get_format() must be able to dectect libfdt header.
6509a4daad0SMarian Balakowicz  *
6519a4daad0SMarian Balakowicz  * returns:
6529a4daad0SMarian Balakowicz  *     image format type or IMAGE_FORMAT_INVALID if no image is present
6539a4daad0SMarian Balakowicz  */
6549a4daad0SMarian Balakowicz int genimg_get_format (void *img_addr)
6559a4daad0SMarian Balakowicz {
6569a4daad0SMarian Balakowicz 	ulong		format = IMAGE_FORMAT_INVALID;
6579a4daad0SMarian Balakowicz 	image_header_t	*hdr;
6589a4daad0SMarian Balakowicz #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
6599a4daad0SMarian Balakowicz 	char		*fit_hdr;
6609a4daad0SMarian Balakowicz #endif
6619a4daad0SMarian Balakowicz 
6629a4daad0SMarian Balakowicz 	hdr = (image_header_t *)img_addr;
6639a4daad0SMarian Balakowicz 	if (image_check_magic(hdr))
6649a4daad0SMarian Balakowicz 		format = IMAGE_FORMAT_LEGACY;
6659a4daad0SMarian Balakowicz #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
6669a4daad0SMarian Balakowicz 	else {
6679a4daad0SMarian Balakowicz 		fit_hdr = (char *)img_addr;
6689a4daad0SMarian Balakowicz 		if (fdt_check_header (fit_hdr) == 0)
6699a4daad0SMarian Balakowicz 			format = IMAGE_FORMAT_FIT;
6709a4daad0SMarian Balakowicz 	}
6719a4daad0SMarian Balakowicz #endif
6729a4daad0SMarian Balakowicz 
6739a4daad0SMarian Balakowicz 	return format;
6749a4daad0SMarian Balakowicz }
6759a4daad0SMarian Balakowicz 
6769a4daad0SMarian Balakowicz /**
6779a4daad0SMarian Balakowicz  * genimg_get_image - get image from special storage (if necessary)
6789a4daad0SMarian Balakowicz  * @img_addr: image start address
6799a4daad0SMarian Balakowicz  *
6809a4daad0SMarian Balakowicz  * genimg_get_image() checks if provided image start adddress is located
6819a4daad0SMarian Balakowicz  * in a dataflash storage. If so, image is moved to a system RAM memory.
6829a4daad0SMarian Balakowicz  *
6839a4daad0SMarian Balakowicz  * returns:
6849a4daad0SMarian Balakowicz  *     image start address after possible relocation from special storage
6859a4daad0SMarian Balakowicz  */
6869a4daad0SMarian Balakowicz ulong genimg_get_image (ulong img_addr)
6879a4daad0SMarian Balakowicz {
6889a4daad0SMarian Balakowicz 	ulong ram_addr = img_addr;
6899a4daad0SMarian Balakowicz 
6909a4daad0SMarian Balakowicz #ifdef CONFIG_HAS_DATAFLASH
6919a4daad0SMarian Balakowicz 	ulong h_size, d_size;
6929a4daad0SMarian Balakowicz 
6939a4daad0SMarian Balakowicz 	if (addr_dataflash (img_addr)){
6949a4daad0SMarian Balakowicz 		/* ger RAM address */
6959a4daad0SMarian Balakowicz 		ram_addr = CFG_LOAD_ADDR;
6969a4daad0SMarian Balakowicz 
6979a4daad0SMarian Balakowicz 		/* get header size */
6989a4daad0SMarian Balakowicz 		h_size = image_get_header_size ();
6999a4daad0SMarian Balakowicz #if defined(CONFIG_FIT)
7009a4daad0SMarian Balakowicz 		if (sizeof(struct fdt_header) > h_size)
7019a4daad0SMarian Balakowicz 			h_size = sizeof(struct fdt_header);
7029a4daad0SMarian Balakowicz #endif
7039a4daad0SMarian Balakowicz 
7049a4daad0SMarian Balakowicz 		/* read in header */
7059a4daad0SMarian Balakowicz 		debug ("   Reading image header from dataflash address "
7069a4daad0SMarian Balakowicz 			"%08lx to RAM address %08lx\n", img_addr, ram_addr);
7079a4daad0SMarian Balakowicz 
7089a4daad0SMarian Balakowicz 		read_dataflash (img_addr, h_size, (char *)ram_addr);
7099a4daad0SMarian Balakowicz 
7109a4daad0SMarian Balakowicz 		/* get data size */
7119a4daad0SMarian Balakowicz 		switch (genimg_get_format ((void *)ram_addr)) {
7129a4daad0SMarian Balakowicz 		case IMAGE_FORMAT_LEGACY:
7139a4daad0SMarian Balakowicz 			d_size = image_get_data_size ((image_header_t *)ram_addr);
7149a4daad0SMarian Balakowicz 			debug ("   Legacy format image found at 0x%08lx, size 0x%08lx\n",
7159a4daad0SMarian Balakowicz 					ram_addr, d_size);
7169a4daad0SMarian Balakowicz 			break;
7179a4daad0SMarian Balakowicz #if defined(CONFIG_FIT)
7189a4daad0SMarian Balakowicz 		case IMAGE_FORMAT_FIT:
7195dfb5213SMarian Balakowicz 			d_size = fit_get_size ((const void *)ram_addr) - h_size;
7209a4daad0SMarian Balakowicz 			debug ("   FIT/FDT format image found at 0x%08lx, size 0x%08lx\n",
7219a4daad0SMarian Balakowicz 					ram_addr, d_size);
7229a4daad0SMarian Balakowicz 			break;
7239a4daad0SMarian Balakowicz #endif
7249a4daad0SMarian Balakowicz 		default:
7259a4daad0SMarian Balakowicz 			printf ("   No valid image found at 0x%08lx\n", img_addr);
7269a4daad0SMarian Balakowicz 			return ram_addr;
7279a4daad0SMarian Balakowicz 		}
7289a4daad0SMarian Balakowicz 
7299a4daad0SMarian Balakowicz 		/* read in image data */
7309a4daad0SMarian Balakowicz 		debug ("   Reading image remaining data from dataflash address "
7319a4daad0SMarian Balakowicz 			"%08lx to RAM address %08lx\n", img_addr + h_size,
7329a4daad0SMarian Balakowicz 			ram_addr + h_size);
7339a4daad0SMarian Balakowicz 
7349a4daad0SMarian Balakowicz 		read_dataflash (img_addr + h_size, d_size,
7359a4daad0SMarian Balakowicz 				(char *)(ram_addr + h_size));
7369a4daad0SMarian Balakowicz 
7379a4daad0SMarian Balakowicz 	}
7389a4daad0SMarian Balakowicz #endif /* CONFIG_HAS_DATAFLASH */
7399a4daad0SMarian Balakowicz 
7409a4daad0SMarian Balakowicz 	return ram_addr;
7419a4daad0SMarian Balakowicz }
7429a4daad0SMarian Balakowicz 
7439a4daad0SMarian Balakowicz /**
7449a4daad0SMarian Balakowicz  * boot_get_ramdisk - main ramdisk handling routine
7455ad03eb3SMarian Balakowicz  * @argc: command argument count
7465ad03eb3SMarian Balakowicz  * @argv: command argument list
7478a5ea3e6SMarian Balakowicz  * @images: pointer to the bootm images structure
7485ad03eb3SMarian Balakowicz  * @arch: expected ramdisk architecture
7495ad03eb3SMarian Balakowicz  * @rd_start: pointer to a ulong variable, will hold ramdisk start address
7505ad03eb3SMarian Balakowicz  * @rd_end: pointer to a ulong variable, will hold ramdisk end
7515ad03eb3SMarian Balakowicz  *
7529a4daad0SMarian Balakowicz  * boot_get_ramdisk() is responsible for finding a valid ramdisk image.
7535ad03eb3SMarian Balakowicz  * Curently supported are the following ramdisk sources:
7545ad03eb3SMarian Balakowicz  *      - multicomponent kernel/ramdisk image,
7555ad03eb3SMarian Balakowicz  *      - commandline provided address of decicated ramdisk image.
7565ad03eb3SMarian Balakowicz  *
7575ad03eb3SMarian Balakowicz  * returns:
758d985c849SMarian Balakowicz  *     0, if ramdisk image was found and valid, or skiped
7595ad03eb3SMarian Balakowicz  *     rd_start and rd_end are set to ramdisk start/end addresses if
7605ad03eb3SMarian Balakowicz  *     ramdisk image is found and valid
761d985c849SMarian Balakowicz  *
762d985c849SMarian Balakowicz  *     1, if ramdisk image is found but corrupted
7635ad03eb3SMarian Balakowicz  *     rd_start and rd_end are set to 0 if no ramdisk exists
7645ad03eb3SMarian Balakowicz  */
765d985c849SMarian Balakowicz int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
766d985c849SMarian Balakowicz 		uint8_t arch, ulong *rd_start, ulong *rd_end)
7675ad03eb3SMarian Balakowicz {
768d5934ad7SMarian Balakowicz 	ulong rd_addr, rd_load;
7695ad03eb3SMarian Balakowicz 	ulong rd_data, rd_len;
7705ad03eb3SMarian Balakowicz 	image_header_t *rd_hdr;
771d5934ad7SMarian Balakowicz #if defined(CONFIG_FIT)
772d5934ad7SMarian Balakowicz 	void		*fit_hdr;
773d5934ad7SMarian Balakowicz 	const char	*fit_uname_config = NULL;
774d5934ad7SMarian Balakowicz 	const char	*fit_uname_ramdisk = NULL;
775d5934ad7SMarian Balakowicz 	ulong		default_addr;
776c8779648SMarian Balakowicz 	int		rd_noffset;
777c8779648SMarian Balakowicz 	int		conf_noffset;
778c8779648SMarian Balakowicz 	const void	*data;
779c8779648SMarian Balakowicz 	size_t		size;
780d5934ad7SMarian Balakowicz #endif
7815ad03eb3SMarian Balakowicz 
782c8779648SMarian Balakowicz 	*rd_start = 0;
783c8779648SMarian Balakowicz 	*rd_end = 0;
784c8779648SMarian Balakowicz 
7855ad03eb3SMarian Balakowicz 	/*
7865ad03eb3SMarian Balakowicz 	 * Look for a '-' which indicates to ignore the
7875ad03eb3SMarian Balakowicz 	 * ramdisk argument
7885ad03eb3SMarian Balakowicz 	 */
789d5934ad7SMarian Balakowicz 	if ((argc >= 3) && (strcmp(argv[2], "-") ==  0)) {
7905ad03eb3SMarian Balakowicz 		debug ("## Skipping init Ramdisk\n");
7915ad03eb3SMarian Balakowicz 		rd_len = rd_data = 0;
792d5934ad7SMarian Balakowicz 	} else if (argc >= 3) {
793d5934ad7SMarian Balakowicz #if defined(CONFIG_FIT)
794d5934ad7SMarian Balakowicz 		/*
795d5934ad7SMarian Balakowicz 		 * If the init ramdisk comes from the FIT image and the FIT image
796d5934ad7SMarian Balakowicz 		 * address is omitted in the command line argument, try to use
797d5934ad7SMarian Balakowicz 		 * os FIT image address or default load address.
798d5934ad7SMarian Balakowicz 		 */
799d5934ad7SMarian Balakowicz 		if (images->fit_uname_os)
800d5934ad7SMarian Balakowicz 			default_addr = (ulong)images->fit_hdr_os;
801d5934ad7SMarian Balakowicz 		else
802d5934ad7SMarian Balakowicz 			default_addr = load_addr;
803d5934ad7SMarian Balakowicz 
804d5934ad7SMarian Balakowicz 		if (fit_parse_conf (argv[2], default_addr,
805d5934ad7SMarian Balakowicz 					&rd_addr, &fit_uname_config)) {
806d5934ad7SMarian Balakowicz 			debug ("*  ramdisk: config '%s' from image at 0x%08lx\n",
807d5934ad7SMarian Balakowicz 					fit_uname_config, rd_addr);
808d5934ad7SMarian Balakowicz 		} else if (fit_parse_subimage (argv[2], default_addr,
809d5934ad7SMarian Balakowicz 					&rd_addr, &fit_uname_ramdisk)) {
810d5934ad7SMarian Balakowicz 			debug ("*  ramdisk: subimage '%s' from image at 0x%08lx\n",
811d5934ad7SMarian Balakowicz 					fit_uname_ramdisk, rd_addr);
812d5934ad7SMarian Balakowicz 		} else
813d5934ad7SMarian Balakowicz #endif
814d5934ad7SMarian Balakowicz 		{
815d5934ad7SMarian Balakowicz 			rd_addr = simple_strtoul(argv[2], NULL, 16);
816d5934ad7SMarian Balakowicz 			debug ("*  ramdisk: cmdline image address = 0x%08lx\n",
817d5934ad7SMarian Balakowicz 					rd_addr);
818d5934ad7SMarian Balakowicz 		}
819d5934ad7SMarian Balakowicz 
820d5934ad7SMarian Balakowicz 		/* copy from dataflash if needed */
8219a4daad0SMarian Balakowicz 		rd_addr = genimg_get_image (rd_addr);
822d5934ad7SMarian Balakowicz 
8235ad03eb3SMarian Balakowicz 		/*
8245ad03eb3SMarian Balakowicz 		 * Check if there is an initrd image at the
8255ad03eb3SMarian Balakowicz 		 * address provided in the second bootm argument
826d5934ad7SMarian Balakowicz 		 * check image type, for FIT images get FIT node.
8275ad03eb3SMarian Balakowicz 		 */
8289a4daad0SMarian Balakowicz 		switch (genimg_get_format ((void *)rd_addr)) {
829d5934ad7SMarian Balakowicz 		case IMAGE_FORMAT_LEGACY:
830c8779648SMarian Balakowicz 			printf ("## Loading init Ramdisk from Legacy "
831c8779648SMarian Balakowicz 					"Image at %08lx ...\n", rd_addr);
8325ad03eb3SMarian Balakowicz 
833d985c849SMarian Balakowicz 			rd_hdr = image_get_ramdisk (rd_addr, arch,
834d985c849SMarian Balakowicz 							images->verify);
8355ad03eb3SMarian Balakowicz 
836c8779648SMarian Balakowicz 			if (rd_hdr == NULL)
837274cea2bSKumar Gala 				return 1;
838274cea2bSKumar Gala 
8395ad03eb3SMarian Balakowicz 			rd_data = image_get_data (rd_hdr);
8405ad03eb3SMarian Balakowicz 			rd_len = image_get_data_size (rd_hdr);
841d5934ad7SMarian Balakowicz 			rd_load = image_get_load (rd_hdr);
842d5934ad7SMarian Balakowicz 			break;
843d5934ad7SMarian Balakowicz #if defined(CONFIG_FIT)
844d5934ad7SMarian Balakowicz 		case IMAGE_FORMAT_FIT:
845d5934ad7SMarian Balakowicz 			fit_hdr = (void *)rd_addr;
846c8779648SMarian Balakowicz 			printf ("## Loading init Ramdisk from FIT "
847c8779648SMarian Balakowicz 					"Image at %08lx ...\n", rd_addr);
848c8779648SMarian Balakowicz 
849c8779648SMarian Balakowicz 			if (!fit_check_format (fit_hdr)) {
850c8779648SMarian Balakowicz 				puts ("Bad FIT ramdisk image format!\n");
851c8779648SMarian Balakowicz 				return 0;
852c8779648SMarian Balakowicz 			}
853c8779648SMarian Balakowicz 
854c8779648SMarian Balakowicz 			if (!fit_uname_ramdisk) {
855c8779648SMarian Balakowicz 				/*
856c8779648SMarian Balakowicz 				 * no ramdisk image node unit name, try to get config
857c8779648SMarian Balakowicz 				 * node first. If config unit node name is NULL
858c8779648SMarian Balakowicz 				 * fit_conf_get_node() will try to find default config node
859c8779648SMarian Balakowicz 				 */
860c8779648SMarian Balakowicz 				conf_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
861c8779648SMarian Balakowicz 				if (conf_noffset < 0)
862c8779648SMarian Balakowicz 					return 0;
863c8779648SMarian Balakowicz 
864c8779648SMarian Balakowicz 				rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, conf_noffset);
865c8779648SMarian Balakowicz 				fit_uname_ramdisk = fit_get_name (fit_hdr, rd_noffset, NULL);
866c8779648SMarian Balakowicz 			} else {
867c8779648SMarian Balakowicz 				/* get ramdisk component image node offset */
868c8779648SMarian Balakowicz 				rd_noffset = fit_image_get_node (fit_hdr, fit_uname_ramdisk);
869c8779648SMarian Balakowicz 			}
870c8779648SMarian Balakowicz 			if (rd_noffset < 0)
871c8779648SMarian Balakowicz 				return 0;
872c8779648SMarian Balakowicz 
873c8779648SMarian Balakowicz 			printf ("   Trying '%s' ramdisk subimage\n", fit_uname_ramdisk);
874c8779648SMarian Balakowicz 
875c8779648SMarian Balakowicz 			if (!fit_check_ramdisk (fit_hdr, rd_noffset, arch, images->verify))
876c8779648SMarian Balakowicz 				return 0;
877c8779648SMarian Balakowicz 
878c8779648SMarian Balakowicz 			/* get ramdisk image data address and length */
879c8779648SMarian Balakowicz 			if (fit_image_get_data (fit_hdr, rd_noffset, &data, &size)) {
880c8779648SMarian Balakowicz 				puts ("Could not find ramdisk subimage data!\n");
881c8779648SMarian Balakowicz 				return 0;
882c8779648SMarian Balakowicz 			}
883c8779648SMarian Balakowicz 
884c8779648SMarian Balakowicz 			rd_data = (ulong)data;
885c8779648SMarian Balakowicz 			rd_len = size;
886c8779648SMarian Balakowicz 
887c8779648SMarian Balakowicz 			if (fit_image_get_load (fit_hdr, rd_noffset, &rd_load)) {
888c8779648SMarian Balakowicz 				puts ("Can't get ramdisk subimage load address!\n");
889c8779648SMarian Balakowicz 				return 0;
890c8779648SMarian Balakowicz 			}
891c8779648SMarian Balakowicz 
892c8779648SMarian Balakowicz 			images->fit_hdr_rd = fit_hdr;
893c8779648SMarian Balakowicz 			images->fit_uname_rd = fit_uname_ramdisk;
894*3dfe1101SMarian Balakowicz 			images->fit_noffset_rd = rd_noffset;
895c8779648SMarian Balakowicz 			break;
896d5934ad7SMarian Balakowicz #endif
897d5934ad7SMarian Balakowicz 		default:
898d985c849SMarian Balakowicz 			puts ("Wrong Ramdisk Image Format\n");
899c8779648SMarian Balakowicz 			rd_data = rd_len = rd_load = 0;
900d5934ad7SMarian Balakowicz 		}
9015ad03eb3SMarian Balakowicz 
9025ad03eb3SMarian Balakowicz #if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO)
9035ad03eb3SMarian Balakowicz 		/*
904d5934ad7SMarian Balakowicz 		 * We need to copy the ramdisk to SRAM to let Linux boot
9055ad03eb3SMarian Balakowicz 		 */
906d5934ad7SMarian Balakowicz 		if (rd_data) {
907d5934ad7SMarian Balakowicz 			memmove ((void *)rd_load, (uchar *)rd_data, rd_len);
908d5934ad7SMarian Balakowicz 			rd_data = rd_load;
9095ad03eb3SMarian Balakowicz 		}
910d5934ad7SMarian Balakowicz #endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */
9115ad03eb3SMarian Balakowicz 
912d5934ad7SMarian Balakowicz 	} else if (images->legacy_hdr_valid &&
913d5934ad7SMarian Balakowicz 			image_check_type (images->legacy_hdr_os, IH_TYPE_MULTI)) {
9145ad03eb3SMarian Balakowicz 		/*
915d5934ad7SMarian Balakowicz 		 * Now check if we have a legacy mult-component image,
916d5934ad7SMarian Balakowicz 		 * get second entry data start address and len.
9175ad03eb3SMarian Balakowicz 		 */
9185ad03eb3SMarian Balakowicz 		show_boot_progress (13);
9195ad03eb3SMarian Balakowicz 		printf ("## Loading init Ramdisk from multi component "
920c8779648SMarian Balakowicz 				"Legacy Image at %08lx ...\n",
921d5934ad7SMarian Balakowicz 				(ulong)images->legacy_hdr_os);
922d5934ad7SMarian Balakowicz 
923d5934ad7SMarian Balakowicz 		image_multi_getimg (images->legacy_hdr_os, 1, &rd_data, &rd_len);
9245ad03eb3SMarian Balakowicz 	} else {
9255ad03eb3SMarian Balakowicz 		/*
9265ad03eb3SMarian Balakowicz 		 * no initrd image
9275ad03eb3SMarian Balakowicz 		 */
9285ad03eb3SMarian Balakowicz 		show_boot_progress (14);
9295ad03eb3SMarian Balakowicz 		rd_len = rd_data = 0;
9305ad03eb3SMarian Balakowicz 	}
9315ad03eb3SMarian Balakowicz 
9325ad03eb3SMarian Balakowicz 	if (!rd_data) {
9335ad03eb3SMarian Balakowicz 		debug ("## No init Ramdisk\n");
9345ad03eb3SMarian Balakowicz 	} else {
9355ad03eb3SMarian Balakowicz 		*rd_start = rd_data;
9365ad03eb3SMarian Balakowicz 		*rd_end = rd_data + rd_len;
9375ad03eb3SMarian Balakowicz 	}
9385ad03eb3SMarian Balakowicz 	debug ("   ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n",
9395ad03eb3SMarian Balakowicz 			*rd_start, *rd_end);
940274cea2bSKumar Gala 
941274cea2bSKumar Gala 	return 0;
9425ad03eb3SMarian Balakowicz }
943ceaed2b1SMarian Balakowicz 
944ceaed2b1SMarian Balakowicz #if defined(CONFIG_PPC) || defined(CONFIG_M68K)
945ceaed2b1SMarian Balakowicz /**
9469a4daad0SMarian Balakowicz  * boot_ramdisk_high - relocate init ramdisk
947e822d7fcSKumar Gala  * @lmb: pointer to lmb handle, will be used for memory mgmt
948ceaed2b1SMarian Balakowicz  * @rd_data: ramdisk data start address
949ceaed2b1SMarian Balakowicz  * @rd_len: ramdisk data length
950ceaed2b1SMarian Balakowicz  * @initrd_start: pointer to a ulong variable, will hold final init ramdisk
951ceaed2b1SMarian Balakowicz  *      start address (after possible relocation)
952ceaed2b1SMarian Balakowicz  * @initrd_end: pointer to a ulong variable, will hold final init ramdisk
953ceaed2b1SMarian Balakowicz  *      end address (after possible relocation)
954ceaed2b1SMarian Balakowicz  *
9559a4daad0SMarian Balakowicz  * boot_ramdisk_high() takes a relocation hint from "initrd_high" environement
956ceaed2b1SMarian Balakowicz  * variable and if requested ramdisk data is moved to a specified location.
957ceaed2b1SMarian Balakowicz  *
9589a4daad0SMarian Balakowicz  * Initrd_start and initrd_end are set to final (after relocation) ramdisk
9599a4daad0SMarian Balakowicz  * start/end addresses if ramdisk image start and len were provided,
9609a4daad0SMarian Balakowicz  * otherwise set initrd_start and initrd_end set to zeros.
9619a4daad0SMarian Balakowicz  *
962ceaed2b1SMarian Balakowicz  * returns:
963e822d7fcSKumar Gala  *      0 - success
964e822d7fcSKumar Gala  *     -1 - failure
965ceaed2b1SMarian Balakowicz  */
9669a4daad0SMarian Balakowicz int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
967b6b0fe64SMarian Balakowicz 		  ulong *initrd_start, ulong *initrd_end)
968ceaed2b1SMarian Balakowicz {
969ceaed2b1SMarian Balakowicz 	char	*s;
970ceaed2b1SMarian Balakowicz 	ulong	initrd_high;
971ceaed2b1SMarian Balakowicz 	int	initrd_copy_to_ram = 1;
972ceaed2b1SMarian Balakowicz 
973ceaed2b1SMarian Balakowicz 	if ((s = getenv ("initrd_high")) != NULL) {
974ceaed2b1SMarian Balakowicz 		/* a value of "no" or a similar string will act like 0,
975ceaed2b1SMarian Balakowicz 		 * turning the "load high" feature off. This is intentional.
976ceaed2b1SMarian Balakowicz 		 */
977ceaed2b1SMarian Balakowicz 		initrd_high = simple_strtoul (s, NULL, 16);
978ceaed2b1SMarian Balakowicz 		if (initrd_high == ~0)
979ceaed2b1SMarian Balakowicz 			initrd_copy_to_ram = 0;
980ceaed2b1SMarian Balakowicz 	} else {
981ceaed2b1SMarian Balakowicz 		/* not set, no restrictions to load high */
982ceaed2b1SMarian Balakowicz 		initrd_high = ~0;
983ceaed2b1SMarian Balakowicz 	}
984ceaed2b1SMarian Balakowicz 
985ceaed2b1SMarian Balakowicz 	debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
986ceaed2b1SMarian Balakowicz 			initrd_high, initrd_copy_to_ram);
987ceaed2b1SMarian Balakowicz 
988ceaed2b1SMarian Balakowicz 	if (rd_data) {
989ceaed2b1SMarian Balakowicz 		if (!initrd_copy_to_ram) {	/* zero-copy ramdisk support */
990ceaed2b1SMarian Balakowicz 			debug ("   in-place initrd\n");
991ceaed2b1SMarian Balakowicz 			*initrd_start = rd_data;
992ceaed2b1SMarian Balakowicz 			*initrd_end = rd_data + rd_len;
993e822d7fcSKumar Gala 			lmb_reserve(lmb, rd_data, rd_len);
994ceaed2b1SMarian Balakowicz 		} else {
995e822d7fcSKumar Gala 			if (initrd_high)
996e822d7fcSKumar Gala 				*initrd_start = lmb_alloc_base (lmb, rd_len, 0x1000, initrd_high);
997e822d7fcSKumar Gala 			else
998e822d7fcSKumar Gala 				*initrd_start = lmb_alloc (lmb, rd_len, 0x1000);
999ceaed2b1SMarian Balakowicz 
1000e822d7fcSKumar Gala 			if (*initrd_start == 0) {
1001e822d7fcSKumar Gala 				puts ("ramdisk - allocation error\n");
1002e822d7fcSKumar Gala 				goto error;
1003b6b0fe64SMarian Balakowicz 			}
1004ceaed2b1SMarian Balakowicz 			show_boot_progress (12);
1005ceaed2b1SMarian Balakowicz 
1006ceaed2b1SMarian Balakowicz 			*initrd_end = *initrd_start + rd_len;
1007ceaed2b1SMarian Balakowicz 			printf ("   Loading Ramdisk to %08lx, end %08lx ... ",
1008ceaed2b1SMarian Balakowicz 					*initrd_start, *initrd_end);
1009ceaed2b1SMarian Balakowicz 
1010ceaed2b1SMarian Balakowicz 			memmove_wd ((void *)*initrd_start,
1011ceaed2b1SMarian Balakowicz 					(void *)rd_data, rd_len, CHUNKSZ);
1012ceaed2b1SMarian Balakowicz 
1013ceaed2b1SMarian Balakowicz 			puts ("OK\n");
1014ceaed2b1SMarian Balakowicz 		}
1015ceaed2b1SMarian Balakowicz 	} else {
1016ceaed2b1SMarian Balakowicz 		*initrd_start = 0;
1017ceaed2b1SMarian Balakowicz 		*initrd_end = 0;
1018ceaed2b1SMarian Balakowicz 	}
1019ceaed2b1SMarian Balakowicz 	debug ("   ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
1020ceaed2b1SMarian Balakowicz 			*initrd_start, *initrd_end);
10219a4daad0SMarian Balakowicz 
1022e822d7fcSKumar Gala 	return 0;
1023b6b0fe64SMarian Balakowicz 
1024e822d7fcSKumar Gala error:
1025e822d7fcSKumar Gala 	return -1;
1026b6b0fe64SMarian Balakowicz }
1027b6b0fe64SMarian Balakowicz 
1028b6b0fe64SMarian Balakowicz /**
10299a4daad0SMarian Balakowicz  * boot_get_cmdline - allocate and initialize kernel cmdline
1030e822d7fcSKumar Gala  * @lmb: pointer to lmb handle, will be used for memory mgmt
1031b6b0fe64SMarian Balakowicz  * @cmd_start: pointer to a ulong variable, will hold cmdline start
1032b6b0fe64SMarian Balakowicz  * @cmd_end: pointer to a ulong variable, will hold cmdline end
1033e822d7fcSKumar Gala  * @bootmap_base: ulong variable, holds offset in physical memory to
1034e822d7fcSKumar Gala  * base of bootmap
1035b6b0fe64SMarian Balakowicz  *
10369a4daad0SMarian Balakowicz  * boot_get_cmdline() allocates space for kernel command line below
1037e822d7fcSKumar Gala  * BOOTMAPSZ + bootmap_base address. If "bootargs" U-boot environemnt
1038b6b0fe64SMarian Balakowicz  * variable is present its contents is copied to allocated kernel
1039b6b0fe64SMarian Balakowicz  * command line.
1040b6b0fe64SMarian Balakowicz  *
1041b6b0fe64SMarian Balakowicz  * returns:
1042e822d7fcSKumar Gala  *      0 - success
1043e822d7fcSKumar Gala  *     -1 - failure
1044b6b0fe64SMarian Balakowicz  */
10459a4daad0SMarian Balakowicz int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
1046e822d7fcSKumar Gala 			ulong bootmap_base)
1047b6b0fe64SMarian Balakowicz {
1048b6b0fe64SMarian Balakowicz 	char *cmdline;
1049b6b0fe64SMarian Balakowicz 	char *s;
1050b6b0fe64SMarian Balakowicz 
1051e822d7fcSKumar Gala 	cmdline = (char *)lmb_alloc_base(lmb, CFG_BARGSIZE, 0xf,
1052e822d7fcSKumar Gala 					 CFG_BOOTMAPSZ + bootmap_base);
1053e822d7fcSKumar Gala 
1054e822d7fcSKumar Gala 	if (cmdline == NULL)
1055e822d7fcSKumar Gala 		return -1;
1056b6b0fe64SMarian Balakowicz 
1057b6b0fe64SMarian Balakowicz 	if ((s = getenv("bootargs")) == NULL)
1058b6b0fe64SMarian Balakowicz 		s = "";
1059b6b0fe64SMarian Balakowicz 
1060b6b0fe64SMarian Balakowicz 	strcpy(cmdline, s);
1061b6b0fe64SMarian Balakowicz 
1062b6b0fe64SMarian Balakowicz 	*cmd_start = (ulong) & cmdline[0];
1063b6b0fe64SMarian Balakowicz 	*cmd_end = *cmd_start + strlen(cmdline);
1064b6b0fe64SMarian Balakowicz 
1065b6b0fe64SMarian Balakowicz 	debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);
1066b6b0fe64SMarian Balakowicz 
1067e822d7fcSKumar Gala 	return 0;
1068b6b0fe64SMarian Balakowicz }
1069b6b0fe64SMarian Balakowicz 
1070b6b0fe64SMarian Balakowicz /**
10719a4daad0SMarian Balakowicz  * boot_get_kbd - allocate and initialize kernel copy of board info
1072e822d7fcSKumar Gala  * @lmb: pointer to lmb handle, will be used for memory mgmt
1073b6b0fe64SMarian Balakowicz  * @kbd: double pointer to board info data
1074e822d7fcSKumar Gala  * @bootmap_base: ulong variable, holds offset in physical memory to
1075e822d7fcSKumar Gala  * base of bootmap
1076b6b0fe64SMarian Balakowicz  *
10779a4daad0SMarian Balakowicz  * boot_get_kbd() allocates space for kernel copy of board info data below
1078e822d7fcSKumar Gala  * BOOTMAPSZ + bootmap_base address and kernel board info is initialized with
1079e822d7fcSKumar Gala  * the current u-boot board info data.
1080b6b0fe64SMarian Balakowicz  *
1081b6b0fe64SMarian Balakowicz  * returns:
1082e822d7fcSKumar Gala  *      0 - success
1083e822d7fcSKumar Gala  *     -1 - failure
1084b6b0fe64SMarian Balakowicz  */
10859a4daad0SMarian Balakowicz int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base)
1086b6b0fe64SMarian Balakowicz {
1087e822d7fcSKumar Gala 	*kbd = (bd_t *)lmb_alloc_base(lmb, sizeof(bd_t), 0xf,
1088e822d7fcSKumar Gala 				      CFG_BOOTMAPSZ + bootmap_base);
1089e822d7fcSKumar Gala 	if (*kbd == NULL)
1090e822d7fcSKumar Gala 		return -1;
1091e822d7fcSKumar Gala 
1092b6b0fe64SMarian Balakowicz 	**kbd = *(gd->bd);
1093b6b0fe64SMarian Balakowicz 
1094b6b0fe64SMarian Balakowicz 	debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd);
1095b6b0fe64SMarian Balakowicz 
1096b6b0fe64SMarian Balakowicz #if defined(DEBUG) && defined(CONFIG_CMD_BDI)
1097b6b0fe64SMarian Balakowicz 	do_bdinfo(NULL, 0, 0, NULL);
1098b6b0fe64SMarian Balakowicz #endif
1099b6b0fe64SMarian Balakowicz 
1100e822d7fcSKumar Gala 	return 0;
1101ceaed2b1SMarian Balakowicz }
1102ceaed2b1SMarian Balakowicz #endif /* CONFIG_PPC || CONFIG_M68K */
11035dfb5213SMarian Balakowicz #endif /* !USE_HOSTCC */
11045ad03eb3SMarian Balakowicz 
1105f50433d6SMarian Balakowicz #if defined(CONFIG_FIT)
1106f50433d6SMarian Balakowicz /*****************************************************************************/
1107f50433d6SMarian Balakowicz /* New uImage format routines */
1108f50433d6SMarian Balakowicz /*****************************************************************************/
11095dfb5213SMarian Balakowicz #ifndef USE_HOSTCC
1110f50433d6SMarian Balakowicz static int fit_parse_spec (const char *spec, char sepc, ulong addr_curr,
1111f50433d6SMarian Balakowicz 		ulong *addr, const char **name)
1112f50433d6SMarian Balakowicz {
1113f50433d6SMarian Balakowicz 	const char *sep;
1114f50433d6SMarian Balakowicz 
1115f50433d6SMarian Balakowicz 	*addr = addr_curr;
1116f50433d6SMarian Balakowicz 	*name = NULL;
1117f50433d6SMarian Balakowicz 
1118f50433d6SMarian Balakowicz 	sep = strchr (spec, sepc);
1119f50433d6SMarian Balakowicz 	if (sep) {
1120f50433d6SMarian Balakowicz 		if (sep - spec > 0)
1121f50433d6SMarian Balakowicz 			*addr = simple_strtoul (spec, NULL, 16);
1122f50433d6SMarian Balakowicz 
1123f50433d6SMarian Balakowicz 		*name = sep + 1;
1124f50433d6SMarian Balakowicz 		return 1;
1125f50433d6SMarian Balakowicz 	}
1126f50433d6SMarian Balakowicz 
1127f50433d6SMarian Balakowicz 	return 0;
1128f50433d6SMarian Balakowicz }
1129f50433d6SMarian Balakowicz 
1130f50433d6SMarian Balakowicz /**
1131f50433d6SMarian Balakowicz  * fit_parse_conf - parse FIT configuration spec
1132f50433d6SMarian Balakowicz  * @spec: input string, containing configuration spec
1133f50433d6SMarian Balakowicz  * @add_curr: current image address (to be used as a possible default)
1134f50433d6SMarian Balakowicz  * @addr: pointer to a ulong variable, will hold FIT image address of a given
1135f50433d6SMarian Balakowicz  * configuration
1136f50433d6SMarian Balakowicz  * @conf_name double pointer to a char, will hold pointer to a configuration
1137f50433d6SMarian Balakowicz  * unit name
1138f50433d6SMarian Balakowicz  *
1139f50433d6SMarian Balakowicz  * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>,
1140f50433d6SMarian Balakowicz  * where <addr> is a FIT image address that contains configuration
1141f50433d6SMarian Balakowicz  * with a <conf> unit name.
1142f50433d6SMarian Balakowicz  *
1143f50433d6SMarian Balakowicz  * Address part is optional, and if omitted default add_curr will
1144f50433d6SMarian Balakowicz  * be used instead.
1145f50433d6SMarian Balakowicz  *
1146f50433d6SMarian Balakowicz  * returns:
1147f50433d6SMarian Balakowicz  *     1 if spec is a valid configuration string,
1148f50433d6SMarian Balakowicz  *     addr and conf_name are set accordingly
1149f50433d6SMarian Balakowicz  *     0 otherwise
1150f50433d6SMarian Balakowicz  */
1151f50433d6SMarian Balakowicz inline int fit_parse_conf (const char *spec, ulong addr_curr,
1152f50433d6SMarian Balakowicz 		ulong *addr, const char **conf_name)
1153f50433d6SMarian Balakowicz {
1154f50433d6SMarian Balakowicz 	return fit_parse_spec (spec, '#', addr_curr, addr, conf_name);
1155f50433d6SMarian Balakowicz }
1156f50433d6SMarian Balakowicz 
1157f50433d6SMarian Balakowicz /**
1158f50433d6SMarian Balakowicz  * fit_parse_subimage - parse FIT subimage spec
1159f50433d6SMarian Balakowicz  * @spec: input string, containing subimage spec
1160f50433d6SMarian Balakowicz  * @add_curr: current image address (to be used as a possible default)
1161f50433d6SMarian Balakowicz  * @addr: pointer to a ulong variable, will hold FIT image address of a given
1162f50433d6SMarian Balakowicz  * subimage
1163f50433d6SMarian Balakowicz  * @image_name: double pointer to a char, will hold pointer to a subimage name
1164f50433d6SMarian Balakowicz  *
1165f50433d6SMarian Balakowicz  * fit_parse_subimage() expects subimage spec in the for of
1166f50433d6SMarian Balakowicz  * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
1167f50433d6SMarian Balakowicz  * subimage with a <subimg> unit name.
1168f50433d6SMarian Balakowicz  *
1169f50433d6SMarian Balakowicz  * Address part is optional, and if omitted default add_curr will
1170f50433d6SMarian Balakowicz  * be used instead.
1171f50433d6SMarian Balakowicz  *
1172f50433d6SMarian Balakowicz  * returns:
1173f50433d6SMarian Balakowicz  *     1 if spec is a valid subimage string,
1174f50433d6SMarian Balakowicz  *     addr and image_name are set accordingly
1175f50433d6SMarian Balakowicz  *     0 otherwise
1176f50433d6SMarian Balakowicz  */
1177f50433d6SMarian Balakowicz inline int fit_parse_subimage (const char *spec, ulong addr_curr,
1178f50433d6SMarian Balakowicz 		ulong *addr, const char **image_name)
1179f50433d6SMarian Balakowicz {
1180f50433d6SMarian Balakowicz 	return fit_parse_spec (spec, ':', addr_curr, addr, image_name);
1181f50433d6SMarian Balakowicz }
1182570abb0aSMarian Balakowicz #endif /* !USE_HOSTCC */
11835dfb5213SMarian Balakowicz 
11845dfb5213SMarian Balakowicz static void fit_get_debug (const void *fit, int noffset,
11855dfb5213SMarian Balakowicz 		char *prop_name, int err)
11865dfb5213SMarian Balakowicz {
11875dfb5213SMarian Balakowicz 	debug ("Can't get '%s' property from FIT 0x%08lx, "
11885dfb5213SMarian Balakowicz 		"node: offset %d, name %s (%s)\n",
11895dfb5213SMarian Balakowicz 		prop_name, (ulong)fit, noffset,
11905dfb5213SMarian Balakowicz 		fit_get_name (fit, noffset, NULL),
11915dfb5213SMarian Balakowicz 		fdt_strerror (err));
11925dfb5213SMarian Balakowicz }
11935dfb5213SMarian Balakowicz 
11945dfb5213SMarian Balakowicz /**
11955dfb5213SMarian Balakowicz  * __fit_print_contents - prints out the contents of the FIT format image
11965dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
11975dfb5213SMarian Balakowicz  * @p: pointer to prefix string
11985dfb5213SMarian Balakowicz  *
11995dfb5213SMarian Balakowicz  * __fit_print_contents() formats a multi line FIT image contents description.
12005dfb5213SMarian Balakowicz  * The routine prints out FIT image properties (root node level) follwed by
12015dfb5213SMarian Balakowicz  * the details of each component image.
12025dfb5213SMarian Balakowicz  *
12035dfb5213SMarian Balakowicz  * returns:
12045dfb5213SMarian Balakowicz  *     no returned results
12055dfb5213SMarian Balakowicz  */
12065dfb5213SMarian Balakowicz static void __fit_print_contents (const void *fit, const char *p)
12075dfb5213SMarian Balakowicz {
12085dfb5213SMarian Balakowicz 	char *desc;
12095dfb5213SMarian Balakowicz 	char *uname;
12105dfb5213SMarian Balakowicz 	int images_noffset;
12115dfb5213SMarian Balakowicz 	int confs_noffset;
12125dfb5213SMarian Balakowicz 	int noffset;
12135dfb5213SMarian Balakowicz 	int ndepth;
12145dfb5213SMarian Balakowicz 	int count = 0;
12155dfb5213SMarian Balakowicz 	int ret;
12165dfb5213SMarian Balakowicz #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
12175dfb5213SMarian Balakowicz 	time_t timestamp;
12185dfb5213SMarian Balakowicz #endif
12195dfb5213SMarian Balakowicz 
12205dfb5213SMarian Balakowicz 	/* Root node properties */
12215dfb5213SMarian Balakowicz 	ret = fit_get_desc (fit, 0, &desc);
12225dfb5213SMarian Balakowicz 	printf ("%sFIT description: ", p);
12235dfb5213SMarian Balakowicz 	if (ret)
12245dfb5213SMarian Balakowicz 		printf ("unavailable\n");
12255dfb5213SMarian Balakowicz 	else
12265dfb5213SMarian Balakowicz 		printf ("%s\n", desc);
12275dfb5213SMarian Balakowicz 
12285dfb5213SMarian Balakowicz #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
12295dfb5213SMarian Balakowicz 	ret = fit_get_timestamp (fit, 0, &timestamp);
12305dfb5213SMarian Balakowicz 	printf ("%sCreated:         ", p);
12315dfb5213SMarian Balakowicz 	if (ret)
12325dfb5213SMarian Balakowicz 		printf ("unavailable\n");
12335dfb5213SMarian Balakowicz 	else
12345dfb5213SMarian Balakowicz 		genimg_print_time (timestamp);
12355dfb5213SMarian Balakowicz #endif
12365dfb5213SMarian Balakowicz 
12375dfb5213SMarian Balakowicz 	/* Find images parent node offset */
12385dfb5213SMarian Balakowicz 	images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
12395dfb5213SMarian Balakowicz 	if (images_noffset < 0) {
12405dfb5213SMarian Balakowicz 		printf ("Can't find images parent node '%s' (%s)\n",
12415dfb5213SMarian Balakowicz 			FIT_IMAGES_PATH, fdt_strerror (images_noffset));
12425dfb5213SMarian Balakowicz 		return;
12435dfb5213SMarian Balakowicz 	}
12445dfb5213SMarian Balakowicz 
12455dfb5213SMarian Balakowicz 	/* Process its subnodes, print out component images details */
12465dfb5213SMarian Balakowicz 	for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth);
12475dfb5213SMarian Balakowicz 	     (noffset >= 0) && (ndepth > 0);
12485dfb5213SMarian Balakowicz 	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
12495dfb5213SMarian Balakowicz 		if (ndepth == 1) {
12505dfb5213SMarian Balakowicz 			/*
12515dfb5213SMarian Balakowicz 			 * Direct child node of the images parent node,
12525dfb5213SMarian Balakowicz 			 * i.e. component image node.
12535dfb5213SMarian Balakowicz 			 */
12545dfb5213SMarian Balakowicz 			printf ("%s Image %u (%s)\n", p, count++,
12555dfb5213SMarian Balakowicz 					fit_get_name(fit, noffset, NULL));
12565dfb5213SMarian Balakowicz 
12575dfb5213SMarian Balakowicz 			fit_image_print (fit, noffset, p);
12585dfb5213SMarian Balakowicz 		}
12595dfb5213SMarian Balakowicz 	}
12605dfb5213SMarian Balakowicz 
12615dfb5213SMarian Balakowicz 	/* Find configurations parent node offset */
12625dfb5213SMarian Balakowicz 	confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH);
12635dfb5213SMarian Balakowicz 	if (confs_noffset < 0) {
12645dfb5213SMarian Balakowicz 		debug ("Can't get configurations parent node '%s' (%s)\n",
12655dfb5213SMarian Balakowicz 			FIT_CONFS_PATH, fdt_strerror (confs_noffset));
12665dfb5213SMarian Balakowicz 		return;
12675dfb5213SMarian Balakowicz 	}
12685dfb5213SMarian Balakowicz 
12695dfb5213SMarian Balakowicz 	/* get default configuration unit name from default property */
12705dfb5213SMarian Balakowicz 	uname = (char *)fdt_getprop (fit, noffset, FIT_DEFAULT_PROP, NULL);
12715dfb5213SMarian Balakowicz 	if (uname)
12725dfb5213SMarian Balakowicz 		printf ("%s Default Configuration: '%s'\n", p, uname);
12735dfb5213SMarian Balakowicz 
12745dfb5213SMarian Balakowicz 	/* Process its subnodes, print out configurations details */
12755dfb5213SMarian Balakowicz 	for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, confs_noffset, &ndepth);
12765dfb5213SMarian Balakowicz 	     (noffset >= 0) && (ndepth > 0);
12775dfb5213SMarian Balakowicz 	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
12785dfb5213SMarian Balakowicz 		if (ndepth == 1) {
12795dfb5213SMarian Balakowicz 			/*
12805dfb5213SMarian Balakowicz 			 * Direct child node of the configurations parent node,
12815dfb5213SMarian Balakowicz 			 * i.e. configuration node.
12825dfb5213SMarian Balakowicz 			 */
12835dfb5213SMarian Balakowicz 			printf ("%s Configuration %u (%s)\n", p, count++,
12845dfb5213SMarian Balakowicz 					fit_get_name(fit, noffset, NULL));
12855dfb5213SMarian Balakowicz 
12865dfb5213SMarian Balakowicz 			fit_conf_print (fit, noffset, p);
12875dfb5213SMarian Balakowicz 		}
12885dfb5213SMarian Balakowicz 	}
12895dfb5213SMarian Balakowicz }
12905dfb5213SMarian Balakowicz 
12915dfb5213SMarian Balakowicz inline void fit_print_contents (const void *fit)
12925dfb5213SMarian Balakowicz {
12935dfb5213SMarian Balakowicz 	__fit_print_contents (fit, "   ");
12945dfb5213SMarian Balakowicz }
12955dfb5213SMarian Balakowicz 
12965dfb5213SMarian Balakowicz inline void fit_print_contents_noindent (const void *fit)
12975dfb5213SMarian Balakowicz {
12985dfb5213SMarian Balakowicz 	__fit_print_contents (fit, "");
12995dfb5213SMarian Balakowicz }
13005dfb5213SMarian Balakowicz 
13015dfb5213SMarian Balakowicz /**
13025dfb5213SMarian Balakowicz  * fit_image_print - prints out the FIT component image details
13035dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
13045dfb5213SMarian Balakowicz  * @image_noffset: offset of the component image node
13055dfb5213SMarian Balakowicz  * @p: pointer to prefix string
13065dfb5213SMarian Balakowicz  *
13075dfb5213SMarian Balakowicz  * fit_image_print() lists all mandatory properies for the processed component
13085dfb5213SMarian Balakowicz  * image. If present, hash nodes are printed out as well.
13095dfb5213SMarian Balakowicz  *
13105dfb5213SMarian Balakowicz  * returns:
13115dfb5213SMarian Balakowicz  *     no returned results
13125dfb5213SMarian Balakowicz  */
13135dfb5213SMarian Balakowicz void fit_image_print (const void *fit, int image_noffset, const char *p)
13145dfb5213SMarian Balakowicz {
13155dfb5213SMarian Balakowicz 	char *desc;
13165dfb5213SMarian Balakowicz 	uint8_t type, arch, os, comp;
13175dfb5213SMarian Balakowicz 	size_t size;
13185dfb5213SMarian Balakowicz 	ulong load, entry;
13195dfb5213SMarian Balakowicz 	const void *data;
13205dfb5213SMarian Balakowicz 	int noffset;
13215dfb5213SMarian Balakowicz 	int ndepth;
13225dfb5213SMarian Balakowicz 	int ret;
13235dfb5213SMarian Balakowicz 
13245dfb5213SMarian Balakowicz 	/* Mandatory properties */
13255dfb5213SMarian Balakowicz 	ret = fit_get_desc (fit, image_noffset, &desc);
13265dfb5213SMarian Balakowicz 	printf ("%s  Description:  ", p);
13275dfb5213SMarian Balakowicz 	if (ret)
13285dfb5213SMarian Balakowicz 		printf ("unavailable\n");
13295dfb5213SMarian Balakowicz 	else
13305dfb5213SMarian Balakowicz 		printf ("%s\n", desc);
13315dfb5213SMarian Balakowicz 
13325dfb5213SMarian Balakowicz 	fit_image_get_type (fit, image_noffset, &type);
13335dfb5213SMarian Balakowicz 	printf ("%s  Type:         %s\n", p, genimg_get_type_name (type));
13345dfb5213SMarian Balakowicz 
13355dfb5213SMarian Balakowicz 	fit_image_get_comp (fit, image_noffset, &comp);
13365dfb5213SMarian Balakowicz 	printf ("%s  Compression:  %s\n", p, genimg_get_comp_name (comp));
13375dfb5213SMarian Balakowicz 
13385dfb5213SMarian Balakowicz 	ret = fit_image_get_data (fit, image_noffset, &data, &size);
13395dfb5213SMarian Balakowicz 
13405dfb5213SMarian Balakowicz #ifndef USE_HOSTCC
13415dfb5213SMarian Balakowicz 	printf ("%s  Data Start:   ", p);
13425dfb5213SMarian Balakowicz 	if (ret)
13435dfb5213SMarian Balakowicz 		printf ("unavailable\n");
13445dfb5213SMarian Balakowicz 	else
13455dfb5213SMarian Balakowicz 		printf ("0x%08lx\n", (ulong)data);
13465dfb5213SMarian Balakowicz #endif
13475dfb5213SMarian Balakowicz 
13485dfb5213SMarian Balakowicz 	printf ("%s  Data Size:    ", p);
13495dfb5213SMarian Balakowicz 	if (ret)
13505dfb5213SMarian Balakowicz 		printf ("unavailable\n");
13515dfb5213SMarian Balakowicz 	else
13525dfb5213SMarian Balakowicz 		genimg_print_size (size);
13535dfb5213SMarian Balakowicz 
13545dfb5213SMarian Balakowicz 	/* Remaining, type dependent properties */
13555dfb5213SMarian Balakowicz 	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
13565dfb5213SMarian Balakowicz 	    (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
13575dfb5213SMarian Balakowicz 	    (type == IH_TYPE_FLATDT)) {
13585dfb5213SMarian Balakowicz 		fit_image_get_arch (fit, image_noffset, &arch);
13595dfb5213SMarian Balakowicz 		printf ("%s  Architecture: %s\n", p, genimg_get_arch_name (arch));
13605dfb5213SMarian Balakowicz 	}
13615dfb5213SMarian Balakowicz 
13625dfb5213SMarian Balakowicz 	if (type == IH_TYPE_KERNEL) {
13635dfb5213SMarian Balakowicz 		fit_image_get_os (fit, image_noffset, &os);
13645dfb5213SMarian Balakowicz 		printf ("%s  OS:           %s\n", p, genimg_get_os_name (os));
13655dfb5213SMarian Balakowicz 	}
13665dfb5213SMarian Balakowicz 
13675dfb5213SMarian Balakowicz 	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE)) {
13685dfb5213SMarian Balakowicz 		ret = fit_image_get_load (fit, image_noffset, &load);
13695dfb5213SMarian Balakowicz 		printf ("%s  Load Address: ", p);
13705dfb5213SMarian Balakowicz 		if (ret)
13715dfb5213SMarian Balakowicz 			printf ("unavailable\n");
13725dfb5213SMarian Balakowicz 		else
13735dfb5213SMarian Balakowicz 			printf ("0x%08lx\n", load);
13745dfb5213SMarian Balakowicz 
13755dfb5213SMarian Balakowicz 		fit_image_get_entry (fit, image_noffset, &entry);
13765dfb5213SMarian Balakowicz 		printf ("%s  Entry Point:  ", p);
13775dfb5213SMarian Balakowicz 		if (ret)
13785dfb5213SMarian Balakowicz 			printf ("unavailable\n");
13795dfb5213SMarian Balakowicz 		else
13805dfb5213SMarian Balakowicz 			printf ("0x%08lx\n", entry);
13815dfb5213SMarian Balakowicz 	}
13825dfb5213SMarian Balakowicz 
13835dfb5213SMarian Balakowicz 	/* Process all hash subnodes of the component image node */
13845dfb5213SMarian Balakowicz 	for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
13855dfb5213SMarian Balakowicz 	     (noffset >= 0) && (ndepth > 0);
13865dfb5213SMarian Balakowicz 	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
13875dfb5213SMarian Balakowicz 		if (ndepth == 1) {
13885dfb5213SMarian Balakowicz 			/* Direct child node of the component image node */
13895dfb5213SMarian Balakowicz 			fit_image_print_hash (fit, noffset, p);
13905dfb5213SMarian Balakowicz 		}
13915dfb5213SMarian Balakowicz 	}
13925dfb5213SMarian Balakowicz }
13935dfb5213SMarian Balakowicz 
13945dfb5213SMarian Balakowicz /**
13955dfb5213SMarian Balakowicz  * fit_image_print_hash - prints out the hash node details
13965dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
13975dfb5213SMarian Balakowicz  * @noffset: offset of the hash node
13985dfb5213SMarian Balakowicz  * @p: pointer to prefix string
13995dfb5213SMarian Balakowicz  *
14005dfb5213SMarian Balakowicz  * fit_image_print_hash() lists properies for the processed hash node
14015dfb5213SMarian Balakowicz  *
14025dfb5213SMarian Balakowicz  * returns:
14035dfb5213SMarian Balakowicz  *     no returned results
14045dfb5213SMarian Balakowicz  */
14055dfb5213SMarian Balakowicz void fit_image_print_hash (const void *fit, int noffset, const char *p)
14065dfb5213SMarian Balakowicz {
14075dfb5213SMarian Balakowicz 	char *algo;
14085dfb5213SMarian Balakowicz 	uint8_t *value;
14095dfb5213SMarian Balakowicz 	int value_len;
14105dfb5213SMarian Balakowicz 	int i, ret;
14115dfb5213SMarian Balakowicz 
14125dfb5213SMarian Balakowicz 	/*
14135dfb5213SMarian Balakowicz 	 * Check subnode name, must be equal to "hash".
14145dfb5213SMarian Balakowicz 	 * Multiple hash nodes require unique unit node
14155dfb5213SMarian Balakowicz 	 * names, e.g. hash@1, hash@2, etc.
14165dfb5213SMarian Balakowicz 	 */
14175dfb5213SMarian Balakowicz 	if (strncmp (fit_get_name(fit, noffset, NULL),
14185dfb5213SMarian Balakowicz 			FIT_HASH_NODENAME,
14195dfb5213SMarian Balakowicz 			strlen(FIT_HASH_NODENAME)) != 0)
14205dfb5213SMarian Balakowicz 		return;
14215dfb5213SMarian Balakowicz 
14225dfb5213SMarian Balakowicz 	debug ("%s  Hash node:    '%s'\n", p,
14235dfb5213SMarian Balakowicz 			fit_get_name (fit, noffset, NULL));
14245dfb5213SMarian Balakowicz 
14255dfb5213SMarian Balakowicz 	printf ("%s  Hash algo:    ", p);
14265dfb5213SMarian Balakowicz 	if (fit_image_hash_get_algo (fit, noffset, &algo)) {
14275dfb5213SMarian Balakowicz 		printf ("invalid/unsupported\n");
14285dfb5213SMarian Balakowicz 		return;
14295dfb5213SMarian Balakowicz 	}
14305dfb5213SMarian Balakowicz 	printf ("%s\n", algo);
14315dfb5213SMarian Balakowicz 
14325dfb5213SMarian Balakowicz 	ret = fit_image_hash_get_value (fit, noffset, &value,
14335dfb5213SMarian Balakowicz 					&value_len);
14345dfb5213SMarian Balakowicz 	printf ("%s  Hash value:   ", p);
14355dfb5213SMarian Balakowicz 	if (ret) {
14365dfb5213SMarian Balakowicz 		printf ("unavailable\n");
14375dfb5213SMarian Balakowicz 	} else {
14385dfb5213SMarian Balakowicz 		for (i = 0; i < value_len; i++)
14395dfb5213SMarian Balakowicz 			printf ("%02x", value[i]);
14405dfb5213SMarian Balakowicz 		printf ("\n");
14415dfb5213SMarian Balakowicz 	}
14425dfb5213SMarian Balakowicz 
14435dfb5213SMarian Balakowicz 	debug  ("%s  Hash len:     %d\n", p, value_len);
14445dfb5213SMarian Balakowicz }
14455dfb5213SMarian Balakowicz 
14465dfb5213SMarian Balakowicz /**
14475dfb5213SMarian Balakowicz  * fit_get_desc - get node description property
14485dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
14495dfb5213SMarian Balakowicz  * @noffset: node offset
14505dfb5213SMarian Balakowicz  * @desc: double pointer to the char, will hold pointer to the descrption
14515dfb5213SMarian Balakowicz  *
14525dfb5213SMarian Balakowicz  * fit_get_desc() reads description property from a given node, if
14535dfb5213SMarian Balakowicz  * description is found pointer to it is returened in third call argument.
14545dfb5213SMarian Balakowicz  *
14555dfb5213SMarian Balakowicz  * returns:
14565dfb5213SMarian Balakowicz  *     0, on success
14575dfb5213SMarian Balakowicz  *     -1, on failure
14585dfb5213SMarian Balakowicz  */
14595dfb5213SMarian Balakowicz int fit_get_desc (const void *fit, int noffset, char **desc)
14605dfb5213SMarian Balakowicz {
14615dfb5213SMarian Balakowicz 	int len;
14625dfb5213SMarian Balakowicz 
14635dfb5213SMarian Balakowicz 	*desc = (char *)fdt_getprop (fit, noffset, FIT_DESC_PROP, &len);
14645dfb5213SMarian Balakowicz 	if (*desc == NULL) {
14655dfb5213SMarian Balakowicz 		fit_get_debug (fit, noffset, FIT_DESC_PROP, len);
14665dfb5213SMarian Balakowicz 		return -1;
14675dfb5213SMarian Balakowicz 	}
14685dfb5213SMarian Balakowicz 
14695dfb5213SMarian Balakowicz 	return 0;
14705dfb5213SMarian Balakowicz }
14715dfb5213SMarian Balakowicz 
14725dfb5213SMarian Balakowicz /**
14735dfb5213SMarian Balakowicz  * fit_get_timestamp - get node timestamp property
14745dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
14755dfb5213SMarian Balakowicz  * @noffset: node offset
14765dfb5213SMarian Balakowicz  * @timestamp: pointer to the time_t, will hold read timestamp
14775dfb5213SMarian Balakowicz  *
14785dfb5213SMarian Balakowicz  * fit_get_timestamp() reads timestamp poperty from given node, if timestamp
14795dfb5213SMarian Balakowicz  * is found and has a correct size its value is retured in third call
14805dfb5213SMarian Balakowicz  * argument.
14815dfb5213SMarian Balakowicz  *
14825dfb5213SMarian Balakowicz  * returns:
14835dfb5213SMarian Balakowicz  *     0, on success
14845dfb5213SMarian Balakowicz  *     -1, on property read failure
14855dfb5213SMarian Balakowicz  *     -2, on wrong timestamp size
14865dfb5213SMarian Balakowicz  */
14875dfb5213SMarian Balakowicz int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp)
14885dfb5213SMarian Balakowicz {
14895dfb5213SMarian Balakowicz 	int len;
14905dfb5213SMarian Balakowicz 	const void *data;
14915dfb5213SMarian Balakowicz 
14925dfb5213SMarian Balakowicz 	data = fdt_getprop (fit, noffset, FIT_TIMESTAMP_PROP, &len);
14935dfb5213SMarian Balakowicz 	if (data == NULL) {
14945dfb5213SMarian Balakowicz 		fit_get_debug (fit, noffset, FIT_TIMESTAMP_PROP, len);
14955dfb5213SMarian Balakowicz 		return -1;
14965dfb5213SMarian Balakowicz 	}
14975dfb5213SMarian Balakowicz 	if (len != sizeof (uint32_t)) {
14985dfb5213SMarian Balakowicz 		debug ("FIT timestamp with incorrect size of (%u)\n", len);
14995dfb5213SMarian Balakowicz 		return -2;
15005dfb5213SMarian Balakowicz 	}
15015dfb5213SMarian Balakowicz 
15025dfb5213SMarian Balakowicz 	*timestamp = uimage_to_cpu (*((uint32_t *)data));
15035dfb5213SMarian Balakowicz 	return 0;
15045dfb5213SMarian Balakowicz }
15055dfb5213SMarian Balakowicz 
15065dfb5213SMarian Balakowicz /**
15075dfb5213SMarian Balakowicz  * fit_image_get_node - get node offset for component image of a given unit name
15085dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
15095dfb5213SMarian Balakowicz  * @image_uname: component image node unit name
15105dfb5213SMarian Balakowicz  *
15115dfb5213SMarian Balakowicz  * fit_image_get_node() finds a component image (withing the '/images'
15125dfb5213SMarian Balakowicz  * node) of a provided unit name. If image is found its node offset is
15135dfb5213SMarian Balakowicz  * returned to the caller.
15145dfb5213SMarian Balakowicz  *
15155dfb5213SMarian Balakowicz  * returns:
15165dfb5213SMarian Balakowicz  *     image node offset when found (>=0)
15175dfb5213SMarian Balakowicz  *     negative number on failure (FDT_ERR_* code)
15185dfb5213SMarian Balakowicz  */
15195dfb5213SMarian Balakowicz int fit_image_get_node (const void *fit, const char *image_uname)
15205dfb5213SMarian Balakowicz {
15215dfb5213SMarian Balakowicz 	int noffset, images_noffset;
15225dfb5213SMarian Balakowicz 
15235dfb5213SMarian Balakowicz 	images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
15245dfb5213SMarian Balakowicz 	if (images_noffset < 0) {
15255dfb5213SMarian Balakowicz 		debug ("Can't find images parent node '%s' (%s)\n",
15265dfb5213SMarian Balakowicz 			FIT_IMAGES_PATH, fdt_strerror (images_noffset));
15275dfb5213SMarian Balakowicz 		return images_noffset;
15285dfb5213SMarian Balakowicz 	}
15295dfb5213SMarian Balakowicz 
15305dfb5213SMarian Balakowicz 	noffset = fdt_subnode_offset (fit, images_noffset, image_uname);
15315dfb5213SMarian Balakowicz 	if (noffset < 0) {
15325dfb5213SMarian Balakowicz 		debug ("Can't get node offset for image unit name: '%s' (%s)\n",
15335dfb5213SMarian Balakowicz 			image_uname, fdt_strerror (noffset));
15345dfb5213SMarian Balakowicz 	}
15355dfb5213SMarian Balakowicz 
15365dfb5213SMarian Balakowicz 	return noffset;
15375dfb5213SMarian Balakowicz }
15385dfb5213SMarian Balakowicz 
15395dfb5213SMarian Balakowicz /**
15405dfb5213SMarian Balakowicz  * fit_image_get_os - get os id for a given component image node
15415dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
15425dfb5213SMarian Balakowicz  * @noffset: component image node offset
15435dfb5213SMarian Balakowicz  * @os: pointer to the uint8_t, will hold os numeric id
15445dfb5213SMarian Balakowicz  *
15455dfb5213SMarian Balakowicz  * fit_image_get_os() finds os property in a given component image node.
15465dfb5213SMarian Balakowicz  * If the property is found, its (string) value is translated to the numeric
15475dfb5213SMarian Balakowicz  * id which is returned to the caller.
15485dfb5213SMarian Balakowicz  *
15495dfb5213SMarian Balakowicz  * returns:
15505dfb5213SMarian Balakowicz  *     0, on success
15515dfb5213SMarian Balakowicz  *     -1, on failure
15525dfb5213SMarian Balakowicz  */
15535dfb5213SMarian Balakowicz int fit_image_get_os (const void *fit, int noffset, uint8_t *os)
15545dfb5213SMarian Balakowicz {
15555dfb5213SMarian Balakowicz 	int len;
15565dfb5213SMarian Balakowicz 	const void *data;
15575dfb5213SMarian Balakowicz 
15585dfb5213SMarian Balakowicz 	/* Get OS name from property data */
15595dfb5213SMarian Balakowicz 	data = fdt_getprop (fit, noffset, FIT_OS_PROP, &len);
15605dfb5213SMarian Balakowicz 	if (data == NULL) {
15615dfb5213SMarian Balakowicz 		fit_get_debug (fit, noffset, FIT_OS_PROP, len);
15625dfb5213SMarian Balakowicz 		*os = -1;
15635dfb5213SMarian Balakowicz 		return -1;
15645dfb5213SMarian Balakowicz 	}
15655dfb5213SMarian Balakowicz 
15665dfb5213SMarian Balakowicz 	/* Translate OS name to id */
15675dfb5213SMarian Balakowicz 	*os = genimg_get_os_id (data);
15685dfb5213SMarian Balakowicz 	return 0;
15695dfb5213SMarian Balakowicz }
15705dfb5213SMarian Balakowicz 
15715dfb5213SMarian Balakowicz /**
15725dfb5213SMarian Balakowicz  * fit_image_get_arch - get arch id for a given component image node
15735dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
15745dfb5213SMarian Balakowicz  * @noffset: component image node offset
15755dfb5213SMarian Balakowicz  * @arch: pointer to the uint8_t, will hold arch numeric id
15765dfb5213SMarian Balakowicz  *
15775dfb5213SMarian Balakowicz  * fit_image_get_arch() finds arch property in a given component image node.
15785dfb5213SMarian Balakowicz  * If the property is found, its (string) value is translated to the numeric
15795dfb5213SMarian Balakowicz  * id which is returned to the caller.
15805dfb5213SMarian Balakowicz  *
15815dfb5213SMarian Balakowicz  * returns:
15825dfb5213SMarian Balakowicz  *     0, on success
15835dfb5213SMarian Balakowicz  *     -1, on failure
15845dfb5213SMarian Balakowicz  */
15855dfb5213SMarian Balakowicz int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch)
15865dfb5213SMarian Balakowicz {
15875dfb5213SMarian Balakowicz 	int len;
15885dfb5213SMarian Balakowicz 	const void *data;
15895dfb5213SMarian Balakowicz 
15905dfb5213SMarian Balakowicz 	/* Get architecture name from property data */
15915dfb5213SMarian Balakowicz 	data = fdt_getprop (fit, noffset, FIT_ARCH_PROP, &len);
15925dfb5213SMarian Balakowicz 	if (data == NULL) {
15935dfb5213SMarian Balakowicz 		fit_get_debug (fit, noffset, FIT_ARCH_PROP, len);
15945dfb5213SMarian Balakowicz 		*arch = -1;
15955dfb5213SMarian Balakowicz 		return -1;
15965dfb5213SMarian Balakowicz 	}
15975dfb5213SMarian Balakowicz 
15985dfb5213SMarian Balakowicz 	/* Translate architecture name to id */
15995dfb5213SMarian Balakowicz 	*arch = genimg_get_arch_id (data);
16005dfb5213SMarian Balakowicz 	return 0;
16015dfb5213SMarian Balakowicz }
16025dfb5213SMarian Balakowicz 
16035dfb5213SMarian Balakowicz /**
16045dfb5213SMarian Balakowicz  * fit_image_get_type - get type id for a given component image node
16055dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
16065dfb5213SMarian Balakowicz  * @noffset: component image node offset
16075dfb5213SMarian Balakowicz  * @type: pointer to the uint8_t, will hold type numeric id
16085dfb5213SMarian Balakowicz  *
16095dfb5213SMarian Balakowicz  * fit_image_get_type() finds type property in a given component image node.
16105dfb5213SMarian Balakowicz  * If the property is found, its (string) value is translated to the numeric
16115dfb5213SMarian Balakowicz  * id which is returned to the caller.
16125dfb5213SMarian Balakowicz  *
16135dfb5213SMarian Balakowicz  * returns:
16145dfb5213SMarian Balakowicz  *     0, on success
16155dfb5213SMarian Balakowicz  *     -1, on failure
16165dfb5213SMarian Balakowicz  */
16175dfb5213SMarian Balakowicz int fit_image_get_type (const void *fit, int noffset, uint8_t *type)
16185dfb5213SMarian Balakowicz {
16195dfb5213SMarian Balakowicz 	int len;
16205dfb5213SMarian Balakowicz 	const void *data;
16215dfb5213SMarian Balakowicz 
16225dfb5213SMarian Balakowicz 	/* Get image type name from property data */
16235dfb5213SMarian Balakowicz 	data = fdt_getprop (fit, noffset, FIT_TYPE_PROP, &len);
16245dfb5213SMarian Balakowicz 	if (data == NULL) {
16255dfb5213SMarian Balakowicz 		fit_get_debug (fit, noffset, FIT_TYPE_PROP, len);
16265dfb5213SMarian Balakowicz 		*type = -1;
16275dfb5213SMarian Balakowicz 		return -1;
16285dfb5213SMarian Balakowicz 	}
16295dfb5213SMarian Balakowicz 
16305dfb5213SMarian Balakowicz 	/* Translate image type name to id */
16315dfb5213SMarian Balakowicz 	*type = genimg_get_type_id (data);
16325dfb5213SMarian Balakowicz 	return 0;
16335dfb5213SMarian Balakowicz }
16345dfb5213SMarian Balakowicz 
16355dfb5213SMarian Balakowicz /**
16365dfb5213SMarian Balakowicz  * fit_image_get_comp - get comp id for a given component image node
16375dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
16385dfb5213SMarian Balakowicz  * @noffset: component image node offset
16395dfb5213SMarian Balakowicz  * @comp: pointer to the uint8_t, will hold comp numeric id
16405dfb5213SMarian Balakowicz  *
16415dfb5213SMarian Balakowicz  * fit_image_get_comp() finds comp property in a given component image node.
16425dfb5213SMarian Balakowicz  * If the property is found, its (string) value is translated to the numeric
16435dfb5213SMarian Balakowicz  * id which is returned to the caller.
16445dfb5213SMarian Balakowicz  *
16455dfb5213SMarian Balakowicz  * returns:
16465dfb5213SMarian Balakowicz  *     0, on success
16475dfb5213SMarian Balakowicz  *     -1, on failure
16485dfb5213SMarian Balakowicz  */
16495dfb5213SMarian Balakowicz int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp)
16505dfb5213SMarian Balakowicz {
16515dfb5213SMarian Balakowicz 	int len;
16525dfb5213SMarian Balakowicz 	const void *data;
16535dfb5213SMarian Balakowicz 
16545dfb5213SMarian Balakowicz 	/* Get compression name from property data */
16555dfb5213SMarian Balakowicz 	data = fdt_getprop (fit, noffset, FIT_COMP_PROP, &len);
16565dfb5213SMarian Balakowicz 	if (data == NULL) {
16575dfb5213SMarian Balakowicz 		fit_get_debug (fit, noffset, FIT_COMP_PROP, len);
16585dfb5213SMarian Balakowicz 		*comp = -1;
16595dfb5213SMarian Balakowicz 		return -1;
16605dfb5213SMarian Balakowicz 	}
16615dfb5213SMarian Balakowicz 
16625dfb5213SMarian Balakowicz 	/* Translate compression name to id */
16635dfb5213SMarian Balakowicz 	*comp = genimg_get_comp_id (data);
16645dfb5213SMarian Balakowicz 	return 0;
16655dfb5213SMarian Balakowicz }
16665dfb5213SMarian Balakowicz 
16675dfb5213SMarian Balakowicz /**
16685dfb5213SMarian Balakowicz  * fit_image_get_load - get load address property for a given component image node
16695dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
16705dfb5213SMarian Balakowicz  * @noffset: component image node offset
16715dfb5213SMarian Balakowicz  * @load: pointer to the uint32_t, will hold load address
16725dfb5213SMarian Balakowicz  *
16735dfb5213SMarian Balakowicz  * fit_image_get_load() finds load address property in a given component image node.
16745dfb5213SMarian Balakowicz  * If the property is found, its value is returned to the caller.
16755dfb5213SMarian Balakowicz  *
16765dfb5213SMarian Balakowicz  * returns:
16775dfb5213SMarian Balakowicz  *     0, on success
16785dfb5213SMarian Balakowicz  *     -1, on failure
16795dfb5213SMarian Balakowicz  */
16805dfb5213SMarian Balakowicz int fit_image_get_load (const void *fit, int noffset, ulong *load)
16815dfb5213SMarian Balakowicz {
16825dfb5213SMarian Balakowicz 	int len;
16835dfb5213SMarian Balakowicz 	const uint32_t *data;
16845dfb5213SMarian Balakowicz 
16855dfb5213SMarian Balakowicz 	data = fdt_getprop (fit, noffset, FIT_LOAD_PROP, &len);
16865dfb5213SMarian Balakowicz 	if (data == NULL) {
16875dfb5213SMarian Balakowicz 		fit_get_debug (fit, noffset, FIT_LOAD_PROP, len);
16885dfb5213SMarian Balakowicz 		return -1;
16895dfb5213SMarian Balakowicz 	}
16905dfb5213SMarian Balakowicz 
16915dfb5213SMarian Balakowicz 	*load = uimage_to_cpu (*data);
16925dfb5213SMarian Balakowicz 	return 0;
16935dfb5213SMarian Balakowicz }
16945dfb5213SMarian Balakowicz 
16955dfb5213SMarian Balakowicz /**
16965dfb5213SMarian Balakowicz  * fit_image_get_entry - get entry point address property for a given component image node
16975dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
16985dfb5213SMarian Balakowicz  * @noffset: component image node offset
16995dfb5213SMarian Balakowicz  * @entry: pointer to the uint32_t, will hold entry point address
17005dfb5213SMarian Balakowicz  *
17015dfb5213SMarian Balakowicz  * fit_image_get_entry() finds entry point address property in a given component image node.
17025dfb5213SMarian Balakowicz  * If the property is found, its value is returned to the caller.
17035dfb5213SMarian Balakowicz  *
17045dfb5213SMarian Balakowicz  * returns:
17055dfb5213SMarian Balakowicz  *     0, on success
17065dfb5213SMarian Balakowicz  *     -1, on failure
17075dfb5213SMarian Balakowicz  */
17085dfb5213SMarian Balakowicz int fit_image_get_entry (const void *fit, int noffset, ulong *entry)
17095dfb5213SMarian Balakowicz {
17105dfb5213SMarian Balakowicz 	int len;
17115dfb5213SMarian Balakowicz 	const uint32_t *data;
17125dfb5213SMarian Balakowicz 
17135dfb5213SMarian Balakowicz 	data = fdt_getprop (fit, noffset, FIT_ENTRY_PROP, &len);
17145dfb5213SMarian Balakowicz 	if (data == NULL) {
17155dfb5213SMarian Balakowicz 		fit_get_debug (fit, noffset, FIT_ENTRY_PROP, len);
17165dfb5213SMarian Balakowicz 		return -1;
17175dfb5213SMarian Balakowicz 	}
17185dfb5213SMarian Balakowicz 
17195dfb5213SMarian Balakowicz 	*entry = uimage_to_cpu (*data);
17205dfb5213SMarian Balakowicz 	return 0;
17215dfb5213SMarian Balakowicz }
17225dfb5213SMarian Balakowicz 
17235dfb5213SMarian Balakowicz /**
17245dfb5213SMarian Balakowicz  * fit_image_get_data - get data property and its size for a given component image node
17255dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
17265dfb5213SMarian Balakowicz  * @noffset: component image node offset
17275dfb5213SMarian Balakowicz  * @data: double pointer to void, will hold data property's data address
17285dfb5213SMarian Balakowicz  * @size: pointer to size_t, will hold data property's data size
17295dfb5213SMarian Balakowicz  *
17305dfb5213SMarian Balakowicz  * fit_image_get_data() finds data property in a given component image node.
17315dfb5213SMarian Balakowicz  * If the property is found its data start address and size are returned to
17325dfb5213SMarian Balakowicz  * the caller.
17335dfb5213SMarian Balakowicz  *
17345dfb5213SMarian Balakowicz  * returns:
17355dfb5213SMarian Balakowicz  *     0, on success
17365dfb5213SMarian Balakowicz  *     -1, on failure
17375dfb5213SMarian Balakowicz  */
17385dfb5213SMarian Balakowicz int fit_image_get_data (const void *fit, int noffset,
17395dfb5213SMarian Balakowicz 		const void **data, size_t *size)
17405dfb5213SMarian Balakowicz {
17415dfb5213SMarian Balakowicz 	int len;
17425dfb5213SMarian Balakowicz 
17435dfb5213SMarian Balakowicz 	*data = fdt_getprop (fit, noffset, FIT_DATA_PROP, &len);
17445dfb5213SMarian Balakowicz 	if (*data == NULL) {
17455dfb5213SMarian Balakowicz 		fit_get_debug (fit, noffset, FIT_DATA_PROP, len);
17465dfb5213SMarian Balakowicz 		*size = 0;
17475dfb5213SMarian Balakowicz 		return -1;
17485dfb5213SMarian Balakowicz 	}
17495dfb5213SMarian Balakowicz 
17505dfb5213SMarian Balakowicz 	*size = len;
17515dfb5213SMarian Balakowicz 	return 0;
17525dfb5213SMarian Balakowicz }
17535dfb5213SMarian Balakowicz 
17545dfb5213SMarian Balakowicz /**
17555dfb5213SMarian Balakowicz  * fit_image_hash_get_algo - get hash algorithm name
17565dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
17575dfb5213SMarian Balakowicz  * @noffset: hash node offset
17585dfb5213SMarian Balakowicz  * @algo: double pointer to char, will hold pointer to the algorithm name
17595dfb5213SMarian Balakowicz  *
17605dfb5213SMarian Balakowicz  * fit_image_hash_get_algo() finds hash algorithm property in a given hash node.
17615dfb5213SMarian Balakowicz  * If the property is found its data start address is returned to the caller.
17625dfb5213SMarian Balakowicz  *
17635dfb5213SMarian Balakowicz  * returns:
17645dfb5213SMarian Balakowicz  *     0, on success
17655dfb5213SMarian Balakowicz  *     -1, on failure
17665dfb5213SMarian Balakowicz  */
17675dfb5213SMarian Balakowicz int fit_image_hash_get_algo (const void *fit, int noffset, char **algo)
17685dfb5213SMarian Balakowicz {
17695dfb5213SMarian Balakowicz 	int len;
17705dfb5213SMarian Balakowicz 
17715dfb5213SMarian Balakowicz 	*algo = (char *)fdt_getprop (fit, noffset, FIT_ALGO_PROP, &len);
17725dfb5213SMarian Balakowicz 	if (*algo == NULL) {
17735dfb5213SMarian Balakowicz 		fit_get_debug (fit, noffset, FIT_ALGO_PROP, len);
17745dfb5213SMarian Balakowicz 		return -1;
17755dfb5213SMarian Balakowicz 	}
17765dfb5213SMarian Balakowicz 
17775dfb5213SMarian Balakowicz 	return 0;
17785dfb5213SMarian Balakowicz }
17795dfb5213SMarian Balakowicz 
17805dfb5213SMarian Balakowicz /**
17815dfb5213SMarian Balakowicz  * fit_image_hash_get_value - get hash value and length
17825dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
17835dfb5213SMarian Balakowicz  * @noffset: hash node offset
17845dfb5213SMarian Balakowicz  * @value: double pointer to uint8_t, will hold address of a hash value data
17855dfb5213SMarian Balakowicz  * @value_len: pointer to an int, will hold hash data length
17865dfb5213SMarian Balakowicz  *
17875dfb5213SMarian Balakowicz  * fit_image_hash_get_value() finds hash value property in a given hash node.
17885dfb5213SMarian Balakowicz  * If the property is found its data start address and size are returned to
17895dfb5213SMarian Balakowicz  * the caller.
17905dfb5213SMarian Balakowicz  *
17915dfb5213SMarian Balakowicz  * returns:
17925dfb5213SMarian Balakowicz  *     0, on success
17935dfb5213SMarian Balakowicz  *     -1, on failure
17945dfb5213SMarian Balakowicz  */
17955dfb5213SMarian Balakowicz int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value,
17965dfb5213SMarian Balakowicz 				int *value_len)
17975dfb5213SMarian Balakowicz {
17985dfb5213SMarian Balakowicz 	int len;
17995dfb5213SMarian Balakowicz 
18005dfb5213SMarian Balakowicz 	*value = (uint8_t *)fdt_getprop (fit, noffset, FIT_VALUE_PROP, &len);
18015dfb5213SMarian Balakowicz 	if (*value == NULL) {
18025dfb5213SMarian Balakowicz 		fit_get_debug (fit, noffset, FIT_VALUE_PROP, len);
18035dfb5213SMarian Balakowicz 		*value_len = 0;
18045dfb5213SMarian Balakowicz 		return -1;
18055dfb5213SMarian Balakowicz 	}
18065dfb5213SMarian Balakowicz 
18075dfb5213SMarian Balakowicz 	*value_len = len;
18085dfb5213SMarian Balakowicz 	return 0;
18095dfb5213SMarian Balakowicz }
18105dfb5213SMarian Balakowicz 
18115dfb5213SMarian Balakowicz /**
18125dfb5213SMarian Balakowicz  * fit_set_timestamp - set node timestamp property
18135dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
18145dfb5213SMarian Balakowicz  * @noffset: node offset
18155dfb5213SMarian Balakowicz  * @timestamp: timestamp value to be set
18165dfb5213SMarian Balakowicz  *
18175dfb5213SMarian Balakowicz  * fit_set_timestamp() attempts to set timestamp property in the requested
18185dfb5213SMarian Balakowicz  * node and returns operation status to the caller.
18195dfb5213SMarian Balakowicz  *
18205dfb5213SMarian Balakowicz  * returns:
18215dfb5213SMarian Balakowicz  *     0, on success
18225dfb5213SMarian Balakowicz  *     -1, on property read failure
18235dfb5213SMarian Balakowicz  */
18245dfb5213SMarian Balakowicz int fit_set_timestamp (void *fit, int noffset, time_t timestamp)
18255dfb5213SMarian Balakowicz {
18265dfb5213SMarian Balakowicz 	uint32_t t;
18275dfb5213SMarian Balakowicz 	int ret;
18285dfb5213SMarian Balakowicz 
18295dfb5213SMarian Balakowicz 	t = cpu_to_uimage (timestamp);
18305dfb5213SMarian Balakowicz 	ret = fdt_setprop (fit, noffset, FIT_TIMESTAMP_PROP, &t,
18315dfb5213SMarian Balakowicz 				sizeof (uint32_t));
18325dfb5213SMarian Balakowicz 	if (ret) {
18335dfb5213SMarian Balakowicz 		printf ("Can't set '%s' property for '%s' node (%s)\n",
18345dfb5213SMarian Balakowicz 			FIT_TIMESTAMP_PROP, fit_get_name (fit, noffset, NULL),
18355dfb5213SMarian Balakowicz 			fdt_strerror (ret));
18365dfb5213SMarian Balakowicz 		return -1;
18375dfb5213SMarian Balakowicz 	}
18385dfb5213SMarian Balakowicz 
18395dfb5213SMarian Balakowicz 	return 0;
18405dfb5213SMarian Balakowicz }
18415dfb5213SMarian Balakowicz 
18425dfb5213SMarian Balakowicz /**
18435dfb5213SMarian Balakowicz  * calculate_hash - calculate and return hash for provided input data
18445dfb5213SMarian Balakowicz  * @data: pointer to the input data
18455dfb5213SMarian Balakowicz  * @data_len: data length
18465dfb5213SMarian Balakowicz  * @algo: requested hash algorithm
18475dfb5213SMarian Balakowicz  * @value: pointer to the char, will hold hash value data (caller must
18485dfb5213SMarian Balakowicz  * allocate enough free space)
18495dfb5213SMarian Balakowicz  * value_len: length of the calculated hash
18505dfb5213SMarian Balakowicz  *
18515dfb5213SMarian Balakowicz  * calculate_hash() computes input data hash according to the requested algorithm.
18525dfb5213SMarian Balakowicz  * Resulting hash value is placed in caller provided 'value' buffer, length
18535dfb5213SMarian Balakowicz  * of the calculated hash is returned via value_len pointer argument.
18545dfb5213SMarian Balakowicz  *
18555dfb5213SMarian Balakowicz  * returns:
18565dfb5213SMarian Balakowicz  *     0, on success
18575dfb5213SMarian Balakowicz  *    -1, when algo is unsupported
18585dfb5213SMarian Balakowicz  */
18595dfb5213SMarian Balakowicz static int calculate_hash (const void *data, int data_len, const char *algo,
18605dfb5213SMarian Balakowicz 			uint8_t *value, int *value_len)
18615dfb5213SMarian Balakowicz {
18625dfb5213SMarian Balakowicz 	if (strcmp (algo, "crc32") == 0 ) {
18635dfb5213SMarian Balakowicz 		*((uint32_t *)value) = crc32 (0, data, data_len);
18645dfb5213SMarian Balakowicz 		*((uint32_t *)value) = cpu_to_uimage (*((uint32_t *)value));
18655dfb5213SMarian Balakowicz 		*value_len = 4;
18665dfb5213SMarian Balakowicz 	} else if (strcmp (algo, "sha1") == 0 ) {
18675dfb5213SMarian Balakowicz 		sha1_csum ((unsigned char *) data, data_len,
18685dfb5213SMarian Balakowicz 				(unsigned char *) value);
18695dfb5213SMarian Balakowicz 		*value_len = 20;
18705dfb5213SMarian Balakowicz 	} else if (strcmp (algo, "md5") == 0 ) {
18715dfb5213SMarian Balakowicz 		printf ("MD5 not supported\n");
18725dfb5213SMarian Balakowicz 		*value_len = 0;
18735dfb5213SMarian Balakowicz 	} else {
18745dfb5213SMarian Balakowicz 		debug ("Unsupported hash alogrithm\n");
18755dfb5213SMarian Balakowicz 		return -1;
18765dfb5213SMarian Balakowicz 	}
18775dfb5213SMarian Balakowicz 	return 0;
18785dfb5213SMarian Balakowicz }
18795dfb5213SMarian Balakowicz 
18805dfb5213SMarian Balakowicz #ifdef USE_HOSTCC
18815dfb5213SMarian Balakowicz /**
18825dfb5213SMarian Balakowicz  * fit_set_hashes - process FIT component image nodes and calculate hashes
18835dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
18845dfb5213SMarian Balakowicz  *
18855dfb5213SMarian Balakowicz  * fit_set_hashes() adds hash values for all component images in the FIT blob.
18865dfb5213SMarian Balakowicz  * Hashes are calculated for all component images which have hash subnodes
18875dfb5213SMarian Balakowicz  * with algorithm property set to one of the supported hash algorithms.
18885dfb5213SMarian Balakowicz  *
18895dfb5213SMarian Balakowicz  * returns
18905dfb5213SMarian Balakowicz  *     0, on success
18915dfb5213SMarian Balakowicz  *     libfdt error code, on failure
18925dfb5213SMarian Balakowicz  */
18935dfb5213SMarian Balakowicz int fit_set_hashes (void *fit)
18945dfb5213SMarian Balakowicz {
18955dfb5213SMarian Balakowicz 	int images_noffset;
18965dfb5213SMarian Balakowicz 	int noffset;
18975dfb5213SMarian Balakowicz 	int ndepth;
18985dfb5213SMarian Balakowicz 	int ret;
18995dfb5213SMarian Balakowicz 
19005dfb5213SMarian Balakowicz 	/* Find images parent node offset */
19015dfb5213SMarian Balakowicz 	images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
19025dfb5213SMarian Balakowicz 	if (images_noffset < 0) {
19035dfb5213SMarian Balakowicz 		printf ("Can't find images parent node '%s' (%s)\n",
19045dfb5213SMarian Balakowicz 			FIT_IMAGES_PATH, fdt_strerror (images_noffset));
19055dfb5213SMarian Balakowicz 		return images_noffset;
19065dfb5213SMarian Balakowicz 	}
19075dfb5213SMarian Balakowicz 
19085dfb5213SMarian Balakowicz 	/* Process its subnodes, print out component images details */
19095dfb5213SMarian Balakowicz 	for (ndepth = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth);
19105dfb5213SMarian Balakowicz 	     (noffset >= 0) && (ndepth > 0);
19115dfb5213SMarian Balakowicz 	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
19125dfb5213SMarian Balakowicz 		if (ndepth == 1) {
19135dfb5213SMarian Balakowicz 			/*
19145dfb5213SMarian Balakowicz 			 * Direct child node of the images parent node,
19155dfb5213SMarian Balakowicz 			 * i.e. component image node.
19165dfb5213SMarian Balakowicz 			 */
19175dfb5213SMarian Balakowicz 			ret = fit_image_set_hashes (fit, noffset);
19185dfb5213SMarian Balakowicz 			if (ret)
19195dfb5213SMarian Balakowicz 				return ret;
19205dfb5213SMarian Balakowicz 		}
19215dfb5213SMarian Balakowicz 	}
19225dfb5213SMarian Balakowicz 
19235dfb5213SMarian Balakowicz 	return 0;
19245dfb5213SMarian Balakowicz }
19255dfb5213SMarian Balakowicz 
19265dfb5213SMarian Balakowicz /**
19275dfb5213SMarian Balakowicz  * fit_image_set_hashes - calculate/set hashes for given component image node
19285dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
19295dfb5213SMarian Balakowicz  * @image_noffset: requested component image node
19305dfb5213SMarian Balakowicz  *
19315dfb5213SMarian Balakowicz  * fit_image_set_hashes() adds hash values for an component image node. All
19325dfb5213SMarian Balakowicz  * existing hash subnodes are checked, if algorithm property is set to one of
19335dfb5213SMarian Balakowicz  * the supported hash algorithms, hash value is computed and corresponding
19345dfb5213SMarian Balakowicz  * hash node property is set, for example:
19355dfb5213SMarian Balakowicz  *
19365dfb5213SMarian Balakowicz  * Input component image node structure:
19375dfb5213SMarian Balakowicz  *
19385dfb5213SMarian Balakowicz  * o image@1 (at image_noffset)
19395dfb5213SMarian Balakowicz  *   | - data = [binary data]
19405dfb5213SMarian Balakowicz  *   o hash@1
19415dfb5213SMarian Balakowicz  *     |- algo = "sha1"
19425dfb5213SMarian Balakowicz  *
19435dfb5213SMarian Balakowicz  * Output component image node structure:
19445dfb5213SMarian Balakowicz  *
19455dfb5213SMarian Balakowicz  * o image@1 (at image_noffset)
19465dfb5213SMarian Balakowicz  *   | - data = [binary data]
19475dfb5213SMarian Balakowicz  *   o hash@1
19485dfb5213SMarian Balakowicz  *     |- algo = "sha1"
19495dfb5213SMarian Balakowicz  *     |- value = sha1(data)
19505dfb5213SMarian Balakowicz  *
19515dfb5213SMarian Balakowicz  * returns:
19525dfb5213SMarian Balakowicz  *     0 on sucess
19535dfb5213SMarian Balakowicz  *    <0 on failure
19545dfb5213SMarian Balakowicz  */
19555dfb5213SMarian Balakowicz int fit_image_set_hashes (void *fit, int image_noffset)
19565dfb5213SMarian Balakowicz {
19575dfb5213SMarian Balakowicz 	const void *data;
19585dfb5213SMarian Balakowicz 	size_t size;
19595dfb5213SMarian Balakowicz 	char *algo;
19605dfb5213SMarian Balakowicz 	uint8_t value[FIT_MAX_HASH_LEN];
19615dfb5213SMarian Balakowicz 	int value_len;
19625dfb5213SMarian Balakowicz 	int noffset;
19635dfb5213SMarian Balakowicz 	int ndepth;
19645dfb5213SMarian Balakowicz 
19655dfb5213SMarian Balakowicz 	/* Get image data and data length */
19665dfb5213SMarian Balakowicz 	if (fit_image_get_data (fit, image_noffset, &data, &size)) {
19675dfb5213SMarian Balakowicz 		printf ("Can't get image data/size\n");
19685dfb5213SMarian Balakowicz 		return -1;
19695dfb5213SMarian Balakowicz 	}
19705dfb5213SMarian Balakowicz 
19715dfb5213SMarian Balakowicz 	/* Process all hash subnodes of the component image node */
19725dfb5213SMarian Balakowicz 	for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
19735dfb5213SMarian Balakowicz 	     (noffset >= 0) && (ndepth > 0);
19745dfb5213SMarian Balakowicz 	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
19755dfb5213SMarian Balakowicz 		if (ndepth == 1) {
19765dfb5213SMarian Balakowicz 			/* Direct child node of the component image node */
19775dfb5213SMarian Balakowicz 
19785dfb5213SMarian Balakowicz 			/*
19795dfb5213SMarian Balakowicz 			 * Check subnode name, must be equal to "hash".
19805dfb5213SMarian Balakowicz 			 * Multiple hash nodes require unique unit node
19815dfb5213SMarian Balakowicz 			 * names, e.g. hash@1, hash@2, etc.
19825dfb5213SMarian Balakowicz 			 */
19835dfb5213SMarian Balakowicz 			if (strncmp (fit_get_name(fit, noffset, NULL),
19845dfb5213SMarian Balakowicz 						FIT_HASH_NODENAME,
19855dfb5213SMarian Balakowicz 						strlen(FIT_HASH_NODENAME)) != 0) {
19865dfb5213SMarian Balakowicz 				/* Not a hash subnode, skip it */
19875dfb5213SMarian Balakowicz 				continue;
19885dfb5213SMarian Balakowicz 			}
19895dfb5213SMarian Balakowicz 
19905dfb5213SMarian Balakowicz 			if (fit_image_hash_get_algo (fit, noffset, &algo)) {
19915dfb5213SMarian Balakowicz 				printf ("Can't get hash algo property for "
19925dfb5213SMarian Balakowicz 					"'%s' hash node in '%s' image node\n",
19935dfb5213SMarian Balakowicz 					fit_get_name (fit, noffset, NULL),
19945dfb5213SMarian Balakowicz 					fit_get_name (fit, image_noffset, NULL));
19955dfb5213SMarian Balakowicz 				return -1;
19965dfb5213SMarian Balakowicz 			}
19975dfb5213SMarian Balakowicz 
19985dfb5213SMarian Balakowicz 			if (calculate_hash (data, size, algo, value, &value_len)) {
19995dfb5213SMarian Balakowicz 				printf ("Unsupported hash algorithm (%s) for "
20005dfb5213SMarian Balakowicz 					"'%s' hash node in '%s' image node\n",
20015dfb5213SMarian Balakowicz 					algo, fit_get_name (fit, noffset, NULL),
20025dfb5213SMarian Balakowicz 					fit_get_name (fit, image_noffset, NULL));
20035dfb5213SMarian Balakowicz 				return -1;
20045dfb5213SMarian Balakowicz 			}
20055dfb5213SMarian Balakowicz 
20065dfb5213SMarian Balakowicz 			if (fit_image_hash_set_value (fit, noffset, value,
20075dfb5213SMarian Balakowicz 							value_len)) {
20085dfb5213SMarian Balakowicz 				printf ("Can't set hash value for "
20095dfb5213SMarian Balakowicz 					"'%s' hash node in '%s' image node\n",
20105dfb5213SMarian Balakowicz 					fit_get_name (fit, noffset, NULL),
20115dfb5213SMarian Balakowicz 					fit_get_name (fit, image_noffset, NULL));
20125dfb5213SMarian Balakowicz 				return -1;
20135dfb5213SMarian Balakowicz 			}
20145dfb5213SMarian Balakowicz 		}
20155dfb5213SMarian Balakowicz 	}
20165dfb5213SMarian Balakowicz 
20175dfb5213SMarian Balakowicz 	return 0;
20185dfb5213SMarian Balakowicz }
20195dfb5213SMarian Balakowicz 
20205dfb5213SMarian Balakowicz /**
20215dfb5213SMarian Balakowicz  * fit_image_hash_set_value - set hash value in requested has node
20225dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
20235dfb5213SMarian Balakowicz  * @noffset: hash node offset
20245dfb5213SMarian Balakowicz  * @value: hash value to be set
20255dfb5213SMarian Balakowicz  * @value_len: hash value length
20265dfb5213SMarian Balakowicz  *
20275dfb5213SMarian Balakowicz  * fit_image_hash_set_value() attempts to set hash value in a node at offset
20285dfb5213SMarian Balakowicz  * given and returns operation status to the caller.
20295dfb5213SMarian Balakowicz  *
20305dfb5213SMarian Balakowicz  * returns
20315dfb5213SMarian Balakowicz  *     0, on success
20325dfb5213SMarian Balakowicz  *     -1, on failure
20335dfb5213SMarian Balakowicz  */
20345dfb5213SMarian Balakowicz int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value,
20355dfb5213SMarian Balakowicz 				int value_len)
20365dfb5213SMarian Balakowicz {
20375dfb5213SMarian Balakowicz 	int ret;
20385dfb5213SMarian Balakowicz 
20395dfb5213SMarian Balakowicz 	ret = fdt_setprop (fit, noffset, FIT_VALUE_PROP, value, value_len);
20405dfb5213SMarian Balakowicz 	if (ret) {
20415dfb5213SMarian Balakowicz 		printf ("Can't set hash '%s' property for '%s' node (%s)\n",
20425dfb5213SMarian Balakowicz 			FIT_VALUE_PROP, fit_get_name (fit, noffset, NULL),
20435dfb5213SMarian Balakowicz 			fdt_strerror (ret));
20445dfb5213SMarian Balakowicz 		return -1;
20455dfb5213SMarian Balakowicz 	}
20465dfb5213SMarian Balakowicz 
20475dfb5213SMarian Balakowicz 	return 0;
20485dfb5213SMarian Balakowicz }
20495dfb5213SMarian Balakowicz #endif /* USE_HOSTCC */
20505dfb5213SMarian Balakowicz 
20515dfb5213SMarian Balakowicz /**
20525dfb5213SMarian Balakowicz  * fit_image_check_hashes - verify data intergity
20535dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
20545dfb5213SMarian Balakowicz  * @image_noffset: component image node offset
20555dfb5213SMarian Balakowicz  *
20565dfb5213SMarian Balakowicz  * fit_image_check_hashes() goes over component image hash nodes,
20575dfb5213SMarian Balakowicz  * re-calculates each data hash and compares with the value stored in hash
20585dfb5213SMarian Balakowicz  * node.
20595dfb5213SMarian Balakowicz  *
20605dfb5213SMarian Balakowicz  * returns:
20615dfb5213SMarian Balakowicz  *     1, if all hashes are valid
20625dfb5213SMarian Balakowicz  *     0, otherwise (or on error)
20635dfb5213SMarian Balakowicz  */
20645dfb5213SMarian Balakowicz int fit_image_check_hashes (const void *fit, int image_noffset)
20655dfb5213SMarian Balakowicz {
20665dfb5213SMarian Balakowicz 	const void	*data;
20675dfb5213SMarian Balakowicz 	size_t		size;
20685dfb5213SMarian Balakowicz 	char		*algo;
20695dfb5213SMarian Balakowicz 	uint8_t		*fit_value;
20705dfb5213SMarian Balakowicz 	int		fit_value_len;
20715dfb5213SMarian Balakowicz 	uint8_t		value[FIT_MAX_HASH_LEN];
20725dfb5213SMarian Balakowicz 	int		value_len;
20735dfb5213SMarian Balakowicz 	int		noffset;
20745dfb5213SMarian Balakowicz 	int		ndepth;
20755dfb5213SMarian Balakowicz 	char		*err_msg = "";
20765dfb5213SMarian Balakowicz 
20775dfb5213SMarian Balakowicz 	/* Get image data and data length */
20785dfb5213SMarian Balakowicz 	if (fit_image_get_data (fit, image_noffset, &data, &size)) {
20795dfb5213SMarian Balakowicz 		printf ("Can't get image data/size\n");
20805dfb5213SMarian Balakowicz 		return 0;
20815dfb5213SMarian Balakowicz 	}
20825dfb5213SMarian Balakowicz 
20835dfb5213SMarian Balakowicz 	/* Process all hash subnodes of the component image node */
20845dfb5213SMarian Balakowicz 	for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
20855dfb5213SMarian Balakowicz 	     (noffset >= 0) && (ndepth > 0);
20865dfb5213SMarian Balakowicz 	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
20875dfb5213SMarian Balakowicz 		if (ndepth == 1) {
20885dfb5213SMarian Balakowicz 			/* Direct child node of the component image node */
20895dfb5213SMarian Balakowicz 
20905dfb5213SMarian Balakowicz 			/*
20915dfb5213SMarian Balakowicz 			 * Check subnode name, must be equal to "hash".
20925dfb5213SMarian Balakowicz 			 * Multiple hash nodes require unique unit node
20935dfb5213SMarian Balakowicz 			 * names, e.g. hash@1, hash@2, etc.
20945dfb5213SMarian Balakowicz 			 */
20955dfb5213SMarian Balakowicz 			if (strncmp (fit_get_name(fit, noffset, NULL),
20965dfb5213SMarian Balakowicz 					FIT_HASH_NODENAME,
20975dfb5213SMarian Balakowicz 					strlen(FIT_HASH_NODENAME)) != 0)
20985dfb5213SMarian Balakowicz 				continue;
20995dfb5213SMarian Balakowicz 
21005dfb5213SMarian Balakowicz 			if (fit_image_hash_get_algo (fit, noffset, &algo)) {
21015dfb5213SMarian Balakowicz 				err_msg = "Can't get hash algo property";
21025dfb5213SMarian Balakowicz 				goto error;
21035dfb5213SMarian Balakowicz 			}
21045dfb5213SMarian Balakowicz 			printf ("%s", algo);
21055dfb5213SMarian Balakowicz 
21065dfb5213SMarian Balakowicz 			if (fit_image_hash_get_value (fit, noffset, &fit_value,
21075dfb5213SMarian Balakowicz 							&fit_value_len)) {
21085dfb5213SMarian Balakowicz 				err_msg = "Can't get hash value property";
21095dfb5213SMarian Balakowicz 				goto error;
21105dfb5213SMarian Balakowicz 			}
21115dfb5213SMarian Balakowicz 
21125dfb5213SMarian Balakowicz 			if (calculate_hash (data, size, algo, value, &value_len)) {
21135dfb5213SMarian Balakowicz 				err_msg = "Unsupported hash algorithm";
21145dfb5213SMarian Balakowicz 				goto error;
21155dfb5213SMarian Balakowicz 			}
21165dfb5213SMarian Balakowicz 
21175dfb5213SMarian Balakowicz 			if (value_len != fit_value_len) {
21185dfb5213SMarian Balakowicz 				err_msg = "Bad hash value len";
21195dfb5213SMarian Balakowicz 				goto error;
21205dfb5213SMarian Balakowicz 			} else if (memcmp (value, fit_value, value_len) != 0) {
21215dfb5213SMarian Balakowicz 				err_msg = "Bad hash value";
21225dfb5213SMarian Balakowicz 				goto error;
21235dfb5213SMarian Balakowicz 			}
21245dfb5213SMarian Balakowicz 			printf ("+ ");
21255dfb5213SMarian Balakowicz 		}
21265dfb5213SMarian Balakowicz 	}
21275dfb5213SMarian Balakowicz 
21285dfb5213SMarian Balakowicz 	return 1;
21295dfb5213SMarian Balakowicz 
21305dfb5213SMarian Balakowicz error:
21315dfb5213SMarian Balakowicz 	printf ("%s for '%s' hash node in '%s' image node\n",
21325dfb5213SMarian Balakowicz 			err_msg, fit_get_name (fit, noffset, NULL),
21335dfb5213SMarian Balakowicz 			fit_get_name (fit, image_noffset, NULL));
21345dfb5213SMarian Balakowicz 	return 0;
21355dfb5213SMarian Balakowicz }
21365dfb5213SMarian Balakowicz 
21375dfb5213SMarian Balakowicz /**
21385dfb5213SMarian Balakowicz  * fit_image_check_os - check whether image node is of a given os type
21395dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
21405dfb5213SMarian Balakowicz  * @noffset: component image node offset
21415dfb5213SMarian Balakowicz  * @os: requested image os
21425dfb5213SMarian Balakowicz  *
21435dfb5213SMarian Balakowicz  * fit_image_check_os() reads image os property and compares its numeric
21445dfb5213SMarian Balakowicz  * id with the requested os. Comparison result is returned to the caller.
21455dfb5213SMarian Balakowicz  *
21465dfb5213SMarian Balakowicz  * returns:
21475dfb5213SMarian Balakowicz  *     1 if image is of given os type
21485dfb5213SMarian Balakowicz  *     0 otherwise (or on error)
21495dfb5213SMarian Balakowicz  */
21505dfb5213SMarian Balakowicz int fit_image_check_os (const void *fit, int noffset, uint8_t os)
21515dfb5213SMarian Balakowicz {
21525dfb5213SMarian Balakowicz 	uint8_t image_os;
21535dfb5213SMarian Balakowicz 
21545dfb5213SMarian Balakowicz 	if (fit_image_get_os (fit, noffset, &image_os))
21555dfb5213SMarian Balakowicz 		return 0;
21565dfb5213SMarian Balakowicz 	return (os == image_os);
21575dfb5213SMarian Balakowicz }
21585dfb5213SMarian Balakowicz 
21595dfb5213SMarian Balakowicz /**
21605dfb5213SMarian Balakowicz  * fit_image_check_arch - check whether image node is of a given arch
21615dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
21625dfb5213SMarian Balakowicz  * @noffset: component image node offset
21635dfb5213SMarian Balakowicz  * @arch: requested imagearch
21645dfb5213SMarian Balakowicz  *
21655dfb5213SMarian Balakowicz  * fit_image_check_arch() reads image arch property and compares its numeric
21665dfb5213SMarian Balakowicz  * id with the requested arch. Comparison result is returned to the caller.
21675dfb5213SMarian Balakowicz  *
21685dfb5213SMarian Balakowicz  * returns:
21695dfb5213SMarian Balakowicz  *     1 if image is of given arch
21705dfb5213SMarian Balakowicz  *     0 otherwise (or on error)
21715dfb5213SMarian Balakowicz  */
21725dfb5213SMarian Balakowicz int fit_image_check_arch (const void *fit, int noffset, uint8_t arch)
21735dfb5213SMarian Balakowicz {
21745dfb5213SMarian Balakowicz 	uint8_t image_arch;
21755dfb5213SMarian Balakowicz 
21765dfb5213SMarian Balakowicz 	if (fit_image_get_arch (fit, noffset, &image_arch))
21775dfb5213SMarian Balakowicz 		return 0;
21785dfb5213SMarian Balakowicz 	return (arch == image_arch);
21795dfb5213SMarian Balakowicz }
21805dfb5213SMarian Balakowicz 
21815dfb5213SMarian Balakowicz /**
21825dfb5213SMarian Balakowicz  * fit_image_check_type - check whether image node is of a given type
21835dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
21845dfb5213SMarian Balakowicz  * @noffset: component image node offset
21855dfb5213SMarian Balakowicz  * @type: requested image type
21865dfb5213SMarian Balakowicz  *
21875dfb5213SMarian Balakowicz  * fit_image_check_type() reads image type property and compares its numeric
21885dfb5213SMarian Balakowicz  * id with the requested type. Comparison result is returned to the caller.
21895dfb5213SMarian Balakowicz  *
21905dfb5213SMarian Balakowicz  * returns:
21915dfb5213SMarian Balakowicz  *     1 if image is of given type
21925dfb5213SMarian Balakowicz  *     0 otherwise (or on error)
21935dfb5213SMarian Balakowicz  */
21945dfb5213SMarian Balakowicz int fit_image_check_type (const void *fit, int noffset, uint8_t type)
21955dfb5213SMarian Balakowicz {
21965dfb5213SMarian Balakowicz 	uint8_t image_type;
21975dfb5213SMarian Balakowicz 
21985dfb5213SMarian Balakowicz 	if (fit_image_get_type (fit, noffset, &image_type))
21995dfb5213SMarian Balakowicz 		return 0;
22005dfb5213SMarian Balakowicz 	return (type == image_type);
22015dfb5213SMarian Balakowicz }
22025dfb5213SMarian Balakowicz 
22035dfb5213SMarian Balakowicz /**
22045dfb5213SMarian Balakowicz  * fit_image_check_comp - check whether image node uses given compression
22055dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
22065dfb5213SMarian Balakowicz  * @noffset: component image node offset
22075dfb5213SMarian Balakowicz  * @comp: requested image compression type
22085dfb5213SMarian Balakowicz  *
22095dfb5213SMarian Balakowicz  * fit_image_check_comp() reads image compression property and compares its
22105dfb5213SMarian Balakowicz  * numeric id with the requested compression type. Comparison result is
22115dfb5213SMarian Balakowicz  * returned to the caller.
22125dfb5213SMarian Balakowicz  *
22135dfb5213SMarian Balakowicz  * returns:
22145dfb5213SMarian Balakowicz  *     1 if image uses requested compression
22155dfb5213SMarian Balakowicz  *     0 otherwise (or on error)
22165dfb5213SMarian Balakowicz  */
22175dfb5213SMarian Balakowicz int fit_image_check_comp (const void *fit, int noffset, uint8_t comp)
22185dfb5213SMarian Balakowicz {
22195dfb5213SMarian Balakowicz 	uint8_t image_comp;
22205dfb5213SMarian Balakowicz 
22215dfb5213SMarian Balakowicz 	if (fit_image_get_comp (fit, noffset, &image_comp))
22225dfb5213SMarian Balakowicz 		return 0;
22235dfb5213SMarian Balakowicz 	return (comp == image_comp);
22245dfb5213SMarian Balakowicz }
22255dfb5213SMarian Balakowicz 
22265dfb5213SMarian Balakowicz /**
22275dfb5213SMarian Balakowicz  * fit_check_format - sanity check FIT image format
22285dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
22295dfb5213SMarian Balakowicz  *
22305dfb5213SMarian Balakowicz  * fit_check_format() runs a basic sanity FIT image verification.
22315dfb5213SMarian Balakowicz  * Routine checks for mandatory properties, nodes, etc.
22325dfb5213SMarian Balakowicz  *
22335dfb5213SMarian Balakowicz  * returns:
22345dfb5213SMarian Balakowicz  *     1, on success
22355dfb5213SMarian Balakowicz  *     0, on failure
22365dfb5213SMarian Balakowicz  */
22375dfb5213SMarian Balakowicz int fit_check_format (const void *fit)
22385dfb5213SMarian Balakowicz {
22395dfb5213SMarian Balakowicz 	/* mandatory / node 'description' property */
22405dfb5213SMarian Balakowicz 	if (fdt_getprop (fit, 0, FIT_DESC_PROP, NULL) == NULL) {
22415dfb5213SMarian Balakowicz 		debug ("Wrong FIT format: no description\n");
22425dfb5213SMarian Balakowicz 		return 0;
22435dfb5213SMarian Balakowicz 	}
22445dfb5213SMarian Balakowicz 
22455dfb5213SMarian Balakowicz #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
22465dfb5213SMarian Balakowicz 	/* mandatory / node 'timestamp' property */
22475dfb5213SMarian Balakowicz 	if (fdt_getprop (fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) {
22485dfb5213SMarian Balakowicz 		debug ("Wrong FIT format: no description\n");
22495dfb5213SMarian Balakowicz 		return 0;
22505dfb5213SMarian Balakowicz 	}
22515dfb5213SMarian Balakowicz #endif
22525dfb5213SMarian Balakowicz 
22535dfb5213SMarian Balakowicz 	/* mandatory subimages parent '/images' node */
22545dfb5213SMarian Balakowicz 	if (fdt_path_offset (fit, FIT_IMAGES_PATH) < 0) {
22555dfb5213SMarian Balakowicz 		debug ("Wrong FIT format: no images parent node\n");
22565dfb5213SMarian Balakowicz 		return 0;
22575dfb5213SMarian Balakowicz 	}
22585dfb5213SMarian Balakowicz 
22595dfb5213SMarian Balakowicz 	return 1;
22605dfb5213SMarian Balakowicz }
22615dfb5213SMarian Balakowicz 
22625dfb5213SMarian Balakowicz /**
22635dfb5213SMarian Balakowicz  * fit_conf_get_node - get node offset for configuration of a given unit name
22645dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
22655dfb5213SMarian Balakowicz  * @conf_uname: configuration node unit name
22665dfb5213SMarian Balakowicz  *
22675dfb5213SMarian Balakowicz  * fit_conf_get_node() finds a configuration (withing the '/configurations'
22685dfb5213SMarian Balakowicz  * parant node) of a provided unit name. If configuration is found its node offset
22695dfb5213SMarian Balakowicz  * is returned to the caller.
22705dfb5213SMarian Balakowicz  *
22715dfb5213SMarian Balakowicz  * When NULL is provided in second argument fit_conf_get_node() will search
22725dfb5213SMarian Balakowicz  * for a default configuration node instead. Default configuration node unit name
22735dfb5213SMarian Balakowicz  * is retrived from FIT_DEFAULT_PROP property of the '/configurations' node.
22745dfb5213SMarian Balakowicz  *
22755dfb5213SMarian Balakowicz  * returns:
22765dfb5213SMarian Balakowicz  *     configuration node offset when found (>=0)
22775dfb5213SMarian Balakowicz  *     negative number on failure (FDT_ERR_* code)
22785dfb5213SMarian Balakowicz  */
22795dfb5213SMarian Balakowicz int fit_conf_get_node (const void *fit, const char *conf_uname)
22805dfb5213SMarian Balakowicz {
22815dfb5213SMarian Balakowicz 	int noffset, confs_noffset;
22825dfb5213SMarian Balakowicz 	int len;
22835dfb5213SMarian Balakowicz 
22845dfb5213SMarian Balakowicz 	confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH);
22855dfb5213SMarian Balakowicz 	if (confs_noffset < 0) {
22865dfb5213SMarian Balakowicz 		debug ("Can't find configurations parent node '%s' (%s)\n",
22875dfb5213SMarian Balakowicz 			FIT_CONFS_PATH, fdt_strerror (confs_noffset));
22885dfb5213SMarian Balakowicz 		return confs_noffset;
22895dfb5213SMarian Balakowicz 	}
22905dfb5213SMarian Balakowicz 
22915dfb5213SMarian Balakowicz 	if (conf_uname == NULL) {
22925dfb5213SMarian Balakowicz 		/* get configuration unit name from the default property */
22935dfb5213SMarian Balakowicz 		debug ("No configuration specified, trying default...\n");
22945dfb5213SMarian Balakowicz 		conf_uname = (char *)fdt_getprop (fit, confs_noffset, FIT_DEFAULT_PROP, &len);
22955dfb5213SMarian Balakowicz 		if (conf_uname == NULL) {
22965dfb5213SMarian Balakowicz 			fit_get_debug (fit, confs_noffset, FIT_DEFAULT_PROP, len);
22975dfb5213SMarian Balakowicz 			return len;
22985dfb5213SMarian Balakowicz 		}
22995dfb5213SMarian Balakowicz 		debug ("Found default configuration: '%s'\n", conf_uname);
23005dfb5213SMarian Balakowicz 	}
23015dfb5213SMarian Balakowicz 
23025dfb5213SMarian Balakowicz 	noffset = fdt_subnode_offset (fit, confs_noffset, conf_uname);
23035dfb5213SMarian Balakowicz 	if (noffset < 0) {
23045dfb5213SMarian Balakowicz 		debug ("Can't get node offset for configuration unit name: '%s' (%s)\n",
23055dfb5213SMarian Balakowicz 			conf_uname, fdt_strerror (noffset));
23065dfb5213SMarian Balakowicz 	}
23075dfb5213SMarian Balakowicz 
23085dfb5213SMarian Balakowicz 	return noffset;
23095dfb5213SMarian Balakowicz }
23105dfb5213SMarian Balakowicz 
23115dfb5213SMarian Balakowicz static int __fit_conf_get_prop_node (const void *fit, int noffset,
23125dfb5213SMarian Balakowicz 		const char *prop_name)
23135dfb5213SMarian Balakowicz {
23145dfb5213SMarian Balakowicz 	char *uname;
23155dfb5213SMarian Balakowicz 	int len;
23165dfb5213SMarian Balakowicz 
23175dfb5213SMarian Balakowicz 	/* get kernel image unit name from configuration kernel property */
23185dfb5213SMarian Balakowicz 	uname = (char *)fdt_getprop (fit, noffset, prop_name, &len);
23195dfb5213SMarian Balakowicz 	if (uname == NULL)
23205dfb5213SMarian Balakowicz 		return len;
23215dfb5213SMarian Balakowicz 
23225dfb5213SMarian Balakowicz 	return fit_image_get_node (fit, uname);
23235dfb5213SMarian Balakowicz }
23245dfb5213SMarian Balakowicz 
23255dfb5213SMarian Balakowicz /**
23265dfb5213SMarian Balakowicz  * fit_conf_get_kernel_node - get kernel image node offset that corresponds to
23275dfb5213SMarian Balakowicz  * a given configuration
23285dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
23295dfb5213SMarian Balakowicz  * @noffset: configuration node offset
23305dfb5213SMarian Balakowicz  *
23315dfb5213SMarian Balakowicz  * fit_conf_get_kernel_node() retrives kernel image node unit name from
23325dfb5213SMarian Balakowicz  * configuration FIT_KERNEL_PROP property and translates it to the node
23335dfb5213SMarian Balakowicz  * offset.
23345dfb5213SMarian Balakowicz  *
23355dfb5213SMarian Balakowicz  * returns:
23365dfb5213SMarian Balakowicz  *     image node offset when found (>=0)
23375dfb5213SMarian Balakowicz  *     negative number on failure (FDT_ERR_* code)
23385dfb5213SMarian Balakowicz  */
23395dfb5213SMarian Balakowicz int fit_conf_get_kernel_node (const void *fit, int noffset)
23405dfb5213SMarian Balakowicz {
23415dfb5213SMarian Balakowicz 	return __fit_conf_get_prop_node (fit, noffset, FIT_KERNEL_PROP);
23425dfb5213SMarian Balakowicz }
23435dfb5213SMarian Balakowicz 
23445dfb5213SMarian Balakowicz /**
23455dfb5213SMarian Balakowicz  * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to
23465dfb5213SMarian Balakowicz  * a given configuration
23475dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
23485dfb5213SMarian Balakowicz  * @noffset: configuration node offset
23495dfb5213SMarian Balakowicz  *
23505dfb5213SMarian Balakowicz  * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from
23515dfb5213SMarian Balakowicz  * configuration FIT_KERNEL_PROP property and translates it to the node
23525dfb5213SMarian Balakowicz  * offset.
23535dfb5213SMarian Balakowicz  *
23545dfb5213SMarian Balakowicz  * returns:
23555dfb5213SMarian Balakowicz  *     image node offset when found (>=0)
23565dfb5213SMarian Balakowicz  *     negative number on failure (FDT_ERR_* code)
23575dfb5213SMarian Balakowicz  */
23585dfb5213SMarian Balakowicz int fit_conf_get_ramdisk_node (const void *fit, int noffset)
23595dfb5213SMarian Balakowicz {
23605dfb5213SMarian Balakowicz 	return __fit_conf_get_prop_node (fit, noffset, FIT_RAMDISK_PROP);
23615dfb5213SMarian Balakowicz }
23625dfb5213SMarian Balakowicz 
23635dfb5213SMarian Balakowicz /**
23645dfb5213SMarian Balakowicz  * fit_conf_get_fdt_node - get fdt image node offset that corresponds to
23655dfb5213SMarian Balakowicz  * a given configuration
23665dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
23675dfb5213SMarian Balakowicz  * @noffset: configuration node offset
23685dfb5213SMarian Balakowicz  *
23695dfb5213SMarian Balakowicz  * fit_conf_get_fdt_node() retrives fdt image node unit name from
23705dfb5213SMarian Balakowicz  * configuration FIT_KERNEL_PROP property and translates it to the node
23715dfb5213SMarian Balakowicz  * offset.
23725dfb5213SMarian Balakowicz  *
23735dfb5213SMarian Balakowicz  * returns:
23745dfb5213SMarian Balakowicz  *     image node offset when found (>=0)
23755dfb5213SMarian Balakowicz  *     negative number on failure (FDT_ERR_* code)
23765dfb5213SMarian Balakowicz  */
23775dfb5213SMarian Balakowicz int fit_conf_get_fdt_node (const void *fit, int noffset)
23785dfb5213SMarian Balakowicz {
23795dfb5213SMarian Balakowicz 	return __fit_conf_get_prop_node (fit, noffset, FIT_FDT_PROP);
23805dfb5213SMarian Balakowicz }
23815dfb5213SMarian Balakowicz 
23825dfb5213SMarian Balakowicz /**
23835dfb5213SMarian Balakowicz  * fit_conf_print - prints out the FIT configuration details
23845dfb5213SMarian Balakowicz  * @fit: pointer to the FIT format image header
23855dfb5213SMarian Balakowicz  * @conf_noffset: offset of the configuration node
23865dfb5213SMarian Balakowicz  * @p: pointer to prefix string
23875dfb5213SMarian Balakowicz  *
23885dfb5213SMarian Balakowicz  * fit_conf_print() lists all mandatory properies for the processed
23895dfb5213SMarian Balakowicz  * configuration node.
23905dfb5213SMarian Balakowicz  *
23915dfb5213SMarian Balakowicz  * returns:
23925dfb5213SMarian Balakowicz  *     no returned results
23935dfb5213SMarian Balakowicz  */
23945dfb5213SMarian Balakowicz void fit_conf_print (const void *fit, int noffset, const char *p)
23955dfb5213SMarian Balakowicz {
23965dfb5213SMarian Balakowicz 	char *desc;
23975dfb5213SMarian Balakowicz 	char *uname;
23985dfb5213SMarian Balakowicz 	int ret;
23995dfb5213SMarian Balakowicz 
24005dfb5213SMarian Balakowicz 	/* Mandatory properties */
24015dfb5213SMarian Balakowicz 	ret = fit_get_desc (fit, noffset, &desc);
24025dfb5213SMarian Balakowicz 	printf ("%s  Description:  ", p);
24035dfb5213SMarian Balakowicz 	if (ret)
24045dfb5213SMarian Balakowicz 		printf ("unavailable\n");
24055dfb5213SMarian Balakowicz 	else
24065dfb5213SMarian Balakowicz 		printf ("%s\n", desc);
24075dfb5213SMarian Balakowicz 
24085dfb5213SMarian Balakowicz 	uname = (char *)fdt_getprop (fit, noffset, FIT_KERNEL_PROP, NULL);
24095dfb5213SMarian Balakowicz 	printf ("%s  Kernel:       ", p);
24105dfb5213SMarian Balakowicz 	if (uname == NULL)
24115dfb5213SMarian Balakowicz 		printf ("unavailable\n");
24125dfb5213SMarian Balakowicz 	else
24135dfb5213SMarian Balakowicz 		printf ("%s\n", uname);
24145dfb5213SMarian Balakowicz 
24155dfb5213SMarian Balakowicz 	/* Optional properties */
24165dfb5213SMarian Balakowicz 	uname = (char *)fdt_getprop (fit, noffset, FIT_RAMDISK_PROP, NULL);
24175dfb5213SMarian Balakowicz 	if (uname)
24185dfb5213SMarian Balakowicz 		printf ("%s  Init Ramdisk: %s\n", p, uname);
24195dfb5213SMarian Balakowicz 
24205dfb5213SMarian Balakowicz 	uname = (char *)fdt_getprop (fit, noffset, FIT_FDT_PROP, NULL);
24215dfb5213SMarian Balakowicz 	if (uname)
24225dfb5213SMarian Balakowicz 		printf ("%s  FDT:          %s\n", p, uname);
24235dfb5213SMarian Balakowicz }
2424c8779648SMarian Balakowicz 
2425c8779648SMarian Balakowicz /**
2426c8779648SMarian Balakowicz  * fit_check_ramdisk - verify FIT format ramdisk subimage
2427c8779648SMarian Balakowicz  * @fit_hdr: pointer to the FIT ramdisk header
2428c8779648SMarian Balakowicz  * @rd_noffset: ramdisk subimage node offset within FIT image
2429c8779648SMarian Balakowicz  * @arch: requested ramdisk image architecture type
2430c8779648SMarian Balakowicz  * @verify: data CRC verification flag
2431c8779648SMarian Balakowicz  *
2432c8779648SMarian Balakowicz  * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from
2433c8779648SMarian Balakowicz  * specified FIT image.
2434c8779648SMarian Balakowicz  *
2435c8779648SMarian Balakowicz  * returns:
2436c8779648SMarian Balakowicz  *     1, on success
2437c8779648SMarian Balakowicz  *     0, on failure
2438c8779648SMarian Balakowicz  */
2439c8779648SMarian Balakowicz #ifndef USE_HOSTCC
2440c8779648SMarian Balakowicz static int fit_check_ramdisk (const void *fit, int rd_noffset, uint8_t arch, int verify)
2441c8779648SMarian Balakowicz {
2442c8779648SMarian Balakowicz 	fit_image_print (fit, rd_noffset, "   ");
2443c8779648SMarian Balakowicz 
2444c8779648SMarian Balakowicz 	if (verify) {
2445c8779648SMarian Balakowicz 		puts ("   Verifying Hash Integrity ... ");
2446c8779648SMarian Balakowicz 		if (!fit_image_check_hashes (fit, rd_noffset)) {
2447c8779648SMarian Balakowicz 			puts ("Bad Data Hash\n");
2448c8779648SMarian Balakowicz 			return 0;
2449c8779648SMarian Balakowicz 		}
2450c8779648SMarian Balakowicz 		puts ("OK\n");
2451c8779648SMarian Balakowicz 	}
2452c8779648SMarian Balakowicz 
2453c8779648SMarian Balakowicz 	if (!fit_image_check_os (fit, rd_noffset, IH_OS_LINUX) ||
2454c8779648SMarian Balakowicz 	    !fit_image_check_arch (fit, rd_noffset, arch) ||
2455c8779648SMarian Balakowicz 	    !fit_image_check_type (fit, rd_noffset, IH_TYPE_RAMDISK)) {
2456c8779648SMarian Balakowicz 		printf ("No Linux %s Ramdisk Image\n",
2457c8779648SMarian Balakowicz 				genimg_get_arch_name(arch));
2458c8779648SMarian Balakowicz 		return 0;
2459c8779648SMarian Balakowicz 	}
2460c8779648SMarian Balakowicz 
2461c8779648SMarian Balakowicz 	return 1;
2462c8779648SMarian Balakowicz }
2463c8779648SMarian Balakowicz #endif /* USE_HOSTCC */
24645dfb5213SMarian Balakowicz #endif /* CONFIG_FIT */
2465