1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2013 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 #define MBRDBR_BOOT_SIG_55 0x1fe 18 #define MBRDBR_BOOT_SIG_AA 0x1ff 19 #define CONFIG_CFG_DATA_SECTOR 0 20 21 22 void mmc_spl_load_image(uint32_t offs, unsigned int size, void *vdst) 23 { 24 uint blk_start, blk_cnt, err; 25 26 struct mmc *mmc = find_mmc_device(0); 27 if (!mmc) { 28 puts("spl: mmc device not found!!\n"); 29 hang(); 30 } 31 32 if (mmc_init(mmc)) { 33 puts("MMC init failed\n"); 34 return; 35 } 36 37 blk_start = ALIGN(offs, mmc->read_bl_len) / mmc->read_bl_len; 38 blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len; 39 40 err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt, 41 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(&mmc->block_dev, 89 CONFIG_CFG_DATA_SECTOR, 1, tmp_buf); 90 if (err != 1) { 91 puts("spl: mmc read failed!!\n"); 92 free(tmp_buf); 93 hang(); 94 } 95 96 val = *(tmp_buf + MBRDBR_BOOT_SIG_55); 97 if (0x55 != val) { 98 puts("spl: mmc signature is not valid!!\n"); 99 free(tmp_buf); 100 hang(); 101 } 102 val = *(tmp_buf + MBRDBR_BOOT_SIG_AA); 103 if (0xAA != val) { 104 puts("spl: mmc signature is not valid!!\n"); 105 free(tmp_buf); 106 hang(); 107 } 108 109 byte_num = 4; 110 offset = 0; 111 for (i = 0; i < byte_num; i++) { 112 val = *(tmp_buf + ESDHC_BOOT_IMAGE_ADDR + i); 113 offset = (offset << 8) + val; 114 } 115 offset += CONFIG_SYS_MMC_U_BOOT_OFFS; 116 /* Get the code size from offset 0x48 */ 117 byte_num = 4; 118 code_len = 0; 119 for (i = 0; i < byte_num; i++) { 120 val = *(tmp_buf + ESDHC_BOOT_IMAGE_SIZE + i); 121 code_len = (code_len << 8) + val; 122 } 123 code_len -= CONFIG_SYS_MMC_U_BOOT_OFFS; 124 /* 125 * Load U-Boot image from mmc into RAM 126 */ 127 #endif 128 blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len; 129 blk_cnt = ALIGN(code_len, mmc->read_bl_len) / mmc->read_bl_len; 130 err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt, 131 (uchar *)CONFIG_SYS_MMC_U_BOOT_DST); 132 if (err != blk_cnt) { 133 puts("spl: mmc read failed!!\n"); 134 #ifndef CONFIG_FSL_CORENET 135 free(tmp_buf); 136 #endif 137 hang(); 138 } 139 140 /* 141 * Clean d-cache and invalidate i-cache, to 142 * make sure that no stale data is executed. 143 */ 144 flush_cache(CONFIG_SYS_MMC_U_BOOT_DST, CONFIG_SYS_MMC_U_BOOT_SIZE); 145 146 /* 147 * Jump to U-Boot image 148 */ 149 uboot = (void *)CONFIG_SYS_MMC_U_BOOT_START; 150 (*uboot)(); 151 } 152