xref: /rk3399_rockchip-uboot/cmd/disk.c (revision 04681cb3a4d2ef5351f94132e325fb8841d37961)
12e192b24SSimon Glass /*
22e192b24SSimon Glass  * (C) Copyright 2000-2011
32e192b24SSimon Glass  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
42e192b24SSimon Glass  *
52e192b24SSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
62e192b24SSimon Glass  */
72e192b24SSimon Glass #include <common.h>
82e192b24SSimon Glass #include <command.h>
92e192b24SSimon Glass #include <part.h>
102e192b24SSimon Glass 
11c649e3c9SSimon Glass #if defined(CONFIG_CMD_IDE) || defined(CONFIG_SCSI) || \
122e192b24SSimon Glass 	defined(CONFIG_USB_STORAGE)
132e192b24SSimon Glass int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,
142e192b24SSimon Glass 		    char *const argv[])
152e192b24SSimon Glass {
16*04681cb3SMarek Vasut 	__maybe_unused int dev;
17*04681cb3SMarek Vasut 	int part;
182e192b24SSimon Glass 	ulong addr = CONFIG_SYS_LOAD_ADDR;
192e192b24SSimon Glass 	ulong cnt;
202e192b24SSimon Glass 	disk_partition_t info;
212e192b24SSimon Glass #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
222e192b24SSimon Glass 	image_header_t *hdr;
232e192b24SSimon Glass #endif
244101f687SSimon Glass 	struct blk_desc *dev_desc;
252e192b24SSimon Glass 
2673223f0eSSimon Glass #if CONFIG_IS_ENABLED(FIT)
272e192b24SSimon Glass 	const void *fit_hdr = NULL;
282e192b24SSimon Glass #endif
292e192b24SSimon Glass 
302e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_IDE_START);
312e192b24SSimon Glass 	if (argc > 3) {
322e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_IDE_ADDR);
332e192b24SSimon Glass 		return CMD_RET_USAGE;
342e192b24SSimon Glass 	}
352e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_IDE_ADDR);
362e192b24SSimon Glass 
372e192b24SSimon Glass 	if (argc > 1)
382e192b24SSimon Glass 		addr = simple_strtoul(argv[1], NULL, 16);
392e192b24SSimon Glass 
402e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_IDE_BOOT_DEVICE);
412e192b24SSimon Glass 
42e35929e4SSimon Glass 	part = blk_get_device_part_str(intf, (argc == 3) ? argv[2] : NULL,
432e192b24SSimon Glass 					&dev_desc, &info, 1);
442e192b24SSimon Glass 	if (part < 0) {
452e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_IDE_TYPE);
462e192b24SSimon Glass 		return 1;
472e192b24SSimon Glass 	}
482e192b24SSimon Glass 
49bcce53d0SSimon Glass 	dev = dev_desc->devnum;
502e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_IDE_TYPE);
512e192b24SSimon Glass 
522e192b24SSimon Glass 	printf("\nLoading from %s device %d, partition %d: "
532e192b24SSimon Glass 	       "Name: %.32s  Type: %.32s\n", intf, dev, part, info.name,
542e192b24SSimon Glass 	       info.type);
552e192b24SSimon Glass 
562e192b24SSimon Glass 	debug("First Block: " LBAFU ",  # of blocks: " LBAFU
572e192b24SSimon Glass 	      ", Block Size: %ld\n",
582e192b24SSimon Glass 	      info.start, info.size, info.blksz);
592e192b24SSimon Glass 
602a981dc2SSimon Glass 	if (blk_dread(dev_desc, info.start, 1, (ulong *)addr) != 1) {
612e192b24SSimon Glass 		printf("** Read error on %d:%d\n", dev, part);
622e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_IDE_PART_READ);
632e192b24SSimon Glass 		return 1;
642e192b24SSimon Glass 	}
652e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_IDE_PART_READ);
662e192b24SSimon Glass 
672e192b24SSimon Glass 	switch (genimg_get_format((void *) addr)) {
682e192b24SSimon Glass #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
692e192b24SSimon Glass 	case IMAGE_FORMAT_LEGACY:
702e192b24SSimon Glass 		hdr = (image_header_t *) addr;
712e192b24SSimon Glass 
722e192b24SSimon Glass 		bootstage_mark(BOOTSTAGE_ID_IDE_FORMAT);
732e192b24SSimon Glass 
742e192b24SSimon Glass 		if (!image_check_hcrc(hdr)) {
752e192b24SSimon Glass 			puts("\n** Bad Header Checksum **\n");
762e192b24SSimon Glass 			bootstage_error(BOOTSTAGE_ID_IDE_CHECKSUM);
772e192b24SSimon Glass 			return 1;
782e192b24SSimon Glass 		}
792e192b24SSimon Glass 		bootstage_mark(BOOTSTAGE_ID_IDE_CHECKSUM);
802e192b24SSimon Glass 
812e192b24SSimon Glass 		image_print_contents(hdr);
822e192b24SSimon Glass 
832e192b24SSimon Glass 		cnt = image_get_image_size(hdr);
842e192b24SSimon Glass 		break;
852e192b24SSimon Glass #endif
8673223f0eSSimon Glass #if CONFIG_IS_ENABLED(FIT)
872e192b24SSimon Glass 	case IMAGE_FORMAT_FIT:
882e192b24SSimon Glass 		fit_hdr = (const void *) addr;
892e192b24SSimon Glass 		puts("Fit image detected...\n");
902e192b24SSimon Glass 
912e192b24SSimon Glass 		cnt = fit_get_size(fit_hdr);
922e192b24SSimon Glass 		break;
932e192b24SSimon Glass #endif
942e192b24SSimon Glass 	default:
952e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_IDE_FORMAT);
962e192b24SSimon Glass 		puts("** Unknown image type\n");
972e192b24SSimon Glass 		return 1;
982e192b24SSimon Glass 	}
992e192b24SSimon Glass 
1002e192b24SSimon Glass 	cnt += info.blksz - 1;
1012e192b24SSimon Glass 	cnt /= info.blksz;
1022e192b24SSimon Glass 	cnt -= 1;
1032e192b24SSimon Glass 
1042a981dc2SSimon Glass 	if (blk_dread(dev_desc, info.start + 1, cnt,
1052e192b24SSimon Glass 		      (ulong *)(addr + info.blksz)) != cnt) {
1062e192b24SSimon Glass 		printf("** Read error on %d:%d\n", dev, part);
1072e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_IDE_READ);
1082e192b24SSimon Glass 		return 1;
1092e192b24SSimon Glass 	}
1102e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_IDE_READ);
1112e192b24SSimon Glass 
11273223f0eSSimon Glass #if CONFIG_IS_ENABLED(FIT)
1132e192b24SSimon Glass 	/* This cannot be done earlier,
1142e192b24SSimon Glass 	 * we need complete FIT image in RAM first */
1152e192b24SSimon Glass 	if (genimg_get_format((void *) addr) == IMAGE_FORMAT_FIT) {
1162e192b24SSimon Glass 		if (!fit_check_format(fit_hdr)) {
1172e192b24SSimon Glass 			bootstage_error(BOOTSTAGE_ID_IDE_FIT_READ);
1182e192b24SSimon Glass 			puts("** Bad FIT image format\n");
1192e192b24SSimon Glass 			return 1;
1202e192b24SSimon Glass 		}
1212e192b24SSimon Glass 		bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK);
1222e192b24SSimon Glass 		fit_print_contents(fit_hdr);
1232e192b24SSimon Glass 	}
1242e192b24SSimon Glass #endif
1252e192b24SSimon Glass 
1262e192b24SSimon Glass 	flush_cache(addr, (cnt+1)*info.blksz);
1272e192b24SSimon Glass 
1282e192b24SSimon Glass 	/* Loading ok, update default load address */
1292e192b24SSimon Glass 	load_addr = addr;
1302e192b24SSimon Glass 
1312e192b24SSimon Glass 	return bootm_maybe_autostart(cmdtp, argv[0]);
1322e192b24SSimon Glass }
1332e192b24SSimon Glass #endif
134