183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2773b5940SDan Murphy /*
3773b5940SDan Murphy * (C) Copyright 2014
4773b5940SDan Murphy * Texas Instruments, <www.ti.com>
5773b5940SDan Murphy *
6773b5940SDan Murphy * Dan Murphy <dmurphy@ti.com>
7773b5940SDan Murphy *
8773b5940SDan Murphy * FAT Image Functions copied from spl_mmc.c
9773b5940SDan Murphy */
10773b5940SDan Murphy
11773b5940SDan Murphy #include <common.h>
12773b5940SDan Murphy #include <spl.h>
13773b5940SDan Murphy #include <asm/u-boot.h>
14773b5940SDan Murphy #include <fat.h>
15339245b7SNikita Kiryanov #include <errno.h>
16773b5940SDan Murphy #include <image.h>
17b08c8c48SMasahiro Yamada #include <linux/libfdt.h>
18773b5940SDan Murphy
19773b5940SDan Murphy static int fat_registered;
20773b5940SDan Murphy
spl_register_fat_device(struct blk_desc * block_dev,int partition)214101f687SSimon Glass static int spl_register_fat_device(struct blk_desc *block_dev, int partition)
22773b5940SDan Murphy {
23773b5940SDan Murphy int err = 0;
24773b5940SDan Murphy
25773b5940SDan Murphy if (fat_registered)
26773b5940SDan Murphy return err;
27773b5940SDan Murphy
28773b5940SDan Murphy err = fat_register_device(block_dev, partition);
29773b5940SDan Murphy if (err) {
30773b5940SDan Murphy #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
318cffe5bdSDan Murphy printf("%s: fat register err - %d\n", __func__, err);
32773b5940SDan Murphy #endif
337d2b4e77SGuillaume GARDET return err;
34773b5940SDan Murphy }
35773b5940SDan Murphy
36773b5940SDan Murphy fat_registered = 1;
37773b5940SDan Murphy
38773b5940SDan Murphy return err;
39773b5940SDan Murphy }
40773b5940SDan Murphy
spl_fit_read(struct spl_load_info * load,ulong file_offset,ulong size,void * buf)4197ca364fSLokesh Vutla static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset,
4297ca364fSLokesh Vutla ulong size, void *buf)
4397ca364fSLokesh Vutla {
4497ca364fSLokesh Vutla loff_t actread;
4597ca364fSLokesh Vutla int ret;
4697ca364fSLokesh Vutla char *filename = (char *)load->filename;
4797ca364fSLokesh Vutla
4897ca364fSLokesh Vutla ret = fat_read_file(filename, buf, file_offset, size, &actread);
4997ca364fSLokesh Vutla if (ret)
5097ca364fSLokesh Vutla return ret;
5197ca364fSLokesh Vutla
5297ca364fSLokesh Vutla return actread;
5397ca364fSLokesh Vutla }
5497ca364fSLokesh Vutla
spl_load_image_fat(struct spl_image_info * spl_image,struct blk_desc * block_dev,int partition,const char * filename)55710e9ca5SSimon Glass int spl_load_image_fat(struct spl_image_info *spl_image,
56710e9ca5SSimon Glass struct blk_desc *block_dev, int partition,
57773b5940SDan Murphy const char *filename)
58773b5940SDan Murphy {
59773b5940SDan Murphy int err;
60773b5940SDan Murphy struct image_header *header;
61773b5940SDan Murphy
62773b5940SDan Murphy err = spl_register_fat_device(block_dev, partition);
638cffe5bdSDan Murphy if (err)
64773b5940SDan Murphy goto end;
65773b5940SDan Murphy
66*04ce5427SMarek Vasut header = spl_get_load_buffer(-sizeof(*header), sizeof(*header));
67773b5940SDan Murphy
68773b5940SDan Murphy err = file_fat_read(filename, header, sizeof(struct image_header));
69773b5940SDan Murphy if (err <= 0)
70773b5940SDan Murphy goto end;
71773b5940SDan Murphy
728b1531f7SMarek Vasut if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL) &&
738b1531f7SMarek Vasut image_get_magic(header) == FDT_MAGIC) {
748b1531f7SMarek Vasut err = file_fat_read(filename, (void *)CONFIG_SYS_LOAD_ADDR, 0);
758b1531f7SMarek Vasut if (err <= 0)
768b1531f7SMarek Vasut goto end;
778b1531f7SMarek Vasut err = spl_parse_image_header(spl_image,
788b1531f7SMarek Vasut (struct image_header *)CONFIG_SYS_LOAD_ADDR);
798b1531f7SMarek Vasut if (err == -EAGAIN)
808b1531f7SMarek Vasut return err;
818b1531f7SMarek Vasut if (err == 0)
828b1531f7SMarek Vasut err = 1;
838b1531f7SMarek Vasut } else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
8497ca364fSLokesh Vutla image_get_magic(header) == FDT_MAGIC) {
8597ca364fSLokesh Vutla struct spl_load_info load;
8697ca364fSLokesh Vutla
8797ca364fSLokesh Vutla debug("Found FIT\n");
8897ca364fSLokesh Vutla load.read = spl_fit_read;
8997ca364fSLokesh Vutla load.bl_len = 1;
9097ca364fSLokesh Vutla load.filename = (void *)filename;
9197ca364fSLokesh Vutla load.priv = NULL;
9297ca364fSLokesh Vutla
93f4d7d859SSimon Glass return spl_load_simple_fit(spl_image, &load, 0, header);
9497ca364fSLokesh Vutla } else {
95710e9ca5SSimon Glass err = spl_parse_image_header(spl_image, header);
96d550e82eSTom Rini if (err)
977e0f2267SMarek Vasut goto end;
98773b5940SDan Murphy
991eefe14fSMichal Simek err = file_fat_read(filename,
100710e9ca5SSimon Glass (u8 *)(uintptr_t)spl_image->load_addr, 0);
10197ca364fSLokesh Vutla }
102773b5940SDan Murphy
103773b5940SDan Murphy end:
104773b5940SDan Murphy #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
105773b5940SDan Murphy if (err <= 0)
1068cffe5bdSDan Murphy printf("%s: error reading image %s, err - %d\n",
1078cffe5bdSDan Murphy __func__, filename, err);
108773b5940SDan Murphy #endif
109773b5940SDan Murphy
110773b5940SDan Murphy return (err <= 0);
111773b5940SDan Murphy }
112773b5940SDan Murphy
113773b5940SDan Murphy #ifdef CONFIG_SPL_OS_BOOT
spl_load_image_fat_os(struct spl_image_info * spl_image,struct blk_desc * block_dev,int partition)114710e9ca5SSimon Glass int spl_load_image_fat_os(struct spl_image_info *spl_image,
115710e9ca5SSimon Glass struct blk_desc *block_dev, int partition)
116773b5940SDan Murphy {
117773b5940SDan Murphy int err;
118ae1590edSTom Rini __maybe_unused char *file;
119773b5940SDan Murphy
120773b5940SDan Murphy err = spl_register_fat_device(block_dev, partition);
1218cffe5bdSDan Murphy if (err)
1228cffe5bdSDan Murphy return err;
123773b5940SDan Murphy
124ae1590edSTom Rini #if defined(CONFIG_SPL_ENV_SUPPORT) && defined(CONFIG_SPL_OS_BOOT)
12500caae6dSSimon Glass file = env_get("falcon_args_file");
126ae1590edSTom Rini if (file) {
127ae1590edSTom Rini err = file_fat_read(file, (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0);
128ae1590edSTom Rini if (err <= 0) {
129ae1590edSTom Rini printf("spl: error reading image %s, err - %d, falling back to default\n",
130ae1590edSTom Rini file, err);
131ae1590edSTom Rini goto defaults;
132ae1590edSTom Rini }
13300caae6dSSimon Glass file = env_get("falcon_image_file");
134ae1590edSTom Rini if (file) {
135710e9ca5SSimon Glass err = spl_load_image_fat(spl_image, block_dev,
136710e9ca5SSimon Glass partition, file);
137ae1590edSTom Rini if (err != 0) {
138ae1590edSTom Rini puts("spl: falling back to default\n");
139ae1590edSTom Rini goto defaults;
140ae1590edSTom Rini }
141ae1590edSTom Rini
142ae1590edSTom Rini return 0;
143ae1590edSTom Rini } else
144ae1590edSTom Rini puts("spl: falcon_image_file not set in environment, falling back to default\n");
145ae1590edSTom Rini } else
146ae1590edSTom Rini puts("spl: falcon_args_file not set in environment, falling back to default\n");
147ae1590edSTom Rini
148ae1590edSTom Rini defaults:
149ae1590edSTom Rini #endif
150ae1590edSTom Rini
151205b4f33SGuillaume GARDET err = file_fat_read(CONFIG_SPL_FS_LOAD_ARGS_NAME,
152773b5940SDan Murphy (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0);
153773b5940SDan Murphy if (err <= 0) {
154773b5940SDan Murphy #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
1558cffe5bdSDan Murphy printf("%s: error reading image %s, err - %d\n",
156205b4f33SGuillaume GARDET __func__, CONFIG_SPL_FS_LOAD_ARGS_NAME, err);
157773b5940SDan Murphy #endif
158773b5940SDan Murphy return -1;
159773b5940SDan Murphy }
160773b5940SDan Murphy
161710e9ca5SSimon Glass return spl_load_image_fat(spl_image, block_dev, partition,
162205b4f33SGuillaume GARDET CONFIG_SPL_FS_LOAD_KERNEL_NAME);
163773b5940SDan Murphy }
164339245b7SNikita Kiryanov #else
spl_load_image_fat_os(struct spl_image_info * spl_image,struct blk_desc * block_dev,int partition)165710e9ca5SSimon Glass int spl_load_image_fat_os(struct spl_image_info *spl_image,
166710e9ca5SSimon Glass struct blk_desc *block_dev, int partition)
167339245b7SNikita Kiryanov {
168339245b7SNikita Kiryanov return -ENOSYS;
169339245b7SNikita Kiryanov }
170773b5940SDan Murphy #endif
171