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