cmd_disk.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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: %ld, # of blocks: %ld, Block Size: %ld\n",
  62. info.start, info.size, info.blksz);
  63. if (dev_desc->block_read(dev, info.start, 1, (ulong *) addr) != 1) {
  64. printf("** Read error on %d:%d\n", dev, part);
  65. bootstage_error(BOOTSTAGE_ID_IDE_PART_READ);
  66. return 1;
  67. }
  68. bootstage_mark(BOOTSTAGE_ID_IDE_PART_READ);
  69. switch (genimg_get_format((void *) addr)) {
  70. case IMAGE_FORMAT_LEGACY:
  71. hdr = (image_header_t *) addr;
  72. bootstage_mark(BOOTSTAGE_ID_IDE_FORMAT);
  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. image_print_contents(hdr);
  80. cnt = image_get_image_size(hdr);
  81. break;
  82. #if defined(CONFIG_FIT)
  83. case IMAGE_FORMAT_FIT:
  84. fit_hdr = (const void *) addr;
  85. puts("Fit image detected...\n");
  86. cnt = fit_get_size(fit_hdr);
  87. break;
  88. #endif
  89. default:
  90. bootstage_error(BOOTSTAGE_ID_IDE_FORMAT);
  91. puts("** Unknown image type\n");
  92. return 1;
  93. }
  94. cnt += info.blksz - 1;
  95. cnt /= info.blksz;
  96. cnt -= 1;
  97. if (dev_desc->block_read(dev, info.start + 1, cnt,
  98. (ulong *)(addr + info.blksz)) != cnt) {
  99. printf("** Read error on %d:%d\n", dev, part);
  100. bootstage_error(BOOTSTAGE_ID_IDE_READ);
  101. return 1;
  102. }
  103. bootstage_mark(BOOTSTAGE_ID_IDE_READ);
  104. #if defined(CONFIG_FIT)
  105. /* This cannot be done earlier,
  106. * we need complete FIT image in RAM first */
  107. if (genimg_get_format((void *) addr) == IMAGE_FORMAT_FIT) {
  108. if (!fit_check_format(fit_hdr)) {
  109. bootstage_error(BOOTSTAGE_ID_IDE_FIT_READ);
  110. puts("** Bad FIT image format\n");
  111. return 1;
  112. }
  113. bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK);
  114. fit_print_contents(fit_hdr);
  115. }
  116. #endif
  117. flush_cache(addr, (cnt+1)*info.blksz);
  118. /* Loading ok, update default load address */
  119. load_addr = addr;
  120. return bootm_maybe_autostart(cmdtp, argv[0]);
  121. }
  122. #endif