You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

efi_debug.c 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. */
  19. FILE_LICENCE ( GPL2_OR_LATER );
  20. /**
  21. * @file
  22. *
  23. * EFI debugging utilities
  24. *
  25. */
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <errno.h>
  29. #include <ipxe/uuid.h>
  30. #include <ipxe/efi/efi.h>
  31. #include <ipxe/efi/efi_driver.h>
  32. #include <ipxe/efi/Protocol/BlockIo.h>
  33. #include <ipxe/efi/Protocol/BusSpecificDriverOverride.h>
  34. #include <ipxe/efi/Protocol/ComponentName.h>
  35. #include <ipxe/efi/Protocol/ComponentName2.h>
  36. #include <ipxe/efi/Protocol/DevicePath.h>
  37. #include <ipxe/efi/Protocol/DevicePathToText.h>
  38. #include <ipxe/efi/Protocol/DiskIo.h>
  39. #include <ipxe/efi/Protocol/DriverBinding.h>
  40. #include <ipxe/efi/Protocol/LoadFile.h>
  41. #include <ipxe/efi/Protocol/LoadFile2.h>
  42. #include <ipxe/efi/Protocol/LoadedImage.h>
  43. #include <ipxe/efi/Protocol/PciIo.h>
  44. #include <ipxe/efi/Protocol/PciRootBridgeIo.h>
  45. #include <ipxe/efi/Protocol/SimpleFileSystem.h>
  46. #include <ipxe/efi/Protocol/SimpleNetwork.h>
  47. /** Block I/O protocol GUID */
  48. static EFI_GUID efi_block_io_protocol_guid
  49. = EFI_BLOCK_IO_PROTOCOL_GUID;
  50. /** Bus specific driver override protocol GUID */
  51. static EFI_GUID efi_bus_specific_driver_override_protocol_guid
  52. = EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID;
  53. /** Component name protocol GUID */
  54. static EFI_GUID efi_component_name_protocol_guid
  55. = EFI_COMPONENT_NAME_PROTOCOL_GUID;
  56. /** Component name 2 protocol GUID */
  57. static EFI_GUID efi_component_name2_protocol_guid
  58. = EFI_COMPONENT_NAME2_PROTOCOL_GUID;
  59. /** Device path protocol GUID */
  60. static EFI_GUID efi_device_path_protocol_guid
  61. = EFI_DEVICE_PATH_PROTOCOL_GUID;
  62. /** Disk I/O protocol GUID */
  63. static EFI_GUID efi_disk_io_protocol_guid
  64. = EFI_DISK_IO_PROTOCOL_GUID;
  65. /** Driver binding protocol GUID */
  66. static EFI_GUID efi_driver_binding_protocol_guid
  67. = EFI_DRIVER_BINDING_PROTOCOL_GUID;
  68. /** Load file protocol GUID */
  69. static EFI_GUID efi_load_file_protocol_guid
  70. = EFI_LOAD_FILE_PROTOCOL_GUID;
  71. /** Load file 2 protocol GUID */
  72. static EFI_GUID efi_load_file2_protocol_guid
  73. = EFI_LOAD_FILE2_PROTOCOL_GUID;
  74. /** Loaded image protocol GUID */
  75. static EFI_GUID efi_loaded_image_protocol_guid
  76. = EFI_LOADED_IMAGE_PROTOCOL_GUID;
  77. /** Loaded image device path protocol GUID */
  78. static EFI_GUID efi_loaded_image_device_path_protocol_guid
  79. = EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID;
  80. /** PCI I/O protocol GUID */
  81. static EFI_GUID efi_pci_io_protocol_guid
  82. = EFI_PCI_IO_PROTOCOL_GUID;
  83. /** PCI root bridge I/O protocol GUID */
  84. static EFI_GUID efi_pci_root_bridge_io_protocol_guid
  85. = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
  86. /** Simple file system protocol GUID */
  87. static EFI_GUID efi_simple_file_system_protocol_guid
  88. = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
  89. /** Simple network protocol guid */
  90. static EFI_GUID efi_simple_network_protocol_guid
  91. = EFI_SIMPLE_NETWORK_PROTOCOL_GUID;
  92. /** Device path to text protocol */
  93. static EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *efidpt;
  94. EFI_REQUEST_PROTOCOL ( EFI_DEVICE_PATH_TO_TEXT_PROTOCOL, &efidpt );
  95. /** A well-known GUID */
  96. struct efi_well_known_guid {
  97. /** GUID */
  98. EFI_GUID *guid;
  99. /** Name */
  100. const char *name;
  101. };
  102. /** Well-known GUIDs */
  103. static struct efi_well_known_guid efi_well_known_guids[] = {
  104. { &efi_block_io_protocol_guid,
  105. "BlockIo" },
  106. { &efi_bus_specific_driver_override_protocol_guid,
  107. "BusSpecificDriverOverride" },
  108. { &efi_component_name2_protocol_guid,
  109. "ComponentName2" },
  110. { &efi_component_name_protocol_guid,
  111. "ComponentName" },
  112. { &efi_device_path_protocol_guid,
  113. "DevicePath" },
  114. { &efi_driver_binding_protocol_guid,
  115. "DriverBinding" },
  116. { &efi_disk_io_protocol_guid,
  117. "DiskIo" },
  118. { &efi_load_file_protocol_guid,
  119. "LoadFile" },
  120. { &efi_load_file2_protocol_guid,
  121. "LoadFile2" },
  122. { &efi_loaded_image_protocol_guid,
  123. "LoadedImage" },
  124. { &efi_loaded_image_device_path_protocol_guid,
  125. "LoadedImageDevicePath"},
  126. { &efi_pci_io_protocol_guid,
  127. "PciIo" },
  128. { &efi_pci_root_bridge_io_protocol_guid,
  129. "PciRootBridgeIo" },
  130. { &efi_simple_file_system_protocol_guid,
  131. "SimpleFileSystem" },
  132. { &efi_simple_network_protocol_guid,
  133. "SimpleNetwork" },
  134. };
  135. /**
  136. * Convert GUID to a printable string
  137. *
  138. * @v guid GUID
  139. * @ret string Printable string
  140. */
  141. const char * efi_guid_ntoa ( EFI_GUID *guid ) {
  142. union {
  143. union uuid uuid;
  144. EFI_GUID guid;
  145. } u;
  146. unsigned int i;
  147. /* Check for a match against well-known GUIDs */
  148. for ( i = 0 ; i < ( sizeof ( efi_well_known_guids ) /
  149. sizeof ( efi_well_known_guids[0] ) ) ; i++ ) {
  150. if ( memcmp ( guid, efi_well_known_guids[i].guid,
  151. sizeof ( *guid ) ) == 0 ) {
  152. return efi_well_known_guids[i].name;
  153. }
  154. }
  155. /* Convert GUID to standard endianness */
  156. memcpy ( &u.guid, guid, sizeof ( u.guid ) );
  157. uuid_mangle ( &u.uuid );
  158. return uuid_ntoa ( &u.uuid );
  159. }
  160. /**
  161. * Print list of protocol handlers attached to a handle
  162. *
  163. * @v handle EFI handle
  164. */
  165. void dbg_efi_protocols ( EFI_HANDLE handle ) {
  166. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  167. EFI_GUID **protocols;
  168. UINTN count;
  169. unsigned int i;
  170. EFI_STATUS efirc;
  171. int rc;
  172. /* Retrieve list of protocols */
  173. if ( ( efirc = bs->ProtocolsPerHandle ( handle, &protocols,
  174. &count ) ) != 0 ) {
  175. rc = -EEFI ( efirc );
  176. printf ( "EFI could not retrieve protocols for %p: %s\n",
  177. handle, strerror ( rc ) );
  178. return;
  179. }
  180. /* Dump list of protocols */
  181. for ( i = 0 ; i < count ; i++ )
  182. printf ( "%s\n", efi_guid_ntoa ( protocols[i] ) );
  183. /* Free list */
  184. bs->FreePool ( protocols );
  185. }
  186. /**
  187. * Get textual representation of device path
  188. *
  189. * @v path Device path
  190. * @ret text Textual representation of device path, or NULL
  191. */
  192. const char * efi_devpath_text ( EFI_DEVICE_PATH_PROTOCOL *path ) {
  193. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  194. static char text[256];
  195. CHAR16 *wtext;
  196. /* Convert path to a textual representation */
  197. if ( ! efidpt )
  198. return NULL;
  199. wtext = efidpt->ConvertDevicePathToText ( path, TRUE, FALSE );
  200. if ( ! wtext )
  201. return NULL;
  202. /* Store path in buffer */
  203. snprintf ( text, sizeof ( text ), "%ls", wtext );
  204. /* Free path */
  205. bs->FreePool ( wtext );
  206. return text;
  207. }
  208. /**
  209. * Get textual representation of device path for a handle
  210. *
  211. * @v handle EFI handle
  212. * @ret text Textual representation of device path, or NULL
  213. */
  214. const char * efi_handle_devpath_text ( EFI_HANDLE handle ) {
  215. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  216. union {
  217. EFI_DEVICE_PATH_PROTOCOL *path;
  218. void *interface;
  219. } path;
  220. const char *text;
  221. EFI_STATUS efirc;
  222. /* Obtain device path, if any */
  223. if ( ( efirc = bs->OpenProtocol ( handle,
  224. &efi_device_path_protocol_guid,
  225. &path.interface, efi_image_handle,
  226. handle,
  227. EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
  228. return NULL;
  229. }
  230. /* Format device path */
  231. text = efi_devpath_text ( path.path );
  232. /* Close device path */
  233. bs->CloseProtocol ( handle, &efi_device_path_protocol_guid,
  234. efi_image_handle, handle );
  235. return text;
  236. }