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 <env.h>
12 #include <log.h>
13 #include <spl.h>
14 #include <spl_load.h>
15 #include <fat.h>
16 #include <errno.h>
17 #include <image.h>
18 #include <linux/libfdt.h>
19 #include <asm/cache.h>
20
21 static int fat_registered;
22
spl_fat_force_reregister(void)23 void spl_fat_force_reregister(void)
24 {
25 fat_registered = 0;
26 }
27
spl_register_fat_device(struct blk_desc * block_dev,int partition)28 static int spl_register_fat_device(struct blk_desc *block_dev, int partition)
29 {
30 int err = 0;
31
32 if (fat_registered)
33 return err;
34
35 err = fat_register_device(block_dev, partition);
36 if (err) {
37 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
38 printf("%s: fat register err - %d\n", __func__, err);
39 #endif
40 return err;
41 }
42
43 fat_registered = 1;
44
45 return err;
46 }
47
spl_fit_read(struct spl_load_info * load,ulong file_offset,ulong size,void * buf)48 static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset,
49 ulong size, void *buf)
50 {
51 struct legacy_img_hdr *header;
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 if (CONFIG_IS_ENABLED(OS_BOOT)) {
61 header = (struct legacy_img_hdr *)buf;
62 if (image_get_magic(header) != FDT_MAGIC)
63 return size;
64 }
65
66 return actread;
67 }
68
spl_load_image_fat(struct spl_image_info * spl_image,struct spl_boot_device * bootdev,struct blk_desc * block_dev,int partition,const char * filename)69 int spl_load_image_fat(struct spl_image_info *spl_image,
70 struct spl_boot_device *bootdev,
71 struct blk_desc *block_dev, int partition,
72 const char *filename)
73 {
74 int err;
75 loff_t size;
76 struct spl_load_info load;
77
78 err = spl_register_fat_device(block_dev, partition);
79 if (err)
80 goto end;
81
82 /*
83 * Avoid pulling in this function for other image types since we are
84 * very short on space on some boards.
85 */
86 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL)) {
87 err = fat_size(filename, &size);
88 if (err)
89 goto end;
90 } else {
91 size = 0;
92 }
93
94 spl_load_init(&load, spl_fit_read, (void *)filename,
95 IS_ENABLED(CONFIG_SPL_FS_FAT_DMA_ALIGN) ?
96 ARCH_DMA_MINALIGN : 1);
97
98 err = spl_load(spl_image, bootdev, &load, size, 0);
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;
108 }
109
110 #if CONFIG_IS_ENABLED(OS_BOOT)
spl_load_image_fat_os(struct spl_image_info * spl_image,struct spl_boot_device * bootdev,struct blk_desc * block_dev,int partition)111 int spl_load_image_fat_os(struct spl_image_info *spl_image,
112 struct spl_boot_device *bootdev,
113 struct blk_desc *block_dev, int partition)
114 {
115 int err;
116 __maybe_unused char *file;
117
118 err = spl_register_fat_device(block_dev, partition);
119 if (err)
120 return err;
121
122 #if defined(CONFIG_SPL_ENV_SUPPORT) && defined(CONFIG_SPL_OS_BOOT)
123 file = env_get("falcon_args_file");
124 if (file) {
125 err = file_fat_read(file, (void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR, 0);
126 if (err <= 0) {
127 printf("spl: error reading image %s, err - %d, falling back to default\n",
128 file, err);
129 goto defaults;
130 }
131 file = env_get("falcon_image_file");
132 if (file) {
133 err = spl_load_image_fat(spl_image, bootdev, block_dev,
134 partition, file);
135 if (err != 0) {
136 puts("spl: falling back to default\n");
137 goto defaults;
138 }
139
140 return 0;
141 } else
142 puts("spl: falcon_image_file not set in environment, falling back to default\n");
143 } else
144 puts("spl: falcon_args_file not set in environment, falling back to default\n");
145
146 defaults:
147 #endif
148
149 err = file_fat_read(CONFIG_SPL_FS_LOAD_ARGS_NAME,
150 (void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR, 0);
151 if (err <= 0) {
152 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
153 printf("%s: error reading image %s, err - %d\n",
154 __func__, CONFIG_SPL_FS_LOAD_ARGS_NAME, err);
155 #endif
156 return -1;
157 }
158
159 return spl_load_image_fat(spl_image, bootdev, block_dev, partition,
160 CONFIG_SPL_FS_LOAD_KERNEL_NAME);
161 }
162 #else
spl_load_image_fat_os(struct spl_image_info * spl_image,struct spl_boot_device * bootdev,struct blk_desc * block_dev,int partition)163 int spl_load_image_fat_os(struct spl_image_info *spl_image,
164 struct spl_boot_device *bootdev,
165 struct blk_desc *block_dev, int partition)
166 {
167 return -ENOSYS;
168 }
169 #endif
170