1b9944a77SDirk Eibach /*
2b9944a77SDirk Eibach * Copyright 2011 Freescale Semiconductor, Inc.
3b9944a77SDirk Eibach *
4b9944a77SDirk Eibach * See file CREDITS for list of people who contributed to this
5b9944a77SDirk Eibach * project.
6b9944a77SDirk Eibach *
7b9944a77SDirk Eibach * This program is free software; you can redistribute it and/or
8b9944a77SDirk Eibach * modify it under the terms of the GNU General Public License as
9b9944a77SDirk Eibach * published by the Free Software Foundation; either version 2 of
10b9944a77SDirk Eibach * the License, or (at your option) any later version.
11b9944a77SDirk Eibach *
12b9944a77SDirk Eibach * This program is distributed in the hope that it will be useful,
13b9944a77SDirk Eibach * but WITHOUT ANY WARRANTY; without even the implied warranty of
14b9944a77SDirk Eibach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15b9944a77SDirk Eibach * GNU General Public License for more details.
16b9944a77SDirk Eibach *
17b9944a77SDirk Eibach * You should have received a copy of the GNU General Public License
18b9944a77SDirk Eibach * along with this program; if not, write to the Free Software
19b9944a77SDirk Eibach * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20b9944a77SDirk Eibach * MA 02111-1307 USA
21b9944a77SDirk Eibach */
22b9944a77SDirk Eibach
23b9944a77SDirk Eibach #include <common.h>
24b9944a77SDirk Eibach #include <mmc.h>
25b9944a77SDirk Eibach #include <malloc.h>
26b9944a77SDirk Eibach
27b9944a77SDirk Eibach /*
28b9944a77SDirk Eibach * The environment variables are written to just after the u-boot image
29b9944a77SDirk Eibach * on SDCard, so we must read the MBR to get the start address and code
30b9944a77SDirk Eibach * length of the u-boot image, then calculate the address of the env.
31b9944a77SDirk Eibach */
32b9944a77SDirk Eibach #define ESDHC_BOOT_IMAGE_SIZE 0x48
33b9944a77SDirk Eibach #define ESDHC_BOOT_IMAGE_ADDR 0x50
34b9944a77SDirk Eibach
mmc_get_env_addr(struct mmc * mmc,int copy,u32 * env_addr)35e9e37421SDirk Eibach int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)
36b9944a77SDirk Eibach {
37b9944a77SDirk Eibach u8 *tmp_buf;
38b9944a77SDirk Eibach u32 blklen, code_offset, code_len, n;
39b9944a77SDirk Eibach
40b9944a77SDirk Eibach blklen = mmc->read_bl_len;
41b9944a77SDirk Eibach tmp_buf = malloc(blklen);
42b9944a77SDirk Eibach if (!tmp_buf)
43b9944a77SDirk Eibach return 1;
44b9944a77SDirk Eibach
45b9944a77SDirk Eibach /* read out the first block, get the config data information */
46*7c4213f6SStephen Warren n = mmc->block_dev.block_read(&mmc->block_dev, 0, 1, tmp_buf);
47b9944a77SDirk Eibach if (!n) {
48b9944a77SDirk Eibach free(tmp_buf);
49b9944a77SDirk Eibach return 1;
50b9944a77SDirk Eibach }
51b9944a77SDirk Eibach
52b9944a77SDirk Eibach /* Get the Source Address, from offset 0x50 */
53b9944a77SDirk Eibach code_offset = *(u32 *)(tmp_buf + ESDHC_BOOT_IMAGE_ADDR);
54b9944a77SDirk Eibach
55b9944a77SDirk Eibach /* Get the code size from offset 0x48 */
56b9944a77SDirk Eibach code_len = *(u32 *)(tmp_buf + ESDHC_BOOT_IMAGE_SIZE);
57b9944a77SDirk Eibach
58b9944a77SDirk Eibach *env_addr = code_offset + code_len;
59b9944a77SDirk Eibach
60b9944a77SDirk Eibach free(tmp_buf);
61b9944a77SDirk Eibach
62b9944a77SDirk Eibach return 0;
63b9944a77SDirk Eibach }
64