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