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