xref: /rk3399_rockchip-uboot/lib/efi_loader/efi_device_path_to_text.c (revision 2218b32d88f9b4b4484cea9a8b034ddab0be298b)
1cc5b7081Sxypron.glpk@gmx.de /*
2cc5b7081Sxypron.glpk@gmx.de  *  EFI device path interface
3cc5b7081Sxypron.glpk@gmx.de  *
4cc5b7081Sxypron.glpk@gmx.de  *  Copyright (c) 2017 Heinrich Schuchardt
5cc5b7081Sxypron.glpk@gmx.de  *
6cc5b7081Sxypron.glpk@gmx.de  *  SPDX-License-Identifier:     GPL-2.0+
7cc5b7081Sxypron.glpk@gmx.de  */
8cc5b7081Sxypron.glpk@gmx.de 
9cc5b7081Sxypron.glpk@gmx.de #include <common.h>
10cc5b7081Sxypron.glpk@gmx.de #include <efi_loader.h>
11cc5b7081Sxypron.glpk@gmx.de 
1209c5ab90Sxypron.glpk@gmx.de #define MAC_OUTPUT_LEN 22
1309c5ab90Sxypron.glpk@gmx.de #define UNKNOWN_OUTPUT_LEN 23
14cc5b7081Sxypron.glpk@gmx.de 
15cc5b7081Sxypron.glpk@gmx.de const efi_guid_t efi_guid_device_path_to_text_protocol =
16cc5b7081Sxypron.glpk@gmx.de 		EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID;
17cc5b7081Sxypron.glpk@gmx.de 
efi_convert_device_node_to_text(struct efi_device_path_protocol * device_node,bool display_only,bool allow_shortcuts)1809c5ab90Sxypron.glpk@gmx.de static uint16_t *efi_convert_device_node_to_text(
19cc5b7081Sxypron.glpk@gmx.de 		struct efi_device_path_protocol *device_node,
20cc5b7081Sxypron.glpk@gmx.de 		bool display_only,
21cc5b7081Sxypron.glpk@gmx.de 		bool allow_shortcuts)
22cc5b7081Sxypron.glpk@gmx.de {
23cc5b7081Sxypron.glpk@gmx.de 	unsigned long buffer_size;
24cc5b7081Sxypron.glpk@gmx.de 	efi_status_t r;
25cc5b7081Sxypron.glpk@gmx.de 	uint16_t *buffer = NULL;
2609c5ab90Sxypron.glpk@gmx.de 	int i;
27cc5b7081Sxypron.glpk@gmx.de 
2809c5ab90Sxypron.glpk@gmx.de 	switch (device_node->type) {
2909c5ab90Sxypron.glpk@gmx.de 	case DEVICE_PATH_TYPE_END:
3009c5ab90Sxypron.glpk@gmx.de 		return NULL;
3109c5ab90Sxypron.glpk@gmx.de 	case DEVICE_PATH_TYPE_MESSAGING_DEVICE:
3209c5ab90Sxypron.glpk@gmx.de 		switch (device_node->sub_type) {
3309c5ab90Sxypron.glpk@gmx.de 		case DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR: {
3409c5ab90Sxypron.glpk@gmx.de 			struct efi_device_path_mac_addr *dp =
3509c5ab90Sxypron.glpk@gmx.de 				(struct efi_device_path_mac_addr *)device_node;
3609c5ab90Sxypron.glpk@gmx.de 
3709c5ab90Sxypron.glpk@gmx.de 			if (dp->if_type != 0 && dp->if_type != 1)
3809c5ab90Sxypron.glpk@gmx.de 				break;
3909c5ab90Sxypron.glpk@gmx.de 			r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
4009c5ab90Sxypron.glpk@gmx.de 					      2 * MAC_OUTPUT_LEN,
4109c5ab90Sxypron.glpk@gmx.de 					      (void **)&buffer);
4209c5ab90Sxypron.glpk@gmx.de 			if (r != EFI_SUCCESS)
4309c5ab90Sxypron.glpk@gmx.de 				return NULL;
4409c5ab90Sxypron.glpk@gmx.de 			sprintf((char *)buffer,
4509c5ab90Sxypron.glpk@gmx.de 				"MAC(%02x%02x%02x%02x%02x%02x,0x%1x)",
4609c5ab90Sxypron.glpk@gmx.de 				dp->mac.addr[0], dp->mac.addr[1],
4709c5ab90Sxypron.glpk@gmx.de 				dp->mac.addr[2], dp->mac.addr[3],
4809c5ab90Sxypron.glpk@gmx.de 				dp->mac.addr[4], dp->mac.addr[5],
4909c5ab90Sxypron.glpk@gmx.de 				dp->if_type);
5009c5ab90Sxypron.glpk@gmx.de 			for (i = MAC_OUTPUT_LEN - 1; i >= 0; --i)
5109c5ab90Sxypron.glpk@gmx.de 				buffer[i] = ((uint8_t *)buffer)[i];
5209c5ab90Sxypron.glpk@gmx.de 			break;
5309c5ab90Sxypron.glpk@gmx.de 			}
5409c5ab90Sxypron.glpk@gmx.de 		}
55*6cfd5f13SRob Clark 		break;
5609c5ab90Sxypron.glpk@gmx.de 	case DEVICE_PATH_TYPE_MEDIA_DEVICE:
5709c5ab90Sxypron.glpk@gmx.de 		switch (device_node->sub_type) {
5809c5ab90Sxypron.glpk@gmx.de 		case DEVICE_PATH_SUB_TYPE_FILE_PATH:
5909c5ab90Sxypron.glpk@gmx.de 			buffer_size = device_node->length - 4;
60cc5b7081Sxypron.glpk@gmx.de 			r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
61cc5b7081Sxypron.glpk@gmx.de 					      buffer_size, (void **) &buffer);
6209c5ab90Sxypron.glpk@gmx.de 			if (r != EFI_SUCCESS)
6309c5ab90Sxypron.glpk@gmx.de 				return NULL;
6409c5ab90Sxypron.glpk@gmx.de 			memcpy(buffer, device_node->data, buffer_size);
65cc5b7081Sxypron.glpk@gmx.de 			break;
66cc5b7081Sxypron.glpk@gmx.de 		}
67*6cfd5f13SRob Clark 		break;
68cc5b7081Sxypron.glpk@gmx.de 	}
69cc5b7081Sxypron.glpk@gmx.de 
7009c5ab90Sxypron.glpk@gmx.de 	/*
7109c5ab90Sxypron.glpk@gmx.de 	 * For all node types that we do not yet support return
7209c5ab90Sxypron.glpk@gmx.de 	 * 'UNKNOWN(type,subtype)'.
7309c5ab90Sxypron.glpk@gmx.de 	 */
7409c5ab90Sxypron.glpk@gmx.de 	if (!buffer) {
7509c5ab90Sxypron.glpk@gmx.de 		r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
7609c5ab90Sxypron.glpk@gmx.de 				      2 * UNKNOWN_OUTPUT_LEN,
7709c5ab90Sxypron.glpk@gmx.de 				      (void **)&buffer);
7809c5ab90Sxypron.glpk@gmx.de 		if (r != EFI_SUCCESS)
7909c5ab90Sxypron.glpk@gmx.de 			return NULL;
8009c5ab90Sxypron.glpk@gmx.de 		sprintf((char *)buffer,
8109c5ab90Sxypron.glpk@gmx.de 			"UNKNOWN(%04x,%04x)",
8209c5ab90Sxypron.glpk@gmx.de 			device_node->type,
8309c5ab90Sxypron.glpk@gmx.de 			device_node->sub_type);
8409c5ab90Sxypron.glpk@gmx.de 		for (i = UNKNOWN_OUTPUT_LEN - 1; i >= 0; --i)
8509c5ab90Sxypron.glpk@gmx.de 			buffer[i] = ((uint8_t *)buffer)[i];
86cc5b7081Sxypron.glpk@gmx.de 	}
87cc5b7081Sxypron.glpk@gmx.de 
88cc5b7081Sxypron.glpk@gmx.de 	return buffer;
89cc5b7081Sxypron.glpk@gmx.de }
90cc5b7081Sxypron.glpk@gmx.de 
efi_convert_device_node_to_text_ext(struct efi_device_path_protocol * device_node,bool display_only,bool allow_shortcuts)9109c5ab90Sxypron.glpk@gmx.de static uint16_t EFIAPI *efi_convert_device_node_to_text_ext(
9209c5ab90Sxypron.glpk@gmx.de 		struct efi_device_path_protocol *device_node,
9309c5ab90Sxypron.glpk@gmx.de 		bool display_only,
9409c5ab90Sxypron.glpk@gmx.de 		bool allow_shortcuts)
9509c5ab90Sxypron.glpk@gmx.de {
9609c5ab90Sxypron.glpk@gmx.de 	uint16_t *buffer;
9709c5ab90Sxypron.glpk@gmx.de 
9809c5ab90Sxypron.glpk@gmx.de 	EFI_ENTRY("%p, %d, %d", device_node, display_only, allow_shortcuts);
9909c5ab90Sxypron.glpk@gmx.de 
10009c5ab90Sxypron.glpk@gmx.de 	buffer = efi_convert_device_node_to_text(device_node, display_only,
10109c5ab90Sxypron.glpk@gmx.de 						 allow_shortcuts);
10209c5ab90Sxypron.glpk@gmx.de 
10309c5ab90Sxypron.glpk@gmx.de 	EFI_EXIT(EFI_SUCCESS);
10409c5ab90Sxypron.glpk@gmx.de 	return buffer;
10509c5ab90Sxypron.glpk@gmx.de }
10609c5ab90Sxypron.glpk@gmx.de 
efi_convert_device_path_to_text(struct efi_device_path_protocol * device_path,bool display_only,bool allow_shortcuts)10709c5ab90Sxypron.glpk@gmx.de static uint16_t EFIAPI *efi_convert_device_path_to_text(
10809c5ab90Sxypron.glpk@gmx.de 		struct efi_device_path_protocol *device_path,
10909c5ab90Sxypron.glpk@gmx.de 		bool display_only,
11009c5ab90Sxypron.glpk@gmx.de 		bool allow_shortcuts)
11109c5ab90Sxypron.glpk@gmx.de {
11209c5ab90Sxypron.glpk@gmx.de 	uint16_t *buffer;
11309c5ab90Sxypron.glpk@gmx.de 
11409c5ab90Sxypron.glpk@gmx.de 	EFI_ENTRY("%p, %d, %d", device_path, display_only, allow_shortcuts);
11509c5ab90Sxypron.glpk@gmx.de 
11609c5ab90Sxypron.glpk@gmx.de 	/*
11709c5ab90Sxypron.glpk@gmx.de 	 * Our device paths are all of depth one. So its is sufficient to
11809c5ab90Sxypron.glpk@gmx.de 	 * to convert the first node.
11909c5ab90Sxypron.glpk@gmx.de 	 */
12009c5ab90Sxypron.glpk@gmx.de 	buffer = efi_convert_device_node_to_text(device_path, display_only,
12109c5ab90Sxypron.glpk@gmx.de 						 allow_shortcuts);
12209c5ab90Sxypron.glpk@gmx.de 
12309c5ab90Sxypron.glpk@gmx.de 	EFI_EXIT(EFI_SUCCESS);
12409c5ab90Sxypron.glpk@gmx.de 	return buffer;
12509c5ab90Sxypron.glpk@gmx.de }
12609c5ab90Sxypron.glpk@gmx.de 
127cc5b7081Sxypron.glpk@gmx.de const struct efi_device_path_to_text_protocol efi_device_path_to_text = {
12809c5ab90Sxypron.glpk@gmx.de 	.convert_device_node_to_text = efi_convert_device_node_to_text_ext,
129cc5b7081Sxypron.glpk@gmx.de 	.convert_device_path_to_text = efi_convert_device_path_to_text,
130cc5b7081Sxypron.glpk@gmx.de };
131