xref: /openbmc/u-boot/common/image.c (revision 4efbe9db)
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 
48fff888a1SMarian Balakowicz #if defined(CONFIG_FIT)
49fff888a1SMarian Balakowicz #include <fdt.h>
50fff888a1SMarian Balakowicz #include <libfdt.h>
51fff888a1SMarian Balakowicz #include <fdt_support.h>
52fff888a1SMarian Balakowicz #endif
53fff888a1SMarian Balakowicz 
545ad03eb3SMarian Balakowicz extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
55b6b0fe64SMarian Balakowicz 
56b6b0fe64SMarian Balakowicz #ifdef CONFIG_CMD_BDI
57b6b0fe64SMarian Balakowicz extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
58b6b0fe64SMarian Balakowicz #endif
59b6b0fe64SMarian Balakowicz 
60b6b0fe64SMarian Balakowicz DECLARE_GLOBAL_DATA_PTR;
618a5ea3e6SMarian Balakowicz 
628a5ea3e6SMarian Balakowicz static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag,
638a5ea3e6SMarian Balakowicz 		int argc, char *argv[],
648a5ea3e6SMarian Balakowicz 		ulong rd_addr, uint8_t arch, int verify);
65b97a2a0aSMarian Balakowicz #else
66b97a2a0aSMarian Balakowicz #include "mkimage.h"
67b6b0fe64SMarian Balakowicz #endif /* USE_HOSTCC*/
68b97a2a0aSMarian Balakowicz 
69b97a2a0aSMarian Balakowicz #include <image.h>
70b97a2a0aSMarian Balakowicz 
71b97a2a0aSMarian Balakowicz unsigned long crc32 (unsigned long, const unsigned char *, unsigned int);
72b97a2a0aSMarian Balakowicz 
73b97a2a0aSMarian Balakowicz int image_check_hcrc (image_header_t *hdr)
74b97a2a0aSMarian Balakowicz {
75b97a2a0aSMarian Balakowicz 	ulong hcrc;
76b97a2a0aSMarian Balakowicz 	ulong len = image_get_header_size ();
77b97a2a0aSMarian Balakowicz 	image_header_t header;
78b97a2a0aSMarian Balakowicz 
79b97a2a0aSMarian Balakowicz 	/* Copy header so we can blank CRC field for re-calculation */
80b97a2a0aSMarian Balakowicz 	memmove (&header, (char *)hdr, image_get_header_size ());
81b97a2a0aSMarian Balakowicz 	image_set_hcrc (&header, 0);
82b97a2a0aSMarian Balakowicz 
83b97a2a0aSMarian Balakowicz 	hcrc = crc32 (0, (unsigned char *)&header, len);
84b97a2a0aSMarian Balakowicz 
85b97a2a0aSMarian Balakowicz 	return (hcrc == image_get_hcrc (hdr));
86b97a2a0aSMarian Balakowicz }
87b97a2a0aSMarian Balakowicz 
88b97a2a0aSMarian Balakowicz int image_check_dcrc (image_header_t *hdr)
89b97a2a0aSMarian Balakowicz {
90b97a2a0aSMarian Balakowicz 	ulong data = image_get_data (hdr);
91b97a2a0aSMarian Balakowicz 	ulong len = image_get_data_size (hdr);
92b97a2a0aSMarian Balakowicz 	ulong dcrc = crc32 (0, (unsigned char *)data, len);
93b97a2a0aSMarian Balakowicz 
94b97a2a0aSMarian Balakowicz 	return (dcrc == image_get_dcrc (hdr));
95b97a2a0aSMarian Balakowicz }
96b97a2a0aSMarian Balakowicz 
97af13cdbcSMarian Balakowicz #ifndef USE_HOSTCC
98b97a2a0aSMarian Balakowicz int image_check_dcrc_wd (image_header_t *hdr, ulong chunksz)
99b97a2a0aSMarian Balakowicz {
100b97a2a0aSMarian Balakowicz 	ulong dcrc = 0;
101b97a2a0aSMarian Balakowicz 	ulong len = image_get_data_size (hdr);
102b97a2a0aSMarian Balakowicz 	ulong data = image_get_data (hdr);
103b97a2a0aSMarian Balakowicz 
104b97a2a0aSMarian Balakowicz #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
105b97a2a0aSMarian Balakowicz 	ulong cdata = data;
106b97a2a0aSMarian Balakowicz 	ulong edata = cdata + len;
107b97a2a0aSMarian Balakowicz 
108b97a2a0aSMarian Balakowicz 	while (cdata < edata) {
109b97a2a0aSMarian Balakowicz 		ulong chunk = edata - cdata;
110b97a2a0aSMarian Balakowicz 
111b97a2a0aSMarian Balakowicz 		if (chunk > chunksz)
112b97a2a0aSMarian Balakowicz 			chunk = chunksz;
113b97a2a0aSMarian Balakowicz 		dcrc = crc32 (dcrc, (unsigned char *)cdata, chunk);
114b97a2a0aSMarian Balakowicz 		cdata += chunk;
115b97a2a0aSMarian Balakowicz 
116b97a2a0aSMarian Balakowicz 		WATCHDOG_RESET ();
117b97a2a0aSMarian Balakowicz 	}
118b97a2a0aSMarian Balakowicz #else
119b97a2a0aSMarian Balakowicz 	dcrc = crc32 (0, (unsigned char *)data, len);
120b97a2a0aSMarian Balakowicz #endif
121b97a2a0aSMarian Balakowicz 
122b97a2a0aSMarian Balakowicz 	return (dcrc == image_get_dcrc (hdr));
123b97a2a0aSMarian Balakowicz }
124b97a2a0aSMarian Balakowicz 
125b97a2a0aSMarian Balakowicz int getenv_verify (void)
126b97a2a0aSMarian Balakowicz {
127b97a2a0aSMarian Balakowicz 	char *s = getenv ("verify");
128b97a2a0aSMarian Balakowicz 	return (s && (*s == 'n')) ? 0 : 1;
129b97a2a0aSMarian Balakowicz }
130af13cdbcSMarian Balakowicz 
131af13cdbcSMarian Balakowicz void memmove_wd (void *to, void *from, size_t len, ulong chunksz)
132af13cdbcSMarian Balakowicz {
133af13cdbcSMarian Balakowicz #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
134af13cdbcSMarian Balakowicz 	while (len > 0) {
135af13cdbcSMarian Balakowicz 		size_t tail = (len > chunksz) ? chunksz : len;
136af13cdbcSMarian Balakowicz 		WATCHDOG_RESET ();
137af13cdbcSMarian Balakowicz 		memmove (to, from, tail);
138af13cdbcSMarian Balakowicz 		to += tail;
139af13cdbcSMarian Balakowicz 		from += tail;
140af13cdbcSMarian Balakowicz 		len -= tail;
141af13cdbcSMarian Balakowicz 	}
142af13cdbcSMarian Balakowicz #else	/* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
143af13cdbcSMarian Balakowicz 	memmove (to, from, len);
144af13cdbcSMarian Balakowicz #endif	/* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
145af13cdbcSMarian Balakowicz }
146af13cdbcSMarian Balakowicz #endif /* USE_HOSTCC */
147f13e7b2eSMarian Balakowicz 
148f13e7b2eSMarian Balakowicz /**
149f13e7b2eSMarian Balakowicz  * image_multi_count - get component (sub-image) count
150f13e7b2eSMarian Balakowicz  * @hdr: pointer to the header of the multi component image
151f13e7b2eSMarian Balakowicz  *
152f13e7b2eSMarian Balakowicz  * image_multi_count() returns number of components in a multi
153f13e7b2eSMarian Balakowicz  * component image.
154f13e7b2eSMarian Balakowicz  *
155f13e7b2eSMarian Balakowicz  * Note: no checking of the image type is done, caller must pass
156f13e7b2eSMarian Balakowicz  * a valid multi component image.
157f13e7b2eSMarian Balakowicz  *
158f13e7b2eSMarian Balakowicz  * returns:
159f13e7b2eSMarian Balakowicz  *     number of components
160f13e7b2eSMarian Balakowicz  */
161f13e7b2eSMarian Balakowicz ulong image_multi_count (image_header_t *hdr)
162f13e7b2eSMarian Balakowicz {
163f13e7b2eSMarian Balakowicz 	ulong i, count = 0;
164f13e7b2eSMarian Balakowicz 	ulong *size;
165f13e7b2eSMarian Balakowicz 
166f13e7b2eSMarian Balakowicz 	/* get start of the image payload, which in case of multi
167f13e7b2eSMarian Balakowicz 	 * component images that points to a table of component sizes */
168f13e7b2eSMarian Balakowicz 	size = (ulong *)image_get_data (hdr);
169f13e7b2eSMarian Balakowicz 
170f13e7b2eSMarian Balakowicz 	/* count non empty slots */
171f13e7b2eSMarian Balakowicz 	for (i = 0; size[i]; ++i)
172f13e7b2eSMarian Balakowicz 		count++;
173f13e7b2eSMarian Balakowicz 
174f13e7b2eSMarian Balakowicz 	return count;
175f13e7b2eSMarian Balakowicz }
176f13e7b2eSMarian Balakowicz 
177f13e7b2eSMarian Balakowicz /**
178f13e7b2eSMarian Balakowicz  * image_multi_getimg - get component data address and size
179f13e7b2eSMarian Balakowicz  * @hdr: pointer to the header of the multi component image
180f13e7b2eSMarian Balakowicz  * @idx: index of the requested component
181f13e7b2eSMarian Balakowicz  * @data: pointer to a ulong variable, will hold component data address
182f13e7b2eSMarian Balakowicz  * @len: pointer to a ulong variable, will hold component size
183f13e7b2eSMarian Balakowicz  *
184f13e7b2eSMarian Balakowicz  * image_multi_getimg() returns size and data address for the requested
185f13e7b2eSMarian Balakowicz  * component in a multi component image.
186f13e7b2eSMarian Balakowicz  *
187f13e7b2eSMarian Balakowicz  * Note: no checking of the image type is done, caller must pass
188f13e7b2eSMarian Balakowicz  * a valid multi component image.
189f13e7b2eSMarian Balakowicz  *
190f13e7b2eSMarian Balakowicz  * returns:
191f13e7b2eSMarian Balakowicz  *     data address and size of the component, if idx is valid
192f13e7b2eSMarian Balakowicz  *     0 in data and len, if idx is out of range
193f13e7b2eSMarian Balakowicz  */
194f13e7b2eSMarian Balakowicz void image_multi_getimg (image_header_t *hdr, ulong idx,
195f13e7b2eSMarian Balakowicz 			ulong *data, ulong *len)
196f13e7b2eSMarian Balakowicz {
197f13e7b2eSMarian Balakowicz 	int i;
198f13e7b2eSMarian Balakowicz 	ulong *size;
199f13e7b2eSMarian Balakowicz 	ulong offset, tail, count, img_data;
200f13e7b2eSMarian Balakowicz 
201f13e7b2eSMarian Balakowicz 	/* get number of component */
202f13e7b2eSMarian Balakowicz 	count = image_multi_count (hdr);
203f13e7b2eSMarian Balakowicz 
204f13e7b2eSMarian Balakowicz 	/* get start of the image payload, which in case of multi
205f13e7b2eSMarian Balakowicz 	 * component images that points to a table of component sizes */
206f13e7b2eSMarian Balakowicz 	size = (ulong *)image_get_data (hdr);
207f13e7b2eSMarian Balakowicz 
208f13e7b2eSMarian Balakowicz 	/* get address of the proper component data start, which means
209f13e7b2eSMarian Balakowicz 	 * skipping sizes table (add 1 for last, null entry) */
210f13e7b2eSMarian Balakowicz 	img_data = image_get_data (hdr) + (count + 1) * sizeof (ulong);
211f13e7b2eSMarian Balakowicz 
212f13e7b2eSMarian Balakowicz 	if (idx < count) {
213f13e7b2eSMarian Balakowicz 		*len = size[idx];
214f13e7b2eSMarian Balakowicz 		offset = 0;
215f13e7b2eSMarian Balakowicz 		tail = 0;
216f13e7b2eSMarian Balakowicz 
217f13e7b2eSMarian Balakowicz 		/* go over all indices preceding requested component idx */
218f13e7b2eSMarian Balakowicz 		for (i = 0; i < idx; i++) {
219f13e7b2eSMarian Balakowicz 			/* add up i-th component size */
220f13e7b2eSMarian Balakowicz 			offset += size[i];
221f13e7b2eSMarian Balakowicz 
222f13e7b2eSMarian Balakowicz 			/* add up alignment for i-th component */
223f13e7b2eSMarian Balakowicz 			tail += (4 - size[i] % 4);
224f13e7b2eSMarian Balakowicz 		}
225f13e7b2eSMarian Balakowicz 
226f13e7b2eSMarian Balakowicz 		/* calculate idx-th component data address */
227f13e7b2eSMarian Balakowicz 		*data = img_data + offset + tail;
228f13e7b2eSMarian Balakowicz 	} else {
229f13e7b2eSMarian Balakowicz 		*len = 0;
230f13e7b2eSMarian Balakowicz 		*data = 0;
231f13e7b2eSMarian Balakowicz 	}
232f13e7b2eSMarian Balakowicz }
23342b73e8eSMarian Balakowicz 
23442b73e8eSMarian Balakowicz #ifndef USE_HOSTCC
23542b73e8eSMarian Balakowicz const char* image_get_os_name (uint8_t os)
23642b73e8eSMarian Balakowicz {
23742b73e8eSMarian Balakowicz 	const char *name;
23842b73e8eSMarian Balakowicz 
23942b73e8eSMarian Balakowicz 	switch (os) {
24042b73e8eSMarian Balakowicz 	case IH_OS_INVALID:	name = "Invalid OS";		break;
24142b73e8eSMarian Balakowicz 	case IH_OS_NETBSD:	name = "NetBSD";		break;
24242b73e8eSMarian Balakowicz 	case IH_OS_LINUX:	name = "Linux";			break;
24342b73e8eSMarian Balakowicz 	case IH_OS_VXWORKS:	name = "VxWorks";		break;
24442b73e8eSMarian Balakowicz 	case IH_OS_QNX:		name = "QNX";			break;
24542b73e8eSMarian Balakowicz 	case IH_OS_U_BOOT:	name = "U-Boot";		break;
24642b73e8eSMarian Balakowicz 	case IH_OS_RTEMS:	name = "RTEMS";			break;
24742b73e8eSMarian Balakowicz #ifdef CONFIG_ARTOS
24842b73e8eSMarian Balakowicz 	case IH_OS_ARTOS:	name = "ARTOS";			break;
24942b73e8eSMarian Balakowicz #endif
25042b73e8eSMarian Balakowicz #ifdef CONFIG_LYNXKDI
25142b73e8eSMarian Balakowicz 	case IH_OS_LYNXOS:	name = "LynxOS";		break;
25242b73e8eSMarian Balakowicz #endif
25342b73e8eSMarian Balakowicz 	default:		name = "Unknown OS";		break;
25442b73e8eSMarian Balakowicz 	}
25542b73e8eSMarian Balakowicz 
25642b73e8eSMarian Balakowicz 	return name;
25742b73e8eSMarian Balakowicz }
25842b73e8eSMarian Balakowicz 
25942b73e8eSMarian Balakowicz const char* image_get_arch_name (uint8_t arch)
26042b73e8eSMarian Balakowicz {
26142b73e8eSMarian Balakowicz 	const char *name;
26242b73e8eSMarian Balakowicz 
26342b73e8eSMarian Balakowicz 	switch (arch) {
26442b73e8eSMarian Balakowicz 	case IH_ARCH_INVALID:	name = "Invalid Architecture";	break;
26542b73e8eSMarian Balakowicz 	case IH_ARCH_ALPHA:	name = "Alpha";			break;
26642b73e8eSMarian Balakowicz 	case IH_ARCH_ARM:	name = "ARM";			break;
26742b73e8eSMarian Balakowicz 	case IH_ARCH_AVR32:	name = "AVR32";			break;
26842b73e8eSMarian Balakowicz 	case IH_ARCH_BLACKFIN:	name = "Blackfin";		break;
26942b73e8eSMarian Balakowicz 	case IH_ARCH_I386:	name = "Intel x86";		break;
27042b73e8eSMarian Balakowicz 	case IH_ARCH_IA64:	name = "IA64";			break;
27142b73e8eSMarian Balakowicz 	case IH_ARCH_M68K:	name = "M68K"; 			break;
27242b73e8eSMarian Balakowicz 	case IH_ARCH_MICROBLAZE:name = "Microblaze"; 		break;
27342b73e8eSMarian Balakowicz 	case IH_ARCH_MIPS64:	name = "MIPS 64 Bit";		break;
27442b73e8eSMarian Balakowicz 	case IH_ARCH_MIPS:	name = "MIPS";			break;
27542b73e8eSMarian Balakowicz 	case IH_ARCH_NIOS2:	name = "Nios-II";		break;
27642b73e8eSMarian Balakowicz 	case IH_ARCH_NIOS:	name = "Nios";			break;
27742b73e8eSMarian Balakowicz 	case IH_ARCH_PPC:	name = "PowerPC";		break;
27842b73e8eSMarian Balakowicz 	case IH_ARCH_S390:	name = "IBM S390";		break;
27942b73e8eSMarian Balakowicz 	case IH_ARCH_SH:	name = "SuperH";		break;
28042b73e8eSMarian Balakowicz 	case IH_ARCH_SPARC64:	name = "SPARC 64 Bit";		break;
28142b73e8eSMarian Balakowicz 	case IH_ARCH_SPARC:	name = "SPARC";			break;
28242b73e8eSMarian Balakowicz 	default:		name = "Unknown Architecture";	break;
28342b73e8eSMarian Balakowicz 	}
28442b73e8eSMarian Balakowicz 
28542b73e8eSMarian Balakowicz 	return name;
28642b73e8eSMarian Balakowicz }
28742b73e8eSMarian Balakowicz 
28842b73e8eSMarian Balakowicz const char* image_get_type_name (uint8_t type)
28942b73e8eSMarian Balakowicz {
29042b73e8eSMarian Balakowicz 	const char *name;
29142b73e8eSMarian Balakowicz 
29242b73e8eSMarian Balakowicz 	switch (type) {
29342b73e8eSMarian Balakowicz 	case IH_TYPE_INVALID:	name = "Invalid Image";		break;
29442b73e8eSMarian Balakowicz 	case IH_TYPE_STANDALONE:name = "Standalone Program";	break;
29542b73e8eSMarian Balakowicz 	case IH_TYPE_KERNEL:	name = "Kernel Image";		break;
29642b73e8eSMarian Balakowicz 	case IH_TYPE_RAMDISK:	name = "RAMDisk Image";		break;
29742b73e8eSMarian Balakowicz 	case IH_TYPE_MULTI:	name = "Multi-File Image";	break;
29842b73e8eSMarian Balakowicz 	case IH_TYPE_FIRMWARE:	name = "Firmware";		break;
29942b73e8eSMarian Balakowicz 	case IH_TYPE_SCRIPT:	name = "Script";		break;
30042b73e8eSMarian Balakowicz 	case IH_TYPE_FLATDT:	name = "Flat Device Tree";	break;
30142b73e8eSMarian Balakowicz 	default:		name = "Unknown Image";		break;
30242b73e8eSMarian Balakowicz 	}
30342b73e8eSMarian Balakowicz 
30442b73e8eSMarian Balakowicz 	return name;
30542b73e8eSMarian Balakowicz }
30642b73e8eSMarian Balakowicz 
30742b73e8eSMarian Balakowicz const char* image_get_comp_name (uint8_t comp)
30842b73e8eSMarian Balakowicz {
30942b73e8eSMarian Balakowicz 	const char *name;
31042b73e8eSMarian Balakowicz 
31142b73e8eSMarian Balakowicz 	switch (comp) {
31242b73e8eSMarian Balakowicz 	case IH_COMP_NONE:	name = "uncompressed";		break;
31342b73e8eSMarian Balakowicz 	case IH_COMP_GZIP:	name = "gzip compressed";	break;
31442b73e8eSMarian Balakowicz 	case IH_COMP_BZIP2:	name = "bzip2 compressed";	break;
31542b73e8eSMarian Balakowicz 	default:		name = "unknown compression";	break;
31642b73e8eSMarian Balakowicz 	}
31742b73e8eSMarian Balakowicz 
31842b73e8eSMarian Balakowicz 	return name;
31942b73e8eSMarian Balakowicz }
3205ad03eb3SMarian Balakowicz 
3212242f536SMarian Balakowicz static void image_print_type (image_header_t *hdr)
3222242f536SMarian Balakowicz {
3232242f536SMarian Balakowicz 	const char *os, *arch, *type, *comp;
3242242f536SMarian Balakowicz 
3252242f536SMarian Balakowicz 	os = image_get_os_name (image_get_os (hdr));
3262242f536SMarian Balakowicz 	arch = image_get_arch_name (image_get_arch (hdr));
3272242f536SMarian Balakowicz 	type = image_get_type_name (image_get_type (hdr));
3282242f536SMarian Balakowicz 	comp = image_get_comp_name (image_get_comp (hdr));
3292242f536SMarian Balakowicz 
3302242f536SMarian Balakowicz 	printf ("%s %s %s (%s)", arch, os, type, comp);
3312242f536SMarian Balakowicz }
3322242f536SMarian Balakowicz 
3332242f536SMarian Balakowicz void image_print_contents (image_header_t *hdr)
3342242f536SMarian Balakowicz {
3352242f536SMarian Balakowicz #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE)
3362242f536SMarian Balakowicz 	time_t timestamp = (time_t)image_get_time (hdr);
3372242f536SMarian Balakowicz 	struct rtc_time tm;
3382242f536SMarian Balakowicz #endif
3392242f536SMarian Balakowicz 
3402242f536SMarian Balakowicz 	printf ("   Image Name:   %.*s\n", IH_NMLEN, image_get_name (hdr));
3412242f536SMarian Balakowicz 
3422242f536SMarian Balakowicz #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE)
3432242f536SMarian Balakowicz 	to_tm (timestamp, &tm);
3442242f536SMarian Balakowicz 	printf ("   Created:      %4d-%02d-%02d  %2d:%02d:%02d UTC\n",
3452242f536SMarian Balakowicz 		tm.tm_year, tm.tm_mon, tm.tm_mday,
3462242f536SMarian Balakowicz 		tm.tm_hour, tm.tm_min, tm.tm_sec);
3472242f536SMarian Balakowicz #endif
3482242f536SMarian Balakowicz 	puts ("   Image Type:   ");
3492242f536SMarian Balakowicz 	image_print_type (hdr);
3502242f536SMarian Balakowicz 
3512242f536SMarian Balakowicz 	printf ("\n   Data Size:    %d Bytes = ", image_get_data_size (hdr));
3522242f536SMarian Balakowicz 	print_size (image_get_data_size (hdr), "\n");
3532242f536SMarian Balakowicz 	printf ("   Load Address: %08x\n"
3542242f536SMarian Balakowicz 		"   Entry Point:  %08x\n",
3552242f536SMarian Balakowicz 		 image_get_load (hdr), image_get_ep (hdr));
3562242f536SMarian Balakowicz 
3572242f536SMarian Balakowicz 	if (image_check_type (hdr, IH_TYPE_MULTI)) {
3582242f536SMarian Balakowicz 		int i;
3592242f536SMarian Balakowicz 		ulong data, len;
3602242f536SMarian Balakowicz 		ulong count = image_multi_count (hdr);
3612242f536SMarian Balakowicz 
3622242f536SMarian Balakowicz 		puts ("   Contents:\n");
3632242f536SMarian Balakowicz 		for (i = 0; i < count; i++) {
3642242f536SMarian Balakowicz 			image_multi_getimg (hdr, i, &data, &len);
3652242f536SMarian Balakowicz 			printf ("   Image %d: %8ld Bytes = ", i, len);
3662242f536SMarian Balakowicz 			print_size (len, "\n");
3672242f536SMarian Balakowicz 		}
3682242f536SMarian Balakowicz 	}
3692242f536SMarian Balakowicz }
3702242f536SMarian Balakowicz 
3715ad03eb3SMarian Balakowicz /**
372fff888a1SMarian Balakowicz  * gen_image_get_format - get image format type
373fff888a1SMarian Balakowicz  * @img_addr: image start address
374fff888a1SMarian Balakowicz  *
375fff888a1SMarian Balakowicz  * gen_image_get_format() checks whether provided address points to a valid
376fff888a1SMarian Balakowicz  * legacy or FIT image.
377fff888a1SMarian Balakowicz  *
378*4efbe9dbSMarian Balakowicz  * New uImage format and FDT blob are based on a libfdt. FDT blob
379*4efbe9dbSMarian Balakowicz  * may be passed directly or embedded in a FIT image. In both situations
380*4efbe9dbSMarian Balakowicz  * gen_image_get_format() must be able to dectect libfdt header.
381*4efbe9dbSMarian Balakowicz  *
382fff888a1SMarian Balakowicz  * returns:
383fff888a1SMarian Balakowicz  *     image format type or IMAGE_FORMAT_INVALID if no image is present
384fff888a1SMarian Balakowicz  */
385fff888a1SMarian Balakowicz int gen_image_get_format (void *img_addr)
386fff888a1SMarian Balakowicz {
387fff888a1SMarian Balakowicz 	ulong		format = IMAGE_FORMAT_INVALID;
388fff888a1SMarian Balakowicz 	image_header_t	*hdr;
389*4efbe9dbSMarian Balakowicz #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
390fff888a1SMarian Balakowicz 	char		*fit_hdr;
391fff888a1SMarian Balakowicz #endif
392fff888a1SMarian Balakowicz 
393fff888a1SMarian Balakowicz 	hdr = (image_header_t *)img_addr;
394fff888a1SMarian Balakowicz 	if (image_check_magic(hdr))
395fff888a1SMarian Balakowicz 		format = IMAGE_FORMAT_LEGACY;
396*4efbe9dbSMarian Balakowicz #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
397fff888a1SMarian Balakowicz 	else {
398fff888a1SMarian Balakowicz 		fit_hdr = (char *)img_addr;
399fff888a1SMarian Balakowicz 		if (fdt_check_header (fit_hdr) == 0)
400fff888a1SMarian Balakowicz 			format = IMAGE_FORMAT_FIT;
401fff888a1SMarian Balakowicz 	}
402fff888a1SMarian Balakowicz #endif
403fff888a1SMarian Balakowicz 
404fff888a1SMarian Balakowicz 	return format;
405fff888a1SMarian Balakowicz }
406fff888a1SMarian Balakowicz 
407fff888a1SMarian Balakowicz /**
408fff888a1SMarian Balakowicz  * gen_get_image - get image from special storage (if necessary)
409fff888a1SMarian Balakowicz  * @img_addr: image start address
410fff888a1SMarian Balakowicz  *
411fff888a1SMarian Balakowicz  * gen_get_image() checks if provided image start adddress is located
412fff888a1SMarian Balakowicz  * in a dataflash storage. If so, image is moved to a system RAM memory.
413fff888a1SMarian Balakowicz  *
414fff888a1SMarian Balakowicz  * returns:
415fff888a1SMarian Balakowicz  *     image start address after possible relocation from special storage
416fff888a1SMarian Balakowicz  */
417fff888a1SMarian Balakowicz ulong gen_get_image (ulong img_addr)
418fff888a1SMarian Balakowicz {
4196f0f9dfcSMarian Balakowicz 	ulong ram_addr = img_addr;
420fff888a1SMarian Balakowicz 
4216f0f9dfcSMarian Balakowicz #ifdef CONFIG_HAS_DATAFLASH
4226f0f9dfcSMarian Balakowicz 	ulong h_size, d_size;
4236f0f9dfcSMarian Balakowicz 
4246f0f9dfcSMarian Balakowicz 	if (addr_dataflash (img_addr)){
4256f0f9dfcSMarian Balakowicz 		/* ger RAM address */
4266f0f9dfcSMarian Balakowicz 		ram_addr = CFG_LOAD_ADDR;
4276f0f9dfcSMarian Balakowicz 
4286f0f9dfcSMarian Balakowicz 		/* get header size */
429fff888a1SMarian Balakowicz 		h_size = image_get_header_size ();
430fff888a1SMarian Balakowicz #if defined(CONFIG_FIT)
431fff888a1SMarian Balakowicz 		if (sizeof(struct fdt_header) > h_size)
432fff888a1SMarian Balakowicz 			h_size = sizeof(struct fdt_header);
433fff888a1SMarian Balakowicz #endif
434fff888a1SMarian Balakowicz 
4356f0f9dfcSMarian Balakowicz 		/* read in header */
436fff888a1SMarian Balakowicz 		debug ("   Reading image header from dataflash address "
437fff888a1SMarian Balakowicz 			"%08lx to RAM address %08lx\n", img_addr, ram_addr);
4386f0f9dfcSMarian Balakowicz 
439fff888a1SMarian Balakowicz 		read_dataflash (img_addr, h_size, (char *)ram_addr);
440fff888a1SMarian Balakowicz 
4416f0f9dfcSMarian Balakowicz 		/* get data size */
442fff888a1SMarian Balakowicz 		switch (gen_image_get_format ((void *)ram_addr)) {
443fff888a1SMarian Balakowicz 		case IMAGE_FORMAT_LEGACY:
444fff888a1SMarian Balakowicz 			d_size = image_get_data_size ((image_header_t *)ram_addr);
445fff888a1SMarian Balakowicz 			debug ("   Legacy format image found at 0x%08lx, size 0x%08lx\n",
446fff888a1SMarian Balakowicz 					ram_addr, d_size);
447fff888a1SMarian Balakowicz 			break;
448fff888a1SMarian Balakowicz #if defined(CONFIG_FIT)
449fff888a1SMarian Balakowicz 		case IMAGE_FORMAT_FIT:
450fff888a1SMarian Balakowicz 			d_size = fdt_totalsize((void *)ram_addr) - h_size;
451fff888a1SMarian Balakowicz 			debug ("   FIT/FDT format image found at 0x%08lx, size 0x%08lx\n",
452fff888a1SMarian Balakowicz 					ram_addr, d_size);
453fff888a1SMarian Balakowicz 			break;
454fff888a1SMarian Balakowicz #endif
455fff888a1SMarian Balakowicz 		default:
456fff888a1SMarian Balakowicz 			printf ("   No valid image found at 0x%08lx\n", img_addr);
457fff888a1SMarian Balakowicz 			return ram_addr;
458fff888a1SMarian Balakowicz 		}
459fff888a1SMarian Balakowicz 
4606f0f9dfcSMarian Balakowicz 		/* read in image data */
461fff888a1SMarian Balakowicz 		debug ("   Reading image remaining data from dataflash address "
462fff888a1SMarian Balakowicz 			"%08lx to RAM address %08lx\n", img_addr + h_size,
463fff888a1SMarian Balakowicz 			ram_addr + h_size);
464fff888a1SMarian Balakowicz 
465fff888a1SMarian Balakowicz 		read_dataflash (img_addr + h_size, d_size,
466fff888a1SMarian Balakowicz 				(char *)(ram_addr + h_size));
4676f0f9dfcSMarian Balakowicz 
468fff888a1SMarian Balakowicz 	}
4696f0f9dfcSMarian Balakowicz #endif /* CONFIG_HAS_DATAFLASH */
470fff888a1SMarian Balakowicz 
471fff888a1SMarian Balakowicz 	return ram_addr;
472fff888a1SMarian Balakowicz }
473fff888a1SMarian Balakowicz 
474fff888a1SMarian Balakowicz /**
4755ad03eb3SMarian Balakowicz  * image_get_ramdisk - get and verify ramdisk image
4765ad03eb3SMarian Balakowicz  * @cmdtp: command table pointer
4775ad03eb3SMarian Balakowicz  * @flag: command flag
4785ad03eb3SMarian Balakowicz  * @argc: command argument count
4795ad03eb3SMarian Balakowicz  * @argv: command argument list
4805ad03eb3SMarian Balakowicz  * @rd_addr: ramdisk image start address
4815ad03eb3SMarian Balakowicz  * @arch: expected ramdisk architecture
4825ad03eb3SMarian Balakowicz  * @verify: checksum verification flag
4835ad03eb3SMarian Balakowicz  *
4845ad03eb3SMarian Balakowicz  * image_get_ramdisk() returns a pointer to the verified ramdisk image
4855ad03eb3SMarian Balakowicz  * header. Routine receives image start address and expected architecture
4865ad03eb3SMarian Balakowicz  * flag. Verification done covers data and header integrity and os/type/arch
4875ad03eb3SMarian Balakowicz  * fields checking.
4885ad03eb3SMarian Balakowicz  *
4895ad03eb3SMarian Balakowicz  * If dataflash support is enabled routine checks for dataflash addresses
4905ad03eb3SMarian Balakowicz  * and handles required dataflash reads.
4915ad03eb3SMarian Balakowicz  *
4925ad03eb3SMarian Balakowicz  * returns:
4935ad03eb3SMarian Balakowicz  *     pointer to a ramdisk image header, if image was found and valid
4945ad03eb3SMarian Balakowicz  *     otherwise, board is reset
4955ad03eb3SMarian Balakowicz  */
4968a5ea3e6SMarian Balakowicz static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag,
4975ad03eb3SMarian Balakowicz 		int argc, char *argv[],
4985ad03eb3SMarian Balakowicz 		ulong rd_addr, uint8_t arch, int verify)
4995ad03eb3SMarian Balakowicz {
5005ad03eb3SMarian Balakowicz 	image_header_t *rd_hdr;
5015ad03eb3SMarian Balakowicz 
5025ad03eb3SMarian Balakowicz 	show_boot_progress (9);
5035ad03eb3SMarian Balakowicz 	rd_hdr = (image_header_t *)rd_addr;
5045ad03eb3SMarian Balakowicz 
5055ad03eb3SMarian Balakowicz 	if (!image_check_magic (rd_hdr)) {
5065ad03eb3SMarian Balakowicz 		puts ("Bad Magic Number\n");
5075ad03eb3SMarian Balakowicz 		show_boot_progress (-10);
5085ad03eb3SMarian Balakowicz 		do_reset (cmdtp, flag, argc, argv);
5095ad03eb3SMarian Balakowicz 	}
5105ad03eb3SMarian Balakowicz 
5115ad03eb3SMarian Balakowicz 	if (!image_check_hcrc (rd_hdr)) {
5125ad03eb3SMarian Balakowicz 		puts ("Bad Header Checksum\n");
5135ad03eb3SMarian Balakowicz 		show_boot_progress (-11);
5145ad03eb3SMarian Balakowicz 		do_reset (cmdtp, flag, argc, argv);
5155ad03eb3SMarian Balakowicz 	}
5165ad03eb3SMarian Balakowicz 
5175ad03eb3SMarian Balakowicz 	show_boot_progress (10);
5182242f536SMarian Balakowicz 	image_print_contents (rd_hdr);
5195ad03eb3SMarian Balakowicz 
5205ad03eb3SMarian Balakowicz 	if (verify) {
5215ad03eb3SMarian Balakowicz 		puts("   Verifying Checksum ... ");
5225ad03eb3SMarian Balakowicz 		if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) {
5235ad03eb3SMarian Balakowicz 			puts ("Bad Data CRC\n");
5245ad03eb3SMarian Balakowicz 			show_boot_progress (-12);
5255ad03eb3SMarian Balakowicz 			do_reset (cmdtp, flag, argc, argv);
5265ad03eb3SMarian Balakowicz 		}
5275ad03eb3SMarian Balakowicz 		puts("OK\n");
5285ad03eb3SMarian Balakowicz 	}
5295ad03eb3SMarian Balakowicz 
5305ad03eb3SMarian Balakowicz 	show_boot_progress (11);
5315ad03eb3SMarian Balakowicz 
5325ad03eb3SMarian Balakowicz 	if (!image_check_os (rd_hdr, IH_OS_LINUX) ||
5335ad03eb3SMarian Balakowicz 	    !image_check_arch (rd_hdr, arch) ||
5345ad03eb3SMarian Balakowicz 	    !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {
5355ad03eb3SMarian Balakowicz 		printf ("No Linux %s Ramdisk Image\n",
5365ad03eb3SMarian Balakowicz 				image_get_arch_name(arch));
5375ad03eb3SMarian Balakowicz 		show_boot_progress (-13);
5385ad03eb3SMarian Balakowicz 		do_reset (cmdtp, flag, argc, argv);
5395ad03eb3SMarian Balakowicz 	}
5405ad03eb3SMarian Balakowicz 
5415ad03eb3SMarian Balakowicz 	return rd_hdr;
5425ad03eb3SMarian Balakowicz }
5435ad03eb3SMarian Balakowicz 
5445ad03eb3SMarian Balakowicz /**
5455ad03eb3SMarian Balakowicz  * get_ramdisk - main ramdisk handling routine
5465ad03eb3SMarian Balakowicz  * @cmdtp: command table pointer
5475ad03eb3SMarian Balakowicz  * @flag: command flag
5485ad03eb3SMarian Balakowicz  * @argc: command argument count
5495ad03eb3SMarian Balakowicz  * @argv: command argument list
5508a5ea3e6SMarian Balakowicz  * @images: pointer to the bootm images structure
5515ad03eb3SMarian Balakowicz  * @arch: expected ramdisk architecture
5525ad03eb3SMarian Balakowicz  * @rd_start: pointer to a ulong variable, will hold ramdisk start address
5535ad03eb3SMarian Balakowicz  * @rd_end: pointer to a ulong variable, will hold ramdisk end
5545ad03eb3SMarian Balakowicz  *
5555ad03eb3SMarian Balakowicz  * get_ramdisk() is responsible for finding a valid ramdisk image.
5565ad03eb3SMarian Balakowicz  * Curently supported are the following ramdisk sources:
5575ad03eb3SMarian Balakowicz  *      - multicomponent kernel/ramdisk image,
5585ad03eb3SMarian Balakowicz  *      - commandline provided address of decicated ramdisk image.
5595ad03eb3SMarian Balakowicz  *
5605ad03eb3SMarian Balakowicz  * returns:
5615ad03eb3SMarian Balakowicz  *     rd_start and rd_end are set to ramdisk start/end addresses if
5625ad03eb3SMarian Balakowicz  *     ramdisk image is found and valid
5635ad03eb3SMarian Balakowicz  *     rd_start and rd_end are set to 0 if no ramdisk exists
5645ad03eb3SMarian Balakowicz  *     board is reset if ramdisk image is found but corrupted
5655ad03eb3SMarian Balakowicz  */
5665ad03eb3SMarian Balakowicz void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
5678a5ea3e6SMarian Balakowicz 		bootm_headers_t *images, uint8_t arch,
5685ad03eb3SMarian Balakowicz 		ulong *rd_start, ulong *rd_end)
5695ad03eb3SMarian Balakowicz {
570d5934ad7SMarian Balakowicz 	ulong rd_addr, rd_load;
5715ad03eb3SMarian Balakowicz 	ulong rd_data, rd_len;
5725ad03eb3SMarian Balakowicz 	image_header_t *rd_hdr;
573d5934ad7SMarian Balakowicz #if defined(CONFIG_FIT)
574d5934ad7SMarian Balakowicz 	void		*fit_hdr;
575d5934ad7SMarian Balakowicz 	const char	*fit_uname_config = NULL;
576d5934ad7SMarian Balakowicz 	const char	*fit_uname_ramdisk = NULL;
577d5934ad7SMarian Balakowicz 	ulong		default_addr;
578d5934ad7SMarian Balakowicz #endif
5795ad03eb3SMarian Balakowicz 
5805ad03eb3SMarian Balakowicz 	/*
5815ad03eb3SMarian Balakowicz 	 * Look for a '-' which indicates to ignore the
5825ad03eb3SMarian Balakowicz 	 * ramdisk argument
5835ad03eb3SMarian Balakowicz 	 */
584d5934ad7SMarian Balakowicz 	if ((argc >= 3) && (strcmp(argv[2], "-") ==  0)) {
5855ad03eb3SMarian Balakowicz 		debug ("## Skipping init Ramdisk\n");
5865ad03eb3SMarian Balakowicz 		rd_len = rd_data = 0;
587d5934ad7SMarian Balakowicz 	} else if (argc >= 3) {
588d5934ad7SMarian Balakowicz #if defined(CONFIG_FIT)
589d5934ad7SMarian Balakowicz 		/*
590d5934ad7SMarian Balakowicz 		 * If the init ramdisk comes from the FIT image and the FIT image
591d5934ad7SMarian Balakowicz 		 * address is omitted in the command line argument, try to use
592d5934ad7SMarian Balakowicz 		 * os FIT image address or default load address.
593d5934ad7SMarian Balakowicz 		 */
594d5934ad7SMarian Balakowicz 		if (images->fit_uname_os)
595d5934ad7SMarian Balakowicz 			default_addr = (ulong)images->fit_hdr_os;
596d5934ad7SMarian Balakowicz 		else
597d5934ad7SMarian Balakowicz 			default_addr = load_addr;
598d5934ad7SMarian Balakowicz 
599d5934ad7SMarian Balakowicz 		if (fit_parse_conf (argv[2], default_addr,
600d5934ad7SMarian Balakowicz 					&rd_addr, &fit_uname_config)) {
601d5934ad7SMarian Balakowicz 			debug ("*  ramdisk: config '%s' from image at 0x%08lx\n",
602d5934ad7SMarian Balakowicz 					fit_uname_config, rd_addr);
603d5934ad7SMarian Balakowicz 		} else if (fit_parse_subimage (argv[2], default_addr,
604d5934ad7SMarian Balakowicz 					&rd_addr, &fit_uname_ramdisk)) {
605d5934ad7SMarian Balakowicz 			debug ("*  ramdisk: subimage '%s' from image at 0x%08lx\n",
606d5934ad7SMarian Balakowicz 					fit_uname_ramdisk, rd_addr);
607d5934ad7SMarian Balakowicz 		} else
608d5934ad7SMarian Balakowicz #endif
609d5934ad7SMarian Balakowicz 		{
610d5934ad7SMarian Balakowicz 			rd_addr = simple_strtoul(argv[2], NULL, 16);
611d5934ad7SMarian Balakowicz 			debug ("*  ramdisk: cmdline image address = 0x%08lx\n",
612d5934ad7SMarian Balakowicz 					rd_addr);
613d5934ad7SMarian Balakowicz 		}
614d5934ad7SMarian Balakowicz 
615d5934ad7SMarian Balakowicz 		/* copy from dataflash if needed */
616d5934ad7SMarian Balakowicz 		printf ("## Loading init Ramdisk Image at %08lx ...\n",
617d5934ad7SMarian Balakowicz 				rd_addr);
618d5934ad7SMarian Balakowicz 		rd_addr = gen_get_image (rd_addr);
619d5934ad7SMarian Balakowicz 
6205ad03eb3SMarian Balakowicz 		/*
6215ad03eb3SMarian Balakowicz 		 * Check if there is an initrd image at the
6225ad03eb3SMarian Balakowicz 		 * address provided in the second bootm argument
623d5934ad7SMarian Balakowicz 		 * check image type, for FIT images get FIT node.
6245ad03eb3SMarian Balakowicz 		 */
625d5934ad7SMarian Balakowicz 		switch (gen_image_get_format ((void *)rd_addr)) {
626d5934ad7SMarian Balakowicz 		case IMAGE_FORMAT_LEGACY:
627d5934ad7SMarian Balakowicz 
628d5934ad7SMarian Balakowicz 			debug ("*  ramdisk: legacy format image\n");
6295ad03eb3SMarian Balakowicz 
6305ad03eb3SMarian Balakowicz 			rd_hdr = image_get_ramdisk (cmdtp, flag, argc, argv,
6318a5ea3e6SMarian Balakowicz 						rd_addr, arch, images->verify);
6325ad03eb3SMarian Balakowicz 
6335ad03eb3SMarian Balakowicz 			rd_data = image_get_data (rd_hdr);
6345ad03eb3SMarian Balakowicz 			rd_len = image_get_data_size (rd_hdr);
635d5934ad7SMarian Balakowicz 			rd_load = image_get_load (rd_hdr);
636d5934ad7SMarian Balakowicz 			break;
637d5934ad7SMarian Balakowicz #if defined(CONFIG_FIT)
638d5934ad7SMarian Balakowicz 		case IMAGE_FORMAT_FIT:
639d5934ad7SMarian Balakowicz 			fit_hdr = (void *)rd_addr;
640d5934ad7SMarian Balakowicz 			debug ("*  ramdisk: FIT format image\n");
641d5934ad7SMarian Balakowicz 			fit_unsupported_reset ("ramdisk");
642d5934ad7SMarian Balakowicz 			do_reset (cmdtp, flag, argc, argv);
643d5934ad7SMarian Balakowicz #endif
644d5934ad7SMarian Balakowicz 		default:
645d5934ad7SMarian Balakowicz 			printf ("Wrong Image Format for %s command\n",
646d5934ad7SMarian Balakowicz 					cmdtp->name);
647d5934ad7SMarian Balakowicz 			rd_data = rd_len = 0;
648d5934ad7SMarian Balakowicz 		}
6495ad03eb3SMarian Balakowicz 
6505ad03eb3SMarian Balakowicz #if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO)
6515ad03eb3SMarian Balakowicz 		/*
652d5934ad7SMarian Balakowicz 		 * We need to copy the ramdisk to SRAM to let Linux boot
6535ad03eb3SMarian Balakowicz 		 */
654d5934ad7SMarian Balakowicz 		if (rd_data) {
655d5934ad7SMarian Balakowicz 			memmove ((void *)rd_load, (uchar *)rd_data, rd_len);
656d5934ad7SMarian Balakowicz 			rd_data = rd_load;
6575ad03eb3SMarian Balakowicz 		}
658d5934ad7SMarian Balakowicz #endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */
6595ad03eb3SMarian Balakowicz 
660d5934ad7SMarian Balakowicz 	} else if (images->legacy_hdr_valid &&
661d5934ad7SMarian Balakowicz 			image_check_type (images->legacy_hdr_os, IH_TYPE_MULTI)) {
6625ad03eb3SMarian Balakowicz 		/*
663d5934ad7SMarian Balakowicz 		 * Now check if we have a legacy mult-component image,
664d5934ad7SMarian Balakowicz 		 * get second entry data start address and len.
6655ad03eb3SMarian Balakowicz 		 */
6665ad03eb3SMarian Balakowicz 		show_boot_progress (13);
6675ad03eb3SMarian Balakowicz 		printf ("## Loading init Ramdisk from multi component "
668d5934ad7SMarian Balakowicz 				"Image at %08lx ...\n",
669d5934ad7SMarian Balakowicz 				(ulong)images->legacy_hdr_os);
670d5934ad7SMarian Balakowicz 
671d5934ad7SMarian Balakowicz 		image_multi_getimg (images->legacy_hdr_os, 1, &rd_data, &rd_len);
6725ad03eb3SMarian Balakowicz 	} else {
6735ad03eb3SMarian Balakowicz 		/*
6745ad03eb3SMarian Balakowicz 		 * no initrd image
6755ad03eb3SMarian Balakowicz 		 */
6765ad03eb3SMarian Balakowicz 		show_boot_progress (14);
6775ad03eb3SMarian Balakowicz 		rd_len = rd_data = 0;
6785ad03eb3SMarian Balakowicz 	}
6795ad03eb3SMarian Balakowicz 
6805ad03eb3SMarian Balakowicz 	if (!rd_data) {
6815ad03eb3SMarian Balakowicz 		debug ("## No init Ramdisk\n");
6825ad03eb3SMarian Balakowicz 		*rd_start = 0;
6835ad03eb3SMarian Balakowicz 		*rd_end = 0;
6845ad03eb3SMarian Balakowicz 	} else {
6855ad03eb3SMarian Balakowicz 		*rd_start = rd_data;
6865ad03eb3SMarian Balakowicz 		*rd_end = rd_data + rd_len;
6875ad03eb3SMarian Balakowicz 	}
6885ad03eb3SMarian Balakowicz 	debug ("   ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n",
6895ad03eb3SMarian Balakowicz 			*rd_start, *rd_end);
6905ad03eb3SMarian Balakowicz }
691ceaed2b1SMarian Balakowicz 
692ceaed2b1SMarian Balakowicz #if defined(CONFIG_PPC) || defined(CONFIG_M68K)
693ceaed2b1SMarian Balakowicz /**
694ceaed2b1SMarian Balakowicz  * ramdisk_high - relocate init ramdisk
695ceaed2b1SMarian Balakowicz  * @rd_data: ramdisk data start address
696ceaed2b1SMarian Balakowicz  * @rd_len: ramdisk data length
697ceaed2b1SMarian Balakowicz  * @kbd: kernel board info copy (within BOOTMAPSZ boundary)
698ceaed2b1SMarian Balakowicz  * @sp_limit: stack pointer limit (including BOOTMAPSZ)
699ceaed2b1SMarian Balakowicz  * @sp: current stack pointer
700ceaed2b1SMarian Balakowicz  * @initrd_start: pointer to a ulong variable, will hold final init ramdisk
701ceaed2b1SMarian Balakowicz  *      start address (after possible relocation)
702ceaed2b1SMarian Balakowicz  * @initrd_end: pointer to a ulong variable, will hold final init ramdisk
703ceaed2b1SMarian Balakowicz  *      end address (after possible relocation)
704ceaed2b1SMarian Balakowicz  *
705ceaed2b1SMarian Balakowicz  * ramdisk_high() takes a relocation hint from "initrd_high" environement
706ceaed2b1SMarian Balakowicz  * variable and if requested ramdisk data is moved to a specified location.
707ceaed2b1SMarian Balakowicz  *
708ceaed2b1SMarian Balakowicz  * returns:
709b6b0fe64SMarian Balakowicz  *     - initrd_start and initrd_end are set to final (after relocation) ramdisk
710ceaed2b1SMarian Balakowicz  *     start/end addresses if ramdisk image start and len were provided
711b6b0fe64SMarian Balakowicz  *     otherwise set initrd_start and initrd_end set to zeros
712b6b0fe64SMarian Balakowicz  *     - returns new allc_current, next free address below BOOTMAPSZ
713ceaed2b1SMarian Balakowicz  */
714b6b0fe64SMarian Balakowicz ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len,
715b6b0fe64SMarian Balakowicz 		bd_t *kbd, ulong sp_limit, ulong sp,
716b6b0fe64SMarian Balakowicz 		ulong *initrd_start, ulong *initrd_end)
717ceaed2b1SMarian Balakowicz {
718ceaed2b1SMarian Balakowicz 	char	*s;
719ceaed2b1SMarian Balakowicz 	ulong	initrd_high;
720ceaed2b1SMarian Balakowicz 	int	initrd_copy_to_ram = 1;
721b6b0fe64SMarian Balakowicz 	ulong	new_alloc_current = alloc_current;
722ceaed2b1SMarian Balakowicz 
723ceaed2b1SMarian Balakowicz 	if ((s = getenv ("initrd_high")) != NULL) {
724ceaed2b1SMarian Balakowicz 		/* a value of "no" or a similar string will act like 0,
725ceaed2b1SMarian Balakowicz 		 * turning the "load high" feature off. This is intentional.
726ceaed2b1SMarian Balakowicz 		 */
727ceaed2b1SMarian Balakowicz 		initrd_high = simple_strtoul (s, NULL, 16);
728ceaed2b1SMarian Balakowicz 		if (initrd_high == ~0)
729ceaed2b1SMarian Balakowicz 			initrd_copy_to_ram = 0;
730ceaed2b1SMarian Balakowicz 	} else {
731ceaed2b1SMarian Balakowicz 		/* not set, no restrictions to load high */
732ceaed2b1SMarian Balakowicz 		initrd_high = ~0;
733ceaed2b1SMarian Balakowicz 	}
734ceaed2b1SMarian Balakowicz 
735ceaed2b1SMarian Balakowicz #ifdef CONFIG_LOGBUFFER
736ceaed2b1SMarian Balakowicz 	/* Prevent initrd from overwriting logbuffer */
737ceaed2b1SMarian Balakowicz 	if (initrd_high < (kbd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD))
738ceaed2b1SMarian Balakowicz 		initrd_high = kbd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD;
739ceaed2b1SMarian Balakowicz 	debug ("## Logbuffer at 0x%08lx ", kbd->bi_memsize - LOGBUFF_LEN);
740ceaed2b1SMarian Balakowicz #endif
741ceaed2b1SMarian Balakowicz 	debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
742ceaed2b1SMarian Balakowicz 			initrd_high, initrd_copy_to_ram);
743ceaed2b1SMarian Balakowicz 
744ceaed2b1SMarian Balakowicz 	if (rd_data) {
745ceaed2b1SMarian Balakowicz 		if (!initrd_copy_to_ram) {	/* zero-copy ramdisk support */
746ceaed2b1SMarian Balakowicz 			debug ("   in-place initrd\n");
747ceaed2b1SMarian Balakowicz 			*initrd_start = rd_data;
748ceaed2b1SMarian Balakowicz 			*initrd_end = rd_data + rd_len;
749ceaed2b1SMarian Balakowicz 		} else {
750b6b0fe64SMarian Balakowicz 			new_alloc_current = alloc_current - rd_len;
751b6b0fe64SMarian Balakowicz 			*initrd_start  = new_alloc_current;
752ceaed2b1SMarian Balakowicz 			*initrd_start &= ~(4096 - 1);	/* align on page */
753ceaed2b1SMarian Balakowicz 
754ceaed2b1SMarian Balakowicz 			if (initrd_high) {
755ceaed2b1SMarian Balakowicz 				ulong nsp;
756ceaed2b1SMarian Balakowicz 
757ceaed2b1SMarian Balakowicz 				/*
758ceaed2b1SMarian Balakowicz 				 * the inital ramdisk does not need to be within
759ceaed2b1SMarian Balakowicz 				 * CFG_BOOTMAPSZ as it is not accessed until after
760ceaed2b1SMarian Balakowicz 				 * the mm system is initialised.
761ceaed2b1SMarian Balakowicz 				 *
762ceaed2b1SMarian Balakowicz 				 * do the stack bottom calculation again and see if
763ceaed2b1SMarian Balakowicz 				 * the initrd will fit just below the monitor stack
764ceaed2b1SMarian Balakowicz 				 * bottom without overwriting the area allocated
765ceaed2b1SMarian Balakowicz 				 * for command line args and board info.
766ceaed2b1SMarian Balakowicz 				 */
767ceaed2b1SMarian Balakowicz 				nsp = sp;
768ceaed2b1SMarian Balakowicz 				nsp -= 2048;		/* just to be sure */
769ceaed2b1SMarian Balakowicz 				nsp &= ~0xF;
770ceaed2b1SMarian Balakowicz 
771ceaed2b1SMarian Balakowicz 				if (nsp > initrd_high)	/* limit as specified */
772ceaed2b1SMarian Balakowicz 					nsp = initrd_high;
773ceaed2b1SMarian Balakowicz 
774ceaed2b1SMarian Balakowicz 				nsp -= rd_len;
775ceaed2b1SMarian Balakowicz 				nsp &= ~(4096 - 1);	/* align on page */
776ceaed2b1SMarian Balakowicz 
777b6b0fe64SMarian Balakowicz 				if (nsp >= sp_limit) {
778ceaed2b1SMarian Balakowicz 					*initrd_start = nsp;
779b6b0fe64SMarian Balakowicz 					new_alloc_current = alloc_current;
780b6b0fe64SMarian Balakowicz 				}
781ceaed2b1SMarian Balakowicz 			}
782ceaed2b1SMarian Balakowicz 
783ceaed2b1SMarian Balakowicz 			show_boot_progress (12);
784ceaed2b1SMarian Balakowicz 
785ceaed2b1SMarian Balakowicz 			*initrd_end = *initrd_start + rd_len;
786ceaed2b1SMarian Balakowicz 			printf ("   Loading Ramdisk to %08lx, end %08lx ... ",
787ceaed2b1SMarian Balakowicz 					*initrd_start, *initrd_end);
788ceaed2b1SMarian Balakowicz 
789ceaed2b1SMarian Balakowicz 			memmove_wd((void *)*initrd_start,
790ceaed2b1SMarian Balakowicz 					(void *)rd_data, rd_len, CHUNKSZ);
791ceaed2b1SMarian Balakowicz 
792ceaed2b1SMarian Balakowicz 			puts ("OK\n");
793ceaed2b1SMarian Balakowicz 		}
794ceaed2b1SMarian Balakowicz 	} else {
795ceaed2b1SMarian Balakowicz 		*initrd_start = 0;
796ceaed2b1SMarian Balakowicz 		*initrd_end = 0;
797ceaed2b1SMarian Balakowicz 	}
798ceaed2b1SMarian Balakowicz 	debug ("   ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
799ceaed2b1SMarian Balakowicz 			*initrd_start, *initrd_end);
800b6b0fe64SMarian Balakowicz 
801b6b0fe64SMarian Balakowicz 	return new_alloc_current;
802b6b0fe64SMarian Balakowicz }
803b6b0fe64SMarian Balakowicz 
804b6b0fe64SMarian Balakowicz /**
805b6b0fe64SMarian Balakowicz  * get_boot_sp_limit - calculate stack pointer limit
806b6b0fe64SMarian Balakowicz  * @sp: current stack pointer
807b6b0fe64SMarian Balakowicz  *
808b6b0fe64SMarian Balakowicz  * get_boot_sp_limit() takes current stack pointer adrress and calculates
809b6b0fe64SMarian Balakowicz  * stack pointer limit, below which kernel boot data (cmdline, board info,
810b6b0fe64SMarian Balakowicz  * etc.) will be allocated.
811b6b0fe64SMarian Balakowicz  *
812b6b0fe64SMarian Balakowicz  * returns:
813b6b0fe64SMarian Balakowicz  *     stack pointer limit
814b6b0fe64SMarian Balakowicz  */
815b6b0fe64SMarian Balakowicz ulong get_boot_sp_limit(ulong sp)
816b6b0fe64SMarian Balakowicz {
817b6b0fe64SMarian Balakowicz 	ulong sp_limit = sp;
818b6b0fe64SMarian Balakowicz 
819b6b0fe64SMarian Balakowicz 	sp_limit -= 2048;	/* just to be sure */
820b6b0fe64SMarian Balakowicz 
821b6b0fe64SMarian Balakowicz 	/* make sure sp_limit is within kernel mapped space */
822b6b0fe64SMarian Balakowicz 	if (sp_limit > CFG_BOOTMAPSZ)
823b6b0fe64SMarian Balakowicz 		sp_limit = CFG_BOOTMAPSZ;
824b6b0fe64SMarian Balakowicz 	sp_limit &= ~0xF;
825b6b0fe64SMarian Balakowicz 
826b6b0fe64SMarian Balakowicz 	return sp_limit;
827b6b0fe64SMarian Balakowicz }
828b6b0fe64SMarian Balakowicz 
829b6b0fe64SMarian Balakowicz /**
830b6b0fe64SMarian Balakowicz  * get_boot_cmdline - allocate and initialize kernel cmdline
831b6b0fe64SMarian Balakowicz  * @alloc_current: current boot allocation address (counting down
832b6b0fe64SMarian Balakowicz  *      from sp_limit)
833b6b0fe64SMarian Balakowicz  * @cmd_start: pointer to a ulong variable, will hold cmdline start
834b6b0fe64SMarian Balakowicz  * @cmd_end: pointer to a ulong variable, will hold cmdline end
835b6b0fe64SMarian Balakowicz  *
836b6b0fe64SMarian Balakowicz  * get_boot_cmdline() allocates space for kernel command line below
837b6b0fe64SMarian Balakowicz  * provided alloc_current address. If "bootargs" U-boot environemnt
838b6b0fe64SMarian Balakowicz  * variable is present its contents is copied to allocated kernel
839b6b0fe64SMarian Balakowicz  * command line.
840b6b0fe64SMarian Balakowicz  *
841b6b0fe64SMarian Balakowicz  * returns:
842b6b0fe64SMarian Balakowicz  *     alloc_current after cmdline allocation
843b6b0fe64SMarian Balakowicz  */
844b6b0fe64SMarian Balakowicz ulong get_boot_cmdline (ulong alloc_current, ulong *cmd_start, ulong *cmd_end)
845b6b0fe64SMarian Balakowicz {
846b6b0fe64SMarian Balakowicz 	char *cmdline;
847b6b0fe64SMarian Balakowicz 	char *s;
848b6b0fe64SMarian Balakowicz 
849b6b0fe64SMarian Balakowicz 	cmdline = (char *)((alloc_current - CFG_BARGSIZE) & ~0xF);
850b6b0fe64SMarian Balakowicz 
851b6b0fe64SMarian Balakowicz 	if ((s = getenv("bootargs")) == NULL)
852b6b0fe64SMarian Balakowicz 		s = "";
853b6b0fe64SMarian Balakowicz 
854b6b0fe64SMarian Balakowicz 	strcpy(cmdline, s);
855b6b0fe64SMarian Balakowicz 
856b6b0fe64SMarian Balakowicz 	*cmd_start = (ulong) & cmdline[0];
857b6b0fe64SMarian Balakowicz 	*cmd_end = *cmd_start + strlen(cmdline);
858b6b0fe64SMarian Balakowicz 
859b6b0fe64SMarian Balakowicz 	debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);
860b6b0fe64SMarian Balakowicz 
861b6b0fe64SMarian Balakowicz 	return (ulong)cmdline;
862b6b0fe64SMarian Balakowicz }
863b6b0fe64SMarian Balakowicz 
864b6b0fe64SMarian Balakowicz /**
865b6b0fe64SMarian Balakowicz  * get_boot_kbd - allocate and initialize kernel copy of board info
866b6b0fe64SMarian Balakowicz  * @alloc_current: current boot allocation address (counting down
867b6b0fe64SMarian Balakowicz  *      from sp_limit)
868b6b0fe64SMarian Balakowicz  * @kbd: double pointer to board info data
869b6b0fe64SMarian Balakowicz  *
870b6b0fe64SMarian Balakowicz  * get_boot_kbd() - allocates space for kernel copy of board info data.
871b6b0fe64SMarian Balakowicz  * Space is allocated below provided alloc_current address and kernel
872b6b0fe64SMarian Balakowicz  * board info is initialized with the current u-boot board info data.
873b6b0fe64SMarian Balakowicz  *
874b6b0fe64SMarian Balakowicz  * returns:
875b6b0fe64SMarian Balakowicz  *     alloc_current after kbd allocation
876b6b0fe64SMarian Balakowicz  */
877b6b0fe64SMarian Balakowicz ulong get_boot_kbd (ulong alloc_current, bd_t **kbd)
878b6b0fe64SMarian Balakowicz {
879b6b0fe64SMarian Balakowicz 	*kbd = (bd_t *) (((ulong)alloc_current - sizeof(bd_t)) & ~0xF);
880b6b0fe64SMarian Balakowicz 	**kbd = *(gd->bd);
881b6b0fe64SMarian Balakowicz 
882b6b0fe64SMarian Balakowicz 	debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd);
883b6b0fe64SMarian Balakowicz 
884b6b0fe64SMarian Balakowicz #if defined(DEBUG) && defined(CONFIG_CMD_BDI)
885b6b0fe64SMarian Balakowicz 	do_bdinfo(NULL, 0, 0, NULL);
886b6b0fe64SMarian Balakowicz #endif
887b6b0fe64SMarian Balakowicz 
888b6b0fe64SMarian Balakowicz 	return (ulong)*kbd;
889ceaed2b1SMarian Balakowicz }
890ceaed2b1SMarian Balakowicz #endif /* CONFIG_PPC || CONFIG_M68K */
8915ad03eb3SMarian Balakowicz 
892f50433d6SMarian Balakowicz #if defined(CONFIG_FIT)
893f50433d6SMarian Balakowicz /*****************************************************************************/
894f50433d6SMarian Balakowicz /* New uImage format routines */
895f50433d6SMarian Balakowicz /*****************************************************************************/
896f50433d6SMarian Balakowicz static int fit_parse_spec (const char *spec, char sepc, ulong addr_curr,
897f50433d6SMarian Balakowicz 		ulong *addr, const char **name)
898f50433d6SMarian Balakowicz {
899f50433d6SMarian Balakowicz 	const char *sep;
900f50433d6SMarian Balakowicz 
901f50433d6SMarian Balakowicz 	*addr = addr_curr;
902f50433d6SMarian Balakowicz 	*name = NULL;
903f50433d6SMarian Balakowicz 
904f50433d6SMarian Balakowicz 	sep = strchr (spec, sepc);
905f50433d6SMarian Balakowicz 	if (sep) {
906f50433d6SMarian Balakowicz 		if (sep - spec > 0)
907f50433d6SMarian Balakowicz 			*addr = simple_strtoul (spec, NULL, 16);
908f50433d6SMarian Balakowicz 
909f50433d6SMarian Balakowicz 		*name = sep + 1;
910f50433d6SMarian Balakowicz 		return 1;
911f50433d6SMarian Balakowicz 	}
912f50433d6SMarian Balakowicz 
913f50433d6SMarian Balakowicz 	return 0;
914f50433d6SMarian Balakowicz }
915f50433d6SMarian Balakowicz 
916f50433d6SMarian Balakowicz /**
917f50433d6SMarian Balakowicz  * fit_parse_conf - parse FIT configuration spec
918f50433d6SMarian Balakowicz  * @spec: input string, containing configuration spec
919f50433d6SMarian Balakowicz  * @add_curr: current image address (to be used as a possible default)
920f50433d6SMarian Balakowicz  * @addr: pointer to a ulong variable, will hold FIT image address of a given
921f50433d6SMarian Balakowicz  * configuration
922f50433d6SMarian Balakowicz  * @conf_name double pointer to a char, will hold pointer to a configuration
923f50433d6SMarian Balakowicz  * unit name
924f50433d6SMarian Balakowicz  *
925f50433d6SMarian Balakowicz  * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>,
926f50433d6SMarian Balakowicz  * where <addr> is a FIT image address that contains configuration
927f50433d6SMarian Balakowicz  * with a <conf> unit name.
928f50433d6SMarian Balakowicz  *
929f50433d6SMarian Balakowicz  * Address part is optional, and if omitted default add_curr will
930f50433d6SMarian Balakowicz  * be used instead.
931f50433d6SMarian Balakowicz  *
932f50433d6SMarian Balakowicz  * returns:
933f50433d6SMarian Balakowicz  *     1 if spec is a valid configuration string,
934f50433d6SMarian Balakowicz  *     addr and conf_name are set accordingly
935f50433d6SMarian Balakowicz  *     0 otherwise
936f50433d6SMarian Balakowicz  */
937f50433d6SMarian Balakowicz inline int fit_parse_conf (const char *spec, ulong addr_curr,
938f50433d6SMarian Balakowicz 		ulong *addr, const char **conf_name)
939f50433d6SMarian Balakowicz {
940f50433d6SMarian Balakowicz 	return fit_parse_spec (spec, '#', addr_curr, addr, conf_name);
941f50433d6SMarian Balakowicz }
942f50433d6SMarian Balakowicz 
943f50433d6SMarian Balakowicz /**
944f50433d6SMarian Balakowicz  * fit_parse_subimage - parse FIT subimage spec
945f50433d6SMarian Balakowicz  * @spec: input string, containing subimage spec
946f50433d6SMarian Balakowicz  * @add_curr: current image address (to be used as a possible default)
947f50433d6SMarian Balakowicz  * @addr: pointer to a ulong variable, will hold FIT image address of a given
948f50433d6SMarian Balakowicz  * subimage
949f50433d6SMarian Balakowicz  * @image_name: double pointer to a char, will hold pointer to a subimage name
950f50433d6SMarian Balakowicz  *
951f50433d6SMarian Balakowicz  * fit_parse_subimage() expects subimage spec in the for of
952f50433d6SMarian Balakowicz  * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
953f50433d6SMarian Balakowicz  * subimage with a <subimg> unit name.
954f50433d6SMarian Balakowicz  *
955f50433d6SMarian Balakowicz  * Address part is optional, and if omitted default add_curr will
956f50433d6SMarian Balakowicz  * be used instead.
957f50433d6SMarian Balakowicz  *
958f50433d6SMarian Balakowicz  * returns:
959f50433d6SMarian Balakowicz  *     1 if spec is a valid subimage string,
960f50433d6SMarian Balakowicz  *     addr and image_name are set accordingly
961f50433d6SMarian Balakowicz  *     0 otherwise
962f50433d6SMarian Balakowicz  */
963f50433d6SMarian Balakowicz inline int fit_parse_subimage (const char *spec, ulong addr_curr,
964f50433d6SMarian Balakowicz 		ulong *addr, const char **image_name)
965f50433d6SMarian Balakowicz {
966f50433d6SMarian Balakowicz 	return fit_parse_spec (spec, ':', addr_curr, addr, image_name);
967f50433d6SMarian Balakowicz }
968d5934ad7SMarian Balakowicz 
969f50433d6SMarian Balakowicz #endif /* CONFIG_FIT */
970f50433d6SMarian Balakowicz 
971b6b0fe64SMarian Balakowicz #endif /* USE_HOSTCC */
972