1 /* SPDX-License-Identifier: GPL-2.0+ */
3 * Copyright (C) Sean Anderson <seanga2@gmail.com>
9 #include <imx_container.h>
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
,
18 struct legacy_img_hdr
*header
=
19 spl_get_load_buffer(-sizeof(*header
), sizeof(*header
));
20 ulong base_offset
, image_offset
, overhead
;
23 read
= info
->read(info
, offset
, ALIGN(sizeof(*header
),
24 spl_get_bl_len(info
)), header
);
25 if (read
< sizeof(*header
))
28 if (image_get_magic(header
) == FDT_MAGIC
) {
29 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL
)) {
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.
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
)),
48 return spl_parse_image_header(spl_image
, bootdev
, buf
);
51 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT
))
52 return spl_load_simple_fit(spl_image
, info
, offset
,
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
);
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
);
68 return spl_load_legacy_lzma(spl_image
, info
, offset
);
71 ret
= spl_parse_image_header(spl_image
, bootdev
, header
);
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
));
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;
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.
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) + \
109 #if SPL_LOAD_USERS > 1
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().
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
129 * Return: 0 on success, or a negative error on failure
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
);
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
,
140 return _spl_load(spl_image
, bootdev
, info
, size
, offset
);
144 #endif /* _SPL_LOAD_H_ */