fsl_esdhc_spl.c 3.5 KB

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