spl: don't assume NVMe partition 1 exists
[platform/kernel/u-boot.git] / common / spl / spl_blk_fs.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2023
4  * Ventana Micro Systems Inc.
5  *
6  */
7
8 #include <common.h>
9 #include <spl.h>
10 #include <image.h>
11 #include <fs.h>
12
13 struct blk_dev {
14         const char *ifname;
15         char dev_part_str[8];
16 };
17
18 static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset,
19                           ulong size, void *buf)
20 {
21         loff_t actlen;
22         int ret;
23         struct blk_dev *dev = (struct blk_dev *)load->priv;
24
25         ret = fs_set_blk_dev(dev->ifname, dev->dev_part_str, FS_TYPE_ANY);
26         if (ret) {
27                 printf("spl: unable to set blk_dev %s %s. Err - %d\n",
28                        dev->ifname, dev->dev_part_str, ret);
29                 return ret;
30         }
31
32         ret = fs_read(load->filename, (ulong)buf, file_offset, size, &actlen);
33         if (ret < 0) {
34                 printf("spl: error reading image %s. Err - %d\n",
35                        load->filename, ret);
36                 return ret;
37         }
38
39         return actlen;
40 }
41
42 int spl_blk_load_image(struct spl_image_info *spl_image,
43                        struct spl_boot_device *bootdev,
44                        enum uclass_id uclass_id, int devnum, int partnum)
45 {
46         const char *filename = CONFIG_SPL_FS_LOAD_PAYLOAD_NAME;
47         struct legacy_img_hdr *header;
48         struct blk_desc *blk_desc;
49         loff_t actlen, filesize;
50         struct blk_dev dev;
51         int ret;
52
53         blk_desc = blk_get_devnum_by_uclass_id(uclass_id, devnum);
54         if (!blk_desc) {
55                 printf("blk desc for %d %d not found\n", uclass_id, devnum);
56                 goto out;
57         }
58
59         blk_show_device(uclass_id, devnum);
60         header = spl_get_load_buffer(-sizeof(*header), sizeof(*header));
61
62         dev.ifname = blk_get_uclass_name(uclass_id);
63         snprintf(dev.dev_part_str, sizeof(dev.dev_part_str) - 1, "%x:%x",
64                  devnum, partnum);
65         ret = fs_set_blk_dev(dev.ifname, dev.dev_part_str, FS_TYPE_ANY);
66         if (ret) {
67                 printf("spl: unable to set blk_dev %s %s. Err - %d\n",
68                        dev.ifname, dev.dev_part_str, ret);
69                 goto out;
70         }
71
72         ret = fs_read(filename, (ulong)header, 0,
73                       sizeof(struct legacy_img_hdr), &actlen);
74         if (ret) {
75                 printf("spl: unable to read file %s. Err - %d\n", filename,
76                        ret);
77                 goto out;
78         }
79
80         if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
81             image_get_magic(header) == FDT_MAGIC) {
82                 struct spl_load_info load;
83
84                 debug("Found FIT\n");
85                 load.read = spl_fit_read;
86                 load.bl_len = 1;
87                 load.filename = (void *)filename;
88                 load.priv = &dev;
89
90                 return spl_load_simple_fit(spl_image, &load, 0, header);
91         }
92
93         ret = spl_parse_image_header(spl_image, bootdev, header);
94         if (ret) {
95                 printf("spl: unable to parse image header. Err - %d\n",
96                        ret);
97                 goto out;
98         }
99
100         ret = fs_set_blk_dev(dev.ifname, dev.dev_part_str, FS_TYPE_ANY);
101         if (ret) {
102                 printf("spl: unable to set blk_dev %s %s. Err - %d\n",
103                        dev.ifname, dev.dev_part_str, ret);
104                 goto out;
105         }
106
107         ret = fs_size(filename, &filesize);
108         if (ret) {
109                 printf("spl: unable to get file size: %s. Err - %d\n",
110                        filename, ret);
111                 goto out;
112         }
113
114         ret = fs_set_blk_dev(dev.ifname, dev.dev_part_str, FS_TYPE_ANY);
115         if (ret) {
116                 printf("spl: unable to set blk_dev %s %s. Err - %d\n",
117                        dev.ifname, dev.dev_part_str, ret);
118                 goto out;
119         }
120
121         ret = fs_read(filename, (ulong)spl_image->load_addr, 0, filesize,
122                       &actlen);
123         if (ret)
124                 printf("spl: unable to read file %s. Err - %d\n",
125                        filename, ret);
126 out:
127         return ret;
128 }