From 6b9b44319fa1c50d9c91c80cd266b15cbd173ada Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 15 Mar 2013 19:09:45 +0000 Subject: [PATCH] [efi] Add EFI-specific debugging macros Signed-off-by: Michael Brown --- .../ipxe/efi/Protocol/DevicePathToText.h | 87 +++++++++++++++++ src/include/ipxe/efi/efi.h | 34 +++++++ src/interface/efi/efi_debug.c | 95 +++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 src/include/ipxe/efi/Protocol/DevicePathToText.h create mode 100644 src/interface/efi/efi_debug.c diff --git a/src/include/ipxe/efi/Protocol/DevicePathToText.h b/src/include/ipxe/efi/Protocol/DevicePathToText.h new file mode 100644 index 00000000..edca965b --- /dev/null +++ b/src/include/ipxe/efi/Protocol/DevicePathToText.h @@ -0,0 +1,87 @@ +/** @file + EFI_DEVICE_PATH_TO_TEXT_PROTOCOL as defined in UEFI 2.0. + This protocol provides service to convert device nodes and paths to text. + + Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __DEVICE_PATH_TO_TEXT_PROTOCOL_H__ +#define __DEVICE_PATH_TO_TEXT_PROTOCOL_H__ + +FILE_LICENCE ( BSD3 ); + +/// +/// Device Path To Text protocol +/// +#define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \ + { \ + 0x8b843e20, 0x8132, 0x4852, {0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } \ + } + +/** + Convert a device node to its text representation. + + @param DeviceNode Points to the device node to be converted. + @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation + of the display node is used, where applicable. If DisplayOnly + is FALSE, then the longer text representation of the display node + is used. + @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text + representation for a device node can be used, where applicable. + + @retval a_pointer a pointer to the allocated text representation of the device node data + @retval NULL if DeviceNode is NULL or there was insufficient memory. + +**/ +typedef +CHAR16* +(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_NODE)( + IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode, + IN BOOLEAN DisplayOnly, + IN BOOLEAN AllowShortcuts + ); + +/** + Convert a device path to its text representation. + + @param DevicePath Points to the device path to be converted. + @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation + of the display node is used, where applicable. If DisplayOnly + is FALSE, then the longer text representation of the display node + is used. + @param AllowShortcuts The AllowShortcuts is FALSE, then the shortcut forms of + text representation for a device node cannot be used. + + @retval a_pointer a pointer to the allocated text representation of the device node. + @retval NULL if DevicePath is NULL or there was insufficient memory. + +**/ +typedef +CHAR16* +(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_PATH)( + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN BOOLEAN DisplayOnly, + IN BOOLEAN AllowShortcuts + ); + +/// +/// This protocol converts device paths and device nodes to text. +/// +typedef struct { + EFI_DEVICE_PATH_TO_TEXT_NODE ConvertDeviceNodeToText; + EFI_DEVICE_PATH_TO_TEXT_PATH ConvertDevicePathToText; +} EFI_DEVICE_PATH_TO_TEXT_PROTOCOL; + +extern EFI_GUID gEfiDevicePathToTextProtocolGuid; + +#endif + + diff --git a/src/include/ipxe/efi/efi.h b/src/include/ipxe/efi/efi.h index 8a216b53..880872aa 100644 --- a/src/include/ipxe/efi/efi.h +++ b/src/include/ipxe/efi/efi.h @@ -140,6 +140,40 @@ extern EFI_LOADED_IMAGE_PROTOCOL *efi_loaded_image; extern EFI_SYSTEM_TABLE *efi_systab; extern const char * efi_strerror ( EFI_STATUS efirc ); + +extern void dbg_efi_protocols ( EFI_HANDLE handle ); +extern void dbg_efi_devpath ( EFI_DEVICE_PATH_PROTOCOL *path ); + +#define DBG_EFI_PROTOCOLS_IF( level, handle ) do { \ + if ( DBG_ ## level ) { \ + dbg_efi_protocols ( handle ); \ + } \ + } while ( 0 ) + +#define DBG_EFI_DEVPATH_IF( level, path ) do { \ + if ( DBG_ ## level ) { \ + dbg_efi_devpath ( path ); \ + } \ + } while ( 0 ) + +#define DBGC_EFI_PROTOCOLS_IF( level, id, ... ) do { \ + DBG_AC_IF ( level, id ); \ + DBG_EFI_PROTOCOLS_IF ( level, __VA_ARGS__ ); \ + DBG_DC_IF ( level ); \ + } while ( 0 ) + +#define DBGC_EFI_DEVPATH_IF( level, id, ... ) do { \ + DBG_AC_IF ( level, id ); \ + DBG_EFI_DEVPATH_IF ( level, __VA_ARGS__ ); \ + DBG_DC_IF ( level ); \ + } while ( 0 ) + +#define DBGC_EFI_PROTOCOLS( ... ) \ + DBGC_EFI_PROTOCOLS_IF( LOG, ##__VA_ARGS__ ) + +#define DBGC_EFI_DEVPATH( ... ) \ + DBGC_EFI_DEVPATH_IF( LOG, ##__VA_ARGS__ ) + extern EFI_STATUS efi_init ( EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab ); diff --git a/src/interface/efi/efi_debug.c b/src/interface/efi/efi_debug.c new file mode 100644 index 00000000..7f3c115d --- /dev/null +++ b/src/interface/efi/efi_debug.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2013 Michael Brown . + * + * 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 +#include +#include +#include +#include + +/** Device path to text protocol */ +static EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *efidpt; +EFI_REQUIRE_PROTOCOL ( EFI_DEVICE_PATH_TO_TEXT_PROTOCOL, &efidpt ); + +/** + * 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; + + /* Retrieve list of protocols */ + if ( ( efirc = bs->ProtocolsPerHandle ( handle, &protocols, + &count ) ) != 0 ) { + printf ( "EFI could not retrieve protocols for %p: %s\n", + handle, efi_strerror ( efirc ) ); + return; + } + + /* Dump list of protocols */ + for ( i = 0 ; i < count ; i++ ) { + printf ( "%s\n", uuid_ntoa ( ( union uuid * ) protocols[i] ) ); + } + + /* Free list */ + bs->FreePool ( protocols ); +} + +/** + * Print device path + * + * @v path Device path + */ +void dbg_efi_devpath ( EFI_DEVICE_PATH_PROTOCOL *path ) { + EFI_BOOT_SERVICES *bs = efi_systab->BootServices; + EFI_DEVICE_PATH_PROTOCOL *end; + CHAR16 *text; + size_t len; + + /* Convert path to a textual representation */ + text = efidpt->ConvertDevicePathToText ( path, TRUE, FALSE ); + if ( ! text ) { + printf ( ":\n" ); + end = efi_devpath_end ( path ); + len = ( ( ( void * ) end ) - ( ( void * ) path ) + + sizeof ( *end ) ); + dbg_hex_dump_da ( 0, path, len ); + return; + } + + /* Print path */ + printf ( "%ls", text ); + + /* Free path */ + bs->FreePool ( text ); +}