aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--cmd/Kconfig1
-rw-r--r--cmd/bootefi.c110
-rw-r--r--include/charset.h12
-rw-r--r--lib/efi_loader/Kconfig69
-rw-r--r--lib/efi_loader/Makefile6
-rw-r--r--lib/efi_loader/efi_boottime.c16
-rw-r--r--lib/efi_loader/efi_device_path_to_text.c6
-rw-r--r--lib/efi_loader/efi_memory.c92
-rw-r--r--lib/efi_loader/efi_root_node.c4
-rw-r--r--lib/efi_selftest/Makefile5
-rw-r--r--lib/vsprintf.c4
12 files changed, 188 insertions, 138 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 33fd4652a4..c41bc89fe9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -476,6 +476,7 @@ F: doc/README.uefi
F: doc/README.iscsi
F: Documentation/efi.rst
F: include/capitalization.h
+F: include/charset.h
F: include/cp1250.h
F: include/cp437.h
F: include/efi*
diff --git a/cmd/Kconfig b/cmd/Kconfig
index fd1beb0684..0d36da2a5c 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1436,6 +1436,7 @@ config CMD_DISPLAY
config CMD_EFIDEBUG
bool "efidebug - display/configure UEFI environment"
depends on EFI_LOADER
+ select EFI_DEVICE_PATH_TO_TEXT
default n
help
Enable the 'efidebug' command which provides a subset of UEFI
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 52116b308c..c19256e00d 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -196,11 +196,16 @@ static void *get_config_table(const efi_guid_t *guid)
/**
* efi_install_fdt() - install fdt passed by a command argument
+ *
+ * If fdt_opt is available, the device tree located at that memory address will
+ * will be installed as configuration table, otherwise the device tree located
+ * at the address indicated by environment variable fdtcontroladdr will be used.
+ *
+ * On architectures (x86) using ACPI tables device trees shall not be installed
+ * as configuration table.
+ *
* @fdt_opt: pointer to argument
* Return: status code
- *
- * If specified, fdt will be installed as configuration table,
- * otherwise no fdt will be passed.
*/
static efi_status_t efi_install_fdt(const char *fdt_opt)
{
@@ -314,32 +319,15 @@ static efi_status_t do_bootefi_exec(efi_handle_t handle)
}
/**
- * do_efibootmgr() - execute EFI Boot Manager
+ * do_efibootmgr() - execute EFI boot manager
*
- * @fdt_opt: string of fdt start address
* Return: status code
- *
- * Execute EFI Boot Manager
*/
-static int do_efibootmgr(const char *fdt_opt)
+static int do_efibootmgr(void)
{
efi_handle_t handle;
efi_status_t ret;
- /* Initialize EFI drivers */
- ret = efi_init_obj_list();
- if (ret != EFI_SUCCESS) {
- printf("Error: Cannot initialize UEFI sub-system, r = %lu\n",
- ret & ~EFI_ERROR_MASK);
- return CMD_RET_FAILURE;
- }
-
- ret = efi_install_fdt(fdt_opt);
- if (ret == EFI_INVALID_PARAMETER)
- return CMD_RET_USAGE;
- else if (ret != EFI_SUCCESS)
- return CMD_RET_FAILURE;
-
ret = efi_bootmgr_load(&handle);
if (ret != EFI_SUCCESS) {
printf("EFI boot manager: Cannot load any image\n");
@@ -355,16 +343,15 @@ static int do_efibootmgr(const char *fdt_opt)
}
/*
- * do_bootefi_image() - execute EFI binary from command line
+ * do_bootefi_image() - execute EFI binary
+ *
+ * Set up memory image for the binary to be loaded, prepare device path, and
+ * then call do_bootefi_exec() to execute it.
*
* @image_opt: string of image start address
- * @fdt_opt: string of fdt start address
* Return: status code
- *
- * Set up memory image for the binary to be loaded, prepare
- * device path and then call do_bootefi_exec() to execute it.
*/
-static int do_bootefi_image(const char *image_opt, const char *fdt_opt)
+static int do_bootefi_image(const char *image_opt)
{
void *image_buf;
struct efi_device_path *device_path, *image_path;
@@ -374,20 +361,6 @@ static int do_bootefi_image(const char *image_opt, const char *fdt_opt)
efi_handle_t mem_handle = NULL, handle;
efi_status_t ret;
- /* Initialize EFI drivers */
- ret = efi_init_obj_list();
- if (ret != EFI_SUCCESS) {
- printf("Error: Cannot initialize UEFI sub-system, r = %lu\n",
- ret & ~EFI_ERROR_MASK);
- return CMD_RET_FAILURE;
- }
-
- ret = efi_install_fdt(fdt_opt);
- if (ret == EFI_INVALID_PARAMETER)
- return CMD_RET_USAGE;
- else if (ret != EFI_SUCCESS)
- return CMD_RET_FAILURE;
-
#ifdef CONFIG_CMD_BOOTEFI_HELLO
if (!strcmp(image_opt, "hello")) {
char *saddr;
@@ -547,33 +520,16 @@ static void bootefi_run_finish(struct efi_loaded_image_obj *image_obj,
}
/**
- * do_efi_selftest() - execute EFI Selftest
+ * do_efi_selftest() - execute EFI selftest
*
- * @fdt_opt: string of fdt start address
* Return: status code
- *
- * Execute EFI Selftest
*/
-static int do_efi_selftest(const char *fdt_opt)
+static int do_efi_selftest(void)
{
struct efi_loaded_image_obj *image_obj;
struct efi_loaded_image *loaded_image_info;
efi_status_t ret;
- /* Initialize EFI drivers */
- ret = efi_init_obj_list();
- if (ret != EFI_SUCCESS) {
- printf("Error: Cannot initialize UEFI sub-system, r = %lu\n",
- ret & ~EFI_ERROR_MASK);
- return CMD_RET_FAILURE;
- }
-
- ret = efi_install_fdt(fdt_opt);
- if (ret == EFI_INVALID_PARAMETER)
- return CMD_RET_USAGE;
- else if (ret != EFI_SUCCESS)
- return CMD_RET_FAILURE;
-
ret = bootefi_test_prepare(&image_obj, &loaded_image_info,
"\\selftest", "efi_selftest");
if (ret != EFI_SUCCESS)
@@ -587,20 +543,44 @@ static int do_efi_selftest(const char *fdt_opt)
}
#endif /* CONFIG_CMD_BOOTEFI_SELFTEST */
-/* Interpreter command to boot an arbitrary EFI image from memory */
+/**
+ * do_bootefi() - execute `bootefi` command
+ *
+ * @cmdtp: table entry describing command
+ * @flag: bitmap indicating how the command was invoked
+ * @argc: number of arguments
+ * @argv: command line arguments
+ * Return: status code
+ */
static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
+ efi_status_t ret;
+
if (argc < 2)
return CMD_RET_USAGE;
+ /* Initialize EFI drivers */
+ ret = efi_init_obj_list();
+ if (ret != EFI_SUCCESS) {
+ printf("Error: Cannot initialize UEFI sub-system, r = %lu\n",
+ ret & ~EFI_ERROR_MASK);
+ return CMD_RET_FAILURE;
+ }
+
+ ret = efi_install_fdt(argc > 2 ? argv[2] : NULL);
+ if (ret == EFI_INVALID_PARAMETER)
+ return CMD_RET_USAGE;
+ else if (ret != EFI_SUCCESS)
+ return CMD_RET_FAILURE;
+
if (!strcmp(argv[1], "bootmgr"))
- return do_efibootmgr(argc > 2 ? argv[2] : NULL);
+ return do_efibootmgr();
#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
else if (!strcmp(argv[1], "selftest"))
- return do_efi_selftest(argc > 2 ? argv[2] : NULL);
+ return do_efi_selftest();
#endif
- return do_bootefi_image(argv[1], argc > 2 ? argv[2] : NULL);
+ return do_bootefi_image(argv[1]);
}
#ifdef CONFIG_SYS_LONGHELP
diff --git a/include/charset.h b/include/charset.h
index 65087f76d1..4f7ae8fafd 100644
--- a/include/charset.h
+++ b/include/charset.h
@@ -46,9 +46,9 @@ int utf8_put(s32 code, char **dst);
*
* @src: utf-8 string
* @count: maximum number of code points to convert
- * Return: length in bytes after conversion to utf-16 without the
+ * Return: length in u16 after conversion to utf-16 without the
* trailing \0. If an invalid UTF-8 sequence is hit one
- * word will be reserved for a replacement character.
+ * u16 will be reserved for a replacement character.
*/
size_t utf8_utf16_strnlen(const char *src, size_t count);
@@ -56,8 +56,9 @@ size_t utf8_utf16_strnlen(const char *src, size_t count);
* utf8_utf16_strlen() - length of a utf-8 string after conversion to utf-16
*
* @src: utf-8 string
- * Return: length in bytes after conversion to utf-16 without the
- * trailing \0. -1 if the utf-8 string is not valid.
+ * Return: length in u16 after conversion to utf-16 without the
+ * trailing \0. If an invalid UTF-8 sequence is hit one
+ * u16 will be reserved for a replacement character.
*/
#define utf8_utf16_strlen(a) utf8_utf16_strnlen((a), SIZE_MAX)
@@ -127,7 +128,8 @@ size_t utf16_utf8_strnlen(const u16 *src, size_t count);
*
* @src: utf-16 string
* Return: length in bytes after conversion to utf-8 without the
- * trailing \0. -1 if the utf-16 string is not valid.
+ * trailing \0. If an invalid UTF-16 sequence is hit one
+ * byte will be reserved for a replacement character.
*/
#define utf16_utf8_strlen(a) utf16_utf8_strnlen((a), SIZE_MAX)
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 50b050159c..6501ee56aa 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -1,5 +1,5 @@
config EFI_LOADER
- bool "Support running EFI Applications in U-Boot"
+ bool "Support running UEFI applications"
depends on (ARM || X86 || RISCV || SANDBOX) && OF_LIBFDT
# We need EFI_STUB_64BIT to be set on x86_64 with EFI_STUB
depends on !EFI_STUB || !X86_64 || EFI_STUB_64BIT
@@ -11,14 +11,42 @@ config EFI_LOADER
select REGEX
imply CFB_CONSOLE_ANSI
help
- Select this option if you want to run EFI applications (like grub2)
- on top of U-Boot. If this option is enabled, U-Boot will expose EFI
- interfaces to a loaded EFI application, enabling it to reuse U-Boot's
- device drivers.
+ Select this option if you want to run UEFI applications (like GNU
+ GRUB or iPXE) on top of U-Boot. If this option is enabled, U-Boot
+ will expose the UEFI API to a loaded application, enabling it to
+ reuse U-Boot's device drivers.
+
+if EFI_LOADER
+
+config EFI_DEVICE_PATH_TO_TEXT
+ bool "Device path to text protocol"
+ default y
+ help
+ The device path to text protocol converts device nodes and paths to
+ human readable strings.
+
+config EFI_LOADER_HII
+ bool "HII protocols"
+ default y
+ help
+ The Human Interface Infrastructure is a complicated framework that
+ allows UEFI applications to draw fancy menus and hook strings using
+ a translation framework.
+
+ U-Boot implements enough of its features to be able to run the UEFI
+ Shell, but not more than that.
+
+config EFI_UNICODE_COLLATION_PROTOCOL
+ bool "Unicode collation protocol"
+ default y
+ help
+ The Unicode collation protocol is used for lexical comparisons. It is
+ required to run the UEFI shell.
+
+if EFI_UNICODE_COLLATION_PROTOCOL
config EFI_UNICODE_CAPITALIZATION
bool "Support Unicode capitalization"
- depends on EFI_LOADER
default y
help
Select this option to enable correct handling of the capitalization of
@@ -26,33 +54,24 @@ config EFI_UNICODE_CAPITALIZATION
set, only the the correct handling of the letters of the codepage
used by the FAT file system is ensured.
-config EFI_PLATFORM_LANG_CODES
- string "Language codes supported by firmware"
- depends on EFI_LOADER
- default "en-US"
- help
- This value is used to initialize the PlatformLangCodes variable. Its
- value is a semicolon (;) separated list of language codes in native
- RFC 4646 format, e.g. "en-US;de-DE". The first language code is used
- to initialize the PlatformLang variable.
+endif
config EFI_LOADER_BOUNCE_BUFFER
bool "EFI Applications use bounce buffers for DMA operations"
- depends on EFI_LOADER && ARM64
+ depends on ARM64
default n
help
Some hardware does not support DMA to full 64bit addresses. For this
hardware we can create a bounce buffer so that payloads don't have to
worry about platform details.
-config EFI_LOADER_HII
- bool "Expose HII protocols to EFI applications"
- depends on EFI_LOADER
- default y
+config EFI_PLATFORM_LANG_CODES
+ string "Language codes supported by firmware"
+ default "en-US"
help
- The Human Interface Infrastructure is a complicated framework that
- allows UEFI applications to draw fancy menus and hook strings using
- a translation framework.
+ This value is used to initialize the PlatformLangCodes variable. Its
+ value is a semicolon (;) separated list of language codes in native
+ RFC 4646 format, e.g. "en-US;de-DE". The first language code is used
+ to initialize the PlatformLang variable.
- U-Boot implements enough of its features to be able to run the UEFI
- Shell, but not more than that.
+endif
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index 4e90a35896..f3d6773bf6 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -21,16 +21,16 @@ obj-y += efi_bootmgr.o
obj-y += efi_boottime.o
obj-y += efi_console.o
obj-y += efi_device_path.o
-obj-y += efi_device_path_to_text.o
+obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o
obj-y += efi_device_path_utilities.o
obj-y += efi_file.o
-obj-y += efi_hii.o efi_hii_config.o
+obj-$(CONFIG_EFI_LOADER_HII) += efi_hii.o efi_hii_config.o
obj-y += efi_image_loader.o
obj-y += efi_memory.o
obj-y += efi_root_node.o
obj-y += efi_runtime.o
obj-y += efi_setup.o
-obj-y += efi_unicode_collation.o
+obj-$(CONFIG_EFI_UNICODE_COLLATION_PROTOCOL) += efi_unicode_collation.o
obj-y += efi_variable.o
obj-y += efi_watchdog.o
obj-$(CONFIG_LCD) += efi_gop.o
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index b97d55cb45..ec6f5758de 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -181,10 +181,12 @@ static void efi_queue_event(struct efi_event *event, bool check_tpl)
/* Check TPL */
if (check_tpl && efi_tpl >= event->notify_tpl)
return;
+ event->is_queued = false;
EFI_CALL_VOID(event->notify_function(event,
event->notify_context));
+ } else {
+ event->is_queued = false;
}
- event->is_queued = false;
}
/**
@@ -513,10 +515,8 @@ efi_status_t efi_remove_protocol(const efi_handle_t handle,
ret = efi_search_protocol(handle, protocol, &handler);
if (ret != EFI_SUCCESS)
return ret;
- if (guidcmp(handler->guid, protocol))
- return EFI_INVALID_PARAMETER;
if (handler->protocol_interface != protocol_interface)
- return EFI_INVALID_PARAMETER;
+ return EFI_NOT_FOUND;
list_del(&handler->link);
free(handler);
return EFI_SUCCESS;
@@ -1439,7 +1439,7 @@ static efi_status_t efi_locate_handle(
*buffer_size = size;
- /* The buffer size is sufficient but there is not buffer */
+ /* The buffer size is sufficient but there is no buffer */
if (!buffer)
return EFI_INVALID_PARAMETER;
@@ -2261,7 +2261,7 @@ static efi_status_t EFIAPI efi_locate_device_path(
EFI_ENTRY("%pUl, %p, %p", protocol, device_path, device);
- if (!protocol || !device_path || !*device_path || !device) {
+ if (!protocol || !device_path || !*device_path) {
ret = EFI_INVALID_PARAMETER;
goto out;
}
@@ -2294,6 +2294,10 @@ static efi_status_t EFIAPI efi_locate_device_path(
/* Check if dp is a subpath of device_path */
if (memcmp(*device_path, dp, len_dp))
continue;
+ if (!device) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
*device = handles[i];
len_best = len_dp;
}
diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c
index e219f84b28..f3a9579076 100644
--- a/lib/efi_loader/efi_device_path_to_text.c
+++ b/lib/efi_loader/efi_device_path_to_text.c
@@ -78,9 +78,9 @@ static char *dp_acpi(char *s, struct efi_device_path *dp)
case DEVICE_PATH_SUB_TYPE_ACPI_DEVICE: {
struct efi_device_path_acpi_path *adp =
(struct efi_device_path_acpi_path *)dp;
- s += sprintf(s, "Acpi(PNP%04x", EISA_PNP_NUM(adp->hid));
- if (adp->uid)
- s += sprintf(s, ",%d", adp->uid);
+
+ s += sprintf(s, "Acpi(PNP%04X", EISA_PNP_NUM(adp->hid));
+ s += sprintf(s, ",%d", adp->uid);
s += sprintf(s, ")");
break;
}
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 776077cc35..76dcaa48f4 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -318,6 +318,44 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
return start;
}
+/**
+ * efi_check_allocated() - validate address to be freed
+ *
+ * Check that the address is within allocated memory:
+ *
+ * * The address cannot be NULL.
+ * * The address must be in a range of the memory map.
+ * * The address may not point to EFI_CONVENTIONAL_MEMORY.
+ *
+ * Page alignment is not checked as this is not a requirement of
+ * efi_free_pool().
+ *
+ * @addr: address of page to be freed
+ * @must_be_allocated: return success if the page is allocated
+ * Return: status code
+ */
+static efi_status_t efi_check_allocated(u64 addr, bool must_be_allocated)
+{
+ struct efi_mem_list *item;
+
+ if (!addr)
+ return EFI_INVALID_PARAMETER;
+ list_for_each_entry(item, &efi_mem, link) {
+ u64 start = item->desc.physical_start;
+ u64 end = start + (item->desc.num_pages << EFI_PAGE_SHIFT);
+
+ if (addr >= start && addr < end) {
+ if (must_be_allocated ^
+ (item->desc.type == EFI_CONVENTIONAL_MEMORY))
+ return EFI_SUCCESS;
+ else
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr)
{
struct list_head *lhandle;
@@ -373,7 +411,7 @@ efi_status_t efi_allocate_pages(int type, int memory_type,
efi_uintn_t pages, uint64_t *memory)
{
u64 len = pages << EFI_PAGE_SHIFT;
- efi_status_t r = EFI_SUCCESS;
+ efi_status_t ret;
uint64_t addr;
/* Check import parameters */
@@ -387,43 +425,35 @@ efi_status_t efi_allocate_pages(int type, int memory_type,
case EFI_ALLOCATE_ANY_PAGES:
/* Any page */
addr = efi_find_free_memory(len, -1ULL);
- if (!addr) {
- r = EFI_NOT_FOUND;
- break;
- }
+ if (!addr)
+ return EFI_OUT_OF_RESOURCES;
break;
case EFI_ALLOCATE_MAX_ADDRESS:
/* Max address */
addr = efi_find_free_memory(len, *memory);
- if (!addr) {
- r = EFI_NOT_FOUND;
- break;
- }
+ if (!addr)
+ return EFI_OUT_OF_RESOURCES;
break;
case EFI_ALLOCATE_ADDRESS:
/* Exact address, reserve it. The addr is already in *memory. */
+ ret = efi_check_allocated(*memory, false);
+ if (ret != EFI_SUCCESS)
+ return EFI_NOT_FOUND;
addr = *memory;
break;
default:
/* UEFI doesn't specify other allocation types */
- r = EFI_INVALID_PARAMETER;
- break;
+ return EFI_INVALID_PARAMETER;
}
- if (r == EFI_SUCCESS) {
- uint64_t ret;
+ /* Reserve that map in our memory maps */
+ if (efi_add_memory_map(addr, pages, memory_type, true) != addr)
+ /* Map would overlap, bail out */
+ return EFI_OUT_OF_RESOURCES;
- /* Reserve that map in our memory maps */
- ret = efi_add_memory_map(addr, pages, memory_type, true);
- if (ret == addr) {
- *memory = addr;
- } else {
- /* Map would overlap, bail out */
- r = EFI_OUT_OF_RESOURCES;
- }
- }
+ *memory = addr;
- return r;
+ return EFI_SUCCESS;
}
void *efi_alloc(uint64_t len, int memory_type)
@@ -450,6 +480,11 @@ void *efi_alloc(uint64_t len, int memory_type)
efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
{
uint64_t r = 0;
+ efi_status_t ret;
+
+ ret = efi_check_allocated(memory, true);
+ if (ret != EFI_SUCCESS)
+ return ret;
/* Sanity check */
if (!memory || (memory & EFI_PAGE_MASK) || !pages) {
@@ -511,11 +546,12 @@ efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size, void **buffer)
*/
efi_status_t efi_free_pool(void *buffer)
{
- efi_status_t r;
+ efi_status_t ret;
struct efi_pool_allocation *alloc;
- if (buffer == NULL)
- return EFI_INVALID_PARAMETER;
+ ret = efi_check_allocated((uintptr_t)buffer, true);
+ if (ret != EFI_SUCCESS)
+ return ret;
alloc = container_of(buffer, struct efi_pool_allocation, data);
@@ -528,9 +564,9 @@ efi_status_t efi_free_pool(void *buffer)
/* Avoid double free */
alloc->checksum = 0;
- r = efi_free_pages((uintptr_t)alloc, alloc->num_pages);
+ ret = efi_free_pages((uintptr_t)alloc, alloc->num_pages);
- return r;
+ return ret;
}
/*
diff --git a/lib/efi_loader/efi_root_node.c b/lib/efi_loader/efi_root_node.c
index 38514e0820..d8496cc3c2 100644
--- a/lib/efi_loader/efi_root_node.c
+++ b/lib/efi_loader/efi_root_node.c
@@ -52,15 +52,19 @@ efi_status_t efi_root_node_register(void)
(&efi_root,
/* Device path protocol */
&efi_guid_device_path, dp,
+#if CONFIG_IS_ENABLED(EFI_DEVICE_PATH_TO_TEXT)
/* Device path to text protocol */
&efi_guid_device_path_to_text_protocol,
(void *)&efi_device_path_to_text,
+#endif
/* Device path utilities protocol */
&efi_guid_device_path_utilities_protocol,
(void *)&efi_device_path_utilities,
+#if CONFIG_IS_ENABLED(EFI_UNICODE_COLLATION_PROTOCOL)
/* Unicode collation protocol */
&efi_guid_unicode_collation_protocol,
(void *)&efi_unicode_collation_protocol,
+#endif
#if CONFIG_IS_ENABLED(EFI_LOADER_HII)
/* HII string protocol */
&efi_guid_hii_string_protocol,
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index c69ad7a9c0..d0bebc7d0c 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -17,7 +17,6 @@ efi_selftest_config_table.o \
efi_selftest_controllers.o \
efi_selftest_console.o \
efi_selftest_crc32.o \
-efi_selftest_devicepath.o \
efi_selftest_devicepath_util.o \
efi_selftest_events.o \
efi_selftest_event_groups.o \
@@ -34,11 +33,13 @@ efi_selftest_textinput.o \
efi_selftest_textinputex.o \
efi_selftest_textoutput.o \
efi_selftest_tpl.o \
-efi_selftest_unicode_collation.o \
efi_selftest_util.o \
efi_selftest_variables.o \
efi_selftest_watchdog.o
+obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_selftest_devicepath.o
+obj-$(CONFIG_EFI_UNICODE_COLLATION_PROTOCOL) += efi_selftest_unicode_collation.o
+
obj-$(CONFIG_CPU_V7) += efi_selftest_unaligned.o
obj-$(CONFIG_EFI_LOADER_HII) += efi_selftest_hii.o
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 3502b8088f..8bbbd48c54 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -296,6 +296,7 @@ static char *string16(char *buf, char *end, u16 *s, int field_width,
return buf;
}
+#if CONFIG_IS_ENABLED(EFI_DEVICE_PATH_TO_TEXT)
static char *device_path_string(char *buf, char *end, void *dp, int field_width,
int precision, int flags)
{
@@ -314,6 +315,7 @@ static char *device_path_string(char *buf, char *end, void *dp, int field_width,
return buf;
}
#endif
+#endif
#ifdef CONFIG_CMD_NET
static char *mac_address_string(char *buf, char *end, u8 *addr, int field_width,
@@ -451,7 +453,7 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
switch (*fmt) {
/* Device paths only exist in the EFI context. */
-#if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD)
+#if CONFIG_IS_ENABLED(EFI_DEVICE_PATH_TO_TEXT) && !defined(API_BUILD)
case 'D':
return device_path_string(buf, end, ptr, field_width,
precision, flags);