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 if (err == 0) 48 printf("spl: mmc blk read err - %lu\n", err); 49 50 return (err == 0); 51 } 52 53 #ifdef CONFIG_SPL_OS_BOOT 54 static int mmc_load_image_raw_os(struct mmc *mmc) 55 { 56 if (!mmc->block_dev.block_read(0, 57 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, 58 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS, 59 (void *)CONFIG_SYS_SPL_ARGS_ADDR)) { 60 printf("mmc args blk read error\n"); 61 return -1; 62 } 63 64 return mmc_load_image_raw(mmc, CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR); 65 } 66 #endif 67 68 #ifdef CONFIG_SPL_FAT_SUPPORT 69 static int mmc_load_image_fat(struct mmc *mmc, const char *filename) 70 { 71 int err; 72 struct image_header *header; 73 74 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 75 sizeof(struct image_header)); 76 77 err = file_fat_read(filename, header, sizeof(struct image_header)); 78 if (err <= 0) 79 goto end; 80 81 spl_parse_image_header(header); 82 83 err = file_fat_read(filename, (u8 *)spl_image.load_addr, 0); 84 85 end: 86 if (err <= 0) 87 printf("spl: error reading image %s, err - %d\n", 88 filename, err); 89 90 return (err <= 0); 91 } 92 93 #ifdef CONFIG_SPL_OS_BOOT 94 static int mmc_load_image_fat_os(struct mmc *mmc) 95 { 96 int err; 97 98 err = file_fat_read(CONFIG_SPL_FAT_LOAD_ARGS_NAME, 99 (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0); 100 if (err <= 0) { 101 printf("spl: error reading image %s, err - %d\n", 102 CONFIG_SPL_FAT_LOAD_ARGS_NAME, err); 103 return -1; 104 } 105 106 return mmc_load_image_fat(mmc, CONFIG_SPL_FAT_LOAD_KERNEL_NAME); 107 } 108 #endif 109 110 #endif 111 112 void spl_mmc_load_image(void) 113 { 114 struct mmc *mmc; 115 int err; 116 u32 boot_mode; 117 118 mmc_initialize(gd->bd); 119 /* We register only one device. So, the dev id is always 0 */ 120 mmc = find_mmc_device(0); 121 if (!mmc) { 122 puts("spl: mmc device not found!!\n"); 123 hang(); 124 } 125 126 err = mmc_init(mmc); 127 if (err) { 128 printf("spl: mmc init failed: err - %d\n", err); 129 hang(); 130 } 131 132 boot_mode = spl_boot_mode(); 133 if (boot_mode == MMCSD_MODE_RAW) { 134 debug("boot mode - RAW\n"); 135 #ifdef CONFIG_SPL_OS_BOOT 136 if (spl_start_uboot() || mmc_load_image_raw_os(mmc)) 137 #endif 138 err = mmc_load_image_raw(mmc, 139 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 140 #ifdef CONFIG_SPL_FAT_SUPPORT 141 } else if (boot_mode == MMCSD_MODE_FAT) { 142 debug("boot mode - FAT\n"); 143 144 err = fat_register_device(&mmc->block_dev, 145 CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION); 146 if (err) { 147 printf("spl: fat register err - %d\n", err); 148 hang(); 149 } 150 151 #ifdef CONFIG_SPL_OS_BOOT 152 if (spl_start_uboot() || mmc_load_image_fat_os(mmc)) 153 #endif 154 err = mmc_load_image_fat(mmc, CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME); 155 #endif 156 } else { 157 puts("spl: wrong MMC boot mode\n"); 158 hang(); 159 } 160 161 if (err) 162 hang(); 163 } 164