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