fsl_esdhc_spl.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2013 Freescale Semiconductor, Inc.
  4. */
  5. #include <common.h>
  6. #include <mmc.h>
  7. #include <malloc.h>
  8. /*
  9. * The environment variables are written to just after the u-boot image
  10. * on SDCard, so we must read the MBR to get the start address and code
  11. * length of the u-boot image, then calculate the address of the env.
  12. */
  13. #define ESDHC_BOOT_IMAGE_SIZE 0x48
  14. #define ESDHC_BOOT_IMAGE_ADDR 0x50
  15. #define MBRDBR_BOOT_SIG_55 0x1fe
  16. #define MBRDBR_BOOT_SIG_AA 0x1ff
  17. #define CONFIG_CFG_DATA_SECTOR 0
  18. void mmc_spl_load_image(uint32_t offs, unsigned int size, void *vdst)
  19. {
  20. uint blk_start, blk_cnt, err;
  21. struct mmc *mmc = find_mmc_device(0);
  22. if (!mmc) {
  23. puts("spl: mmc device not found!!\n");
  24. hang();
  25. }
  26. if (mmc_init(mmc)) {
  27. puts("MMC init failed\n");
  28. return;
  29. }
  30. blk_start = ALIGN(offs, mmc->read_bl_len) / mmc->read_bl_len;
  31. blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len;
  32. err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt,
  33. vdst);
  34. if (err != blk_cnt) {
  35. puts("spl: mmc read failed!!\n");
  36. hang();
  37. }
  38. }
  39. /*
  40. * The main entry for mmc booting. It's necessary that SDRAM is already
  41. * configured and available since this code loads the main U-Boot image
  42. * from mmc into SDRAM and starts it from there.
  43. */
  44. void __noreturn mmc_boot(void)
  45. {
  46. __attribute__((noreturn)) void (*uboot)(void);
  47. uint blk_start, blk_cnt, err;
  48. #ifndef CONFIG_FSL_CORENET
  49. uchar *tmp_buf;
  50. u32 blklen;
  51. uchar val;
  52. uint i, byte_num;
  53. #endif
  54. u32 offset, code_len;
  55. struct mmc *mmc;
  56. mmc = find_mmc_device(0);
  57. if (!mmc) {
  58. puts("spl: mmc device not found!!\n");
  59. hang();
  60. }
  61. #ifdef CONFIG_FSL_CORENET
  62. offset = CONFIG_SYS_MMC_U_BOOT_OFFS;
  63. code_len = CONFIG_SYS_MMC_U_BOOT_SIZE;
  64. #else
  65. blklen = mmc->read_bl_len;
  66. tmp_buf = malloc(blklen);
  67. if (!tmp_buf) {
  68. puts("spl: malloc memory failed!!\n");
  69. hang();
  70. }
  71. memset(tmp_buf, 0, blklen);
  72. /*
  73. * Read source addr from sd card
  74. */
  75. err = mmc->block_dev.block_read(&mmc->block_dev,
  76. CONFIG_CFG_DATA_SECTOR, 1, tmp_buf);
  77. if (err != 1) {
  78. puts("spl: mmc read failed!!\n");
  79. free(tmp_buf);
  80. hang();
  81. }
  82. val = *(tmp_buf + MBRDBR_BOOT_SIG_55);
  83. if (0x55 != val) {
  84. puts("spl: mmc signature is not valid!!\n");
  85. free(tmp_buf);
  86. hang();
  87. }
  88. val = *(tmp_buf + MBRDBR_BOOT_SIG_AA);
  89. if (0xAA != val) {
  90. puts("spl: mmc signature is not valid!!\n");
  91. free(tmp_buf);
  92. hang();
  93. }
  94. byte_num = 4;
  95. offset = 0;
  96. for (i = 0; i < byte_num; i++) {
  97. val = *(tmp_buf + ESDHC_BOOT_IMAGE_ADDR + i);
  98. offset = (offset << 8) + val;
  99. }
  100. offset += CONFIG_SYS_MMC_U_BOOT_OFFS;
  101. /* Get the code size from offset 0x48 */
  102. byte_num = 4;
  103. code_len = 0;
  104. for (i = 0; i < byte_num; i++) {
  105. val = *(tmp_buf + ESDHC_BOOT_IMAGE_SIZE + i);
  106. code_len = (code_len << 8) + val;
  107. }
  108. code_len -= CONFIG_SYS_MMC_U_BOOT_OFFS;
  109. /*
  110. * Load U-Boot image from mmc into RAM
  111. */
  112. #endif
  113. blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;
  114. blk_cnt = ALIGN(code_len, mmc->read_bl_len) / mmc->read_bl_len;
  115. err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt,
  116. (uchar *)CONFIG_SYS_MMC_U_BOOT_DST);
  117. if (err != blk_cnt) {
  118. puts("spl: mmc read failed!!\n");
  119. #ifndef CONFIG_FSL_CORENET
  120. free(tmp_buf);
  121. #endif
  122. hang();
  123. }
  124. /*
  125. * Clean d-cache and invalidate i-cache, to
  126. * make sure that no stale data is executed.
  127. */
  128. flush_cache(CONFIG_SYS_MMC_U_BOOT_DST, CONFIG_SYS_MMC_U_BOOT_SIZE);
  129. /*
  130. * Jump to U-Boot image
  131. */
  132. uboot = (void *)CONFIG_SYS_MMC_U_BOOT_START;
  133. (*uboot)();
  134. }