1 /* 2 * (C) Copyright 2014 3 * Texas Instruments, <www.ti.com> 4 * 5 * Dan Murphy <dmurphy@ti.com> 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 * 9 * FAT Image Functions copied from spl_mmc.c 10 */ 11 12 #include <common.h> 13 #include <spl.h> 14 #include <asm/u-boot.h> 15 #include <fat.h> 16 #include <errno.h> 17 #include <image.h> 18 #include <linux/libfdt.h> 19 20 static int fat_registered; 21 22 static int spl_register_fat_device(struct blk_desc *block_dev, int partition) 23 { 24 int err = 0; 25 26 if (fat_registered) 27 return err; 28 29 err = fat_register_device(block_dev, partition); 30 if (err) { 31 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 32 printf("%s: fat register err - %d\n", __func__, err); 33 #endif 34 return err; 35 } 36 37 fat_registered = 1; 38 39 return err; 40 } 41 42 static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset, 43 ulong size, void *buf) 44 { 45 loff_t actread; 46 int ret; 47 char *filename = (char *)load->filename; 48 49 ret = fat_read_file(filename, buf, file_offset, size, &actread); 50 if (ret) 51 return ret; 52 53 return actread; 54 } 55 56 int spl_load_image_fat(struct spl_image_info *spl_image, 57 struct blk_desc *block_dev, int partition, 58 const char *filename) 59 { 60 int err; 61 struct image_header *header; 62 63 err = spl_register_fat_device(block_dev, partition); 64 if (err) 65 goto end; 66 67 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 68 sizeof(struct image_header)); 69 70 err = file_fat_read(filename, header, sizeof(struct image_header)); 71 if (err <= 0) 72 goto end; 73 74 #ifdef CONFIG_SPL_FIT_IMAGE_MULTIPLE 75 if ((IS_ENABLED(CONFIG_SPL_LOAD_FIT) && 76 image_get_magic(header) == FDT_MAGIC) || 77 CONFIG_SPL_FIT_IMAGE_MULTIPLE > 1) { 78 #else 79 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && 80 image_get_magic(header) == FDT_MAGIC) { 81 #endif 82 struct spl_load_info load; 83 84 debug("Found FIT\n"); 85 load.read = spl_fit_read; 86 load.bl_len = 1; 87 load.filename = (void *)filename; 88 load.priv = NULL; 89 90 return spl_load_simple_fit(spl_image, &load, 0, header); 91 } else { 92 err = spl_parse_image_header(spl_image, header); 93 if (err) 94 goto end; 95 96 err = file_fat_read(filename, 97 (u8 *)(uintptr_t)spl_image->load_addr, 0); 98 } 99 100 end: 101 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 102 if (err <= 0) 103 printf("%s: error reading image %s, err - %d\n", 104 __func__, filename, err); 105 #endif 106 107 return (err <= 0); 108 } 109 110 #ifdef CONFIG_SPL_OS_BOOT 111 int spl_load_image_fat_os(struct spl_image_info *spl_image, 112 struct blk_desc *block_dev, int partition) 113 { 114 int err; 115 __maybe_unused char *file; 116 117 err = spl_register_fat_device(block_dev, partition); 118 if (err) 119 return err; 120 121 #if defined(CONFIG_SPL_ENV_SUPPORT) && defined(CONFIG_SPL_OS_BOOT) 122 file = env_get("falcon_args_file"); 123 if (file) { 124 err = file_fat_read(file, (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0); 125 if (err <= 0) { 126 printf("spl: error reading image %s, err - %d, falling back to default\n", 127 file, err); 128 goto defaults; 129 } 130 file = env_get("falcon_image_file"); 131 if (file) { 132 err = spl_load_image_fat(spl_image, block_dev, 133 partition, file); 134 if (err != 0) { 135 puts("spl: falling back to default\n"); 136 goto defaults; 137 } 138 139 return 0; 140 } else 141 puts("spl: falcon_image_file not set in environment, falling back to default\n"); 142 } else 143 puts("spl: falcon_args_file not set in environment, falling back to default\n"); 144 145 defaults: 146 #endif 147 148 err = file_fat_read(CONFIG_SPL_FS_LOAD_ARGS_NAME, 149 (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0); 150 if (err <= 0) { 151 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 152 printf("%s: error reading image %s, err - %d\n", 153 __func__, CONFIG_SPL_FS_LOAD_ARGS_NAME, err); 154 #endif 155 return -1; 156 } 157 158 return spl_load_image_fat(spl_image, block_dev, partition, 159 CONFIG_SPL_FS_LOAD_KERNEL_NAME); 160 } 161 #else 162 int spl_load_image_fat_os(struct spl_image_info *spl_image, 163 struct blk_desc *block_dev, int partition) 164 { 165 return -ENOSYS; 166 } 167 #endif 168