]> Git Repo - J-u-boot.git/blame - include/spl_load.h
Merge branch 'next' of https://source.denx.de/u-boot/custodians/u-boot-riscv into...
[J-u-boot.git] / include / spl_load.h
CommitLineData
77507416
SA
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
13static 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);
cf85cd84 25 if (read < (int)sizeof(*header))
77507416
SA
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));
c6eba28c
DP
86
87 if (read < 0)
88 return read;
89
77507416
SA
90 return read < spl_image->size ? -EIO : 0;
91}
92
93/*
94 * Although spl_load results in size reduction for callers, this is generally
95 * not enough to counteract the bloat if there is only one caller. The core
96 * problem is that the compiler can't optimize across translation units. The
97 * general solution to this is CONFIG_LTO, but that is not available on all
98 * architectures. Perform a pseudo-LTO just for this function by declaring it
99 * inline if there is one caller, and extern otherwise.
100 */
101#define SPL_LOAD_USERS \
6029a0e1 102 IS_ENABLED(CONFIG_SPL_BLK_FS) + \
b8ed7225 103 IS_ENABLED(CONFIG_SPL_FS_EXT4) + \
682184e9 104 IS_ENABLED(CONFIG_SPL_FS_FAT) + \
5d3401a4 105 IS_ENABLED(CONFIG_SPL_SYS_MMCSD_RAW_MODE) + \
11f83461 106 (IS_ENABLED(CONFIG_SPL_NAND_SUPPORT) && !IS_ENABLED(CONFIG_SPL_UBI)) + \
2e5476b5 107 IS_ENABLED(CONFIG_SPL_NET) + \
cbe86576 108 IS_ENABLED(CONFIG_SPL_NOR_SUPPORT) + \
9b9c6aaa 109 IS_ENABLED(CONFIG_SPL_SEMIHOSTING) + \
a04d5f60 110 IS_ENABLED(CONFIG_SPL_SPI_LOAD) + \
77507416
SA
111 0
112
113#if SPL_LOAD_USERS > 1
114/**
115 * spl_load() - Parse a header and load the image
116 * @spl_image: Image data which will be filled in by this function
117 * @bootdev: The device to load from
118 * @info: Describes how to load additional information from @bootdev. At the
119 * minimum, read() and bl_len must be populated.
120 * @size: The size of the image, in bytes, if it is known in advance. Some boot
121 * devices (such as filesystems) know how big an image is before parsing
122 * the header. If 0, then the size will be determined from the header.
123 * @offset: The offset from the start of @bootdev, in bytes. This should have
124 * the offset @header was loaded from. It will be added to any offsets
125 * passed to @info->read().
126 *
127 * This function determines the image type (FIT, legacy, i.MX, raw, etc), calls
128 * the appropriate parsing function, determines the load address, and the loads
129 * the image from storage. It is designed to replace ad-hoc image loading which
130 * may not support all image types (especially when config options are
131 * involved).
132 *
133 * Return: 0 on success, or a negative error on failure
134 */
135int spl_load(struct spl_image_info *spl_image,
136 const struct spl_boot_device *bootdev, struct spl_load_info *info,
137 size_t size, size_t offset);
138#else
139static inline int spl_load(struct spl_image_info *spl_image,
140 const struct spl_boot_device *bootdev,
141 struct spl_load_info *info, size_t size,
142 size_t offset)
143{
144 return _spl_load(spl_image, bootdev, info, size, offset);
145}
146#endif
147
148#endif /* _SPL_LOAD_H_ */
This page took 0.104727 seconds and 4 git commands to generate.