diff --git a/include/efi_loader.h b/include/efi_loader.h
index eb11a8c7d4b1..25302628d8a8 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -552,6 +552,11 @@ struct efi_simple_file_system_protocol *efi_simple_file_system(
 /* open file from device-path: */
 struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp);
 
+efi_status_t efi_file_size(struct efi_file_handle *fh, efi_uintn_t *size);
+
+/* get a device path from a Boot#### option */
+struct efi_device_path *efi_get_dp_from_boot(const efi_guid_t guid);
+
 /**
  * efi_size_in_pages() - convert size in bytes to size in pages
  *
@@ -717,6 +722,8 @@ efi_status_t EFIAPI efi_query_variable_info(
 			u64 *remaining_variable_storage_size,
 			u64 *maximum_variable_size);
 
+void *efi_get_var(u16 *name, const efi_guid_t *vendor, efi_uintn_t *size);
+
 /*
  * See section 3.1.3 in the v2.7 UEFI spec for more details on
  * the layout of EFI_LOAD_OPTION.  In short it is:
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index 10b42e8847bf..da2741adecfa 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -23,6 +23,7 @@ endif
 obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
 obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += efi_bootmgr.o
 obj-y += efi_boottime.o
+obj-y += efi_helper.o
 obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o
 obj-$(CONFIG_EFI_CAPSULE_FIRMWARE) += efi_firmware.o
 obj-y += efi_console.o
diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c
index 8ece8e71ee1c..bebcb520272a 100644
--- a/lib/efi_loader/efi_file.c
+++ b/lib/efi_loader/efi_file.c
@@ -409,6 +409,45 @@ static efi_status_t efi_get_file_size(struct file_handle *fh,
 	return EFI_SUCCESS;
 }
 
+/**
+ * efi_file_size() - Get the size of a file using an EFI file handle
+ *
+ * @handle:	EFI file handle
+ * @size:	buffer to fill in the discovered size
+ *
+ * Return:	size of the file
+ */
+efi_status_t efi_file_size(struct efi_file_handle *fh, efi_uintn_t *size)
+{
+	struct efi_file_info *info = NULL;
+	efi_uintn_t bs = 0;
+	efi_status_t ret;
+
+	*size = 0;
+	ret = EFI_CALL(fh->getinfo(fh, (efi_guid_t *)&efi_file_info_guid, &bs,
+				   info));
+	if (ret != EFI_BUFFER_TOO_SMALL) {
+		ret = EFI_DEVICE_ERROR;
+		goto out;
+	}
+
+	info = malloc(bs);
+	if (!info) {
+		ret = EFI_OUT_OF_RESOURCES;
+		goto out;
+	}
+	ret = EFI_CALL(fh->getinfo(fh, (efi_guid_t *)&efi_file_info_guid, &bs,
+				   info));
+	if (ret != EFI_SUCCESS)
+		goto out;
+
+	*size = info->file_size;
+
+out:
+	free(info);
+	return ret;
+}
+
 static efi_status_t file_read(struct file_handle *fh, u64 *buffer_size,
 		void *buffer)
 {
diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c
new file mode 100644
index 000000000000..d03a7364615e
--- /dev/null
+++ b/lib/efi_loader/efi_helper.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020, Linaro Limited
+ */
+
+#define LOG_CATEGORY LOGC_EFI
+#include <common.h>
+#include <env.h>
+#include <malloc.h>
+#include <dm.h>
+#include <fs.h>
+#include <efi_load_initrd.h>
+#include <efi_loader.h>
+#include <efi_variable.h>
+
+/**
+ * efi_create_current_boot_var() - Return Boot#### name were #### is replaced by
+ *			           the value of BootCurrent
+ *
+ * @var_name:		variable name
+ * @var_name_size:	size of var_name
+ *
+ * Return:	Status code
+ */
+static efi_status_t efi_create_current_boot_var(u16 var_name[],
+						size_t var_name_size)
+{
+	efi_uintn_t boot_current_size;
+	efi_status_t ret;
+	u16 boot_current;
+	u16 *pos;
+
+	boot_current_size = sizeof(boot_current);
+	ret = efi_get_variable_int(L"BootCurrent",
+				   &efi_global_variable_guid, NULL,
+				   &boot_current_size, &boot_current, NULL);
+	if (ret != EFI_SUCCESS)
+		goto out;
+
+	pos = efi_create_indexed_name(var_name, var_name_size, "Boot",
+				      boot_current);
+	if (!pos) {
+		ret = EFI_OUT_OF_RESOURCES;
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+/**
+ * efi_get_dp_from_boot() - Retrieve and return a device path from an EFI
+ *			    Boot### variable.
+ *			    A boot option may contain an array of device paths.
+ *			    We use a VenMedia() with a specific GUID to identify
+ *			    the usage of the array members. This function is
+ *			    used to extract a specific device path
+ *
+ * @guid:	vendor GUID of the VenMedia() device path node identifying the
+ *		device path
+ *
+ * Return:	device path or NULL. Caller must free the returned value
+ */
+struct efi_device_path *efi_get_dp_from_boot(const efi_guid_t guid)
+{
+	struct efi_device_path *file_path = NULL;
+	struct efi_device_path *tmp = NULL;
+	struct efi_load_option lo;
+	void *var_value = NULL;
+	efi_uintn_t size;
+	efi_status_t ret;
+	u16 var_name[16];
+
+	ret = efi_create_current_boot_var(var_name, sizeof(var_name));
+	if (ret != EFI_SUCCESS)
+		return NULL;
+
+	var_value = efi_get_var(var_name, &efi_global_variable_guid, &size);
+	if (!var_value)
+		return NULL;
+
+	ret = efi_deserialize_load_option(&lo, var_value, &size);
+	if (ret != EFI_SUCCESS)
+		goto out;
+
+	tmp = efi_dp_from_lo(&lo, &size, guid);
+	if (!tmp)
+		goto out;
+
+	/* efi_dp_dup will just return NULL if efi_dp_next is NULL */
+	file_path = efi_dp_dup(efi_dp_next(tmp));
+
+out:
+	efi_free_pool(tmp);
+	free(var_value);
+
+	return file_path;
+}
diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c
index 1c7459266a38..b11ed91a74a4 100644
--- a/lib/efi_loader/efi_var_common.c
+++ b/lib/efi_loader/efi_var_common.c
@@ -9,6 +9,7 @@
 #include <common.h>
 #include <efi_loader.h>
 #include <efi_variable.h>
+#include <stdlib.h>
 
 enum efi_secure_mode {
 	EFI_MODE_SETUP,
@@ -343,3 +344,35 @@ enum efi_auth_var_type efi_auth_var_get_type(u16 *name, const efi_guid_t *guid)
 	}
 	return EFI_AUTH_VAR_NONE;
 }
+
+/**
+ * efi_get_var() - read value of an EFI variable
+ *
+ * @name:	variable name
+ * @start:	vendor GUID
+ * @size:	size of allocated buffer
+ *
+ * Return:	buffer with variable data or NULL
+ */
+void *efi_get_var(u16 *name, const efi_guid_t *vendor, efi_uintn_t *size)
+{
+	efi_status_t ret;
+	void *buf = NULL;
+
+	*size = 0;
+	ret = efi_get_variable_int(name, vendor, NULL, size, buf, NULL);
+	if (ret == EFI_BUFFER_TOO_SMALL) {
+		buf = malloc(*size);
+		if (!buf)
+			return NULL;
+		ret = efi_get_variable_int(name, vendor, NULL, size, buf, NULL);
+	}
+
+	if (ret != EFI_SUCCESS) {
+		free(buf);
+		*size = 0;
+		return NULL;
+	}
+
+	return buf;
+}
