]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
1ac63e40 JH |
2 | /* |
3 | * Copyright 2011 Freescale Semiconductor, Inc. | |
1ac63e40 JH |
4 | */ |
5 | ||
d678a59d | 6 | #include <common.h> |
1ac63e40 JH |
7 | #include <mmc.h> |
8 | #include <malloc.h> | |
9 | ||
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 | ||
f28bea00 HZ |
18 | #define ESDHC_DEFAULT_ENVADDR 0x400 |
19 | ||
d196bd88 | 20 | int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr) |
1ac63e40 JH |
21 | { |
22 | u8 *tmp_buf; | |
23 | u32 blklen, code_offset, code_len, n; | |
24 | ||
25 | blklen = mmc->read_bl_len; | |
26 | tmp_buf = malloc(blklen); | |
27 | if (!tmp_buf) | |
28 | return 1; | |
29 | ||
30 | /* read out the first block, get the config data information */ | |
7e20c1f4 YZ |
31 | #ifdef CONFIG_BLK |
32 | n = blk_dread(mmc_get_blk_desc(mmc), 0, 1, tmp_buf); | |
33 | #else | |
7c4213f6 | 34 | n = mmc->block_dev.block_read(&mmc->block_dev, 0, 1, tmp_buf); |
7e20c1f4 | 35 | #endif |
1ac63e40 JH |
36 | if (!n) { |
37 | free(tmp_buf); | |
38 | return 1; | |
39 | } | |
40 | ||
41 | /* Get the Source Address, from offset 0x50 */ | |
42 | code_offset = *(u32 *)(tmp_buf + ESDHC_BOOT_IMAGE_ADDR); | |
43 | ||
44 | /* Get the code size from offset 0x48 */ | |
45 | code_len = *(u32 *)(tmp_buf + ESDHC_BOOT_IMAGE_SIZE); | |
46 | ||
f28bea00 HZ |
47 | #ifdef CONFIG_ESDHC_HC_BLK_ADDR |
48 | /* | |
49 | * On soc BSC9131, BSC9132: | |
50 | * In High Capacity SD Cards (> 2 GBytes), the 32-bit source address and | |
51 | * code length of these soc specify the memory address in block address | |
52 | * format. Block length is fixed to 512 bytes as per the SD High | |
53 | * Capacity specification. | |
54 | */ | |
55 | u64 tmp; | |
56 | ||
57 | if (mmc->high_capacity) { | |
58 | tmp = (u64)code_offset * blklen; | |
59 | tmp += code_len * blklen; | |
60 | } else | |
61 | tmp = code_offset + code_len; | |
62 | ||
63 | if ((tmp + CONFIG_ENV_SIZE > mmc->capacity) || | |
64 | (tmp > 0xFFFFFFFFU)) | |
65 | *env_addr = ESDHC_DEFAULT_ENVADDR; | |
66 | else | |
67 | *env_addr = tmp; | |
68 | ||
69 | free(tmp_buf); | |
70 | ||
71 | return 0; | |
72 | #endif | |
73 | ||
1ac63e40 JH |
74 | *env_addr = code_offset + code_len; |
75 | ||
76 | free(tmp_buf); | |
77 | ||
78 | return 0; | |
79 | } |