]> Git Repo - u-boot.git/blob - include/spl_load.h
tpm: Remove <common.h> and add needed includes
[u-boot.git] / include / spl_load.h
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Copyright (C) Sean Anderson <[email protected]>
4  */
5 #ifndef _SPL_LOAD_H_
6 #define _SPL_LOAD_H_
7
8 #include <image.h>
9 #include <imx_container.h>
10 #include <mapmem.h>
11 #include <spl.h>
12
13 static inline int _spl_load(struct spl_image_info *spl_image,
14                             const struct spl_boot_device *bootdev,
15                             struct spl_load_info *info, size_t size,
16                             size_t offset)
17 {
18         struct legacy_img_hdr *header =
19                 spl_get_load_buffer(-sizeof(*header), sizeof(*header));
20         ulong base_offset, image_offset, overhead;
21         int read, ret;
22
23         read = info->read(info, offset, ALIGN(sizeof(*header),
24                                               spl_get_bl_len(info)), header);
25         if (read < sizeof(*header))
26                 return -EIO;
27
28         if (image_get_magic(header) == FDT_MAGIC) {
29                 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL)) {
30                         void *buf;
31
32                         /*
33                          * In order to support verifying images in the FIT, we
34                          * need to load the whole FIT into memory. Try and
35                          * guess how much we need to load by using the total
36                          * size. This will fail for FITs with external data,
37                          * but there's not much we can do about that.
38                          */
39                         if (!size)
40                                 size = round_up(fdt_totalsize(header), 4);
41                         buf = map_sysmem(CONFIG_SYS_LOAD_ADDR, size);
42                         read = info->read(info, offset,
43                                           ALIGN(size, spl_get_bl_len(info)),
44                                           buf);
45                         if (read < size)
46                                 return -EIO;
47
48                         return spl_parse_image_header(spl_image, bootdev, buf);
49                 }
50
51                 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT))
52                         return spl_load_simple_fit(spl_image, info, offset,
53                                                    header);
54         }
55
56         if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER) &&
57             valid_container_hdr((void *)header))
58                 return spl_load_imx_container(spl_image, info, offset);
59
60         if (IS_ENABLED(CONFIG_SPL_LZMA) &&
61             image_get_magic(header) == IH_MAGIC &&
62             image_get_comp(header) == IH_COMP_LZMA) {
63                 spl_image->flags |= SPL_COPY_PAYLOAD_ONLY;
64                 ret = spl_parse_image_header(spl_image, bootdev, header);
65                 if (ret)
66                         return ret;
67
68                 return spl_load_legacy_lzma(spl_image, info, offset);
69         }
70
71         ret = spl_parse_image_header(spl_image, bootdev, header);
72         if (ret)
73                 return ret;
74
75         base_offset = spl_image->offset;
76         /* Only NOR sets this flag. */
77         if (IS_ENABLED(CONFIG_SPL_NOR_SUPPORT) &&
78             spl_image->flags & SPL_COPY_PAYLOAD_ONLY)
79                 base_offset += sizeof(*header);
80         image_offset = ALIGN_DOWN(base_offset, spl_get_bl_len(info));
81         overhead = base_offset - image_offset;
82         size = ALIGN(spl_image->size + overhead, spl_get_bl_len(info));
83
84         read = info->read(info, offset + image_offset, size,
85                           map_sysmem(spl_image->load_addr - overhead, size));
86         return read < spl_image->size ? -EIO : 0;
87 }
88
89 /*
90  * Although spl_load results in size reduction for callers, this is generally
91  * not enough to counteract the bloat if there is only one caller. The core
92  * problem is that the compiler can't optimize across translation units. The
93  * general solution to this is CONFIG_LTO, but that is not available on all
94  * architectures. Perform a pseudo-LTO just for this function by declaring it
95  * inline if there is one caller, and extern otherwise.
96  */
97 #define SPL_LOAD_USERS \
98         IS_ENABLED(CONFIG_SPL_BLK_FS) + \
99         IS_ENABLED(CONFIG_SPL_FS_EXT4) + \
100         IS_ENABLED(CONFIG_SPL_FS_FAT) + \
101         IS_ENABLED(CONFIG_SPL_SYS_MMCSD_RAW_MODE) + \
102         (IS_ENABLED(CONFIG_SPL_NAND_SUPPORT) && !IS_ENABLED(CONFIG_SPL_UBI)) + \
103         IS_ENABLED(CONFIG_SPL_NET) + \
104         IS_ENABLED(CONFIG_SPL_NOR_SUPPORT) + \
105         IS_ENABLED(CONFIG_SPL_SEMIHOSTING) + \
106         IS_ENABLED(CONFIG_SPL_SPI_LOAD) + \
107         0
108
109 #if SPL_LOAD_USERS > 1
110 /**
111  * spl_load() - Parse a header and load the image
112  * @spl_image: Image data which will be filled in by this function
113  * @bootdev: The device to load from
114  * @info: Describes how to load additional information from @bootdev. At the
115  *        minimum, read() and bl_len must be populated.
116  * @size: The size of the image, in bytes, if it is known in advance. Some boot
117  *        devices (such as filesystems) know how big an image is before parsing
118  *        the header. If 0, then the size will be determined from the header.
119  * @offset: The offset from the start of @bootdev, in bytes. This should have
120  *          the offset @header was loaded from. It will be added to any offsets
121  *          passed to @info->read().
122  *
123  * This function determines the image type (FIT, legacy, i.MX, raw, etc), calls
124  * the appropriate parsing function, determines the load address, and the loads
125  * the image from storage. It is designed to replace ad-hoc image loading which
126  * may not support all image types (especially when config options are
127  * involved).
128  *
129  * Return: 0 on success, or a negative error on failure
130  */
131 int spl_load(struct spl_image_info *spl_image,
132              const struct spl_boot_device *bootdev, struct spl_load_info *info,
133              size_t size, size_t offset);
134 #else
135 static inline int spl_load(struct spl_image_info *spl_image,
136                            const struct spl_boot_device *bootdev,
137                            struct spl_load_info *info, size_t size,
138                            size_t offset)
139 {
140         return _spl_load(spl_image, bootdev, info, size, offset);
141 }
142 #endif
143
144 #endif /* _SPL_LOAD_H_ */
This page took 0.035689 seconds and 4 git commands to generate.