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