aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2014-07-31 00:09:58 +0100
committerMichael Brown <mcb30@ipxe.org>2014-07-31 01:50:05 +0100
commit736fcf60d1db389941b4f15f94c31fe0403552a8 (patch)
tree248399626c3d9346d9384d010b8edc2b965a8a2a
parent550f212d157f9f3ae025bbdb654c4184467ad826 (diff)
downloadipxe-736fcf60d1db389941b4f15f94c31fe0403552a8.tar.gz
[efi] Add ability to dump all openers of a given protocol on a handle
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/include/ipxe/efi/efi.h27
-rw-r--r--src/interface/efi/efi_debug.c83
2 files changed, 106 insertions, 4 deletions
diff --git a/src/include/ipxe/efi/efi.h b/src/include/ipxe/efi/efi.h
index b5537dd6c..51b501c11 100644
--- a/src/include/ipxe/efi/efi.h
+++ b/src/include/ipxe/efi/efi.h
@@ -153,22 +153,47 @@ extern const char * efi_devpath_text ( EFI_DEVICE_PATH_PROTOCOL *path );
extern const char * efi_handle_devpath_text ( EFI_HANDLE handle );
extern const char * efi_handle_name ( EFI_HANDLE handle );
+extern void dbg_efi_openers ( EFI_HANDLE handle, EFI_GUID *protocol );
extern void dbg_efi_protocols ( EFI_HANDLE handle );
+#define DBG_EFI_OPENERS_IF( level, handle, protocol ) do { \
+ if ( DBG_ ## level ) { \
+ dbg_efi_openers ( handle, protocol ); \
+ } \
+ } while ( 0 )
+
#define DBG_EFI_PROTOCOLS_IF( level, handle ) do { \
if ( DBG_ ## level ) { \
dbg_efi_protocols ( handle ); \
} \
} while ( 0 )
+#define DBGC_EFI_OPENERS_IF( level, id, ... ) do { \
+ DBG_AC_IF ( level, id ); \
+ DBG_EFI_OPENERS_IF ( level, __VA_ARGS__ ); \
+ DBG_DC_IF ( level ); \
+ } 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_OPENERS( ... ) \
+ DBGC_EFI_OPENERS_IF ( LOG, ##__VA_ARGS__ )
#define DBGC_EFI_PROTOCOLS( ... ) \
- DBGC_EFI_PROTOCOLS_IF( LOG, ##__VA_ARGS__ )
+ DBGC_EFI_PROTOCOLS_IF ( LOG, ##__VA_ARGS__ )
+
+#define DBGC2_EFI_OPENERS( ... ) \
+ DBGC_EFI_OPENERS_IF ( EXTRA, ##__VA_ARGS__ )
+#define DBGC2_EFI_PROTOCOLS( ... ) \
+ DBGC_EFI_PROTOCOLS_IF ( EXTRA, ##__VA_ARGS__ )
+
+#define DBGCP_EFI_OPENERS( ... ) \
+ DBGC_EFI_OPENERS_IF ( PROFILE, ##__VA_ARGS__ )
+#define DBGCP_EFI_PROTOCOLS( ... ) \
+ DBGC_EFI_PROTOCOLS_IF ( PROFILE, ##__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
index b3cb9cb59..21bb5fc67 100644
--- a/src/interface/efi/efi_debug.c
+++ b/src/interface/efi/efi_debug.c
@@ -184,13 +184,85 @@ const char * efi_guid_ntoa ( EFI_GUID *guid ) {
}
/**
+ * Name protocol open attributes
+ *
+ * @v attributes Protocol open attributes
+ * @ret name Protocol open attributes name
+ *
+ * Returns a (static) string with characters for each set bit
+ * corresponding to BY_(H)ANDLE_PROTOCOL, (G)ET_PROTOCOL,
+ * (T)EST_PROTOCOL, BY_(C)HILD_CONTROLLER, BY_(D)RIVER, and
+ * E(X)CLUSIVE.
+ */
+static const char * efi_open_attributes_name ( unsigned int attributes ) {
+ static char attribute_chars[] = "HGTCDX";
+ static char name[ sizeof ( attribute_chars ) ];
+ char *tmp = name;
+ unsigned int i;
+
+ for ( i = 0 ; i < ( sizeof ( attribute_chars ) - 1 ) ; i++ ) {
+ if ( attributes & ( 1 << i ) )
+ *(tmp++) = attribute_chars[i];
+ }
+ *tmp = '\0';
+
+ return name;
+}
+
+/**
+ * Print list of openers of a given protocol on a given handle
+ *
+ * @v handle EFI handle
+ * @v protocol Protocol GUID
+ */
+void dbg_efi_openers ( EFI_HANDLE handle, EFI_GUID *protocol ) {
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *openers;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *opener;
+ UINTN count;
+ unsigned int i;
+ EFI_STATUS efirc;
+ int rc;
+
+ /* Retrieve list of openers */
+ if ( ( efirc = bs->OpenProtocolInformation ( handle, protocol, &openers,
+ &count ) ) != 0 ) {
+ rc = -EEFI ( efirc );
+ printf ( "EFI could not retrieve openers for %s on %p: %s\n",
+ efi_guid_ntoa ( protocol ), handle, strerror ( rc ) );
+ return;
+ }
+
+ /* Dump list of openers */
+ for ( i = 0 ; i < count ; i++ ) {
+ opener = &openers[i];
+ printf ( "HANDLE %p %s %s opened %dx (%s)",
+ handle, efi_handle_name ( handle ),
+ efi_guid_ntoa ( protocol ), opener->OpenCount,
+ efi_open_attributes_name ( opener->Attributes ) );
+ printf ( " by %p %s", opener->AgentHandle,
+ efi_handle_name ( opener->AgentHandle ) );
+ if ( opener->ControllerHandle == handle ) {
+ printf ( "\n" );
+ } else {
+ printf ( " for %p %s\n", opener->ControllerHandle,
+ efi_handle_name ( opener->ControllerHandle ) );
+ }
+ }
+
+ /* Free list */
+ bs->FreePool ( openers );
+}
+
+/**
* 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;
+ EFI_GUID **protocols;
+ EFI_GUID *protocol;
UINTN count;
unsigned int i;
EFI_STATUS efirc;
@@ -206,8 +278,13 @@ void dbg_efi_protocols ( EFI_HANDLE handle ) {
}
/* Dump list of protocols */
- for ( i = 0 ; i < count ; i++ )
- printf ( "%s\n", efi_guid_ntoa ( protocols[i] ) );
+ for ( i = 0 ; i < count ; i++ ) {
+ protocol = protocols[i];
+ printf ( "HANDLE %p %s %s supported\n",
+ handle, efi_handle_name ( handle ),
+ efi_guid_ntoa ( protocol ) );
+ dbg_efi_openers ( handle, protocol );
+ }
/* Free list */
bs->FreePool ( protocols );