2013-03-15 19:09:45 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
|
|
|
* License, or any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
|
|
|
* 02110-1301, USA.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
FILE_LICENCE ( GPL2_OR_LATER );
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @file
|
|
|
|
|
*
|
|
|
|
|
* EFI debugging utilities
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2013-03-20 15:25:16 +00:00
|
|
|
#include <string.h>
|
2013-04-18 21:29:53 +01:00
|
|
|
#include <errno.h>
|
2013-03-20 15:25:16 +00:00
|
|
|
#include <ipxe/uuid.h>
|
2013-03-15 19:09:45 +00:00
|
|
|
#include <ipxe/efi/efi.h>
|
|
|
|
|
#include <ipxe/efi/efi_driver.h>
|
|
|
|
|
#include <ipxe/efi/Protocol/DevicePath.h>
|
|
|
|
|
#include <ipxe/efi/Protocol/DevicePathToText.h>
|
2014-07-16 02:16:24 +01:00
|
|
|
#include <ipxe/efi/Protocol/BlockIo.h>
|
|
|
|
|
#include <ipxe/efi/Protocol/DiskIo.h>
|
|
|
|
|
#include <ipxe/efi/Protocol/SimpleFileSystem.h>
|
|
|
|
|
#include <ipxe/efi/Protocol/SimpleNetwork.h>
|
2013-03-15 19:09:45 +00:00
|
|
|
|
2014-06-25 14:44:13 +01:00
|
|
|
/** Device path protocol GUID */
|
|
|
|
|
static EFI_GUID efi_device_path_protocol_guid
|
|
|
|
|
= EFI_DEVICE_PATH_PROTOCOL_GUID;
|
|
|
|
|
|
2013-03-15 19:09:45 +00:00
|
|
|
/** Device path to text protocol */
|
|
|
|
|
static EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *efidpt;
|
2014-05-19 20:24:04 +01:00
|
|
|
EFI_REQUEST_PROTOCOL ( EFI_DEVICE_PATH_TO_TEXT_PROTOCOL, &efidpt );
|
2013-03-15 19:09:45 +00:00
|
|
|
|
2014-07-16 02:16:24 +01:00
|
|
|
/** A well-known GUID */
|
|
|
|
|
struct efi_well_known_guid {
|
|
|
|
|
/** GUID */
|
|
|
|
|
EFI_GUID guid;
|
|
|
|
|
/** Name */
|
|
|
|
|
const char *name;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** Well-known GUIDs */
|
|
|
|
|
static struct efi_well_known_guid efi_well_known_guids[] = {
|
|
|
|
|
{ EFI_BLOCK_IO_PROTOCOL_GUID, "BlockIo" },
|
|
|
|
|
{ EFI_DISK_IO_PROTOCOL_GUID, "DiskIo" },
|
|
|
|
|
{ EFI_DEVICE_PATH_PROTOCOL_GUID, "DevicePath" },
|
|
|
|
|
{ EFI_LOADED_IMAGE_PROTOCOL_GUID, "LoadedImage" },
|
2014-07-26 11:22:36 +01:00
|
|
|
{ EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID, "LoadedImageDevicePath" },
|
2014-07-16 02:16:24 +01:00
|
|
|
{ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, "SimpleFileSystem" },
|
|
|
|
|
{ EFI_SIMPLE_NETWORK_PROTOCOL_GUID, "SimpleNetwork" },
|
|
|
|
|
};
|
|
|
|
|
|
2013-03-20 15:25:16 +00:00
|
|
|
/**
|
|
|
|
|
* Convert GUID to a printable string
|
|
|
|
|
*
|
|
|
|
|
* @v guid GUID
|
|
|
|
|
* @ret string Printable string
|
|
|
|
|
*/
|
|
|
|
|
const char * efi_guid_ntoa ( EFI_GUID *guid ) {
|
|
|
|
|
union {
|
|
|
|
|
union uuid uuid;
|
|
|
|
|
EFI_GUID guid;
|
|
|
|
|
} u;
|
2014-07-16 02:16:24 +01:00
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
|
|
/* Check for a match against well-known GUIDs */
|
|
|
|
|
for ( i = 0 ; i < ( sizeof ( efi_well_known_guids ) /
|
|
|
|
|
sizeof ( efi_well_known_guids[0] ) ) ; i++ ) {
|
|
|
|
|
if ( memcmp ( guid, &efi_well_known_guids[i].guid,
|
|
|
|
|
sizeof ( *guid ) ) == 0 ) {
|
|
|
|
|
return efi_well_known_guids[i].name;
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-03-20 15:25:16 +00:00
|
|
|
|
|
|
|
|
/* Convert GUID to standard endianness */
|
|
|
|
|
memcpy ( &u.guid, guid, sizeof ( u.guid ) );
|
|
|
|
|
uuid_mangle ( &u.uuid );
|
|
|
|
|
return uuid_ntoa ( &u.uuid );
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-15 19:09:45 +00:00
|
|
|
/**
|
|
|
|
|
* Print list of protocol handlers attached to a handle
|
|
|
|
|
*
|
|
|
|
|
* @v handle EFI handle
|
|
|
|
|
*/
|
|
|
|
|
void dbg_efi_protocols ( EFI_HANDLE handle ) {
|
|
|
|
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
|
|
|
|
EFI_GUID **protocols;
|
|
|
|
|
UINTN count;
|
|
|
|
|
unsigned int i;
|
|
|
|
|
EFI_STATUS efirc;
|
2013-04-18 21:29:53 +01:00
|
|
|
int rc;
|
2013-03-15 19:09:45 +00:00
|
|
|
|
|
|
|
|
/* Retrieve list of protocols */
|
|
|
|
|
if ( ( efirc = bs->ProtocolsPerHandle ( handle, &protocols,
|
|
|
|
|
&count ) ) != 0 ) {
|
2013-04-18 21:29:53 +01:00
|
|
|
rc = -EEFI ( efirc );
|
2013-03-15 19:09:45 +00:00
|
|
|
printf ( "EFI could not retrieve protocols for %p: %s\n",
|
2013-04-18 21:29:53 +01:00
|
|
|
handle, strerror ( rc ) );
|
2013-03-15 19:09:45 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Dump list of protocols */
|
2013-03-20 15:25:16 +00:00
|
|
|
for ( i = 0 ; i < count ; i++ )
|
|
|
|
|
printf ( "%s\n", efi_guid_ntoa ( protocols[i] ) );
|
2013-03-15 19:09:45 +00:00
|
|
|
|
|
|
|
|
/* Free list */
|
|
|
|
|
bs->FreePool ( protocols );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2014-06-25 14:44:13 +01:00
|
|
|
* Get textual representation of device path
|
2013-03-15 19:09:45 +00:00
|
|
|
*
|
|
|
|
|
* @v path Device path
|
2014-06-25 14:44:13 +01:00
|
|
|
* @ret text Textual representation of device path, or NULL
|
2013-03-15 19:09:45 +00:00
|
|
|
*/
|
2014-06-25 14:44:13 +01:00
|
|
|
const char * efi_devpath_text ( EFI_DEVICE_PATH_PROTOCOL *path ) {
|
2013-03-15 19:09:45 +00:00
|
|
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
2014-06-25 14:44:13 +01:00
|
|
|
static char text[256];
|
|
|
|
|
CHAR16 *wtext;
|
2013-03-15 19:09:45 +00:00
|
|
|
|
|
|
|
|
/* Convert path to a textual representation */
|
2014-05-19 20:24:04 +01:00
|
|
|
if ( ! efidpt )
|
2014-06-25 14:44:13 +01:00
|
|
|
return NULL;
|
|
|
|
|
wtext = efidpt->ConvertDevicePathToText ( path, TRUE, FALSE );
|
|
|
|
|
if ( ! wtext )
|
|
|
|
|
return NULL;
|
2013-03-15 19:09:45 +00:00
|
|
|
|
2014-06-25 14:44:13 +01:00
|
|
|
/* Store path in buffer */
|
|
|
|
|
snprintf ( text, sizeof ( text ), "%ls", wtext );
|
2013-03-15 19:09:45 +00:00
|
|
|
|
|
|
|
|
/* Free path */
|
2014-06-25 14:44:13 +01:00
|
|
|
bs->FreePool ( wtext );
|
|
|
|
|
|
|
|
|
|
return text;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get textual representation of device path for a handle
|
|
|
|
|
*
|
|
|
|
|
* @v handle EFI handle
|
|
|
|
|
* @ret text Textual representation of device path, or NULL
|
|
|
|
|
*/
|
|
|
|
|
const char * efi_handle_devpath_text ( EFI_HANDLE handle ) {
|
|
|
|
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
|
|
|
|
union {
|
|
|
|
|
EFI_DEVICE_PATH_PROTOCOL *path;
|
|
|
|
|
void *interface;
|
|
|
|
|
} path;
|
|
|
|
|
const char *text;
|
|
|
|
|
EFI_STATUS efirc;
|
|
|
|
|
|
|
|
|
|
/* Obtain device path, if any */
|
|
|
|
|
if ( ( efirc = bs->OpenProtocol ( handle,
|
|
|
|
|
&efi_device_path_protocol_guid,
|
|
|
|
|
&path.interface, efi_image_handle,
|
|
|
|
|
handle,
|
|
|
|
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Format device path */
|
|
|
|
|
text = efi_devpath_text ( path.path );
|
2014-05-19 20:24:04 +01:00
|
|
|
|
2014-06-25 14:44:13 +01:00
|
|
|
/* Close device path */
|
|
|
|
|
bs->CloseProtocol ( handle, &efi_device_path_protocol_guid,
|
|
|
|
|
efi_image_handle, handle );
|
2014-05-19 20:24:04 +01:00
|
|
|
|
2014-06-25 14:44:13 +01:00
|
|
|
return text;
|
2013-03-15 19:09:45 +00:00
|
|
|
}
|