]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Add ability to dump all openers of a given protocol on a handle
authorMichael Brown <mcb30@ipxe.org>
Wed, 30 Jul 2014 23:09:58 +0000 (00:09 +0100)
committerMichael Brown <mcb30@ipxe.org>
Thu, 31 Jul 2014 00:50:05 +0000 (01:50 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/efi/efi.h
src/interface/efi/efi_debug.c

index b5537dd6cc4eb30a99484a15fbe831295cee17fc..51b501c1107a5e55758507ec1c4fd7eaa93507a4 100644 (file)
@@ -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 );
index b3cb9cb59ddc7556b550f1e00d1889b0ce02c07f..21bb5fc676fd6a280934495aa5f24e7a39437212 100644 (file)
@@ -183,6 +183,77 @@ const char * efi_guid_ntoa ( EFI_GUID *guid ) {
        return uuid_ntoa ( &u.uuid );
 }
 
+/**
+ * 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
  *
@@ -190,7 +261,8 @@ const char * efi_guid_ntoa ( EFI_GUID *guid ) {
  */
 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 );