]> git.ipfire.org Git - people/ms/u-boot.git/blob - lib/efi_loader/efi_device_path_to_text.c
Merge git://git.denx.de/u-boot-dm
[people/ms/u-boot.git] / lib / efi_loader / efi_device_path_to_text.c
1 /*
2 * EFI device path interface
3 *
4 * Copyright (c) 2017 Heinrich Schuchardt
5 *
6 * SPDX-License-Identifier: GPL-2.0+
7 */
8
9 #include <common.h>
10 #include <efi_loader.h>
11
12 #define MAC_OUTPUT_LEN 22
13 #define UNKNOWN_OUTPUT_LEN 23
14
15 const efi_guid_t efi_guid_device_path_to_text_protocol =
16 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID;
17
18 static uint16_t *efi_convert_device_node_to_text(
19 struct efi_device_path_protocol *device_node,
20 bool display_only,
21 bool allow_shortcuts)
22 {
23 unsigned long buffer_size;
24 efi_status_t r;
25 uint16_t *buffer = NULL;
26 int i;
27
28 switch (device_node->type) {
29 case DEVICE_PATH_TYPE_END:
30 return NULL;
31 case DEVICE_PATH_TYPE_MESSAGING_DEVICE:
32 switch (device_node->sub_type) {
33 case DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR: {
34 struct efi_device_path_mac_addr *dp =
35 (struct efi_device_path_mac_addr *)device_node;
36
37 if (dp->if_type != 0 && dp->if_type != 1)
38 break;
39 r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
40 2 * MAC_OUTPUT_LEN,
41 (void **)&buffer);
42 if (r != EFI_SUCCESS)
43 return NULL;
44 sprintf((char *)buffer,
45 "MAC(%02x%02x%02x%02x%02x%02x,0x%1x)",
46 dp->mac.addr[0], dp->mac.addr[1],
47 dp->mac.addr[2], dp->mac.addr[3],
48 dp->mac.addr[4], dp->mac.addr[5],
49 dp->if_type);
50 for (i = MAC_OUTPUT_LEN - 1; i >= 0; --i)
51 buffer[i] = ((uint8_t *)buffer)[i];
52 break;
53 }
54 }
55 break;
56 case DEVICE_PATH_TYPE_MEDIA_DEVICE:
57 switch (device_node->sub_type) {
58 case DEVICE_PATH_SUB_TYPE_FILE_PATH:
59 buffer_size = device_node->length - 4;
60 r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
61 buffer_size, (void **) &buffer);
62 if (r != EFI_SUCCESS)
63 return NULL;
64 memcpy(buffer, device_node->data, buffer_size);
65 break;
66 }
67 break;
68 }
69
70 /*
71 * For all node types that we do not yet support return
72 * 'UNKNOWN(type,subtype)'.
73 */
74 if (!buffer) {
75 r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
76 2 * UNKNOWN_OUTPUT_LEN,
77 (void **)&buffer);
78 if (r != EFI_SUCCESS)
79 return NULL;
80 sprintf((char *)buffer,
81 "UNKNOWN(%04x,%04x)",
82 device_node->type,
83 device_node->sub_type);
84 for (i = UNKNOWN_OUTPUT_LEN - 1; i >= 0; --i)
85 buffer[i] = ((uint8_t *)buffer)[i];
86 }
87
88 return buffer;
89 }
90
91 static uint16_t EFIAPI *efi_convert_device_node_to_text_ext(
92 struct efi_device_path_protocol *device_node,
93 bool display_only,
94 bool allow_shortcuts)
95 {
96 uint16_t *buffer;
97
98 EFI_ENTRY("%p, %d, %d", device_node, display_only, allow_shortcuts);
99
100 buffer = efi_convert_device_node_to_text(device_node, display_only,
101 allow_shortcuts);
102
103 EFI_EXIT(EFI_SUCCESS);
104 return buffer;
105 }
106
107 static uint16_t EFIAPI *efi_convert_device_path_to_text(
108 struct efi_device_path_protocol *device_path,
109 bool display_only,
110 bool allow_shortcuts)
111 {
112 uint16_t *buffer;
113
114 EFI_ENTRY("%p, %d, %d", device_path, display_only, allow_shortcuts);
115
116 /*
117 * Our device paths are all of depth one. So its is sufficient to
118 * to convert the first node.
119 */
120 buffer = efi_convert_device_node_to_text(device_path, display_only,
121 allow_shortcuts);
122
123 EFI_EXIT(EFI_SUCCESS);
124 return buffer;
125 }
126
127 const struct efi_device_path_to_text_protocol efi_device_path_to_text = {
128 .convert_device_node_to_text = efi_convert_device_node_to_text_ext,
129 .convert_device_path_to_text = efi_convert_device_path_to_text,
130 };