Merge branch 'master' of git://source.denx.de/u-boot-usb
diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c
index ec52992..d7f183f 100644
--- a/arch/x86/lib/tables.c
+++ b/arch/x86/lib/tables.c
@@ -126,6 +126,8 @@
 			use_high = true;
 			if (!gd->arch.table_start_high)
 				gd->arch.table_start_high = rom_addr;
+			if (table->tag == BLOBLISTT_SMBIOS_TABLES)
+				gd_set_smbios_start(rom_addr);
 		}
 		rom_table_end = table->write(rom_addr);
 		if (!rom_table_end) {
diff --git a/board/emulation/qemu-x86/Kconfig b/board/emulation/qemu-x86/Kconfig
index b2a4e08..c1564fb 100644
--- a/board/emulation/qemu-x86/Kconfig
+++ b/board/emulation/qemu-x86/Kconfig
@@ -23,5 +23,6 @@
 	imply VIRTIO_PCI
 	imply VIRTIO_NET
 	imply VIRTIO_BLK
+	imply CMD_SMBIOS
 
 endif
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index cea6d35..8e87521 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -9,6 +9,7 @@
 
 #include <command.h>
 #include <efi.h>
+#include <efi_device_path.h>
 #include <efi_loader.h>
 #include <exports.h>
 #include <log.h>
diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c
index 629bf1b..6e14d34 100644
--- a/cmd/eficonfig.c
+++ b/cmd/eficonfig.c
@@ -8,6 +8,7 @@
 #include <ansi.h>
 #include <cli.h>
 #include <charset.h>
+#include <efi_device_path.h>
 #include <efi_loader.h>
 #include <efi_load_initrd.h>
 #include <efi_config.h>
@@ -514,7 +515,7 @@
 	struct efi_device_path_file_path *fp;
 
 	fp_size = sizeof(struct efi_device_path) + u16_strsize(current_path);
-	buf = calloc(1, fp_size + sizeof(END));
+	buf = calloc(1, fp_size + sizeof(EFI_DP_END));
 	if (!buf)
 		return NULL;
 
@@ -526,7 +527,7 @@
 
 	p = buf;
 	p += fp_size;
-	*((struct efi_device_path *)p) = END;
+	*((struct efi_device_path *)p) = EFI_DP_END;
 
 	dp = efi_dp_shorten(dp_volume);
 	if (!dp)
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index 2461425..109496d 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -8,6 +8,7 @@
 #include <charset.h>
 #include <command.h>
 #include <dm/device.h>
+#include <efi_device_path.h>
 #include <efi_dt_fixup.h>
 #include <efi_load_initrd.h>
 #include <efi_loader.h>
@@ -812,7 +813,7 @@
 	lo->label = label;
 
 	uridp_len = sizeof(struct efi_device_path) + strlen(argv[3]) + 1;
-	uridp = efi_alloc(uridp_len + sizeof(END));
+	uridp = efi_alloc(uridp_len + sizeof(EFI_DP_END));
 	if (!uridp) {
 		log_err("Out of memory\n");
 		return CMD_RET_FAILURE;
@@ -822,10 +823,10 @@
 	uridp->dp.length = uridp_len;
 	strcpy(uridp->uri, argv[3]);
 	pos = (char *)uridp + uridp_len;
-	memcpy(pos, &END, sizeof(END));
+	memcpy(pos, &EFI_DP_END, sizeof(EFI_DP_END));
 
 	*file_path = &uridp->dp;
-	*fp_size += uridp_len + sizeof(END);
+	*fp_size += uridp_len + sizeof(EFI_DP_END);
 
 	return CMD_RET_SUCCESS;
 }
diff --git a/doc/api/efi.rst b/doc/api/efi.rst
index 43d6f93..a98298f 100644
--- a/doc/api/efi.rst
+++ b/doc/api/efi.rst
@@ -178,6 +178,12 @@
 .. kernel-doc:: include/efi_driver.h
    :internal:
 
+Device paths
+------------
+
+.. kernel-doc:: include/efi_device_path.h
+   :internal:
+
 Unit testing
 ------------
 
diff --git a/include/efi_device_path.h b/include/efi_device_path.h
new file mode 100644
index 0000000..aae8522
--- /dev/null
+++ b/include/efi_device_path.h
@@ -0,0 +1,421 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * EFI device path functions
+ *
+ * (C) Copyright 2017 Rob Clark
+ */
+
+#ifndef EFI_DEVICE_PATH_H
+#define EFI_DEVICE_PATH_H
+
+#include <efi.h>
+
+struct blk_desc;
+struct efi_load_option;
+struct udevice;
+
+/*
+ * EFI_DP_END - Template end node for EFI device paths.
+ *
+ * Represents the terminating node of an EFI device path.
+ * It has a type of DEVICE_PATH_TYPE_END and sub_type DEVICE_PATH_SUB_TYPE_END
+ */
+extern const struct efi_device_path EFI_DP_END;
+
+/**
+ * efi_dp_next() - Iterate to next block in device-path
+ *
+ * Advance to the next node in an EFI device path.
+ *
+ * @dp: Pointer to the current device path node.
+ * Return: Pointer to the next device path node, or NULL if at the end
+ * or if input is NULL.
+ */
+struct efi_device_path *efi_dp_next(const struct efi_device_path *dp);
+
+/**
+ * efi_dp_match() - Compare two device-paths
+ *
+ * Compare two device paths node by node. The comparison stops when an End
+ * node is reached in the shorter of the two paths. This is useful, for example,
+ * to compare a device-path representing a device with one representing a file
+ * on that device, or a device with a parent device.
+ *
+ * @a: Pointer to the first device path.
+ * @b: Pointer to the second device path.
+ * Return: An integer less than, equal to, or greater than zero if the first
+ * differing node in 'a' is found, respectively, to be less than,
+ * to match, or be greater than the corresponding node in 'b'. Returns 0
+ * if they match up to the end of the shorter path. Compares length first,
+ * then content.
+ */
+int efi_dp_match(const struct efi_device_path *a,
+		 const struct efi_device_path *b);
+
+/**
+ * efi_dp_shorten() - shorten device-path
+ *
+ * When creating a short-boot option we want to use a device-path that is
+ * independent of the location where the block device is plugged in.
+ *
+ * UsbWwi() nodes contain a serial number, hard drive paths a partition
+ * UUID. Both should be unique.
+ *
+ * See UEFI spec, section 3.1.2 for "short-form device path".
+ *
+ * @dp:     original device-path
+ * Return:  shortened device-path or NULL
+ */
+struct efi_device_path *efi_dp_shorten(struct efi_device_path *dp);
+
+/**
+ * efi_dp_find_obj() - find handle by device path
+ *
+ * If @rem is provided, the handle with the longest partial match is returned.
+ *
+ * @dp:     device path to search
+ * @guid:   GUID of protocol that must be installed on path or NULL
+ * @rem:    pointer to receive remaining device path
+ * Return:  matching handle
+ */
+efi_handle_t efi_dp_find_obj(struct efi_device_path *dp, const efi_guid_t *guid,
+			     struct efi_device_path **rem);
+
+/**
+ * efi_dp_last_node() - Determine the last device path node before the end node
+ *
+ * Iterate through the device path to find the very last node before
+ * the terminating EFI_DP_END node.
+ *
+ * @dp: Pointer to the device path.
+ * Return: Pointer to the last actual data node before the end node if it exists
+ * otherwise NULL (e.g., if dp is NULL or only an EFI_DP_END node).
+ */
+const struct efi_device_path *efi_dp_last_node(const struct efi_device_path *dp);
+
+/**
+ * efi_dp_instance_size() - Get size of the first device path instance
+ *
+ * Calculate the total length of all nodes in the first instance of a
+ * (potentially multi-instance) device path. The size of the instance-specific
+ * end node (if any) or the final device path. The end node is not included.
+ *
+ * @dp: Pointer to the device path.
+ * Return: Size in bytes of the first instance, or 0 if dp is NULL or an
+ * EFI_DP_END node
+ */
+efi_uintn_t efi_dp_instance_size(const struct efi_device_path *dp);
+
+/**
+ * efi_dp_size() - Get size of multi-instance device path excluding end node
+ *
+ * Calculate the total size of the entire device path structure, traversing
+ * through all instances, up to but not including the final
+ * END_ENTIRE_DEVICE_PATH node.
+ *
+ * @dp: Pointer to the device path.
+ * Return: Total size in bytes of all nodes in the device path (excluding the
+ * final EFI_DP_END node), or 0 if dp is NULL.
+ */
+efi_uintn_t efi_dp_size(const struct efi_device_path *dp);
+
+/**
+ * efi_dp_dup() - Copy multi-instance device path
+ *
+ * Duplicate the given device path, including its end node(s).
+ * The caller is responsible for freeing the allocated memory (e.g.,
+ * using efi_free()).
+ *
+ * @dp: Pointer to the device path to duplicate.
+ * Return: Pointer to the newly allocated and copied device path, or NULL on
+ * allocation failure or if dp is NULL.
+ */
+struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp);
+
+/**
+ * efi_dp_concat() - Concatenate two device paths and terminate the result
+ *
+ * @dp1:        First device path
+ * @dp2:        Second device path
+ * @split_end_node:
+ * - 0 to concatenate (dp1 is assumed not to have an end node or it's ignored,
+ *   dp2 is appended, then one EFI_DP_END node)
+ * - 1 to concatenate with end node added as separator (dp1, END_THIS_INSTANCE,
+ *   dp2, END_ENTIRE)
+ *
+ * Size of dp1 excluding last end node to concatenate with end node as
+ * separator in case dp1 contains an end node (dp1 (partial), END_THIS_INSTANCE,
+ * dp2, END_ENTIRE)
+ *
+ * Return:
+ * concatenated device path or NULL. Caller must free the returned value.
+ */
+struct efi_device_path *efi_dp_concat(const struct efi_device_path *dp1,
+				      const struct efi_device_path *dp2,
+				      size_t split_end_node);
+
+/**
+ * efi_dp_append_node() - Append a single node to a device path
+ *
+ * Create a new device path by appending a given node to an existing
+ * device path.
+ * If the original device path @dp is NULL, a new path is created
+ * with the given @node followed by an EFI_DP_END node.
+ * If the @node is NULL and @dp is not NULL, the original path @dp is
+ * duplicated.
+ * If both @dp and @node are NULL, a path with only an EFI_DP_END node is
+ * returned.
+ * The caller must free the returned path (e.g., using efi_free()).
+ *
+ * @dp:   Original device path (can be NULL).
+ * @node: Node to append (can be NULL).
+ * Return: New device path with the node appended, or NULL on allocation
+ * failure.
+ */
+struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp,
+					   const struct efi_device_path *node);
+
+/**
+ * efi_dp_create_device_node() - Create a new device path node
+ *
+ * Allocate and initialise the header of a new EFI device path node with the
+ * given type, sub-type, and length. The content of the node beyond the basic
+ * efi_device_path header is zeroed by efi_alloc.
+ *
+ * @type:     Device path type.
+ * @sub_type: Device path sub-type.
+ * @length:   Length of the node (must be >= sizeof(struct efi_device_path)).
+ * Return: Pointer to the new device path node, or NULL on allocation failure
+ * or if length is invalid.
+ */
+struct efi_device_path *efi_dp_create_device_node(const u8 type,
+						  const u8 sub_type,
+						  const u16 length);
+
+/**
+ * efi_dp_append_instance() - Append a device path instance to another
+ *
+ * Concatenate two device paths, treating the second path (@dpi) as a new
+ * instance appended to the first path (@dp). An END_THIS_INSTANCE node is
+ * inserted between @dp and @dpi if @dp is not NULL.
+ * If @dp is NULL, @dpi is duplicated (and terminated appropriately).
+ * @dpi must not be NULL.
+ * The caller is responsible for freeing the returned path (e.g., using
+ * efi_free()).
+ *
+ * @dp:  The base device path. If NULL, @dpi is duplicated.
+ * @dpi: The device path instance to append. Must not be NULL.
+ * Return: A new device path with @dpi appended as a new instance, or NULL on
+ * error  (e.g. allocation failure, @dpi is NULL).
+ */
+struct efi_device_path *
+efi_dp_append_instance(const struct efi_device_path *dp,
+		       const struct efi_device_path *dpi);
+
+/**
+ * efi_dp_get_next_instance() - Extract the next dp instance
+ *
+ * Given a pointer to a pointer to a device path (@dp), this function extracts
+ * the first instance from the path. It allocates a new path for this extracted
+ * instance (including its instance-specific EFI_DP_END node). The input pointer
+ * (*@dp) is then updated to point to the start of the next instance in the
+ * original path, or set to NULL if no more instances remain.
+ * The caller is responsible for freeing the returned instance path (e.g.,
+ * using efi_free()).
+ *
+ * @dp:  On input, a pointer to a pointer to the multi-instance device path.
+ * On output, *@dp is updated to point to the start of the next instance,
+ * or NULL if no more instances.
+ * @size: Optional pointer to an efi_uintn_t variable that will receive the size
+ * of the extracted instance path (including its EFI_DP_END node).
+ * Return: Pointer to a newly allocated device path for the extracted instance,
+ * or NULL if no instance could be extracted or an error occurred (e.g.,
+ * allocation failure).
+ */
+struct efi_device_path *efi_dp_get_next_instance(struct efi_device_path **dp,
+						 efi_uintn_t *size);
+
+/**
+ * efi_dp_is_multi_instance() - Check if a device path is multi-instance
+ *
+ * Traverse the device path to its end. It is considered multi-instance if an
+ * END_THIS_INSTANCE_DEVICE_PATH node (type DEVICE_PATH_TYPE_END, sub-type
+ * DEVICE_PATH_SUB_TYPE_INSTANCE_END) is encountered before the final
+ * END_ENTIRE_DEVICE_PATH node.
+ *
+ * @dp: The device path to check.
+ * Return: True if the device path contains multiple instances, false otherwise
+ * (including if @dp is NULL).
+ */
+bool efi_dp_is_multi_instance(const struct efi_device_path *dp);
+
+/**
+ * efi_dp_from_part() - Construct a dp from a partition on a block device
+ *
+ * Create a full device path for a specified partition on a given block device.
+ * If the partition number @part is 0, the path is for the block device itself.
+ * The caller is responsible for freeing the allocated memory (e.g., using
+ * efi_free()).
+ *
+ * @desc: Pointer to the block device descriptor.
+ * @part: Partition number (0 for the whole device, >0 for a specific
+ * partition).
+ * Return: Pointer to the newly created device path, or NULL on allocation
+ * failure or if the device/partition is not found or invalid.
+ */
+struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part);
+
+/**
+ * efi_dp_part_node() - Create a device node for a block device partition
+ *
+ * Creates a single device path node representing a specific partition
+ * (e.g., HardDrivePath or CDROMPath, depending on desc->part_type).
+ * It does not create the full path from the root, only the partition-specific
+ * node. The caller is responsible for freeing the allocated memory (e.g.,
+ * using efi_free()).
+ *
+ * @desc: Pointer to the block device descriptor.
+ * @part: Partition number (must be > 0 and correspond to a valid partition on
+ * the device).
+ * Return: Pointer to the new device path node for the partition, or NULL on
+ * allocation * failure or error in getting partition information.
+ */
+struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part);
+
+/**
+ * efi_dp_from_file() - append file path node to device path.
+ *
+ * @dp:     device path or NULL
+ * @path:   file path or NULL
+ * Return:  device path or NULL in case of an error
+ */
+struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
+					 const char *path);
+
+/**
+ * efi_dp_from_uart() - Create a device path for a UART device.
+ *
+ * Construct a device path representing the system's default UART,
+ * typically based on the U-Boot device model root and a UART messaging node.
+ * The caller is responsible for freeing the allocated memory (e.g., using
+ * efi_free()).
+ *
+ * Return: Pointer to the new UART device path, or NULL on allocation failure.
+ */
+struct efi_device_path *efi_dp_from_uart(void);
+
+/**
+ * efi_dp_from_eth() - Create a device path for an Ethernet device
+ *
+ * Construct a device path representing the given device. The caller is
+ * responsible for freeing the allocated memory (e.g. using efi_free())
+ *
+ * @dev: UCLASS_ETH device to process
+ *
+ * Return: Pointer to the new Ethernet device path, or NULL on allocation
+ * failure
+ */
+struct efi_device_path *efi_dp_from_eth(struct udevice *dev);
+
+/**
+ * efi_dp_from_mem() - Construct a device-path for a memory-mapped region
+ *
+ * Create an EFI device path representing a specific memory region, defined
+ * by its type, start address, and size.
+ * The caller is responsible for freeing the allocated memory (e.g.,
+ * using efi_free()).
+ *
+ * @memory_type: EFI memory type (e.g., EFI_RESERVED_MEMORY_TYPE).
+ * @start_address: Starting address of the memory region.
+ * @size: Size of the memory region in bytes.
+ * Return: Pointer to the new memory device path, or NULL on allocation failure
+ */
+struct efi_device_path *efi_dp_from_mem(u32 memory_type, u64 start_address,
+					size_t size);
+
+/**
+ * efi_dp_split_file_path() - split of relative file path from device path
+ *
+ * Given a device path indicating a file on a device, separate the device
+ * path in two: the device path of the actual device and the file path
+ * relative to this device.
+ *
+ * @full_path:      device path including device and file path
+ * @device_path:    path of the device
+ * @file_path:      relative path of the file or NULL if there is none
+ * Return:      status code
+ */
+efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path,
+				    struct efi_device_path **device_path,
+				    struct efi_device_path **file_path);
+
+/**
+ * efi_dp_from_name() - convert U-Boot device and file path to device path
+ *
+ * @dev:    U-Boot device, e.g. 'mmc'
+ * @devnr:  U-Boot device number, e.g. 1 for 'mmc:1'
+ * @path:   file path relative to U-Boot device, may be NULL
+ * @device: pointer to receive device path of the device
+ * @file:   pointer to receive device path for the file
+ * Return:  status code
+ */
+efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
+			      const char *path, struct efi_device_path **device,
+			      struct efi_device_path **file);
+
+/**
+ * efi_dp_check_length() - check length of a device path
+ *
+ * @dp:     pointer to device path
+ * @maxlen: maximum length of the device path
+ * Return:
+ * * length of the device path if it is less or equal @maxlen
+ * * -1 if the device path is longer then @maxlen
+ * * -1 if a device path node has a length of less than 4
+ * * -EINVAL if maxlen exceeds SSIZE_MAX
+ */
+ssize_t efi_dp_check_length(const struct efi_device_path *dp,
+			    const size_t maxlen);
+
+/**
+ * efi_dp_from_lo() - get device-path from load option
+ *
+ * The load options in U-Boot may contain multiple concatenated device-paths.
+ * The first device-path indicates the EFI binary to execute. Subsequent
+ * device-paths start with a VenMedia node where the GUID identifies the
+ * function (initrd or fdt).
+ *
+ * @lo:     EFI load option containing a valid device path
+ * @guid:   GUID identifying device-path or NULL for the EFI binary
+ *
+ * Return:
+ * device path excluding the matched VenMedia node or NULL.
+ * Caller must free the returned value.
+ */
+struct efi_device_path *efi_dp_from_lo(struct efi_load_option *lo,
+				       const efi_guid_t *guid);
+
+/**
+ * search_gpt_dp_node() - search gpt device path node
+ *
+ * @device_path:    device path
+ *
+ * Return:  pointer to the gpt device path node
+ */
+struct efi_device_path *search_gpt_dp_node(struct efi_device_path *device_path);
+
+/**
+ * efi_dp_from_http() - set device path from http
+ *
+ * Set the device path to an IPv4 path as provided by efi_dp_from_ipv4
+ * concatenated with a device path of subtype DEVICE_PATH_SUB_TYPE_MSG_URI,
+ * and an EFI_DP_END node.
+ *
+ * @server:	URI of remote server
+ * @dev:	net udevice
+ * Return:	pointer to HTTP device path, NULL on error
+ */
+struct efi_device_path *efi_dp_from_http(const char *server,
+					 struct udevice *dev);
+
+#endif /* EFI_DEVICE_PATH_H */
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 8f9f2bc..b3beda5 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -9,6 +9,7 @@
 #define _EFI_LOADER_H 1
 
 #include <blk.h>
+#include <efi_device_path.h>
 #include <event.h>
 #include <log.h>
 #include <part_efi.h>
@@ -935,66 +936,10 @@
 #define EFI_LOADER_BOUNCE_BUFFER_SIZE (64 * 1024 * 1024)
 #endif
 
-/* shorten device path */
-struct efi_device_path *efi_dp_shorten(struct efi_device_path *dp);
-struct efi_device_path *efi_dp_next(const struct efi_device_path *dp);
-int efi_dp_match(const struct efi_device_path *a,
-		 const struct efi_device_path *b);
-efi_handle_t efi_dp_find_obj(struct efi_device_path *dp,
-			     const efi_guid_t *guid,
-			     struct efi_device_path **rem);
-/* get size of the first device path instance excluding end node */
-efi_uintn_t efi_dp_instance_size(const struct efi_device_path *dp);
-/* size of multi-instance device path excluding end node */
-efi_uintn_t efi_dp_size(const struct efi_device_path *dp);
-struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp);
-struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp,
-					   const struct efi_device_path *node);
-/* Create a device path node of given type, sub-type, length */
-struct efi_device_path *efi_dp_create_device_node(const u8 type,
-						  const u8 sub_type,
-						  const u16 length);
-/* Append device path instance */
-struct efi_device_path *efi_dp_append_instance(
-		const struct efi_device_path *dp,
-		const struct efi_device_path *dpi);
-/* Get next device path instance */
-struct efi_device_path *efi_dp_get_next_instance(struct efi_device_path **dp,
-						 efi_uintn_t *size);
-/* Check if a device path contains muliple instances */
-bool efi_dp_is_multi_instance(const struct efi_device_path *dp);
-
-struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part);
-/* Create a device node for a block device partition. */
-struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part);
-struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
-					 const char *path);
-struct efi_device_path *efi_dp_from_eth(struct udevice *dev);
-struct efi_device_path *efi_dp_from_http(const char *server, struct udevice *dev);
-struct efi_device_path *efi_dp_from_mem(uint32_t mem_type,
-					uint64_t start_address,
-					size_t size);
-/* Determine the last device path node that is not the end node. */
-const struct efi_device_path *efi_dp_last_node(
-			const struct efi_device_path *dp);
-efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path,
-				    struct efi_device_path **device_path,
-				    struct efi_device_path **file_path);
-struct efi_device_path *efi_dp_from_uart(void);
-efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
-			      const char *path,
-			      struct efi_device_path **device,
-			      struct efi_device_path **file);
-ssize_t efi_dp_check_length(const struct efi_device_path *dp,
-			    const size_t maxlen);
-
 #define EFI_DP_TYPE(_dp, _type, _subtype) \
 	(((_dp)->type == DEVICE_PATH_TYPE_##_type) && \
 	 ((_dp)->sub_type == DEVICE_PATH_SUB_TYPE_##_subtype))
 
-/* template END node: */
-extern const struct efi_device_path END;
-
 /* Indicate supported runtime services */
 efi_status_t efi_init_runtime_supported(void);
 
diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c
index 495be53..7392c60 100644
--- a/lib/efi_driver/efi_uclass.c
+++ b/lib/efi_driver/efi_uclass.c
@@ -20,6 +20,7 @@
 #define LOG_CATEGORY LOGC_EFI
 
 #include <dm.h>
+#include <efi_device_path.h>
 #include <efi_driver.h>
 #include <log.h>
 #include <malloc.h>
diff --git a/lib/efi_loader/efi_bootbin.c b/lib/efi_loader/efi_bootbin.c
index 94ba7c5..b394f0d 100644
--- a/lib/efi_loader/efi_bootbin.c
+++ b/lib/efi_loader/efi_bootbin.c
@@ -10,6 +10,7 @@
 #include <charset.h>
 #include <dm.h>
 #include <efi.h>
+#include <efi_device_path.h>
 #include <efi_loader.h>
 #include <env.h>
 #include <image.h>
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index c0df5cb..1a3461f 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -12,6 +12,7 @@
 #include <charset.h>
 #include <dm.h>
 #include <efi.h>
+#include <efi_device_path.h>
 #include <log.h>
 #include <malloc.h>
 #include <net.h>
@@ -479,6 +480,13 @@
 	if (!ctx)
 		return EFI_OUT_OF_RESOURCES;
 
+	s = env_get("ipaddr");
+	if (!s && dhcp_run(0, NULL, false)) {
+		log_err("Error: Can't find a valid IP address\n");
+		ret = EFI_DEVICE_ERROR;
+		goto err;
+	}
+
 	s = env_get("loadaddr");
 	if (!s) {
 		log_err("Error: loadaddr is not set\n");
@@ -527,7 +535,7 @@
 		 * will be freed in return_to_efibootmgr event callback.
 		 */
 		loaded_dp = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
-					    (uintptr_t)image_addr, image_size);
+					    image_addr, image_size);
 		ret = efi_install_multiple_protocol_interfaces(
 			&mem_handle, &efi_guid_device_path, loaded_dp, NULL);
 		if (ret != EFI_SUCCESS)
@@ -855,7 +863,8 @@
 		lo.label = dev_name;
 		lo.attributes = LOAD_OPTION_ACTIVE;
 		lo.file_path = device_path;
-		lo.file_path_length = efi_dp_size(device_path) + sizeof(END);
+		lo.file_path_length = efi_dp_size(device_path) +
+			sizeof(EFI_DP_END);
 		/*
 		 * Set the dedicated guid to optional_data, it is used to identify
 		 * the boot option that automatically generated by the bootmenu.
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index dbebb37..24b0e52 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -11,6 +11,7 @@
 #include <div64.h>
 #include <dm/device.h>
 #include <dm/root.h>
+#include <efi_device_path.h>
 #include <efi_loader.h>
 #include <irq_func.h>
 #include <log.h>
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index 1aa52ac..f19e78a 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -8,6 +8,7 @@
 
 #define LOG_CATEGORY LOGC_EFI
 
+#include <efi_device_path.h>
 #include <efi_loader.h>
 #include <efi_variable.h>
 #include <env.h>
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index e310f2f..953f683 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -9,6 +9,7 @@
 
 #include <ansi.h>
 #include <charset.h>
+#include <efi_device_path.h>
 #include <malloc.h>
 #include <time.h>
 #include <dm/device.h>
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index c9bf272..7316a76 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -10,6 +10,7 @@
 #include <blk.h>
 #include <dm.h>
 #include <dm/root.h>
+#include <efi_device_path.h>
 #include <log.h>
 #include <net.h>
 #include <usb.h>
@@ -21,11 +22,11 @@
 #include <asm-generic/unaligned.h>
 #include <linux/compat.h> /* U16_MAX */
 
-/* template END node: */
-const struct efi_device_path END = {
+/* template EFI_DP_END node: */
+const struct efi_device_path EFI_DP_END = {
 	.type     = DEVICE_PATH_TYPE_END,
 	.sub_type = DEVICE_PATH_SUB_TYPE_END,
-	.length   = sizeof(END),
+	.length   = sizeof(EFI_DP_END),
 };
 
 #if defined(CONFIG_MMC)
@@ -46,10 +47,6 @@
 }
 #endif
 
-/*
- * Iterate to next block in device-path, terminating (returning NULL)
- * at /End* node.
- */
 struct efi_device_path *efi_dp_next(const struct efi_device_path *dp)
 {
 	if (dp == NULL)
@@ -62,12 +59,6 @@
 	return (struct efi_device_path *)dp;
 }
 
-/*
- * Compare two device-paths, stopping when the shorter of the two hits
- * an End* node. This is useful to, for example, compare a device-path
- * representing a device with one representing a file on the device, or
- * a device with a parent device.
- */
 int efi_dp_match(const struct efi_device_path *a,
 		 const struct efi_device_path *b)
 {
@@ -90,20 +81,6 @@
 	}
 }
 
-/**
- * efi_dp_shorten() - shorten device-path
- *
- * When creating a short boot option we want to use a device-path that is
- * independent of the location where the block device is plugged in.
- *
- * UsbWwi() nodes contain a serial number, hard drive paths a partition
- * UUID. Both should be unique.
- *
- * See UEFI spec, section 3.1.2 for "short-form device path".
- *
- * @dp:		original device-path
- * Return:	shortened device-path or NULL
- */
 struct efi_device_path *efi_dp_shorten(struct efi_device_path *dp)
 {
 	while (dp) {
@@ -180,16 +157,6 @@
 	return best_handle;
 }
 
-/**
- * efi_dp_find_obj() - find handle by device path
- *
- * If @rem is provided, the handle with the longest partial match is returned.
- *
- * @dp:		device path to search
- * @guid:	GUID of protocol that must be installed on path or NULL
- * @rem:	pointer to receive remaining device path
- * Return:	matching handle
- */
 efi_handle_t efi_dp_find_obj(struct efi_device_path *dp,
 			     const efi_guid_t *guid,
 			     struct efi_device_path **rem)
@@ -204,13 +171,6 @@
 	return handle;
 }
 
-/*
- * Determine the last device path node that is not the end node.
- *
- * @dp		device path
- * Return:	last node before the end node if it exists
- *		otherwise NULL
- */
 const struct efi_device_path *efi_dp_last_node(const struct efi_device_path *dp)
 {
 	struct efi_device_path *ret;
@@ -224,7 +184,6 @@
 	return ret;
 }
 
-/* get size of the first device path instance excluding end node */
 efi_uintn_t efi_dp_instance_size(const struct efi_device_path *dp)
 {
 	efi_uintn_t sz = 0;
@@ -239,7 +198,6 @@
 	return sz;
 }
 
-/* get size of multi-instance device path excluding end node */
 efi_uintn_t efi_dp_size(const struct efi_device_path *dp)
 {
 	const struct efi_device_path *p = dp;
@@ -253,11 +211,10 @@
 	return (void *)p - (void *)dp;
 }
 
-/* copy multi-instance device path */
 struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp)
 {
 	struct efi_device_path *ndp;
-	size_t sz = efi_dp_size(dp) + sizeof(END);
+	size_t sz = efi_dp_size(dp) + sizeof(EFI_DP_END);
 
 	if (!dp)
 		return NULL;
@@ -270,21 +227,6 @@
 	return ndp;
 }
 
-/**
- * efi_dp_concat() - Concatenate two device paths and add and terminate them
- *                   with an end node.
- *
- * @dp1:	    First device path
- * @dp2:	    Second device path
- * @split_end_node:
- * * 0 to concatenate
- * * 1 to concatenate with end node added as separator
- * * size of dp1 excluding last end node to concatenate with end node as
- *   separator in case dp1 contains an end node
- *
- * Return:
- * concatenated device path or NULL. Caller must free the returned value
- */
 struct
 efi_device_path *efi_dp_concat(const struct efi_device_path *dp1,
 			       const struct efi_device_path *dp2,
@@ -295,7 +237,7 @@
 
 	if (!dp1 && !dp2) {
 		/* return an end node */
-		ret = efi_dp_dup(&END);
+		ret = efi_dp_dup(&EFI_DP_END);
 	} else if (!dp1) {
 		ret = efi_dp_dup(dp2);
 	} else if (!dp2) {
@@ -312,9 +254,9 @@
 			sz1 = split_end_node;
 
 		if (split_end_node)
-			end_size = 2 * sizeof(END);
+			end_size = 2 * sizeof(EFI_DP_END);
 		else
-			end_size = sizeof(END);
+			end_size = sizeof(EFI_DP_END);
 		p = efi_alloc(sz1 + sz2 + end_size);
 		if (!p)
 			return NULL;
@@ -323,14 +265,14 @@
 		p += sz1;
 
 		if (split_end_node) {
-			memcpy(p, &END, sizeof(END));
-			p += sizeof(END);
+			memcpy(p, &EFI_DP_END, sizeof(EFI_DP_END));
+			p += sizeof(EFI_DP_END);
 		}
 
 		/* the end node of the second device path has to be retained */
 		memcpy(p, dp2, sz2);
 		p += sz2;
-		memcpy(p, &END, sizeof(END));
+		memcpy(p, &EFI_DP_END, sizeof(EFI_DP_END));
 	}
 
 	return ret;
@@ -342,26 +284,26 @@
 	struct efi_device_path *ret;
 
 	if (!node && !dp) {
-		ret = efi_dp_dup(&END);
+		ret = efi_dp_dup(&EFI_DP_END);
 	} else if (!node) {
 		ret = efi_dp_dup(dp);
 	} else if (!dp) {
 		size_t sz = node->length;
-		void *p = efi_alloc(sz + sizeof(END));
+		void *p = efi_alloc(sz + sizeof(EFI_DP_END));
 		if (!p)
 			return NULL;
 		memcpy(p, node, sz);
-		memcpy(p + sz, &END, sizeof(END));
+		memcpy(p + sz, &EFI_DP_END, sizeof(EFI_DP_END));
 		ret = p;
 	} else {
 		/* both dp and node are non-null */
 		size_t sz = efi_dp_size(dp);
-		void *p = efi_alloc(sz + node->length + sizeof(END));
+		void *p = efi_alloc(sz + node->length + sizeof(EFI_DP_END));
 		if (!p)
 			return NULL;
 		memcpy(p, dp, sz);
 		memcpy(p + sz, node, node->length);
-		memcpy(p + sz + node->length, &END, sizeof(END));
+		memcpy(p + sz + node->length, &EFI_DP_END, sizeof(EFI_DP_END));
 		ret = p;
 	}
 
@@ -399,17 +341,17 @@
 		return efi_dp_dup(dpi);
 	sz = efi_dp_size(dp);
 	szi = efi_dp_instance_size(dpi);
-	p = efi_alloc(sz + szi + 2 * sizeof(END));
+	p = efi_alloc(sz + szi + 2 * sizeof(EFI_DP_END));
 	if (!p)
 		return NULL;
 	ret = p;
-	memcpy(p, dp, sz + sizeof(END));
+	memcpy(p, dp, sz + sizeof(EFI_DP_END));
 	p = (void *)p + sz;
 	p->sub_type = DEVICE_PATH_SUB_TYPE_INSTANCE_END;
-	p = (void *)p + sizeof(END);
+	p = (void *)p + sizeof(EFI_DP_END);
 	memcpy(p, dpi, szi);
 	p = (void *)p + szi;
-	memcpy(p, &END, sizeof(END));
+	memcpy(p, &EFI_DP_END, sizeof(EFI_DP_END));
 	return ret;
 }
 
@@ -424,17 +366,17 @@
 	if (!dp || !*dp)
 		return NULL;
 	sz = efi_dp_instance_size(*dp);
-	p = efi_alloc(sz + sizeof(END));
+	p = efi_alloc(sz + sizeof(EFI_DP_END));
 	if (!p)
 		return NULL;
-	memcpy(p, *dp, sz + sizeof(END));
+	memcpy(p, *dp, sz + sizeof(EFI_DP_END));
 	*dp = (void *)*dp + sz;
 	if ((*dp)->sub_type == DEVICE_PATH_SUB_TYPE_INSTANCE_END)
-		*dp = (void *)*dp + sizeof(END);
+		*dp = (void *)*dp + sizeof(EFI_DP_END);
 	else
 		*dp = NULL;
 	if (size)
-		*size = sz + sizeof(END);
+		*size = sz + sizeof(EFI_DP_END);
 	return p;
 }
 
@@ -449,9 +391,6 @@
 	return p->sub_type == DEVICE_PATH_SUB_TYPE_INSTANCE_END;
 }
 
-/* size of device-path not including END node for device and all parents
- * up to the root device.
- */
 __maybe_unused static unsigned int dp_size(struct udevice *dev)
 {
 	if (!dev || !dev->driver)
@@ -820,29 +759,21 @@
 	return dp_part_node(buf, desc, part);
 }
 
-/* Construct a device-path from a partition on a block device: */
 struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part)
 {
 	void *buf, *start;
 
-	start = buf = efi_alloc(dp_part_size(desc, part) + sizeof(END));
-	if (!buf)
+	start = efi_alloc(dp_part_size(desc, part) + sizeof(EFI_DP_END));
+	if (!start)
 		return NULL;
 
-	buf = dp_part_fill(buf, desc, part);
+	buf = dp_part_fill(start, desc, part);
 
-	*((struct efi_device_path *)buf) = END;
+	*((struct efi_device_path *)buf) = EFI_DP_END;
 
 	return start;
 }
 
-/*
- * Create a device node for a block device partition.
- *
- * @buf		buffer to which the device path is written
- * @desc	block device descriptor
- * @part	partition number, 0 identifies a block device
- */
 struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part)
 {
 	efi_uintn_t dpsize;
@@ -892,13 +823,6 @@
 	*pos = 0;
 }
 
-/**
- * efi_dp_from_file() - append file path node to device path.
- *
- * @dp:		device path or NULL
- * @path:	file path or NULL
- * Return:	device path or NULL in case of an error
- */
 struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
 					 const char *path)
 {
@@ -912,7 +836,7 @@
 	if (fpsize > U16_MAX)
 		return NULL;
 
-	buf = efi_alloc(dpsize + fpsize + sizeof(END));
+	buf = efi_alloc(dpsize + fpsize + sizeof(EFI_DP_END));
 	if (!buf)
 		return NULL;
 
@@ -929,7 +853,7 @@
 		pos += fpsize;
 	}
 
-	memcpy(pos, &END, sizeof(END));
+	memcpy(pos, &EFI_DP_END, sizeof(EFI_DP_END));
 
 	return buf;
 }
@@ -938,7 +862,7 @@
 {
 	void *buf, *pos;
 	struct efi_device_path_uart *uart;
-	size_t dpsize = dp_size(dm_root()) + sizeof(*uart) + sizeof(END);
+	size_t dpsize = dp_size(dm_root()) + sizeof(*uart) + sizeof(EFI_DP_END);
 
 	buf = efi_alloc(dpsize);
 	if (!buf)
@@ -949,7 +873,7 @@
 	uart->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_UART;
 	uart->dp.length = sizeof(*uart);
 	pos += sizeof(*uart);
-	memcpy(pos, &END, sizeof(END));
+	memcpy(pos, &EFI_DP_END, sizeof(EFI_DP_END));
 
 	return buf;
 }
@@ -963,13 +887,13 @@
 
 	dpsize += dp_size(dev);
 
-	start = buf = efi_alloc(dpsize + sizeof(END));
-	if (!buf)
+	start = efi_alloc(dpsize + sizeof(EFI_DP_END));
+	if (!start)
 		return NULL;
 
-	buf = dp_fill(buf, dev);
+	buf = dp_fill(start, dev);
 
-	*((struct efi_device_path *)buf) = END;
+	*((struct efi_device_path *)buf) = EFI_DP_END;
 
 	return start;
 }
@@ -979,7 +903,7 @@
  *
  * Set the device path to an ethernet device path as provided by
  * efi_dp_from_eth() concatenated with a device path of subtype
- * DEVICE_PATH_SUB_TYPE_MSG_IPV4, and an END node.
+ * DEVICE_PATH_SUB_TYPE_MSG_IPV4, and an EFI_DP_END node.
  *
  * @ip:		IPv4 local address
  * @mask:	network mask
@@ -1010,7 +934,7 @@
 	if (srv)
 		memcpy(&dp.ipv4dp.remote_ip_address, srv, sizeof(*srv));
 	pos = &dp.end;
-	memcpy(pos, &END, sizeof(END));
+	memcpy(pos, &EFI_DP_END, sizeof(EFI_DP_END));
 
 	dp1 = efi_dp_from_eth(dev);
 	if (!dp1)
@@ -1023,17 +947,6 @@
 	return dp2;
 }
 
-/**
- * efi_dp_from_http() - set device path from http
- *
- * Set the device path to an IPv4 path as provided by efi_dp_from_ipv4
- * concatenated with a device path of subtype DEVICE_PATH_SUB_TYPE_MSG_URI,
- * and an END node.
- *
- * @server:	URI of remote server
- * @dev:	net udevice
- * Return:	pointer to HTTP device path, NULL on error
- */
 struct efi_device_path *efi_dp_from_http(const char *server, struct udevice *dev)
 {
 	struct efi_device_path *dp1, *dp2;
@@ -1066,7 +979,7 @@
 	}
 
 	uridp_len = sizeof(struct efi_device_path) + strlen(tmp) + 1;
-	uridp = efi_alloc(uridp_len + sizeof(END));
+	uridp = efi_alloc(uridp_len + sizeof(EFI_DP_END));
 	if (!uridp) {
 		log_err("Out of memory\n");
 		return NULL;
@@ -1078,7 +991,7 @@
 	memcpy(uridp->uri, tmp, strlen(tmp) + 1);
 
 	pos = (char *)uridp + uridp_len;
-	memcpy(pos, &END, sizeof(END));
+	memcpy(pos, &EFI_DP_END, sizeof(EFI_DP_END));
 
 	dp2 = efi_dp_concat(dp1, (const struct efi_device_path *)uridp, 0);
 
@@ -1096,11 +1009,11 @@
 	struct efi_device_path_memory *mdp;
 	void *buf, *start;
 
-	start = buf = efi_alloc(sizeof(*mdp) + sizeof(END));
-	if (!buf)
+	start = efi_alloc(sizeof(*mdp) + sizeof(EFI_DP_END));
+	if (!start)
 		return NULL;
 
-	mdp = buf;
+	mdp = start;
 	mdp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
 	mdp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MEMORY;
 	mdp->dp.length = sizeof(*mdp);
@@ -1109,7 +1022,7 @@
 	mdp->end_address = start_address + size;
 	buf = &mdp[1];
 
-	*((struct efi_device_path *)buf) = END;
+	*((struct efi_device_path *)buf) = EFI_DP_END;
 
 	return start;
 }
diff --git a/lib/efi_loader/efi_device_path_utilities.c b/lib/efi_loader/efi_device_path_utilities.c
index 552c5bb..87d52df 100644
--- a/lib/efi_loader/efi_device_path_utilities.c
+++ b/lib/efi_loader/efi_device_path_utilities.c
@@ -7,6 +7,7 @@
 
 #define LOG_CATEGORY LOGC_EFI
 
+#include <efi_device_path.h>
 #include <efi_loader.h>
 
 const efi_guid_t efi_guid_device_path_utilities_protocol =
@@ -31,7 +32,7 @@
 	efi_uintn_t sz = 0;
 
 	EFI_ENTRY("%pD", device_path);
-	/* size includes the END node: */
+	/* size includes the EFI_DP_END node: */
 	if (device_path)
 		sz = efi_dp_size(device_path) + sizeof(struct efi_device_path);
 	return EFI_EXIT(sz);
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 5452640..47b583c 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -11,6 +11,7 @@
 #include <dm.h>
 #include <dm/device-internal.h>
 #include <dm/tag.h>
+#include <efi_device_path.h>
 #include <event.h>
 #include <efi_driver.h>
 #include <efi_loader.h>
diff --git a/lib/efi_loader/efi_fdt.c b/lib/efi_loader/efi_fdt.c
index 1ba6641..bfaa9cf 100644
--- a/lib/efi_loader/efi_fdt.c
+++ b/lib/efi_loader/efi_fdt.c
@@ -8,6 +8,7 @@
 
 #define LOG_CATEGORY LOGC_EFI
 
+#include <efi_device_path.h>
 #include <efi_loader.h>
 #include <env.h>
 #include <errno.h>
diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c
index 19fb5d0..44b806a 100644
--- a/lib/efi_loader/efi_helper.c
+++ b/lib/efi_loader/efi_helper.c
@@ -7,6 +7,7 @@
 
 #include <blkmap.h>
 #include <bootm.h>
+#include <efi_device_path.h>
 #include <env.h>
 #include <image.h>
 #include <log.h>
@@ -199,7 +200,7 @@
 		efi_free_pool(tmp_dp);
 		if (!*dp)
 			return EFI_OUT_OF_RESOURCES;
-		*dp_size += efi_dp_size(initrd_dp) + sizeof(END);
+		*dp_size += efi_dp_size(initrd_dp) + sizeof(EFI_DP_END);
 	}
 
 	if (fdt_dp) {
@@ -209,10 +210,10 @@
 		efi_free_pool(tmp_dp);
 		if (!*dp)
 			return EFI_OUT_OF_RESOURCES;
-		*dp_size += efi_dp_size(fdt_dp) + sizeof(END);
+		*dp_size += efi_dp_size(fdt_dp) + sizeof(EFI_DP_END);
 	}
 
-	*dp_size += sizeof(END);
+	*dp_size += sizeof(EFI_DP_END);
 
 	return EFI_SUCCESS;
 }
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index 9ff0b69..8e708d8 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -17,6 +17,7 @@
 
 #define LOG_CATEGORY LOGC_EFI
 
+#include <efi_device_path.h>
 #include <efi_loader.h>
 #include <dm.h>
 #include <linux/sizes.h>
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index 210a846..1832eeb 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -10,6 +10,7 @@
 #define LOG_CATEGORY LOGC_EFI
 
 #include <dm.h>
+#include <efi_device_path.h>
 #include <efi_loader.h>
 #include <efi_variable.h>
 #include <efi_tcg2.h>
diff --git a/test/lib/efi_device_path.c b/test/lib/efi_device_path.c
index 5cc001e..5a358dd 100644
--- a/test/lib/efi_device_path.c
+++ b/test/lib/efi_device_path.c
@@ -5,6 +5,7 @@
  * Copyright (c) 2020 Heinrich Schuchardt <xypron.glpk@gmx.de>
  */
 
+#include <efi_device_path.h>
 #include <efi_loader.h>
 #include <test/lib.h>
 #include <test/test.h>