fsl_esdhc_spl.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2013 Freescale Semiconductor, Inc.
  4. */
  5. #include <common.h>
  6. #include <cpu_func.h>
  7. #include <hang.h>
  8. #include <mmc.h>
  9. #include <malloc.h>
  10. #ifndef CFG_SYS_MMC_U_BOOT_OFFS
  11. extern uchar mmc_u_boot_offs[];
  12. #endif
  13. /*
  14. * The environment variables are written to just after the u-boot image
  15. * on SDCard, so we must read the MBR to get the start address and code
  16. * length of the u-boot image, then calculate the address of the env.
  17. */
  18. #define ESDHC_BOOT_SIGNATURE_OFF 0x40
  19. #define ESDHC_BOOT_SIGNATURE 0x424f4f54
  20. #define ESDHC_BOOT_IMAGE_SIZE 0x48
  21. #define ESDHC_BOOT_IMAGE_ADDR 0x50
  22. #define MBRDBR_BOOT_SIG_55 0x1fe
  23. #define MBRDBR_BOOT_SIG_AA 0x1ff
  24. void mmc_spl_load_image(uint32_t offs, unsigned int size, void *vdst)
  25. {
  26. uint blk_start, blk_cnt, err;
  27. struct mmc *mmc = find_mmc_device(0);
  28. if (!mmc) {
  29. puts("spl: mmc device not found!!\n");
  30. hang();
  31. }
  32. if (mmc_init(mmc)) {
  33. puts("MMC init failed\n");
  34. return;
  35. }
  36. blk_start = ALIGN(offs, mmc->read_bl_len) / mmc->read_bl_len;
  37. blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len;
  38. err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt,
  39. vdst);
  40. if (err != blk_cnt) {
  41. puts("spl: mmc read failed!!\n");
  42. hang();
  43. }
  44. }
  45. /*
  46. * The main entry for mmc booting. It's necessary that SDRAM is already
  47. * configured and available since this code loads the main U-Boot image
  48. * from mmc into SDRAM and starts it from there.
  49. */
  50. void __noreturn mmc_boot(void)
  51. {
  52. __attribute__((noreturn)) void (*uboot)(void);
  53. uint blk_start, blk_cnt, err;
  54. uchar *tmp_buf;
  55. u32 blklen;
  56. u32 blk_off;
  57. #ifndef CONFIG_FSL_CORENET
  58. uchar val;
  59. #ifndef CONFIG_SPL_FSL_PBL
  60. u32 val32;
  61. #endif
  62. uint i, byte_num;
  63. u32 sector;
  64. #endif
  65. u32 offset, code_len;
  66. struct mmc *mmc;
  67. mmc = find_mmc_device(0);
  68. if (!mmc) {
  69. puts("spl: mmc device not found!!\n");
  70. hang();
  71. }
  72. if (mmc_init(mmc)) {
  73. puts("spl: mmc device init failed!\n");
  74. hang();
  75. }
  76. blklen = mmc->read_bl_len;
  77. if (blklen < 512)
  78. blklen = 512;
  79. tmp_buf = malloc(blklen);
  80. if (!tmp_buf) {
  81. puts("spl: malloc memory failed!!\n");
  82. hang();
  83. }
  84. #ifdef CONFIG_FSL_CORENET
  85. offset = CFG_SYS_MMC_U_BOOT_OFFS;
  86. #else
  87. sector = 0;
  88. again:
  89. memset(tmp_buf, 0, blklen);
  90. /*
  91. * Read source addr from sd card
  92. */
  93. blk_start = (sector * 512) / mmc->read_bl_len;
  94. blk_off = (sector * 512) % mmc->read_bl_len;
  95. blk_cnt = DIV_ROUND_UP(512, mmc->read_bl_len);
  96. err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt, tmp_buf);
  97. if (err != blk_cnt) {
  98. puts("spl: mmc read failed!!\n");
  99. hang();
  100. }
  101. #ifdef CONFIG_SPL_FSL_PBL
  102. val = *(tmp_buf + blk_off + MBRDBR_BOOT_SIG_55);
  103. if (0x55 != val) {
  104. puts("spl: mmc MBR/DBR signature is not valid!!\n");
  105. hang();
  106. }
  107. val = *(tmp_buf + blk_off + MBRDBR_BOOT_SIG_AA);
  108. if (0xAA != val) {
  109. puts("spl: mmc MBR/DBR signature is not valid!!\n");
  110. hang();
  111. }
  112. #else
  113. /*
  114. * Booting from On-Chip ROM (eSDHC or eSPI), Document Number: AN3659, Rev. 2, 06/2012.
  115. * Pre-PBL BootROMs (MPC8536E, MPC8569E, P2020, P1011, P1012, P1013, P1020, P1021, P1022)
  116. * require custom BOOT signature on sector 0 and MBR/DBR signature is not required at all.
  117. */
  118. byte_num = 4;
  119. val32 = 0;
  120. for (i = 0; i < byte_num; i++) {
  121. val = *(tmp_buf + blk_off + ESDHC_BOOT_SIGNATURE_OFF + i);
  122. val32 = (val32 << 8) + val;
  123. }
  124. if (val32 != ESDHC_BOOT_SIGNATURE) {
  125. /* BOOT signature may be on the first 24 sectors (each being 512 bytes) */
  126. if (++sector < 24)
  127. goto again;
  128. puts("spl: mmc BOOT signature is not valid!!\n");
  129. hang();
  130. }
  131. #endif
  132. byte_num = 4;
  133. offset = 0;
  134. for (i = 0; i < byte_num; i++) {
  135. val = *(tmp_buf + blk_off + ESDHC_BOOT_IMAGE_ADDR + i);
  136. offset = (offset << 8) + val;
  137. }
  138. #ifndef CFG_SYS_MMC_U_BOOT_OFFS
  139. offset += (ulong)&mmc_u_boot_offs - CONFIG_SPL_TEXT_BASE;
  140. #else
  141. offset += CFG_SYS_MMC_U_BOOT_OFFS;
  142. #endif
  143. #endif
  144. /*
  145. * Load U-Boot image from mmc into RAM
  146. */
  147. code_len = CFG_SYS_MMC_U_BOOT_SIZE;
  148. blk_start = offset / mmc->read_bl_len;
  149. blk_off = offset % mmc->read_bl_len;
  150. blk_cnt = ALIGN(code_len, mmc->read_bl_len) / mmc->read_bl_len + 1;
  151. if (blk_off) {
  152. err = mmc->block_dev.block_read(&mmc->block_dev,
  153. blk_start, 1, tmp_buf);
  154. if (err != 1) {
  155. puts("spl: mmc read failed!!\n");
  156. hang();
  157. }
  158. blk_start++;
  159. }
  160. err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt,
  161. (uchar *)CFG_SYS_MMC_U_BOOT_DST +
  162. (blk_off ? (mmc->read_bl_len - blk_off) : 0));
  163. if (err != blk_cnt) {
  164. puts("spl: mmc read failed!!\n");
  165. free(tmp_buf);
  166. hang();
  167. }
  168. /*
  169. * SDHC DMA may erase bytes at dst + bl_len - blk_off - 8
  170. * due to unaligned access. So copy leading bytes from tmp_buf
  171. * after SDHC DMA transfer.
  172. */
  173. if (blk_off)
  174. memcpy((uchar *)CFG_SYS_MMC_U_BOOT_DST,
  175. tmp_buf + blk_off, mmc->read_bl_len - blk_off);
  176. /*
  177. * Clean d-cache and invalidate i-cache, to
  178. * make sure that no stale data is executed.
  179. */
  180. flush_cache(CFG_SYS_MMC_U_BOOT_DST, CFG_SYS_MMC_U_BOOT_SIZE);
  181. /*
  182. * Jump to U-Boot image
  183. */
  184. uboot = (void *)CFG_SYS_MMC_U_BOOT_START;
  185. (*uboot)();
  186. }