sdhc_boot.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /*
  2. * Copyright 2011 Freescale Semiconductor, Inc.
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <mmc.h>
  8. #include <malloc.h>
  9. /*
  10. * The environment variables are written to just after the u-boot image
  11. * on SDCard, so we must read the MBR to get the start address and code
  12. * length of the u-boot image, then calculate the address of the env.
  13. */
  14. #define ESDHC_BOOT_IMAGE_SIZE 0x48
  15. #define ESDHC_BOOT_IMAGE_ADDR 0x50
  16. #define ESDHC_DEFAULT_ENVADDR 0x400
  17. int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)
  18. {
  19. u8 *tmp_buf;
  20. u32 blklen, code_offset, code_len, n;
  21. blklen = mmc->read_bl_len;
  22. tmp_buf = malloc(blklen);
  23. if (!tmp_buf)
  24. return 1;
  25. /* read out the first block, get the config data information */
  26. n = mmc->block_dev.block_read(&mmc->block_dev, 0, 1, tmp_buf);
  27. if (!n) {
  28. free(tmp_buf);
  29. return 1;
  30. }
  31. /* Get the Source Address, from offset 0x50 */
  32. code_offset = *(u32 *)(tmp_buf + ESDHC_BOOT_IMAGE_ADDR);
  33. /* Get the code size from offset 0x48 */
  34. code_len = *(u32 *)(tmp_buf + ESDHC_BOOT_IMAGE_SIZE);
  35. #ifdef CONFIG_ESDHC_HC_BLK_ADDR
  36. /*
  37. * On soc BSC9131, BSC9132:
  38. * In High Capacity SD Cards (> 2 GBytes), the 32-bit source address and
  39. * code length of these soc specify the memory address in block address
  40. * format. Block length is fixed to 512 bytes as per the SD High
  41. * Capacity specification.
  42. */
  43. u64 tmp;
  44. if (mmc->high_capacity) {
  45. tmp = (u64)code_offset * blklen;
  46. tmp += code_len * blklen;
  47. } else
  48. tmp = code_offset + code_len;
  49. if ((tmp + CONFIG_ENV_SIZE > mmc->capacity) ||
  50. (tmp > 0xFFFFFFFFU))
  51. *env_addr = ESDHC_DEFAULT_ENVADDR;
  52. else
  53. *env_addr = tmp;
  54. free(tmp_buf);
  55. return 0;
  56. #endif
  57. *env_addr = code_offset + code_len;
  58. free(tmp_buf);
  59. return 0;
  60. }