efi_loader: implement ConvertDeviceNodeToText

Move the logic for converting a node to text from
efi_convert_device_path_to_text to convert_device_node_to_text.

Provide a wrapper function convert_device_node_to_text_ext.

As we use only shallow device paths so we can call
directly call efi_device_node_to_text from efi_device_path_to_text.

Add output for MAC addresses.

Add output for not yet supported types/subtypes.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
xypron.glpk@gmx.de 2017-07-21 19:12:08 +02:00 committed by Alexander Graf
parent c6e3c3e68a
commit 09c5ab909c

View file

@ -9,59 +9,120 @@
#include <common.h> #include <common.h>
#include <efi_loader.h> #include <efi_loader.h>
#define MEDIA_DEVICE_PATH 4 #define MAC_OUTPUT_LEN 22
#define FILE_PATH_MEDIA_DEVICE_PATH 4 #define UNKNOWN_OUTPUT_LEN 23
const efi_guid_t efi_guid_device_path_to_text_protocol = const efi_guid_t efi_guid_device_path_to_text_protocol =
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID; EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID;
uint16_t *efi_convert_device_node_to_text( static uint16_t *efi_convert_device_node_to_text(
struct efi_device_path_protocol *device_node, struct efi_device_path_protocol *device_node,
bool display_only, bool display_only,
bool allow_shortcuts) bool allow_shortcuts)
{ {
EFI_ENTRY("%p, %d, %d", device_node, display_only, allow_shortcuts);
EFI_EXIT(EFI_UNSUPPORTED);
return NULL;
}
uint16_t *efi_convert_device_path_to_text(
struct efi_device_path_protocol *device_path,
bool display_only,
bool allow_shortcuts)
{
EFI_ENTRY("%p, %d, %d", device_path, display_only, allow_shortcuts);
unsigned long buffer_size; unsigned long buffer_size;
efi_status_t r; efi_status_t r;
uint16_t *buffer = NULL; uint16_t *buffer = NULL;
int i;
switch (device_path->type) { switch (device_node->type) {
case MEDIA_DEVICE_PATH: case DEVICE_PATH_TYPE_END:
switch (device_path->sub_type) { return NULL;
case FILE_PATH_MEDIA_DEVICE_PATH: case DEVICE_PATH_TYPE_MESSAGING_DEVICE:
buffer_size = device_path->length - 4; switch (device_node->sub_type) {
case DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR: {
struct efi_device_path_mac_addr *dp =
(struct efi_device_path_mac_addr *)device_node;
if (dp->if_type != 0 && dp->if_type != 1)
break;
r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
2 * MAC_OUTPUT_LEN,
(void **)&buffer);
if (r != EFI_SUCCESS)
return NULL;
sprintf((char *)buffer,
"MAC(%02x%02x%02x%02x%02x%02x,0x%1x)",
dp->mac.addr[0], dp->mac.addr[1],
dp->mac.addr[2], dp->mac.addr[3],
dp->mac.addr[4], dp->mac.addr[5],
dp->if_type);
for (i = MAC_OUTPUT_LEN - 1; i >= 0; --i)
buffer[i] = ((uint8_t *)buffer)[i];
break;
}
}
case DEVICE_PATH_TYPE_MEDIA_DEVICE:
switch (device_node->sub_type) {
case DEVICE_PATH_SUB_TYPE_FILE_PATH:
buffer_size = device_node->length - 4;
r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
buffer_size, (void **) &buffer); buffer_size, (void **) &buffer);
if (r == EFI_SUCCESS) if (r != EFI_SUCCESS)
memcpy(buffer, device_path->data, buffer_size); return NULL;
memcpy(buffer, device_node->data, buffer_size);
break; break;
} }
} }
if (buffer) { /*
EFI_EXIT(EFI_SUCCESS); * For all node types that we do not yet support return
} else { * 'UNKNOWN(type,subtype)'.
debug("type %d, subtype %d\n", */
device_path->type, device_path->sub_type); if (!buffer) {
EFI_EXIT(EFI_UNSUPPORTED); r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
2 * UNKNOWN_OUTPUT_LEN,
(void **)&buffer);
if (r != EFI_SUCCESS)
return NULL;
sprintf((char *)buffer,
"UNKNOWN(%04x,%04x)",
device_node->type,
device_node->sub_type);
for (i = UNKNOWN_OUTPUT_LEN - 1; i >= 0; --i)
buffer[i] = ((uint8_t *)buffer)[i];
} }
return buffer; return buffer;
} }
static uint16_t EFIAPI *efi_convert_device_node_to_text_ext(
struct efi_device_path_protocol *device_node,
bool display_only,
bool allow_shortcuts)
{
uint16_t *buffer;
EFI_ENTRY("%p, %d, %d", device_node, display_only, allow_shortcuts);
buffer = efi_convert_device_node_to_text(device_node, display_only,
allow_shortcuts);
EFI_EXIT(EFI_SUCCESS);
return buffer;
}
static uint16_t EFIAPI *efi_convert_device_path_to_text(
struct efi_device_path_protocol *device_path,
bool display_only,
bool allow_shortcuts)
{
uint16_t *buffer;
EFI_ENTRY("%p, %d, %d", device_path, display_only, allow_shortcuts);
/*
* Our device paths are all of depth one. So its is sufficient to
* to convert the first node.
*/
buffer = efi_convert_device_node_to_text(device_path, display_only,
allow_shortcuts);
EFI_EXIT(EFI_SUCCESS);
return buffer;
}
const struct efi_device_path_to_text_protocol efi_device_path_to_text = { 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_node_to_text = efi_convert_device_node_to_text_ext,
.convert_device_path_to_text = efi_convert_device_path_to_text, .convert_device_path_to_text = efi_convert_device_path_to_text,
}; };