xref: /rk3399_rockchip-uboot/common/spl/spl_fat.c (revision f8f8bbc62fc911ca724dd0a6184be5982d300b0e)
1773b5940SDan Murphy /*
2773b5940SDan Murphy  * (C) Copyright 2014
3773b5940SDan Murphy  * Texas Instruments, <www.ti.com>
4773b5940SDan Murphy  *
5773b5940SDan Murphy  * Dan Murphy <dmurphy@ti.com>
6773b5940SDan Murphy  *
7773b5940SDan Murphy  * SPDX-License-Identifier:	GPL-2.0+
8773b5940SDan Murphy  *
9773b5940SDan Murphy  * FAT Image Functions copied from spl_mmc.c
10773b5940SDan Murphy  */
11773b5940SDan Murphy 
12773b5940SDan Murphy #include <common.h>
13773b5940SDan Murphy #include <spl.h>
14773b5940SDan Murphy #include <asm/u-boot.h>
15773b5940SDan Murphy #include <fat.h>
16339245b7SNikita Kiryanov #include <errno.h>
17773b5940SDan Murphy #include <image.h>
180e00a84cSMasahiro Yamada #include <linux/libfdt.h>
19773b5940SDan Murphy 
20773b5940SDan Murphy static int fat_registered;
21773b5940SDan Murphy 
spl_register_fat_device(struct blk_desc * block_dev,int partition)224101f687SSimon Glass static int spl_register_fat_device(struct blk_desc *block_dev, int partition)
23773b5940SDan Murphy {
24773b5940SDan Murphy 	int err = 0;
25773b5940SDan Murphy 
26773b5940SDan Murphy 	if (fat_registered)
27773b5940SDan Murphy 		return err;
28773b5940SDan Murphy 
29773b5940SDan Murphy 	err = fat_register_device(block_dev, partition);
30773b5940SDan Murphy 	if (err) {
31773b5940SDan Murphy #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
328cffe5bdSDan Murphy 		printf("%s: fat register err - %d\n", __func__, err);
33773b5940SDan Murphy #endif
347d2b4e77SGuillaume GARDET 		return err;
35773b5940SDan Murphy 	}
36773b5940SDan Murphy 
37773b5940SDan Murphy 	fat_registered = 1;
38773b5940SDan Murphy 
39773b5940SDan Murphy 	return err;
40773b5940SDan Murphy }
41773b5940SDan Murphy 
spl_fit_read(struct spl_load_info * load,ulong file_offset,ulong size,void * buf)4297ca364fSLokesh Vutla static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset,
4397ca364fSLokesh Vutla 			  ulong size, void *buf)
4497ca364fSLokesh Vutla {
4597ca364fSLokesh Vutla 	loff_t actread;
4697ca364fSLokesh Vutla 	int ret;
4797ca364fSLokesh Vutla 	char *filename = (char *)load->filename;
4897ca364fSLokesh Vutla 
4997ca364fSLokesh Vutla 	ret = fat_read_file(filename, buf, file_offset, size, &actread);
5097ca364fSLokesh Vutla 	if (ret)
5197ca364fSLokesh Vutla 		return ret;
5297ca364fSLokesh Vutla 
5397ca364fSLokesh Vutla 	return actread;
5497ca364fSLokesh Vutla }
5597ca364fSLokesh Vutla 
spl_load_image_fat(struct spl_image_info * spl_image,struct blk_desc * block_dev,int partition,const char * filename)56710e9ca5SSimon Glass int spl_load_image_fat(struct spl_image_info *spl_image,
57710e9ca5SSimon Glass 		       struct blk_desc *block_dev, int partition,
58773b5940SDan Murphy 		       const char *filename)
59773b5940SDan Murphy {
60773b5940SDan Murphy 	int err;
61773b5940SDan Murphy 	struct image_header *header;
62773b5940SDan Murphy 
63773b5940SDan Murphy 	err = spl_register_fat_device(block_dev, partition);
648cffe5bdSDan Murphy 	if (err)
65773b5940SDan Murphy 		goto end;
66773b5940SDan Murphy 
67773b5940SDan Murphy 	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
68773b5940SDan Murphy 						sizeof(struct image_header));
69773b5940SDan Murphy 
70773b5940SDan Murphy 	err = file_fat_read(filename, header, sizeof(struct image_header));
71773b5940SDan Murphy 	if (err <= 0)
72773b5940SDan Murphy 		goto end;
73773b5940SDan Murphy 
74*22c7c1a8SJoseph Chen #ifdef CONFIG_SPL_FIT_IMAGE_MULTIPLE
75*22c7c1a8SJoseph Chen 	if ((IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
76*22c7c1a8SJoseph Chen 	     image_get_magic(header) == FDT_MAGIC) ||
77*22c7c1a8SJoseph Chen 	     CONFIG_SPL_FIT_IMAGE_MULTIPLE > 1) {
78*22c7c1a8SJoseph Chen #else
7997ca364fSLokesh Vutla 	if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
8097ca364fSLokesh Vutla 	    image_get_magic(header) == FDT_MAGIC) {
81*22c7c1a8SJoseph Chen #endif
8297ca364fSLokesh Vutla 		struct spl_load_info load;
8397ca364fSLokesh Vutla 
8497ca364fSLokesh Vutla 		debug("Found FIT\n");
8597ca364fSLokesh Vutla 		load.read = spl_fit_read;
8697ca364fSLokesh Vutla 		load.bl_len = 1;
8797ca364fSLokesh Vutla 		load.filename = (void *)filename;
8897ca364fSLokesh Vutla 		load.priv = NULL;
8997ca364fSLokesh Vutla 
90f4d7d859SSimon Glass 		return spl_load_simple_fit(spl_image, &load, 0, header);
9197ca364fSLokesh Vutla 	} else {
92710e9ca5SSimon Glass 		err = spl_parse_image_header(spl_image, header);
93d550e82eSTom Rini 		if (err)
947e0f2267SMarek Vasut 			goto end;
95773b5940SDan Murphy 
961eefe14fSMichal Simek 		err = file_fat_read(filename,
97710e9ca5SSimon Glass 				    (u8 *)(uintptr_t)spl_image->load_addr, 0);
9897ca364fSLokesh Vutla 	}
99773b5940SDan Murphy 
100773b5940SDan Murphy end:
101773b5940SDan Murphy #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
102773b5940SDan Murphy 	if (err <= 0)
1038cffe5bdSDan Murphy 		printf("%s: error reading image %s, err - %d\n",
1048cffe5bdSDan Murphy 		       __func__, filename, err);
105773b5940SDan Murphy #endif
106773b5940SDan Murphy 
107773b5940SDan Murphy 	return (err <= 0);
108773b5940SDan Murphy }
109773b5940SDan Murphy 
110773b5940SDan Murphy #ifdef CONFIG_SPL_OS_BOOT
111710e9ca5SSimon Glass int spl_load_image_fat_os(struct spl_image_info *spl_image,
112710e9ca5SSimon Glass 			  struct blk_desc *block_dev, int partition)
113773b5940SDan Murphy {
114773b5940SDan Murphy 	int err;
115ae1590edSTom Rini 	__maybe_unused char *file;
116773b5940SDan Murphy 
117773b5940SDan Murphy 	err = spl_register_fat_device(block_dev, partition);
1188cffe5bdSDan Murphy 	if (err)
1198cffe5bdSDan Murphy 		return err;
120773b5940SDan Murphy 
121ae1590edSTom Rini #if defined(CONFIG_SPL_ENV_SUPPORT) && defined(CONFIG_SPL_OS_BOOT)
12200caae6dSSimon Glass 	file = env_get("falcon_args_file");
123ae1590edSTom Rini 	if (file) {
124ae1590edSTom Rini 		err = file_fat_read(file, (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0);
125ae1590edSTom Rini 		if (err <= 0) {
126ae1590edSTom Rini 			printf("spl: error reading image %s, err - %d, falling back to default\n",
127ae1590edSTom Rini 			       file, err);
128ae1590edSTom Rini 			goto defaults;
129ae1590edSTom Rini 		}
13000caae6dSSimon Glass 		file = env_get("falcon_image_file");
131ae1590edSTom Rini 		if (file) {
132710e9ca5SSimon Glass 			err = spl_load_image_fat(spl_image, block_dev,
133710e9ca5SSimon Glass 						 partition, file);
134ae1590edSTom Rini 			if (err != 0) {
135ae1590edSTom Rini 				puts("spl: falling back to default\n");
136ae1590edSTom Rini 				goto defaults;
137ae1590edSTom Rini 			}
138ae1590edSTom Rini 
139ae1590edSTom Rini 			return 0;
140ae1590edSTom Rini 		} else
141ae1590edSTom Rini 			puts("spl: falcon_image_file not set in environment, falling back to default\n");
142ae1590edSTom Rini 	} else
143ae1590edSTom Rini 		puts("spl: falcon_args_file not set in environment, falling back to default\n");
144ae1590edSTom Rini 
145ae1590edSTom Rini defaults:
146ae1590edSTom Rini #endif
147ae1590edSTom Rini 
148205b4f33SGuillaume GARDET 	err = file_fat_read(CONFIG_SPL_FS_LOAD_ARGS_NAME,
149773b5940SDan Murphy 			    (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0);
150773b5940SDan Murphy 	if (err <= 0) {
151773b5940SDan Murphy #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
1528cffe5bdSDan Murphy 		printf("%s: error reading image %s, err - %d\n",
153205b4f33SGuillaume GARDET 		       __func__, CONFIG_SPL_FS_LOAD_ARGS_NAME, err);
154773b5940SDan Murphy #endif
155773b5940SDan Murphy 		return -1;
156773b5940SDan Murphy 	}
157773b5940SDan Murphy 
158710e9ca5SSimon Glass 	return spl_load_image_fat(spl_image, block_dev, partition,
159205b4f33SGuillaume GARDET 			CONFIG_SPL_FS_LOAD_KERNEL_NAME);
160773b5940SDan Murphy }
161339245b7SNikita Kiryanov #else
162710e9ca5SSimon Glass int spl_load_image_fat_os(struct spl_image_info *spl_image,
163710e9ca5SSimon Glass 			  struct blk_desc *block_dev, int partition)
164339245b7SNikita Kiryanov {
165339245b7SNikita Kiryanov 	return -ENOSYS;
166339245b7SNikita Kiryanov }
167773b5940SDan Murphy #endif
168