1 // SPDX-License-Identifier: GPL-2.0+
2 
3 #include <common.h>
4 #include <env.h>
5 #include <part.h>
6 #include <spl.h>
7 #include <asm/u-boot.h>
8 #include <ext4fs.h>
9 #include <errno.h>
10 #include <image.h>
11 
spl_load_image_ext(struct spl_image_info * spl_image,struct blk_desc * block_dev,int partition,const char * filename)12 int spl_load_image_ext(struct spl_image_info *spl_image,
13 		       struct blk_desc *block_dev, int partition,
14 		       const char *filename)
15 {
16 	s32 err;
17 	struct image_header *header;
18 	loff_t filelen, actlen;
19 	struct disk_partition part_info = {};
20 
21 	header = spl_get_load_buffer(-sizeof(*header), sizeof(*header));
22 
23 	if (part_get_info(block_dev, partition, &part_info)) {
24 		printf("spl: no partition table found\n");
25 		return -1;
26 	}
27 
28 	ext4fs_set_blk_dev(block_dev, &part_info);
29 
30 	err = ext4fs_mount(0);
31 	if (!err) {
32 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
33 		printf("%s: ext4fs mount err - %d\n", __func__, err);
34 #endif
35 		return -1;
36 	}
37 
38 	err = ext4fs_open(filename, &filelen);
39 	if (err < 0) {
40 		puts("spl: ext4fs_open failed\n");
41 		goto end;
42 	}
43 	err = ext4fs_read((char *)header, 0, sizeof(struct image_header), &actlen);
44 	if (err < 0) {
45 		puts("spl: ext4fs_read failed\n");
46 		goto end;
47 	}
48 
49 	err = spl_parse_image_header(spl_image, header);
50 	if (err < 0) {
51 		puts("spl: ext: failed to parse image header\n");
52 		goto end;
53 	}
54 
55 	err = ext4fs_read((char *)spl_image->load_addr, 0, filelen, &actlen);
56 
57 end:
58 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
59 	if (err < 0)
60 		printf("%s: error reading image %s, err - %d\n",
61 		       __func__, filename, err);
62 #endif
63 
64 	return err < 0;
65 }
66 
67 #ifdef CONFIG_SPL_OS_BOOT
spl_load_image_ext_os(struct spl_image_info * spl_image,struct blk_desc * block_dev,int partition)68 int spl_load_image_ext_os(struct spl_image_info *spl_image,
69 			  struct blk_desc *block_dev, int partition)
70 {
71 	int err;
72 	__maybe_unused loff_t filelen, actlen;
73 	struct disk_partition part_info = {};
74 	__maybe_unused char *file;
75 
76 	if (part_get_info(block_dev, partition, &part_info)) {
77 		printf("spl: no partition table found\n");
78 		return -1;
79 	}
80 
81 	ext4fs_set_blk_dev(block_dev, &part_info);
82 
83 	err = ext4fs_mount(0);
84 	if (!err) {
85 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
86 		printf("%s: ext4fs mount err - %d\n", __func__, err);
87 #endif
88 		return -1;
89 	}
90 #if defined(CONFIG_SPL_ENV_SUPPORT)
91 	file = env_get("falcon_args_file");
92 	if (file) {
93 		err = ext4fs_open(file, &filelen);
94 		if (err < 0) {
95 			puts("spl: ext4fs_open failed\n");
96 			goto defaults;
97 		}
98 		err = ext4fs_read((void *)CONFIG_SYS_SPL_ARGS_ADDR, 0, filelen, &actlen);
99 		if (err < 0) {
100 			printf("spl: error reading image %s, err - %d, falling back to default\n",
101 			       file, err);
102 			goto defaults;
103 		}
104 		file = env_get("falcon_image_file");
105 		if (file) {
106 			err = spl_load_image_ext(spl_image, block_dev,
107 						 partition, file);
108 			if (err != 0) {
109 				puts("spl: falling back to default\n");
110 				goto defaults;
111 			}
112 
113 			return 0;
114 		} else {
115 			puts("spl: falcon_image_file not set in environment, falling back to default\n");
116 		}
117 	} else {
118 		puts("spl: falcon_args_file not set in environment, falling back to default\n");
119 	}
120 
121 defaults:
122 #endif
123 
124 	err = ext4fs_open(CONFIG_SPL_FS_LOAD_ARGS_NAME, &filelen);
125 	if (err < 0)
126 		puts("spl: ext4fs_open failed\n");
127 
128 	err = ext4fs_read((void *)CONFIG_SYS_SPL_ARGS_ADDR, 0, filelen, &actlen);
129 	if (err < 0) {
130 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
131 		printf("%s: error reading image %s, err - %d\n",
132 		       __func__, CONFIG_SPL_FS_LOAD_ARGS_NAME, err);
133 #endif
134 		return -1;
135 	}
136 
137 	return spl_load_image_ext(spl_image, block_dev, partition,
138 			CONFIG_SPL_FS_LOAD_KERNEL_NAME);
139 }
140 #else
spl_load_image_ext_os(struct spl_image_info * spl_image,struct blk_desc * block_dev,int partition)141 int spl_load_image_ext_os(struct spl_image_info *spl_image,
142 			  struct blk_desc *block_dev, int partition)
143 {
144 	return -ENOSYS;
145 }
146 #endif
147