1 /* 2 * (C) Copyright 2010 3 * Texas Instruments, <www.ti.com> 4 * 5 * Aneesh V <aneesh@ti.com> 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 #include <common.h> 10 #include <spl.h> 11 #include <asm/u-boot.h> 12 #include <mmc.h> 13 #include <fat.h> 14 #include <version.h> 15 #include <image.h> 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 static int mmc_load_image_raw(struct mmc *mmc, unsigned long sector) 20 { 21 unsigned long err; 22 u32 image_size_sectors; 23 struct image_header *header; 24 25 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 26 sizeof(struct image_header)); 27 28 /* read image header to find the image size & load address */ 29 err = mmc->block_dev.block_read(0, sector, 1, header); 30 if (err == 0) 31 goto end; 32 33 if (image_get_magic(header) != IH_MAGIC) 34 return -1; 35 36 spl_parse_image_header(header); 37 38 /* convert size to sectors - round up */ 39 image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / 40 mmc->read_bl_len; 41 42 /* Read the header too to avoid extra memcpy */ 43 err = mmc->block_dev.block_read(0, sector, image_size_sectors, 44 (void *)spl_image.load_addr); 45 46 end: 47 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 48 if (err == 0) 49 printf("spl: mmc blk read err - %lu\n", err); 50 #endif 51 52 return (err == 0); 53 } 54 55 #ifdef CONFIG_SPL_OS_BOOT 56 static int mmc_load_image_raw_os(struct mmc *mmc) 57 { 58 if (!mmc->block_dev.block_read(0, 59 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, 60 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS, 61 (void *)CONFIG_SYS_SPL_ARGS_ADDR)) { 62 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 63 printf("mmc args blk read error\n"); 64 #endif 65 return -1; 66 } 67 68 return mmc_load_image_raw(mmc, CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR); 69 } 70 #endif 71 72 #ifdef CONFIG_SPL_FAT_SUPPORT 73 static int mmc_load_image_fat(struct mmc *mmc, const char *filename) 74 { 75 int err; 76 struct image_header *header; 77 78 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 79 sizeof(struct image_header)); 80 81 err = file_fat_read(filename, header, sizeof(struct image_header)); 82 if (err <= 0) 83 goto end; 84 85 spl_parse_image_header(header); 86 87 err = file_fat_read(filename, (u8 *)spl_image.load_addr, 0); 88 89 end: 90 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 91 if (err <= 0) 92 printf("spl: error reading image %s, err - %d\n", 93 filename, err); 94 #endif 95 96 return (err <= 0); 97 } 98 99 #ifdef CONFIG_SPL_OS_BOOT 100 static int mmc_load_image_fat_os(struct mmc *mmc) 101 { 102 int err; 103 104 err = file_fat_read(CONFIG_SPL_FAT_LOAD_ARGS_NAME, 105 (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0); 106 if (err <= 0) { 107 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 108 printf("spl: error reading image %s, err - %d\n", 109 CONFIG_SPL_FAT_LOAD_ARGS_NAME, err); 110 #endif 111 return -1; 112 } 113 114 return mmc_load_image_fat(mmc, CONFIG_SPL_FAT_LOAD_KERNEL_NAME); 115 } 116 #endif 117 118 #endif 119 120 void spl_mmc_load_image(void) 121 { 122 struct mmc *mmc; 123 int err; 124 u32 boot_mode; 125 126 mmc_initialize(gd->bd); 127 /* We register only one device. So, the dev id is always 0 */ 128 mmc = find_mmc_device(0); 129 if (!mmc) { 130 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 131 puts("spl: mmc device not found!!\n"); 132 #endif 133 hang(); 134 } 135 136 err = mmc_init(mmc); 137 if (err) { 138 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 139 printf("spl: mmc init failed: err - %d\n", err); 140 #endif 141 hang(); 142 } 143 144 boot_mode = spl_boot_mode(); 145 if (boot_mode == MMCSD_MODE_RAW) { 146 debug("boot mode - RAW\n"); 147 #ifdef CONFIG_SPL_OS_BOOT 148 if (spl_start_uboot() || mmc_load_image_raw_os(mmc)) 149 #endif 150 err = mmc_load_image_raw(mmc, 151 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 152 #ifdef CONFIG_SPL_FAT_SUPPORT 153 } else if (boot_mode == MMCSD_MODE_FAT) { 154 debug("boot mode - FAT\n"); 155 156 err = fat_register_device(&mmc->block_dev, 157 CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION); 158 if (err) { 159 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 160 printf("spl: fat register err - %d\n", err); 161 #endif 162 hang(); 163 } 164 165 #ifdef CONFIG_SPL_OS_BOOT 166 if (spl_start_uboot() || mmc_load_image_fat_os(mmc)) 167 #endif 168 err = mmc_load_image_fat(mmc, CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME); 169 #endif 170 } else { 171 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 172 puts("spl: wrong MMC boot mode\n"); 173 #endif 174 hang(); 175 } 176 177 if (err) 178 hang(); 179 } 180