blob: d179a5549e842b8cde29f173f34871866d3ba882 [file] [log] [blame]
Simon Glass37972f42025-05-24 11:28:21 -06001/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * EFI device path functions
4 *
5 * (C) Copyright 2017 Rob Clark
6 */
7
8#ifndef EFI_DEVICE_PATH_H
9#define EFI_DEVICE_PATH_H
10
11#include <efi.h>
12
13struct blk_desc;
14struct efi_load_option;
15struct udevice;
16
17/*
18 * END - Template end node for EFI device paths.
19 *
20 * Represents the terminating node of an EFI device path.
21 * It has a type of DEVICE_PATH_TYPE_END and sub_type DEVICE_PATH_SUB_TYPE_END
22 */
23extern const struct efi_device_path END;
24
25/**
26 * efi_dp_next() - Iterate to next block in device-path
27 *
28 * Advance to the next node in an EFI device path.
29 *
30 * @dp: Pointer to the current device path node.
31 * Return: Pointer to the next device path node, or NULL if at the end
32 * or if input is NULL.
33 */
34struct efi_device_path *efi_dp_next(const struct efi_device_path *dp);
35
36/**
37 * efi_dp_match() - Compare two device-paths
38 *
39 * Compare two device paths node by node. The comparison stops when an End
40 * node is reached in the shorter of the two paths. This is useful, for example,
41 * to compare a device-path representing a device with one representing a file
42 * on that device, or a device with a parent device.
43 *
44 * @a: Pointer to the first device path.
45 * @b: Pointer to the second device path.
46 * Return: An integer less than, equal to, or greater than zero if the first
47 * differing node in 'a' is found, respectively, to be less than,
48 * to match, or be greater than the corresponding node in 'b'. Returns 0
49 * if they match up to the end of the shorter path. Compares length first,
50 * then content.
51 */
52int efi_dp_match(const struct efi_device_path *a,
53 const struct efi_device_path *b);
54
55/**
56 * efi_dp_shorten() - shorten device-path
57 *
58 * When creating a short-boot option we want to use a device-path that is
59 * independent of the location where the block device is plugged in.
60 *
61 * UsbWwi() nodes contain a serial number, hard drive paths a partition
62 * UUID. Both should be unique.
63 *
64 * See UEFI spec, section 3.1.2 for "short-form device path".
65 *
66 * @dp: original device-path
67 * Return: shortened device-path or NULL
68 */
69struct efi_device_path *efi_dp_shorten(struct efi_device_path *dp);
70
71/**
72 * efi_dp_find_obj() - find handle by device path
73 *
74 * If @rem is provided, the handle with the longest partial match is returned.
75 *
76 * @dp: device path to search
77 * @guid: GUID of protocol that must be installed on path or NULL
78 * @rem: pointer to receive remaining device path
79 * Return: matching handle
80 */
81efi_handle_t efi_dp_find_obj(struct efi_device_path *dp, const efi_guid_t *guid,
82 struct efi_device_path **rem);
83
84/**
85 * efi_dp_last_node() - Determine the last device path node before the end node
86 *
87 * Iterate through the device path to find the very last node before
88 * the terminating END node.
89 *
90 * @dp: Pointer to the device path.
91 * Return: Pointer to the last actual data node before the end node if it exists
92 * otherwise NULL (e.g., if dp is NULL or only an END node).
93 */
94const struct efi_device_path *efi_dp_last_node(const struct efi_device_path *dp);
95
96/**
97 * efi_dp_instance_size() - Get size of the first device path instance
98 *
99 * Calculate the total length of all nodes in the first instance of a
100 * (potentially multi-instance) device path. The size of the instance-specific
101 * end node (if any) or the final device path. The end node is not included.
102 *
103 * @dp: Pointer to the device path.
104 * Return: Size in bytes of the first instance, or 0 if dp is NULL or an END
105 * node
106 */
107efi_uintn_t efi_dp_instance_size(const struct efi_device_path *dp);
108
109/**
110 * efi_dp_size() - Get size of multi-instance device path excluding end node
111 *
112 * Calculate the total size of the entire device path structure, traversing
113 * through all instances, up to but not including the final
114 * END_ENTIRE_DEVICE_PATH node.
115 *
116 * @dp: Pointer to the device path.
117 * Return: Total size in bytes of all nodes in the device path (excluding the
118 * final END node), or 0 if dp is NULL.
119 */
120efi_uintn_t efi_dp_size(const struct efi_device_path *dp);
121
122/**
123 * efi_dp_dup() - Copy multi-instance device path
124 *
125 * Duplicate the given device path, including its end node(s).
126 * The caller is responsible for freeing the allocated memory (e.g.,
127 * using efi_free()).
128 *
129 * @dp: Pointer to the device path to duplicate.
130 * Return: Pointer to the newly allocated and copied device path, or NULL on
131 * allocation failure or if dp is NULL.
132 */
133struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp);
134
135/**
136 * efi_dp_concat() - Concatenate two device paths and terminate the result
137 *
138 * @dp1: First device path
139 * @dp2: Second device path
140 * @split_end_node:
141 * - 0 to concatenate (dp1 is assumed not to have an end node or it's ignored,
142 * dp2 is appended, then one END node)
143 * - 1 to concatenate with end node added as separator (dp1, END_THIS_INSTANCE,
144 * dp2, END_ENTIRE)
145 *
146 * Size of dp1 excluding last end node to concatenate with end node as
147 * separator in case dp1 contains an end node (dp1 (partial), END_THIS_INSTANCE,
148 * dp2, END_ENTIRE)
149 *
150 * Return:
151 * concatenated device path or NULL. Caller must free the returned value.
152 */
153struct efi_device_path *efi_dp_concat(const struct efi_device_path *dp1,
154 const struct efi_device_path *dp2,
155 size_t split_end_node);
156
157/**
158 * efi_dp_append_node() - Append a single node to a device path
159 *
160 * Create a new device path by appending a given node to an existing
161 * device path.
162 * If the original device path @dp is NULL, a new path is created
163 * with the given @node followed by an END node.
164 * If the @node is NULL and @dp is not NULL, the original path @dp is
165 * duplicated.
166 * If both @dp and @node are NULL, a path with only an END node is returned.
167 * The caller must free the returned path (e.g., using efi_free()).
168 *
169 * @dp: Original device path (can be NULL).
170 * @node: Node to append (can be NULL).
171 * Return: New device path with the node appended, or NULL on allocation
172 * failure.
173 */
174struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp,
175 const struct efi_device_path *node);
176
177/**
178 * efi_dp_create_device_node() - Create a new device path node
179 *
180 * Allocate and initialise the header of a new EFI device path node with the
181 * given type, sub-type, and length. The content of the node beyond the basic
182 * efi_device_path header is zeroed by efi_alloc.
183 *
184 * @type: Device path type.
185 * @sub_type: Device path sub-type.
186 * @length: Length of the node (must be >= sizeof(struct efi_device_path)).
187 * Return: Pointer to the new device path node, or NULL on allocation failure
188 * or if length is invalid.
189 */
190struct efi_device_path *efi_dp_create_device_node(const u8 type,
191 const u8 sub_type,
192 const u16 length);
193
194/**
195 * efi_dp_append_instance() - Append a device path instance to another
196 *
197 * Concatenate two device paths, treating the second path (@dpi) as a new
198 * instance appended to the first path (@dp). An END_THIS_INSTANCE node is
199 * inserted between @dp and @dpi if @dp is not NULL.
200 * If @dp is NULL, @dpi is duplicated (and terminated appropriately).
201 * @dpi must not be NULL.
202 * The caller is responsible for freeing the returned path (e.g., using
203 * efi_free()).
204 *
205 * @dp: The base device path. If NULL, @dpi is duplicated.
206 * @dpi: The device path instance to append. Must not be NULL.
207 * Return: A new device path with @dpi appended as a new instance, or NULL on
208 * error (e.g. allocation failure, @dpi is NULL).
209 */
210struct efi_device_path *
211efi_dp_append_instance(const struct efi_device_path *dp,
212 const struct efi_device_path *dpi);
213
214/**
215 * efi_dp_get_next_instance() - Extract the next dp instance
216 *
217 * Given a pointer to a pointer to a device path (@dp), this function extracts
218 * the first instance from the path. It allocates a new path for this extracted
219 * instance (including its instance-specific END node). The input pointer
220 * (*@dp) is then updated to point to the start of the next instance in the
221 * original path, or set to NULL if no more instances remain.
222 * The caller is responsible for freeing the returned instance path (e.g.,
223 * using efi_free()).
224 *
225 * @dp: On input, a pointer to a pointer to the multi-instance device path.
226 * On output, *@dp is updated to point to the start of the next instance,
227 * or NULL if no more instances.
228 * @size: Optional pointer to an efi_uintn_t variable that will receive the size
229 * of the extracted instance path (including its END node).
230 * Return: Pointer to a newly allocated device path for the extracted instance,
231 * or NULL if no instance could be extracted or an error occurred (e.g.,
232 * allocation failure).
233 */
234struct efi_device_path *efi_dp_get_next_instance(struct efi_device_path **dp,
235 efi_uintn_t *size);
236
237/**
238 * efi_dp_is_multi_instance() - Check if a device path is multi-instance
239 *
240 * Traverse the device path to its end. It is considered multi-instance if an
241 * END_THIS_INSTANCE_DEVICE_PATH node (type DEVICE_PATH_TYPE_END, sub-type
242 * DEVICE_PATH_SUB_TYPE_INSTANCE_END) is encountered before the final
243 * END_ENTIRE_DEVICE_PATH node.
244 *
245 * @dp: The device path to check.
246 * Return: True if the device path contains multiple instances, false otherwise
247 * (including if @dp is NULL).
248 */
249bool efi_dp_is_multi_instance(const struct efi_device_path *dp);
250
251/**
252 * efi_dp_from_part() - Construct a dp from a partition on a block device
253 *
254 * Create a full device path for a specified partition on a given block device.
255 * If the partition number @part is 0, the path is for the block device itself.
256 * The caller is responsible for freeing the allocated memory (e.g., using
257 * efi_free()).
258 *
259 * @desc: Pointer to the block device descriptor.
260 * @part: Partition number (0 for the whole device, >0 for a specific
261 * partition).
262 * Return: Pointer to the newly created device path, or NULL on allocation
263 * failure or if the device/partition is not found or invalid.
264 */
265struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part);
266
267/**
268 * efi_dp_part_node() - Create a device node for a block device partition
269 *
270 * Creates a single device path node representing a specific partition
271 * (e.g., HardDrivePath or CDROMPath, depending on desc->part_type).
272 * It does not create the full path from the root, only the partition-specific
273 * node. The caller is responsible for freeing the allocated memory (e.g.,
274 * using efi_free()).
275 *
276 * @desc: Pointer to the block device descriptor.
277 * @part: Partition number (must be > 0 and correspond to a valid partition on
278 * the device).
279 * Return: Pointer to the new device path node for the partition, or NULL on
280 * allocation * failure or error in getting partition information.
281 */
282struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part);
283
284/**
285 * efi_dp_from_file() - append file path node to device path.
286 *
287 * @dp: device path or NULL
288 * @path: file path or NULL
289 * Return: device path or NULL in case of an error
290 */
291struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
292 const char *path);
293
294/**
295 * efi_dp_from_uart() - Create a device path for a UART device.
296 *
297 * Construct a device path representing the system's default UART,
298 * typically based on the U-Boot device model root and a UART messaging node.
299 * The caller is responsible for freeing the allocated memory (e.g., using
300 * efi_free()).
301 *
302 * Return: Pointer to the new UART device path, or NULL on allocation failure.
303 */
304struct efi_device_path *efi_dp_from_uart(void);
305
306/**
307 * efi_dp_from_eth() - Create a device path for an Ethernet device
308 *
309 * Construct a device path representing the given device. The caller is
310 * responsible for freeing the allocated memory (e.g. using efi_free())
311 *
312 * @dev: UCLASS_ETH device to process
313 *
314 * Return: Pointer to the new Ethernet device path, or NULL on allocation
315 * failure
316 */
317struct efi_device_path *efi_dp_from_eth(struct udevice *dev);
318
319/**
320 * efi_dp_from_mem() - Construct a device-path for a memory-mapped region
321 *
322 * Create an EFI device path representing a specific memory region, defined
323 * by its type, start address, and size.
324 * The caller is responsible for freeing the allocated memory (e.g.,
325 * using efi_free()).
326 *
327 * @memory_type: EFI memory type (e.g., EFI_RESERVED_MEMORY_TYPE).
328 * @start_address: Starting address of the memory region.
329 * @size: Size of the memory region in bytes.
330 * Return: Pointer to the new memory device path, or NULL on allocation failure
331 */
332struct efi_device_path *efi_dp_from_mem(u32 memory_type, u64 start_address,
333 size_t size);
334
335/**
336 * efi_dp_split_file_path() - split of relative file path from device path
337 *
338 * Given a device path indicating a file on a device, separate the device
339 * path in two: the device path of the actual device and the file path
340 * relative to this device.
341 *
342 * @full_path: device path including device and file path
343 * @device_path: path of the device
344 * @file_path: relative path of the file or NULL if there is none
345 * Return: status code
346 */
347efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path,
348 struct efi_device_path **device_path,
349 struct efi_device_path **file_path);
350
351/**
352 * efi_dp_from_name() - convert U-Boot device and file path to device path
353 *
354 * @dev: U-Boot device, e.g. 'mmc'
355 * @devnr: U-Boot device number, e.g. 1 for 'mmc:1'
356 * @path: file path relative to U-Boot device, may be NULL
357 * @device: pointer to receive device path of the device
358 * @file: pointer to receive device path for the file
359 * Return: status code
360 */
361efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
362 const char *path, struct efi_device_path **device,
363 struct efi_device_path **file);
364
365/**
366 * efi_dp_check_length() - check length of a device path
367 *
368 * @dp: pointer to device path
369 * @maxlen: maximum length of the device path
370 * Return:
371 * * length of the device path if it is less or equal @maxlen
372 * * -1 if the device path is longer then @maxlen
373 * * -1 if a device path node has a length of less than 4
374 * * -EINVAL if maxlen exceeds SSIZE_MAX
375 */
376ssize_t efi_dp_check_length(const struct efi_device_path *dp,
377 const size_t maxlen);
378
379/**
380 * efi_dp_from_lo() - get device-path from load option
381 *
382 * The load options in U-Boot may contain multiple concatenated device-paths.
383 * The first device-path indicates the EFI binary to execute. Subsequent
384 * device-paths start with a VenMedia node where the GUID identifies the
385 * function (initrd or fdt).
386 *
387 * @lo: EFI load option containing a valid device path
388 * @guid: GUID identifying device-path or NULL for the EFI binary
389 *
390 * Return:
391 * device path excluding the matched VenMedia node or NULL.
392 * Caller must free the returned value.
393 */
394struct efi_device_path *efi_dp_from_lo(struct efi_load_option *lo,
395 const efi_guid_t *guid);
396
397/**
398 * search_gpt_dp_node() - search gpt device path node
399 *
400 * @device_path: device path
401 *
402 * Return: pointer to the gpt device path node
403 */
404struct efi_device_path *search_gpt_dp_node(struct efi_device_path *device_path);
405
406/**
407 * efi_dp_from_http() - set device path from http
408 *
409 * Set the device path to an IPv4 path as provided by efi_dp_from_ipv4
410 * concatenated with a device path of subtype DEVICE_PATH_SUB_TYPE_MSG_URI,
411 * and an END node.
412 *
413 * @server: URI of remote server
414 * @dev: net udevice
415 * Return: pointer to HTTP device path, NULL on error
416 */
417struct efi_device_path *efi_dp_from_http(const char *server,
418 struct udevice *dev);
419
420#endif /* EFI_DEVICE_PATH_H */