1 /* 2 * Copyright 2013 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 #define MBRDBR_BOOT_SIG_55 0x1fe 19 #define MBRDBR_BOOT_SIG_AA 0x1ff 20 #define CONFIG_CFG_DATA_SECTOR 0 21 22 23 void mmc_spl_load_image(uint32_t offs, unsigned int size, void *vdst) 24 { 25 uint blk_start, blk_cnt, err; 26 27 struct mmc *mmc = find_mmc_device(0); 28 if (!mmc) { 29 puts("spl: mmc device not found!!\n"); 30 hang(); 31 } 32 33 if (mmc_init(mmc)) { 34 puts("MMC init failed\n"); 35 return; 36 } 37 38 blk_start = ALIGN(offs, mmc->read_bl_len) / mmc->read_bl_len; 39 blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len; 40 41 err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt, 42 vdst); 43 if (err != blk_cnt) { 44 puts("spl: mmc read failed!!\n"); 45 hang(); 46 } 47 } 48 49 /* 50 * The main entry for mmc booting. It's necessary that SDRAM is already 51 * configured and available since this code loads the main U-Boot image 52 * from mmc into SDRAM and starts it from there. 53 */ 54 55 void __noreturn mmc_boot(void) 56 { 57 __attribute__((noreturn)) void (*uboot)(void); 58 uint blk_start, blk_cnt, err; 59 #ifndef CONFIG_FSL_CORENET 60 uchar *tmp_buf; 61 u32 blklen; 62 uchar val; 63 uint i, byte_num; 64 #endif 65 u32 offset, code_len; 66 struct mmc *mmc; 67 68 mmc = find_mmc_device(0); 69 if (!mmc) { 70 puts("spl: mmc device not found!!\n"); 71 hang(); 72 } 73 74 #ifdef CONFIG_FSL_CORENET 75 offset = CONFIG_SYS_MMC_U_BOOT_OFFS; 76 code_len = CONFIG_SYS_MMC_U_BOOT_SIZE; 77 #else 78 blklen = mmc->read_bl_len; 79 tmp_buf = malloc(blklen); 80 if (!tmp_buf) { 81 puts("spl: malloc memory failed!!\n"); 82 hang(); 83 } 84 memset(tmp_buf, 0, blklen); 85 86 /* 87 * Read source addr from sd card 88 */ 89 err = mmc->block_dev.block_read(&mmc->block_dev, 90 CONFIG_CFG_DATA_SECTOR, 1, tmp_buf); 91 if (err != 1) { 92 puts("spl: mmc read failed!!\n"); 93 free(tmp_buf); 94 hang(); 95 } 96 97 val = *(tmp_buf + MBRDBR_BOOT_SIG_55); 98 if (0x55 != val) { 99 puts("spl: mmc signature is not valid!!\n"); 100 free(tmp_buf); 101 hang(); 102 } 103 val = *(tmp_buf + MBRDBR_BOOT_SIG_AA); 104 if (0xAA != val) { 105 puts("spl: mmc signature is not valid!!\n"); 106 free(tmp_buf); 107 hang(); 108 } 109 110 byte_num = 4; 111 offset = 0; 112 for (i = 0; i < byte_num; i++) { 113 val = *(tmp_buf + ESDHC_BOOT_IMAGE_ADDR + i); 114 offset = (offset << 8) + val; 115 } 116 offset += CONFIG_SYS_MMC_U_BOOT_OFFS; 117 /* Get the code size from offset 0x48 */ 118 byte_num = 4; 119 code_len = 0; 120 for (i = 0; i < byte_num; i++) { 121 val = *(tmp_buf + ESDHC_BOOT_IMAGE_SIZE + i); 122 code_len = (code_len << 8) + val; 123 } 124 code_len -= CONFIG_SYS_MMC_U_BOOT_OFFS; 125 /* 126 * Load U-Boot image from mmc into RAM 127 */ 128 #endif 129 blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len; 130 blk_cnt = ALIGN(code_len, mmc->read_bl_len) / mmc->read_bl_len; 131 err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt, 132 (uchar *)CONFIG_SYS_MMC_U_BOOT_DST); 133 if (err != blk_cnt) { 134 puts("spl: mmc read failed!!\n"); 135 #ifndef CONFIG_FSL_CORENET 136 free(tmp_buf); 137 #endif 138 hang(); 139 } 140 141 /* 142 * Clean d-cache and invalidate i-cache, to 143 * make sure that no stale data is executed. 144 */ 145 flush_cache(CONFIG_SYS_MMC_U_BOOT_DST, CONFIG_SYS_MMC_U_BOOT_SIZE); 146 147 /* 148 * Jump to U-Boot image 149 */ 150 uboot = (void *)CONFIG_SYS_MMC_U_BOOT_START; 151 (*uboot)(); 152 } 153