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