For use by EFI payloads that don't want to convert device paths into
strings themselves, the loader can provide a protocol with access to its
own routines. device_path_to_str(), which we already in the EFI payload
can fill that role, so add a protocol that calls into it.

Signed-off-by: Ahmad Fatoum <[email protected]>
---
 efi/loader/protocols/Kconfig               |   7 ++
 efi/loader/protocols/Makefile              |   1 +
 efi/loader/protocols/device_path_to_text.c | 130 +++++++++++++++++++++
 include/efi/protocol/devicepath.h          |  11 ++
 4 files changed, 149 insertions(+)
 create mode 100644 efi/loader/protocols/device_path_to_text.c

diff --git a/efi/loader/protocols/Kconfig b/efi/loader/protocols/Kconfig
index 3405de1acdfb..ba6f562b7585 100644
--- a/efi/loader/protocols/Kconfig
+++ b/efi/loader/protocols/Kconfig
@@ -39,6 +39,13 @@ config EFI_LOADER_RNG
          Provide a EFI_RNG_PROTOCOL implementation using the hardware random
          number generator of the platform.
 
+config EFI_LOADER_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_DEVICE_PATH_UTIL
        bool "Device path utilities protocol"
        default y
diff --git a/efi/loader/protocols/Makefile b/efi/loader/protocols/Makefile
index b5ec5cf5dd46..a323927b89e3 100644
--- a/efi/loader/protocols/Makefile
+++ b/efi/loader/protocols/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_EFI_LOADER_HII) += hii.o hii_config.o
 obj-$(CONFIG_EFI_LOADER_UNICODE_COLLATION_PROTOCOL2) += unicode_collation.o
 obj-$(CONFIG_EFI_LOADER_RNG) += rng.o
 obj-$(CONFIG_EFI_LOADER_DEVICE_PATH_UTIL) += device_path_utilities.o
+obj-$(CONFIG_EFI_LOADER_DEVICE_PATH_TO_TEXT) += device_path_to_text.o
diff --git a/efi/loader/protocols/device_path_to_text.c 
b/efi/loader/protocols/device_path_to_text.c
new file mode 100644
index 000000000000..d2907915469c
--- /dev/null
+++ b/efi/loader/protocols/device_path_to_text.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  EFI device path interface
+ *
+ *  Copyright (c) 2017 Heinrich Schuchardt
+ */
+
+#include <charset.h>
+#include <efi/devicepath.h>
+#include <efi/loader/devicepath.h>
+#include <efi/protocol/devicepath.h>
+#include <efi/loader/object.h>
+#include <efi/loader/trace.h>
+#include <efi/loader.h>
+#include <efi/guid.h>
+#include <efi/error.h>
+#include <init.h>
+
+/**
+ * efi_str_to_u16() - convert ASCII string to UTF-16
+ *
+ * A u16 buffer is allocated from pool. The ASCII string is copied to the u16
+ * buffer.
+ *
+ * @str:       ASCII string
+ * Return:     UTF-16 string. NULL if out of memory.
+ */
+static u16 *efi_str_to_u16(const char *str)
+{
+       size_t len;
+       u16 *out, *dst;
+       efi_status_t ret;
+
+       if (!str)
+               return NULL;
+
+       len = sizeof(u16) * (utf8_utf16_strlen(str) + 1);
+       ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, len, (void **)&out, 
"DP");
+       if (ret != EFI_SUCCESS)
+               return NULL;
+       dst = out;
+       utf8_utf16_strcpy(&dst, str);
+       return out;
+}
+
+static uint16_t EFIAPI *__efi_convert_device_path_to_text(
+               const struct efi_device_path *dp,
+               bool all_nodes)
+{
+       char *str;
+       uint16_t *text;
+
+       if (!dp)
+               return NULL;
+
+       str = device_path_to_str(dp, all_nodes);
+       text = efi_str_to_u16(str);
+       free(str);
+
+       return text;
+}
+
+/*
+ * This function implements the ConvertDeviceNodeToText service of the
+ * EFI_DEVICE_PATH_TO_TEXT_PROTOCOL.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * device_node         device node to be converted
+ * display_only                true if the shorter text representation shall 
be used
+ * allow_shortcuts     true if shortcut forms may be used
+ * Return:             text representation of the device path
+ *                     NULL if out of memory of device_path is NULL
+ */
+static uint16_t EFIAPI *efi_convert_device_node_to_text(
+               const struct efi_device_path *device_node,
+               bool display_only,
+               bool allow_shortcuts)
+{
+       uint16_t *text;
+
+       EFI_ENTRY("%p, %d, %d", device_node, display_only, allow_shortcuts);
+
+       text = __efi_convert_device_path_to_text(device_node, false);
+
+       EFI_EXIT(EFI_SUCCESS);
+
+       return text;
+}
+
+/*
+ * This function implements the ConvertDevicePathToText service of the
+ * EFI_DEVICE_PATH_TO_TEXT_PROTOCOL.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * device_path         device path to be converted
+ * display_only                true if the shorter text representation shall 
be used
+ * allow_shortcuts     true if shortcut forms may be used
+ * Return:             text representation of the device path
+ *                     NULL if out of memory of device_path is NULL
+ */
+static uint16_t EFIAPI *efi_convert_device_path_to_text(
+               const struct efi_device_path *device_path,
+               bool display_only,
+               bool allow_shortcuts)
+{
+       uint16_t *text;
+
+       EFI_ENTRY("%p, %d, %d", device_path, display_only, allow_shortcuts);
+
+       text = __efi_convert_device_path_to_text(device_path, true);
+
+       EFI_EXIT(EFI_SUCCESS);
+
+       return text;
+}
+
+static const struct efi_device_path_to_text_protocol efi_device_path_to_text = 
{
+       .convert_device_node_to_text = efi_convert_device_node_to_text,
+       .convert_device_path_to_text = efi_convert_device_path_to_text,
+};
+
+static int efi_device_path_to_text_init(void)
+{
+       
efi_add_root_node_protocol_deferred(&efi_device_path_to_text_protocol_guid,
+                                           &efi_device_path_to_text);
+       return 0;
+}
+postcore_initcall(efi_device_path_to_text_init);
diff --git a/include/efi/protocol/devicepath.h 
b/include/efi/protocol/devicepath.h
index 19a35888f9cc..ca0cbd94d5ce 100644
--- a/include/efi/protocol/devicepath.h
+++ b/include/efi/protocol/devicepath.h
@@ -4,6 +4,17 @@
 
 #include <efi/types.h>
 
+struct efi_device_path_to_text_protocol {
+       uint16_t *(EFIAPI *convert_device_node_to_text)(
+                       const struct efi_device_path *device_node,
+                       bool display_only,
+                       bool allow_shortcuts);
+       uint16_t *(EFIAPI *convert_device_path_to_text)(
+                       const struct efi_device_path *device_path,
+                       bool display_only,
+                       bool allow_shortcuts);
+};
+
 struct efi_device_path_utilities_protocol {
        size_t (EFIAPI *get_device_path_size)(
                const struct efi_device_path *device_path);
-- 
2.47.3


Reply via email to