uboot/board/freescale/common/sdhc_boot.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2011 Freescale Semiconductor, Inc.
   4 */
   5
   6#include <common.h>
   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
  18#define ESDHC_DEFAULT_ENVADDR   0x400
  19
  20int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)
  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 */
  31#ifdef CONFIG_BLK
  32        n = blk_dread(mmc_get_blk_desc(mmc), 0, 1, tmp_buf);
  33#else
  34        n = mmc->block_dev.block_read(&mmc->block_dev, 0, 1, tmp_buf);
  35#endif
  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
  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
  74        *env_addr = code_offset + code_len;
  75
  76        free(tmp_buf);
  77
  78        return 0;
  79}
  80