xref: /rk3399_rockchip-uboot/common/bootm.c (revision 998aeb5fa7dbd44c687a5511a53de3cd7d855aa8)
1 /*
2  * (C) Copyright 2000-2009
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #ifndef USE_HOSTCC
9 #include <common.h>
10 #include <bootstage.h>
11 #include <bzlib.h>
12 #include <errno.h>
13 #include <fdt_support.h>
14 #include <lmb.h>
15 #include <malloc.h>
16 #include <mapmem.h>
17 #include <asm/io.h>
18 #include <linux/lzo.h>
19 #include <lzma/LzmaTypes.h>
20 #include <lzma/LzmaDec.h>
21 #include <lzma/LzmaTools.h>
22 #if defined(CONFIG_CMD_USB)
23 #include <usb.h>
24 #endif
25 #else
26 #include "mkimage.h"
27 #endif
28 
29 #include <command.h>
30 #include <bootm.h>
31 #include <image.h>
32 
33 #ifndef CONFIG_SYS_BOOTM_LEN
34 /* use 8MByte as default max gunzip size */
35 #define CONFIG_SYS_BOOTM_LEN	0x800000
36 #endif
37 
38 #define IH_INITRD_ARCH IH_ARCH_DEFAULT
39 
40 #ifndef USE_HOSTCC
41 
42 DECLARE_GLOBAL_DATA_PTR;
43 
44 bootm_headers_t images;		/* pointers to os/initrd/fdt images */
45 
46 __weak int board_do_bootm(int argc, char * const argv[])
47 {
48 	return 0;
49 }
50 
51 static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
52 				   char * const argv[], bootm_headers_t *images,
53 				   ulong *os_data, ulong *os_len);
54 
55 #ifdef CONFIG_LMB
56 static void boot_start_lmb(bootm_headers_t *images)
57 {
58 
59 	lmb_init(&images->lmb);
60 #ifdef CONFIG_NR_DRAM_BANKS
61 	int i;
62 
63 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
64 		lmb_add(&images->lmb, gd->bd->bi_dram[i].start,
65 			gd->bd->bi_dram[i].size);
66 	}
67 #else
68 	ulong		mem_start;
69 	phys_size_t	mem_size;
70 
71 	mem_start = env_get_bootm_low();
72 	mem_size = env_get_bootm_size();
73 	lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size);
74 #endif
75 	arch_lmb_reserve(&images->lmb);
76 	board_lmb_reserve(&images->lmb);
77 }
78 #else
79 #define lmb_reserve(lmb, base, size)
80 static inline void boot_start_lmb(bootm_headers_t *images) { }
81 #endif
82 
83 static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc,
84 		       char * const argv[])
85 {
86 	memset((void *)&images, 0, sizeof(images));
87 	images.verify = env_get_yesno("verify");
88 
89 	boot_start_lmb(&images);
90 
91 	bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start");
92 	images.state = BOOTM_STATE_START;
93 
94 	return 0;
95 }
96 
97 static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
98 			 char * const argv[])
99 {
100 	const void *os_hdr;
101 	bool ep_found = false;
102 	int ret;
103 
104 	/* get kernel image header, start address and length */
105 	os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
106 			&images, &images.os.image_start, &images.os.image_len);
107 	if (images.os.image_len == 0) {
108 		puts("ERROR: can't get kernel image!\n");
109 		return 1;
110 	}
111 
112 	/* get image parameters */
113 	switch (genimg_get_format(os_hdr)) {
114 #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
115 	case IMAGE_FORMAT_LEGACY:
116 		images.os.type = image_get_type(os_hdr);
117 		images.os.comp = image_get_comp(os_hdr);
118 		images.os.os = image_get_os(os_hdr);
119 
120 		images.os.end = image_get_image_end(os_hdr);
121 		images.os.load = image_get_load(os_hdr);
122 		images.os.arch = image_get_arch(os_hdr);
123 		break;
124 #endif
125 #if IMAGE_ENABLE_FIT
126 	case IMAGE_FORMAT_FIT:
127 		if (fit_image_get_type(images.fit_hdr_os,
128 				       images.fit_noffset_os,
129 				       &images.os.type)) {
130 			puts("Can't get image type!\n");
131 			bootstage_error(BOOTSTAGE_ID_FIT_TYPE);
132 			return 1;
133 		}
134 
135 		if (fit_image_get_comp(images.fit_hdr_os,
136 				       images.fit_noffset_os,
137 				       &images.os.comp)) {
138 			puts("Can't get image compression!\n");
139 			bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION);
140 			return 1;
141 		}
142 
143 		if (fit_image_get_os(images.fit_hdr_os, images.fit_noffset_os,
144 				     &images.os.os)) {
145 			puts("Can't get image OS!\n");
146 			bootstage_error(BOOTSTAGE_ID_FIT_OS);
147 			return 1;
148 		}
149 
150 		if (fit_image_get_arch(images.fit_hdr_os,
151 				       images.fit_noffset_os,
152 				       &images.os.arch)) {
153 			puts("Can't get image ARCH!\n");
154 			return 1;
155 		}
156 
157 		images.os.end = fit_get_end(images.fit_hdr_os);
158 
159 		if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os,
160 				       &images.os.load)) {
161 			puts("Can't get image load address!\n");
162 			bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR);
163 			return 1;
164 		}
165 		break;
166 #endif
167 #ifdef CONFIG_ANDROID_BOOT_IMAGE
168 	case IMAGE_FORMAT_ANDROID:
169 		images.os.type = IH_TYPE_KERNEL;
170 		images.os.comp = android_image_get_comp(os_hdr);
171 		images.os.os = IH_OS_LINUX;
172 
173 		images.os.end = android_image_get_end(os_hdr);
174 		images.os.load = android_image_get_kload(os_hdr);
175 		images.ep = images.os.load;
176 		ep_found = true;
177 		break;
178 #endif
179 	default:
180 		puts("ERROR: unknown image format type!\n");
181 		return 1;
182 	}
183 
184 	/* If we have a valid setup.bin, we will use that for entry (x86) */
185 	if (images.os.arch == IH_ARCH_I386 ||
186 	    images.os.arch == IH_ARCH_X86_64) {
187 		ulong len;
188 
189 		ret = boot_get_setup(&images, IH_ARCH_I386, &images.ep, &len);
190 		if (ret < 0 && ret != -ENOENT) {
191 			puts("Could not find a valid setup.bin for x86\n");
192 			return 1;
193 		}
194 		/* Kernel entry point is the setup.bin */
195 	} else if (images.legacy_hdr_valid) {
196 		images.ep = image_get_ep(&images.legacy_hdr_os_copy);
197 #if IMAGE_ENABLE_FIT
198 	} else if (images.fit_uname_os) {
199 		int ret;
200 
201 		ret = fit_image_get_entry(images.fit_hdr_os,
202 					  images.fit_noffset_os, &images.ep);
203 		if (ret) {
204 			puts("Can't get entry point property!\n");
205 			return 1;
206 		}
207 #endif
208 	} else if (!ep_found) {
209 		puts("Could not find kernel entry point!\n");
210 		return 1;
211 	}
212 
213 	if (images.os.type == IH_TYPE_KERNEL_NOLOAD) {
214 		images.os.load = images.os.image_start;
215 		images.ep += images.os.load;
216 	}
217 
218 	images.os.start = map_to_sysmem(os_hdr);
219 
220 	return 0;
221 }
222 
223 /**
224  * bootm_find_images - wrapper to find and locate various images
225  * @flag: Ignored Argument
226  * @argc: command argument count
227  * @argv: command argument list
228  *
229  * boot_find_images() will attempt to load an available ramdisk,
230  * flattened device tree, as well as specifically marked
231  * "loadable" images (loadables are FIT only)
232  *
233  * Note: bootm_find_images will skip an image if it is not found
234  *
235  * @return:
236  *     0, if all existing images were loaded correctly
237  *     1, if an image is found but corrupted, or invalid
238  */
239 int bootm_find_images(int flag, int argc, char * const argv[])
240 {
241 	int ret;
242 
243 	/* find ramdisk */
244 	ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH,
245 			       &images.rd_start, &images.rd_end);
246 	if (ret) {
247 		puts("Ramdisk image is corrupt or invalid\n");
248 		return 1;
249 	}
250 
251 #if IMAGE_ENABLE_OF_LIBFDT
252 	/* find flattened device tree */
253 	ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
254 			   &images.ft_addr, &images.ft_len);
255 	if (ret) {
256 		puts("Could not find a valid device tree\n");
257 		return 1;
258 	}
259 	set_working_fdt_addr((ulong)images.ft_addr);
260 	lmb_reserve(&images.lmb, (ulong)images.ft_addr, (ulong)images.ft_len);
261 #endif
262 
263 #if IMAGE_ENABLE_FIT
264 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_XILINX)
265 	/* find bitstreams */
266 	ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT,
267 			    NULL, NULL);
268 	if (ret) {
269 		printf("FPGA image is corrupted or invalid\n");
270 		return 1;
271 	}
272 #endif
273 
274 	/* find all of the loadables */
275 	ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT,
276 			       NULL, NULL);
277 	if (ret) {
278 		printf("Loadable(s) is corrupt or invalid\n");
279 		return 1;
280 	}
281 #endif
282 
283 	return 0;
284 }
285 
286 static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc,
287 			    char * const argv[])
288 {
289 	if (((images.os.type == IH_TYPE_KERNEL) ||
290 	     (images.os.type == IH_TYPE_KERNEL_NOLOAD) ||
291 	     (images.os.type == IH_TYPE_MULTI)) &&
292 	    (images.os.os == IH_OS_LINUX ||
293 		 images.os.os == IH_OS_VXWORKS))
294 		return bootm_find_images(flag, argc, argv);
295 
296 	return 0;
297 }
298 #endif /* USE_HOSTC */
299 
300 /**
301  * print_decomp_msg() - Print a suitable decompression/loading message
302  *
303  * @type:	OS type (IH_OS_...)
304  * @comp_type:	Compression type being used (IH_COMP_...)
305  * @is_xip:	true if the load address matches the image start
306  */
307 static void print_decomp_msg(int comp_type, int type, bool is_xip,
308 			     ulong src, ulong dst)
309 {
310 	const char *name = genimg_get_type_name(type);
311 	const char *comp_name[] = {
312 		[IH_COMP_NONE]  = "",
313 		[IH_COMP_GZIP]  = "GZIP",
314 		[IH_COMP_BZIP2] = "BZIP2",
315 		[IH_COMP_LZMA]  = "LZMA",
316 		[IH_COMP_LZO]   = "LZO",
317 		[IH_COMP_LZ4]   = "LZ4",
318 		[IH_COMP_ZIMAGE]= "ZIMAGE",
319 	};
320 
321 	if (comp_type == IH_COMP_NONE)
322 		printf("   %s %s from 0x%08lx to 0x%08lx ... ",
323 		       is_xip ? "XIP" : "Loading", name, src, dst);
324 	else
325 		printf("   Uncompressing %s %s from 0x%08lx to 0x%08lx ... ",
326 		       comp_name[comp_type], name, src, dst);
327 }
328 
329 /**
330  * handle_decomp_error() - display a decompression error
331  *
332  * This function tries to produce a useful message. In the case where the
333  * uncompressed size is the same as the available space, we can assume that
334  * the image is too large for the buffer.
335  *
336  * @comp_type:		Compression type being used (IH_COMP_...)
337  * @uncomp_size:	Number of bytes uncompressed
338  * @unc_len:		Amount of space available for decompression
339  * @ret:		Error code to report
340  * @return BOOTM_ERR_RESET, indicating that the board must be reset
341  */
342 static int handle_decomp_error(int comp_type, size_t uncomp_size,
343 			       size_t unc_len, int ret)
344 {
345 	const char *name = genimg_get_comp_name(comp_type);
346 
347 	if (uncomp_size >= unc_len)
348 		printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n");
349 	else
350 		printf("%s: uncompress error %d\n", name, ret);
351 
352 	/*
353 	 * The decompression routines are now safe, so will not write beyond
354 	 * their bounds. Probably it is not necessary to reset, but maintain
355 	 * the current behaviour for now.
356 	 */
357 	printf("Must RESET board to recover\n");
358 #ifndef USE_HOSTCC
359 	bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
360 #endif
361 
362 	return BOOTM_ERR_RESET;
363 }
364 
365 int bootm_parse_comp(const unsigned char *hdr)
366 {
367 #if defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
368 	ulong start, end;
369 
370 	if (!bootz_setup((ulong)hdr, &start, &end))
371 		return IH_COMP_ZIMAGE;
372 #endif
373 #if defined(CONFIG_LZ4)
374 	if (lz4_is_valid_header(hdr))
375 		return IH_COMP_LZ4;
376 #endif
377 #if defined(CONFIG_LZO)
378 	if (lzop_is_valid_header(hdr))
379 		return IH_COMP_LZO;
380 #endif
381 #if defined(CONFIG_GZIP)
382 	if (gzip_parse_header(hdr, 0xffff) > 0)
383 		return IH_COMP_GZIP;
384 #endif
385 #if defined(CONFIG_BZIP2)
386 	if ((hdr[0] == 'B') && (hdr[1] == 'Z') && (hdr[2] == 'h'))
387 		return IH_COMP_BZIP2;
388 #endif
389 	return IH_COMP_NONE;
390 }
391 
392 int bootm_decomp_image(int comp, ulong load, ulong image_start, int type,
393 		       void *load_buf, void *image_buf, ulong image_len,
394 		       uint unc_len, ulong *load_end)
395 {
396 	int ret = 0;
397 
398 	*load_end = load;
399 	print_decomp_msg(comp, type, load == image_start,
400 		(ulong)image_buf, (ulong)load_buf);
401 
402 	/*
403 	 * Load the image to the right place, decompressing if needed. After
404 	 * this, image_len will be set to the number of uncompressed bytes
405 	 * loaded, ret will be non-zero on error.
406 	 */
407 	switch (comp) {
408 	case IH_COMP_NONE:
409 		if (load == image_start)
410 			break;
411 		if (image_len <= unc_len)
412 			memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
413 		else
414 			ret = 1;
415 		break;
416 #ifdef CONFIG_GZIP
417 	case IH_COMP_GZIP: {
418 		ret = gunzip(load_buf, unc_len, image_buf, &image_len);
419 		break;
420 	}
421 #endif /* CONFIG_GZIP */
422 #ifdef CONFIG_BZIP2
423 	case IH_COMP_BZIP2: {
424 		uint size = unc_len;
425 
426 		/*
427 		 * If we've got less than 4 MB of malloc() space,
428 		 * use slower decompression algorithm which requires
429 		 * at most 2300 KB of memory.
430 		 */
431 		ret = BZ2_bzBuffToBuffDecompress(load_buf, &size,
432 			image_buf, image_len,
433 			CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
434 		image_len = size;
435 		break;
436 	}
437 #endif /* CONFIG_BZIP2 */
438 #ifdef CONFIG_LZMA
439 	case IH_COMP_LZMA: {
440 		SizeT lzma_len = unc_len;
441 
442 		ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
443 					       image_buf, image_len);
444 		image_len = lzma_len;
445 		break;
446 	}
447 #endif /* CONFIG_LZMA */
448 #ifdef CONFIG_LZO
449 	case IH_COMP_LZO: {
450 		size_t size = unc_len;
451 
452 		ret = lzop_decompress(image_buf, image_len, load_buf, &size);
453 		image_len = size;
454 		break;
455 	}
456 #endif /* CONFIG_LZO */
457 #ifdef CONFIG_LZ4
458 	case IH_COMP_LZ4: {
459 		size_t size = unc_len;
460 
461 		ret = ulz4fn(image_buf, image_len, load_buf, &size);
462 		image_len = size;
463 		break;
464 	}
465 #endif /* CONFIG_LZ4 */
466 	default:
467 		printf("Unimplemented compression type %d\n", comp);
468 		return BOOTM_ERR_UNIMPLEMENTED;
469 	}
470 
471 	if (ret)
472 		return handle_decomp_error(comp, image_len, unc_len, ret);
473 	*load_end = load + image_len;
474 
475 	if (comp == IH_COMP_NONE || comp == IH_COMP_ZIMAGE)
476 		puts("OK\n");
477 	else
478 		printf("with %08lx bytes OK\n", image_len);
479 
480 	return 0;
481 }
482 
483 #ifndef USE_HOSTCC
484 static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
485 			 int boot_progress)
486 {
487 	image_info_t os = images->os;
488 	ulong load = os.load;
489 	ulong blob_start = os.start;
490 	ulong blob_end = os.end;
491 	ulong image_start = os.image_start;
492 	ulong image_len = os.image_len;
493 	bool no_overlap;
494 	void *load_buf, *image_buf;
495 	int err;
496 
497 	load_buf = map_sysmem(load, 0);
498 	image_buf = map_sysmem(os.image_start, image_len);
499 	err = bootm_decomp_image(os.comp, load, os.image_start, os.type,
500 				 load_buf, image_buf, image_len,
501 				 CONFIG_SYS_BOOTM_LEN, load_end);
502 	if (err) {
503 		bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
504 		return err;
505 	}
506 	flush_cache(load, ALIGN(*load_end - load, ARCH_DMA_MINALIGN));
507 
508 	debug("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
509 	bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);
510 
511 	no_overlap = (os.comp == IH_COMP_NONE && load == image_start);
512 
513 	if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) {
514 		debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
515 		      blob_start, blob_end);
516 		debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
517 		      *load_end);
518 
519 		/* Check what type of image this is. */
520 		if (images->legacy_hdr_valid) {
521 			if (image_get_type(&images->legacy_hdr_os_copy)
522 					== IH_TYPE_MULTI)
523 				puts("WARNING: legacy format multi component image overwritten\n");
524 			return BOOTM_ERR_OVERLAP;
525 		} else {
526 			puts("ERROR: new format image overwritten - must RESET the board to recover\n");
527 			bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
528 			return BOOTM_ERR_RESET;
529 		}
530 	}
531 
532 	return 0;
533 }
534 
535 /**
536  * bootm_disable_interrupts() - Disable interrupts in preparation for load/boot
537  *
538  * @return interrupt flag (0 if interrupts were disabled, non-zero if they were
539  *	enabled)
540  */
541 ulong bootm_disable_interrupts(void)
542 {
543 	ulong iflag;
544 
545 	/*
546 	 * Do not go further if usb is boot device,
547 	 * We may access usb at late sequence.
548 	 */
549 	if (!strcmp(env_get("devtype"), "usb"))
550 		return 0;
551 
552 	/*
553 	 * We have reached the point of no return: we are going to
554 	 * overwrite all exception vector code, so we cannot easily
555 	 * recover from any failures any more...
556 	 */
557 	iflag = disable_interrupts();
558 #ifdef CONFIG_NETCONSOLE
559 	/* Stop the ethernet stack if NetConsole could have left it up */
560 	eth_halt();
561 # ifndef CONFIG_DM_ETH
562 	eth_unregister(eth_get_dev());
563 # endif
564 #endif
565 
566 #if defined(CONFIG_CMD_USB)
567 	/*
568 	 * turn off USB to prevent the host controller from writing to the
569 	 * SDRAM while Linux is booting. This could happen (at least for OHCI
570 	 * controller), because the HCCA (Host Controller Communication Area)
571 	 * lies within the SDRAM and the host controller writes continously to
572 	 * this area (as busmaster!). The HccaFrameNumber is for example
573 	 * updated every 1 ms within the HCCA structure in SDRAM! For more
574 	 * details see the OpenHCI specification.
575 	 */
576 	usb_stop();
577 #endif
578 	return iflag;
579 }
580 
581 #if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
582 
583 #define CONSOLE_ARG     "console="
584 #define CONSOLE_ARG_LEN (sizeof(CONSOLE_ARG) - 1)
585 
586 static void fixup_silent_linux(void)
587 {
588 	char *buf;
589 	const char *env_val;
590 	char *cmdline = env_get("bootargs");
591 	int want_silent;
592 
593 	/*
594 	 * Only fix cmdline when requested. The environment variable can be:
595 	 *
596 	 *	no - we never fixup
597 	 *	yes - we always fixup
598 	 *	unset - we rely on the console silent flag
599 	 */
600 	want_silent = env_get_yesno("silent_linux");
601 	if (want_silent == 0)
602 		return;
603 	else if (want_silent == -1 && !(gd->flags & GD_FLG_SILENT))
604 		return;
605 
606 	debug("before silent fix-up: %s\n", cmdline);
607 	if (cmdline && (cmdline[0] != '\0')) {
608 		char *start = strstr(cmdline, CONSOLE_ARG);
609 
610 		/* Allocate space for maximum possible new command line */
611 		buf = malloc(strlen(cmdline) + 1 + CONSOLE_ARG_LEN + 1);
612 		if (!buf) {
613 			debug("%s: out of memory\n", __func__);
614 			return;
615 		}
616 
617 		if (start) {
618 			char *end = strchr(start, ' ');
619 			int num_start_bytes = start - cmdline + CONSOLE_ARG_LEN;
620 
621 			strncpy(buf, cmdline, num_start_bytes);
622 			if (end)
623 				strcpy(buf + num_start_bytes, end);
624 			else
625 				buf[num_start_bytes] = '\0';
626 		} else {
627 			sprintf(buf, "%s %s", cmdline, CONSOLE_ARG);
628 		}
629 		env_val = buf;
630 	} else {
631 		buf = NULL;
632 		env_val = CONSOLE_ARG;
633 	}
634 
635 	env_set("bootargs", env_val);
636 	debug("after silent fix-up: %s\n", env_val);
637 	free(buf);
638 }
639 #endif /* CONFIG_SILENT_CONSOLE */
640 
641 /**
642  * Execute selected states of the bootm command.
643  *
644  * Note the arguments to this state must be the first argument, Any 'bootm'
645  * or sub-command arguments must have already been taken.
646  *
647  * Note that if states contains more than one flag it MUST contain
648  * BOOTM_STATE_START, since this handles and consumes the command line args.
649  *
650  * Also note that aside from boot_os_fn functions and bootm_load_os no other
651  * functions we store the return value of in 'ret' may use a negative return
652  * value, without special handling.
653  *
654  * @param cmdtp		Pointer to bootm command table entry
655  * @param flag		Command flags (CMD_FLAG_...)
656  * @param argc		Number of subcommand arguments (0 = no arguments)
657  * @param argv		Arguments
658  * @param states	Mask containing states to run (BOOTM_STATE_...)
659  * @param images	Image header information
660  * @param boot_progress 1 to show boot progress, 0 to not do this
661  * @return 0 if ok, something else on error. Some errors will cause this
662  *	function to perform a reboot! If states contains BOOTM_STATE_OS_GO
663  *	then the intent is to boot an OS, so this function will not return
664  *	unless the image type is standalone.
665  */
666 int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
667 		    int states, bootm_headers_t *images, int boot_progress)
668 {
669 	boot_os_fn *boot_fn;
670 	ulong iflag = 0;
671 	int ret = 0, need_boot_fn;
672 
673 	images->state |= states;
674 
675 	/*
676 	 * Work through the states and see how far we get. We stop on
677 	 * any error.
678 	 */
679 	if (states & BOOTM_STATE_START)
680 		ret = bootm_start(cmdtp, flag, argc, argv);
681 
682 	if (!ret && (states & BOOTM_STATE_FINDOS))
683 		ret = bootm_find_os(cmdtp, flag, argc, argv);
684 
685 	if (!ret && (states & BOOTM_STATE_FINDOTHER))
686 		ret = bootm_find_other(cmdtp, flag, argc, argv);
687 
688 	/* Load the OS */
689 	if (!ret && (states & BOOTM_STATE_LOADOS)) {
690 		ulong load_end;
691 
692 		iflag = bootm_disable_interrupts();
693 		ret = bootm_load_os(images, &load_end, 0);
694 		if (ret == 0)
695 			lmb_reserve(&images->lmb, images->os.load,
696 				    (load_end - images->os.load));
697 		else if (ret && ret != BOOTM_ERR_OVERLAP)
698 			goto err;
699 		else if (ret == BOOTM_ERR_OVERLAP)
700 			ret = 0;
701 	}
702 
703 	/* Resever memory before any lmb_alloc, as early as possible */
704 #if IMAGE_ENABLE_OF_LIBFDT && defined(CONFIG_LMB)
705 	if (!ret && ((states & BOOTM_STATE_RAMDISK) ||
706 	    (states & BOOTM_STATE_FDT)))
707 		boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
708 #endif
709 	/* Relocate the ramdisk */
710 #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
711 	if (!ret && (states & BOOTM_STATE_RAMDISK)) {
712 		ulong rd_len = images->rd_end - images->rd_start;
713 
714 		ret = boot_ramdisk_high(&images->lmb, images->rd_start,
715 			rd_len, &images->initrd_start, &images->initrd_end);
716 		if (!ret) {
717 			env_set_hex("initrd_start", images->initrd_start);
718 			env_set_hex("initrd_end", images->initrd_end);
719 		}
720 	}
721 #endif
722 #if IMAGE_ENABLE_OF_LIBFDT && defined(CONFIG_LMB)
723 	if (!ret && (states & BOOTM_STATE_FDT)) {
724 		ret = boot_relocate_fdt(&images->lmb, &images->ft_addr,
725 					&images->ft_len);
726 	}
727 #endif
728 
729 	/* From now on, we need the OS boot function */
730 	if (ret)
731 		return ret;
732 	boot_fn = bootm_os_get_boot_func(images->os.os);
733 	need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE |
734 			BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP |
735 			BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO);
736 	if (boot_fn == NULL && need_boot_fn) {
737 		if (iflag)
738 			enable_interrupts();
739 		printf("ERROR: booting os '%s' (%d) is not supported\n",
740 		       genimg_get_os_name(images->os.os), images->os.os);
741 		bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
742 		return 1;
743 	}
744 
745 
746 	/* Call various other states that are not generally used */
747 	if (!ret && (states & BOOTM_STATE_OS_CMDLINE))
748 		ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images);
749 	if (!ret && (states & BOOTM_STATE_OS_BD_T))
750 		ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images);
751 	if (!ret && (states & BOOTM_STATE_OS_PREP)) {
752 #if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
753 		if (images->os.os == IH_OS_LINUX)
754 			fixup_silent_linux();
755 #endif
756 		arch_preboot_os(BOOTM_STATE_OS_PREP);
757 
758 		ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images);
759 	}
760 
761 #ifdef CONFIG_TRACE
762 	/* Pretend to run the OS, then run a user command */
763 	if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) {
764 		char *cmd_list = env_get("fakegocmd");
765 
766 		ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO,
767 				images, boot_fn);
768 		if (!ret && cmd_list)
769 			ret = run_command_list(cmd_list, -1, flag);
770 	}
771 #endif
772 
773 	/* Check for unsupported subcommand. */
774 	if (ret) {
775 		puts("subcommand not supported\n");
776 		return ret;
777 	}
778 
779 	/* Now run the OS! We hope this doesn't return */
780 	if (!ret && (states & BOOTM_STATE_OS_GO))
781 		ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,
782 				images, boot_fn);
783 
784 	/* Deal with any fallout */
785 err:
786 	if (iflag)
787 		enable_interrupts();
788 
789 	if (ret == BOOTM_ERR_UNIMPLEMENTED)
790 		bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
791 	else if (ret == BOOTM_ERR_RESET)
792 		do_reset(cmdtp, flag, argc, argv);
793 
794 	return ret;
795 }
796 
797 #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
798 /**
799  * image_get_kernel - verify legacy format kernel image
800  * @img_addr: in RAM address of the legacy format image to be verified
801  * @verify: data CRC verification flag
802  *
803  * image_get_kernel() verifies legacy image integrity and returns pointer to
804  * legacy image header if image verification was completed successfully.
805  *
806  * returns:
807  *     pointer to a legacy image header if valid image was found
808  *     otherwise return NULL
809  */
810 static image_header_t *image_get_kernel(ulong img_addr, int verify)
811 {
812 	image_header_t *hdr = (image_header_t *)img_addr;
813 
814 	if (!image_check_magic(hdr)) {
815 		puts("Bad Magic Number\n");
816 		bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC);
817 		return NULL;
818 	}
819 	bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER);
820 
821 	if (!image_check_hcrc(hdr)) {
822 		puts("Bad Header Checksum\n");
823 		bootstage_error(BOOTSTAGE_ID_CHECK_HEADER);
824 		return NULL;
825 	}
826 
827 	bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM);
828 	image_print_contents(hdr);
829 
830 	if (verify) {
831 		puts("   Verifying Checksum ... ");
832 		if (!image_check_dcrc(hdr)) {
833 			printf("Bad Data CRC\n");
834 			bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM);
835 			return NULL;
836 		}
837 		puts("OK\n");
838 	}
839 	bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH);
840 
841 	if (!image_check_target_arch(hdr)) {
842 		printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr));
843 		bootstage_error(BOOTSTAGE_ID_CHECK_ARCH);
844 		return NULL;
845 	}
846 	return hdr;
847 }
848 #endif
849 
850 /**
851  * boot_get_kernel - find kernel image
852  * @os_data: pointer to a ulong variable, will hold os data start address
853  * @os_len: pointer to a ulong variable, will hold os data length
854  *
855  * boot_get_kernel() tries to find a kernel image, verifies its integrity
856  * and locates kernel data.
857  *
858  * returns:
859  *     pointer to image header if valid image was found, plus kernel start
860  *     address and length, otherwise NULL
861  */
862 static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
863 				   char * const argv[], bootm_headers_t *images,
864 				   ulong *os_data, ulong *os_len)
865 {
866 #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
867 	image_header_t	*hdr;
868 #endif
869 	ulong		img_addr;
870 	const void *buf;
871 	const char	*fit_uname_config = NULL;
872 	const char	*fit_uname_kernel = NULL;
873 #if IMAGE_ENABLE_FIT
874 	int		os_noffset;
875 #endif
876 
877 	img_addr = genimg_get_kernel_addr_fit(argc < 1 ? NULL : argv[0],
878 					      &fit_uname_config,
879 					      &fit_uname_kernel);
880 
881 	bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);
882 
883 	/* check image type, for FIT images get FIT kernel node */
884 	*os_data = *os_len = 0;
885 	buf = map_sysmem(img_addr, 0);
886 	switch (genimg_get_format(buf)) {
887 #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
888 	case IMAGE_FORMAT_LEGACY:
889 		printf("## Booting kernel from Legacy Image at %08lx ...\n",
890 		       img_addr);
891 		hdr = image_get_kernel(img_addr, images->verify);
892 		if (!hdr)
893 			return NULL;
894 		bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE);
895 
896 		/* get os_data and os_len */
897 		switch (image_get_type(hdr)) {
898 		case IH_TYPE_KERNEL:
899 		case IH_TYPE_KERNEL_NOLOAD:
900 			*os_data = image_get_data(hdr);
901 			*os_len = image_get_data_size(hdr);
902 			break;
903 		case IH_TYPE_MULTI:
904 			image_multi_getimg(hdr, 0, os_data, os_len);
905 			break;
906 		case IH_TYPE_STANDALONE:
907 			*os_data = image_get_data(hdr);
908 			*os_len = image_get_data_size(hdr);
909 			break;
910 		default:
911 			if (cmdtp)
912 				printf("Wrong Image Type for %s command\n",
913 				       cmdtp->name);
914 			bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE);
915 			return NULL;
916 		}
917 
918 		/*
919 		 * copy image header to allow for image overwrites during
920 		 * kernel decompression.
921 		 */
922 		memmove(&images->legacy_hdr_os_copy, hdr,
923 			sizeof(image_header_t));
924 
925 		/* save pointer to image header */
926 		images->legacy_hdr_os = hdr;
927 
928 		images->legacy_hdr_valid = 1;
929 		bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE);
930 		break;
931 #endif
932 #if IMAGE_ENABLE_FIT
933 	case IMAGE_FORMAT_FIT:
934 		os_noffset = fit_image_load(images, img_addr,
935 				&fit_uname_kernel, &fit_uname_config,
936 				IH_ARCH_DEFAULT, IH_TYPE_KERNEL,
937 				BOOTSTAGE_ID_FIT_KERNEL_START,
938 				FIT_LOAD_IGNORED, os_data, os_len);
939 		if (os_noffset < 0)
940 			return NULL;
941 
942 		images->fit_hdr_os = map_sysmem(img_addr, 0);
943 		images->fit_uname_os = fit_uname_kernel;
944 		images->fit_uname_cfg = fit_uname_config;
945 		images->fit_noffset_os = os_noffset;
946 		break;
947 #endif
948 #ifdef CONFIG_ANDROID_BOOT_IMAGE
949 	case IMAGE_FORMAT_ANDROID:
950 		printf("## Booting Android Image at 0x%08lx ...\n", img_addr);
951 		if (android_image_get_kernel(buf, images->verify,
952 					     os_data, os_len))
953 			return NULL;
954 		break;
955 #endif
956 	default:
957 		if (cmdtp)
958 			printf("Wrong Image Format for %s command\n",
959 			       cmdtp->name);
960 		bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO);
961 		return NULL;
962 	}
963 
964 	debug("   kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
965 	      *os_data, *os_len, *os_len);
966 
967 	return buf;
968 }
969 #else /* USE_HOSTCC */
970 
971 void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
972 {
973 	memmove(to, from, len);
974 }
975 
976 static int bootm_host_load_image(const void *fit, int req_image_type)
977 {
978 	const char *fit_uname_config = NULL;
979 	ulong data, len;
980 	bootm_headers_t images;
981 	int noffset;
982 	ulong load_end;
983 	uint8_t image_type;
984 	uint8_t imape_comp;
985 	void *load_buf;
986 	int ret;
987 
988 	memset(&images, '\0', sizeof(images));
989 	images.verify = 1;
990 	noffset = fit_image_load(&images, (ulong)fit,
991 		NULL, &fit_uname_config,
992 		IH_ARCH_DEFAULT, req_image_type, -1,
993 		FIT_LOAD_IGNORED, &data, &len);
994 	if (noffset < 0)
995 		return noffset;
996 	if (fit_image_get_type(fit, noffset, &image_type)) {
997 		puts("Can't get image type!\n");
998 		return -EINVAL;
999 	}
1000 
1001 	if (fit_image_get_comp(fit, noffset, &imape_comp)) {
1002 		puts("Can't get image compression!\n");
1003 		return -EINVAL;
1004 	}
1005 
1006 	/* Allow the image to expand by a factor of 4, should be safe */
1007 	load_buf = malloc((1 << 20) + len * 4);
1008 	ret = bootm_decomp_image(imape_comp, 0, data, image_type, load_buf,
1009 				 (void *)data, len, CONFIG_SYS_BOOTM_LEN,
1010 				 &load_end);
1011 	free(load_buf);
1012 
1013 	if (ret && ret != BOOTM_ERR_UNIMPLEMENTED)
1014 		return ret;
1015 
1016 	return 0;
1017 }
1018 
1019 int bootm_host_load_images(const void *fit, int cfg_noffset)
1020 {
1021 	static uint8_t image_types[] = {
1022 		IH_TYPE_KERNEL,
1023 		IH_TYPE_FLATDT,
1024 		IH_TYPE_RAMDISK,
1025 	};
1026 	int err = 0;
1027 	int i;
1028 
1029 	for (i = 0; i < ARRAY_SIZE(image_types); i++) {
1030 		int ret;
1031 
1032 		ret = bootm_host_load_image(fit, image_types[i]);
1033 		if (!err && ret && ret != -ENOENT)
1034 			err = ret;
1035 	}
1036 
1037 	/* Return the first error we found */
1038 	return err;
1039 }
1040 
1041 #endif /* ndef USE_HOSTCC */
1042