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