spl.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /*
  2. * (C) Copyright 2010
  3. * Texas Instruments, <www.ti.com>
  4. *
  5. * Aneesh V <aneesh@ti.com>
  6. *
  7. * See file CREDITS for list of people who contributed to this
  8. * project.
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License as
  12. * published by the Free Software Foundation; either version 2 of
  13. * the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23. * MA 02111-1307 USA
  24. */
  25. #include <common.h>
  26. #include <asm/u-boot.h>
  27. #include <asm/utils.h>
  28. #include <asm/arch/sys_proto.h>
  29. #include <mmc.h>
  30. #include <fat.h>
  31. #include <timestamp_autogenerated.h>
  32. #include <version_autogenerated.h>
  33. #include <asm/omap_common.h>
  34. #include <asm/arch/mmc_host_def.h>
  35. #include <i2c.h>
  36. #include <image.h>
  37. DECLARE_GLOBAL_DATA_PTR;
  38. /* Define global data structure pointer to it*/
  39. static gd_t gdata __attribute__ ((section(".data")));
  40. static bd_t bdata __attribute__ ((section(".data")));
  41. static const char *image_name;
  42. static u8 image_os;
  43. static u32 image_load_addr;
  44. static u32 image_entry_point;
  45. static u32 image_size;
  46. inline void hang(void)
  47. {
  48. puts("### ERROR ### Please RESET the board ###\n");
  49. for (;;)
  50. ;
  51. }
  52. void board_init_f(ulong dummy)
  53. {
  54. /*
  55. * We call relocate_code() with relocation target same as the
  56. * CONFIG_SYS_SPL_TEXT_BASE. This will result in relocation getting
  57. * skipped. Instead, only .bss initialization will happen. That's
  58. * all we need
  59. */
  60. debug(">>board_init_f()\n");
  61. relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE);
  62. }
  63. #ifdef CONFIG_GENERIC_MMC
  64. int board_mmc_init(bd_t *bis)
  65. {
  66. switch (omap_boot_device()) {
  67. case BOOT_DEVICE_MMC1:
  68. omap_mmc_init(0);
  69. break;
  70. case BOOT_DEVICE_MMC2:
  71. omap_mmc_init(1);
  72. break;
  73. }
  74. return 0;
  75. }
  76. #endif
  77. static void parse_image_header(const struct image_header *header)
  78. {
  79. u32 header_size = sizeof(struct image_header);
  80. if (__be32_to_cpu(header->ih_magic) == IH_MAGIC) {
  81. image_size = __be32_to_cpu(header->ih_size) + header_size;
  82. image_entry_point = __be32_to_cpu(header->ih_load);
  83. /* Load including the header */
  84. image_load_addr = image_entry_point - header_size;
  85. image_os = header->ih_os;
  86. image_name = (const char *)&header->ih_name;
  87. debug("spl: payload image: %s load addr: 0x%x size: %d\n",
  88. image_name, image_load_addr, image_size);
  89. } else {
  90. /* Signature not found - assume u-boot.bin */
  91. printf("mkimage signature not found - ih_magic = %x\n",
  92. header->ih_magic);
  93. puts("Assuming u-boot.bin ..\n");
  94. /* Let's assume U-Boot will not be more than 200 KB */
  95. image_size = 200 * 1024;
  96. image_entry_point = CONFIG_SYS_TEXT_BASE;
  97. image_load_addr = CONFIG_SYS_TEXT_BASE;
  98. image_os = IH_OS_U_BOOT;
  99. image_name = "U-Boot";
  100. }
  101. }
  102. static void mmc_load_image_raw(struct mmc *mmc)
  103. {
  104. u32 image_size_sectors, err;
  105. const struct image_header *header;
  106. header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
  107. sizeof(struct image_header));
  108. /* read image header to find the image size & load address */
  109. err = mmc->block_dev.block_read(0,
  110. CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1,
  111. (void *)header);
  112. if (err <= 0)
  113. goto end;
  114. parse_image_header(header);
  115. /* convert size to sectors - round up */
  116. image_size_sectors = (image_size + MMCSD_SECTOR_SIZE - 1) /
  117. MMCSD_SECTOR_SIZE;
  118. /* Read the header too to avoid extra memcpy */
  119. err = mmc->block_dev.block_read(0,
  120. CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR,
  121. image_size_sectors, (void *)image_load_addr);
  122. end:
  123. if (err <= 0) {
  124. printf("spl: mmc blk read err - %d\n", err);
  125. hang();
  126. }
  127. }
  128. static void mmc_load_image_fat(struct mmc *mmc)
  129. {
  130. s32 err;
  131. struct image_header *header;
  132. header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
  133. sizeof(struct image_header));
  134. err = fat_register_device(&mmc->block_dev,
  135. CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION);
  136. if (err) {
  137. printf("spl: fat register err - %d\n", err);
  138. hang();
  139. }
  140. err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
  141. (u8 *)header, sizeof(struct image_header));
  142. if (err <= 0)
  143. goto end;
  144. parse_image_header(header);
  145. err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
  146. (u8 *)image_load_addr, 0);
  147. end:
  148. if (err <= 0) {
  149. printf("spl: error reading image %s, err - %d\n",
  150. CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, err);
  151. hang();
  152. }
  153. }
  154. static void mmc_load_image(void)
  155. {
  156. struct mmc *mmc;
  157. int err;
  158. u32 boot_mode;
  159. mmc_initialize(gd->bd);
  160. /* We register only one device. So, the dev id is always 0 */
  161. mmc = find_mmc_device(0);
  162. if (!mmc) {
  163. puts("spl: mmc device not found!!\n");
  164. hang();
  165. }
  166. err = mmc_init(mmc);
  167. if (err) {
  168. printf("spl: mmc init failed: err - %d\n", err);
  169. hang();
  170. }
  171. boot_mode = omap_boot_mode();
  172. if (boot_mode == MMCSD_MODE_RAW) {
  173. debug("boot mode - RAW\n");
  174. mmc_load_image_raw(mmc);
  175. } else if (boot_mode == MMCSD_MODE_FAT) {
  176. debug("boot mode - FAT\n");
  177. mmc_load_image_fat(mmc);
  178. } else {
  179. puts("spl: wrong MMC boot mode\n");
  180. hang();
  181. }
  182. }
  183. void jump_to_image_no_args(void)
  184. {
  185. typedef void (*image_entry_noargs_t)(void)__attribute__ ((noreturn));
  186. image_entry_noargs_t image_entry =
  187. (image_entry_noargs_t) image_entry_point;
  188. image_entry();
  189. }
  190. void jump_to_image_no_args(void) __attribute__ ((noreturn));
  191. void board_init_r(gd_t *id, ulong dummy)
  192. {
  193. u32 boot_device;
  194. debug(">>spl:board_init_r()\n");
  195. timer_init();
  196. i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
  197. boot_device = omap_boot_device();
  198. debug("boot device - %d\n", boot_device);
  199. switch (boot_device) {
  200. case BOOT_DEVICE_MMC1:
  201. case BOOT_DEVICE_MMC2:
  202. mmc_load_image();
  203. break;
  204. default:
  205. printf("SPL: Un-supported Boot Device - %d!!!\n", boot_device);
  206. hang();
  207. break;
  208. }
  209. switch (image_os) {
  210. case IH_OS_U_BOOT:
  211. debug("Jumping to U-Boot\n");
  212. jump_to_image_no_args();
  213. break;
  214. default:
  215. puts("Unsupported OS image.. Jumping nevertheless..\n");
  216. jump_to_image_no_args();
  217. }
  218. }
  219. void preloader_console_init(void)
  220. {
  221. const char *u_boot_rev = U_BOOT_VERSION;
  222. char rev_string_buffer[50];
  223. gd = &gdata;
  224. gd->bd = &bdata;
  225. gd->flags |= GD_FLG_RELOC;
  226. gd->baudrate = CONFIG_BAUDRATE;
  227. setup_clocks_for_console();
  228. serial_init(); /* serial communications setup */
  229. /* Avoid a second "U-Boot" coming from this string */
  230. u_boot_rev = &u_boot_rev[7];
  231. printf("\nU-Boot SPL %s (%s - %s)\n", u_boot_rev, U_BOOT_DATE,
  232. U_BOOT_TIME);
  233. omap_rev_string(rev_string_buffer);
  234. printf("Texas Instruments %s\n", rev_string_buffer);
  235. }