]> git.sur5r.net Git - u-boot/blob - lib/efi_loader/efi_device_path_to_text.c
efi_loader: drop redundant efi_device_path_protocol
[u-boot] / 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 *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                         struct efi_device_path_file_path *fp =
60                                 (struct efi_device_path_file_path *)device_node;
61                         buffer_size = device_node->length - 4;
62                         r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
63                                               buffer_size, (void **) &buffer);
64                         if (r != EFI_SUCCESS)
65                                 return NULL;
66                         memcpy(buffer, fp->str, buffer_size);
67                         break;
68                 }
69                 }
70                 break;
71         }
72
73         /*
74          * For all node types that we do not yet support return
75          * 'UNKNOWN(type,subtype)'.
76          */
77         if (!buffer) {
78                 r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
79                                       2 * UNKNOWN_OUTPUT_LEN,
80                                       (void **)&buffer);
81                 if (r != EFI_SUCCESS)
82                         return NULL;
83                 sprintf((char *)buffer,
84                         "UNKNOWN(%04x,%04x)",
85                         device_node->type,
86                         device_node->sub_type);
87                 for (i = UNKNOWN_OUTPUT_LEN - 1; i >= 0; --i)
88                         buffer[i] = ((uint8_t *)buffer)[i];
89         }
90
91         return buffer;
92 }
93
94 static uint16_t EFIAPI *efi_convert_device_node_to_text_ext(
95                 struct efi_device_path *device_node,
96                 bool display_only,
97                 bool allow_shortcuts)
98 {
99         uint16_t *buffer;
100
101         EFI_ENTRY("%p, %d, %d", device_node, display_only, allow_shortcuts);
102
103         buffer = efi_convert_device_node_to_text(device_node, display_only,
104                                                  allow_shortcuts);
105
106         EFI_EXIT(EFI_SUCCESS);
107         return buffer;
108 }
109
110 static uint16_t EFIAPI *efi_convert_device_path_to_text(
111                 struct efi_device_path *device_path,
112                 bool display_only,
113                 bool allow_shortcuts)
114 {
115         uint16_t *buffer;
116
117         EFI_ENTRY("%p, %d, %d", device_path, display_only, allow_shortcuts);
118
119         /*
120          * Our device paths are all of depth one. So its is sufficient to
121          * to convert the first node.
122          */
123         buffer = efi_convert_device_node_to_text(device_path, display_only,
124                                                  allow_shortcuts);
125
126         EFI_EXIT(EFI_SUCCESS);
127         return buffer;
128 }
129
130 const struct efi_device_path_to_text_protocol efi_device_path_to_text = {
131         .convert_device_node_to_text = efi_convert_device_node_to_text_ext,
132         .convert_device_path_to_text = efi_convert_device_path_to_text,
133 };