cmd_disk.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * (C) Copyright 2000-2011
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. *
  23. */
  24. #include <common.h>
  25. #include <command.h>
  26. #include <part.h>
  27. #if defined(CONFIG_CMD_IDE) || defined(CONFIG_CMD_SCSI) || \
  28. defined(CONFIG_USB_STORAGE)
  29. int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,
  30. char *const argv[])
  31. {
  32. int dev, part;
  33. ulong addr = CONFIG_SYS_LOAD_ADDR;
  34. ulong cnt;
  35. disk_partition_t info;
  36. image_header_t *hdr;
  37. block_dev_desc_t *dev_desc;
  38. #if defined(CONFIG_FIT)
  39. const void *fit_hdr = NULL;
  40. #endif
  41. bootstage_mark(BOOTSTAGE_ID_IDE_START);
  42. if (argc > 3) {
  43. bootstage_error(BOOTSTAGE_ID_IDE_ADDR);
  44. return CMD_RET_USAGE;
  45. }
  46. bootstage_mark(BOOTSTAGE_ID_IDE_ADDR);
  47. if (argc > 1)
  48. addr = simple_strtoul(argv[1], NULL, 16);
  49. bootstage_mark(BOOTSTAGE_ID_IDE_BOOT_DEVICE);
  50. part = get_device_and_partition(intf, (argc == 3) ? argv[2] : NULL,
  51. &dev_desc, &info, 1);
  52. if (part < 0) {
  53. bootstage_error(BOOTSTAGE_ID_IDE_TYPE);
  54. return 1;
  55. }
  56. dev = dev_desc->dev;
  57. bootstage_mark(BOOTSTAGE_ID_IDE_TYPE);
  58. printf("\nLoading from %s device %d, partition %d: "
  59. "Name: %.32s Type: %.32s\n", intf, dev, part, info.name,
  60. info.type);
  61. debug("First Block: " LBAFU ", # of blocks: " LBAFU
  62. ", Block Size: %ld\n",
  63. info.start, info.size, info.blksz);
  64. if (dev_desc->block_read(dev, info.start, 1, (ulong *) addr) != 1) {
  65. printf("** Read error on %d:%d\n", dev, part);
  66. bootstage_error(BOOTSTAGE_ID_IDE_PART_READ);
  67. return 1;
  68. }
  69. bootstage_mark(BOOTSTAGE_ID_IDE_PART_READ);
  70. switch (genimg_get_format((void *) addr)) {
  71. case IMAGE_FORMAT_LEGACY:
  72. hdr = (image_header_t *) addr;
  73. bootstage_mark(BOOTSTAGE_ID_IDE_FORMAT);
  74. if (!image_check_hcrc(hdr)) {
  75. puts("\n** Bad Header Checksum **\n");
  76. bootstage_error(BOOTSTAGE_ID_IDE_CHECKSUM);
  77. return 1;
  78. }
  79. bootstage_mark(BOOTSTAGE_ID_IDE_CHECKSUM);
  80. image_print_contents(hdr);
  81. cnt = image_get_image_size(hdr);
  82. break;
  83. #if defined(CONFIG_FIT)
  84. case IMAGE_FORMAT_FIT:
  85. fit_hdr = (const void *) addr;
  86. puts("Fit image detected...\n");
  87. cnt = fit_get_size(fit_hdr);
  88. break;
  89. #endif
  90. default:
  91. bootstage_error(BOOTSTAGE_ID_IDE_FORMAT);
  92. puts("** Unknown image type\n");
  93. return 1;
  94. }
  95. cnt += info.blksz - 1;
  96. cnt /= info.blksz;
  97. cnt -= 1;
  98. if (dev_desc->block_read(dev, info.start + 1, cnt,
  99. (ulong *)(addr + info.blksz)) != cnt) {
  100. printf("** Read error on %d:%d\n", dev, part);
  101. bootstage_error(BOOTSTAGE_ID_IDE_READ);
  102. return 1;
  103. }
  104. bootstage_mark(BOOTSTAGE_ID_IDE_READ);
  105. #if defined(CONFIG_FIT)
  106. /* This cannot be done earlier,
  107. * we need complete FIT image in RAM first */
  108. if (genimg_get_format((void *) addr) == IMAGE_FORMAT_FIT) {
  109. if (!fit_check_format(fit_hdr)) {
  110. bootstage_error(BOOTSTAGE_ID_IDE_FIT_READ);
  111. puts("** Bad FIT image format\n");
  112. return 1;
  113. }
  114. bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK);
  115. fit_print_contents(fit_hdr);
  116. }
  117. #endif
  118. flush_cache(addr, (cnt+1)*info.blksz);
  119. /* Loading ok, update default load address */
  120. load_addr = addr;
  121. return bootm_maybe_autostart(cmdtp, argv[0]);
  122. }
  123. #endif