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