xref: /rk3399_rockchip-uboot/cmd/disk.c (revision 2e192b245ed36a63bab0ef576999a95e23f60ecd)
1*2e192b24SSimon Glass /*
2*2e192b24SSimon Glass  * (C) Copyright 2000-2011
3*2e192b24SSimon Glass  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4*2e192b24SSimon Glass  *
5*2e192b24SSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
6*2e192b24SSimon Glass  */
7*2e192b24SSimon Glass #include <common.h>
8*2e192b24SSimon Glass #include <command.h>
9*2e192b24SSimon Glass #include <part.h>
10*2e192b24SSimon Glass 
11*2e192b24SSimon Glass #if defined(CONFIG_CMD_IDE) || defined(CONFIG_CMD_SCSI) || \
12*2e192b24SSimon Glass 	defined(CONFIG_USB_STORAGE)
13*2e192b24SSimon Glass int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,
14*2e192b24SSimon Glass 		    char *const argv[])
15*2e192b24SSimon Glass {
16*2e192b24SSimon Glass 	int dev, part;
17*2e192b24SSimon Glass 	ulong addr = CONFIG_SYS_LOAD_ADDR;
18*2e192b24SSimon Glass 	ulong cnt;
19*2e192b24SSimon Glass 	disk_partition_t info;
20*2e192b24SSimon Glass #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
21*2e192b24SSimon Glass 	image_header_t *hdr;
22*2e192b24SSimon Glass #endif
23*2e192b24SSimon Glass 	block_dev_desc_t *dev_desc;
24*2e192b24SSimon Glass 
25*2e192b24SSimon Glass #if defined(CONFIG_FIT)
26*2e192b24SSimon Glass 	const void *fit_hdr = NULL;
27*2e192b24SSimon Glass #endif
28*2e192b24SSimon Glass 
29*2e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_IDE_START);
30*2e192b24SSimon Glass 	if (argc > 3) {
31*2e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_IDE_ADDR);
32*2e192b24SSimon Glass 		return CMD_RET_USAGE;
33*2e192b24SSimon Glass 	}
34*2e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_IDE_ADDR);
35*2e192b24SSimon Glass 
36*2e192b24SSimon Glass 	if (argc > 1)
37*2e192b24SSimon Glass 		addr = simple_strtoul(argv[1], NULL, 16);
38*2e192b24SSimon Glass 
39*2e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_IDE_BOOT_DEVICE);
40*2e192b24SSimon Glass 
41*2e192b24SSimon Glass 	part = get_device_and_partition(intf, (argc == 3) ? argv[2] : NULL,
42*2e192b24SSimon Glass 					&dev_desc, &info, 1);
43*2e192b24SSimon Glass 	if (part < 0) {
44*2e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_IDE_TYPE);
45*2e192b24SSimon Glass 		return 1;
46*2e192b24SSimon Glass 	}
47*2e192b24SSimon Glass 
48*2e192b24SSimon Glass 	dev = dev_desc->dev;
49*2e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_IDE_TYPE);
50*2e192b24SSimon Glass 
51*2e192b24SSimon Glass 	printf("\nLoading from %s device %d, partition %d: "
52*2e192b24SSimon Glass 	       "Name: %.32s  Type: %.32s\n", intf, dev, part, info.name,
53*2e192b24SSimon Glass 	       info.type);
54*2e192b24SSimon Glass 
55*2e192b24SSimon Glass 	debug("First Block: " LBAFU ",  # of blocks: " LBAFU
56*2e192b24SSimon Glass 	      ", Block Size: %ld\n",
57*2e192b24SSimon Glass 	      info.start, info.size, info.blksz);
58*2e192b24SSimon Glass 
59*2e192b24SSimon Glass 	if (dev_desc->block_read(dev_desc, info.start, 1, (ulong *)addr) != 1) {
60*2e192b24SSimon Glass 		printf("** Read error on %d:%d\n", dev, part);
61*2e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_IDE_PART_READ);
62*2e192b24SSimon Glass 		return 1;
63*2e192b24SSimon Glass 	}
64*2e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_IDE_PART_READ);
65*2e192b24SSimon Glass 
66*2e192b24SSimon Glass 	switch (genimg_get_format((void *) addr)) {
67*2e192b24SSimon Glass #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
68*2e192b24SSimon Glass 	case IMAGE_FORMAT_LEGACY:
69*2e192b24SSimon Glass 		hdr = (image_header_t *) addr;
70*2e192b24SSimon Glass 
71*2e192b24SSimon Glass 		bootstage_mark(BOOTSTAGE_ID_IDE_FORMAT);
72*2e192b24SSimon Glass 
73*2e192b24SSimon Glass 		if (!image_check_hcrc(hdr)) {
74*2e192b24SSimon Glass 			puts("\n** Bad Header Checksum **\n");
75*2e192b24SSimon Glass 			bootstage_error(BOOTSTAGE_ID_IDE_CHECKSUM);
76*2e192b24SSimon Glass 			return 1;
77*2e192b24SSimon Glass 		}
78*2e192b24SSimon Glass 		bootstage_mark(BOOTSTAGE_ID_IDE_CHECKSUM);
79*2e192b24SSimon Glass 
80*2e192b24SSimon Glass 		image_print_contents(hdr);
81*2e192b24SSimon Glass 
82*2e192b24SSimon Glass 		cnt = image_get_image_size(hdr);
83*2e192b24SSimon Glass 		break;
84*2e192b24SSimon Glass #endif
85*2e192b24SSimon Glass #if defined(CONFIG_FIT)
86*2e192b24SSimon Glass 	case IMAGE_FORMAT_FIT:
87*2e192b24SSimon Glass 		fit_hdr = (const void *) addr;
88*2e192b24SSimon Glass 		puts("Fit image detected...\n");
89*2e192b24SSimon Glass 
90*2e192b24SSimon Glass 		cnt = fit_get_size(fit_hdr);
91*2e192b24SSimon Glass 		break;
92*2e192b24SSimon Glass #endif
93*2e192b24SSimon Glass 	default:
94*2e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_IDE_FORMAT);
95*2e192b24SSimon Glass 		puts("** Unknown image type\n");
96*2e192b24SSimon Glass 		return 1;
97*2e192b24SSimon Glass 	}
98*2e192b24SSimon Glass 
99*2e192b24SSimon Glass 	cnt += info.blksz - 1;
100*2e192b24SSimon Glass 	cnt /= info.blksz;
101*2e192b24SSimon Glass 	cnt -= 1;
102*2e192b24SSimon Glass 
103*2e192b24SSimon Glass 	if (dev_desc->block_read(dev_desc, info.start + 1, cnt,
104*2e192b24SSimon Glass 				 (ulong *)(addr + info.blksz)) != cnt) {
105*2e192b24SSimon Glass 		printf("** Read error on %d:%d\n", dev, part);
106*2e192b24SSimon Glass 		bootstage_error(BOOTSTAGE_ID_IDE_READ);
107*2e192b24SSimon Glass 		return 1;
108*2e192b24SSimon Glass 	}
109*2e192b24SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_IDE_READ);
110*2e192b24SSimon Glass 
111*2e192b24SSimon Glass #if defined(CONFIG_FIT)
112*2e192b24SSimon Glass 	/* This cannot be done earlier,
113*2e192b24SSimon Glass 	 * we need complete FIT image in RAM first */
114*2e192b24SSimon Glass 	if (genimg_get_format((void *) addr) == IMAGE_FORMAT_FIT) {
115*2e192b24SSimon Glass 		if (!fit_check_format(fit_hdr)) {
116*2e192b24SSimon Glass 			bootstage_error(BOOTSTAGE_ID_IDE_FIT_READ);
117*2e192b24SSimon Glass 			puts("** Bad FIT image format\n");
118*2e192b24SSimon Glass 			return 1;
119*2e192b24SSimon Glass 		}
120*2e192b24SSimon Glass 		bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK);
121*2e192b24SSimon Glass 		fit_print_contents(fit_hdr);
122*2e192b24SSimon Glass 	}
123*2e192b24SSimon Glass #endif
124*2e192b24SSimon Glass 
125*2e192b24SSimon Glass 	flush_cache(addr, (cnt+1)*info.blksz);
126*2e192b24SSimon Glass 
127*2e192b24SSimon Glass 	/* Loading ok, update default load address */
128*2e192b24SSimon Glass 	load_addr = addr;
129*2e192b24SSimon Glass 
130*2e192b24SSimon Glass 	return bootm_maybe_autostart(cmdtp, argv[0]);
131*2e192b24SSimon Glass }
132*2e192b24SSimon Glass #endif
133