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_wrap.c 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * Copyright (C) 2014 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 image wrapping
  24. *
  25. */
  26. #include <string.h>
  27. #include <stdio.h>
  28. #include <ipxe/efi/efi.h>
  29. #include <ipxe/efi/Protocol/LoadedImage.h>
  30. #include <ipxe/efi/efi_wrap.h>
  31. /** EFI system table wrapper */
  32. static EFI_SYSTEM_TABLE efi_systab_wrapper;
  33. /** EFI boot services table wrapper */
  34. static EFI_BOOT_SERVICES efi_bs_wrapper;
  35. /** Colour for debug messages */
  36. #define colour &efi_systab_wrapper
  37. /**
  38. * Convert EFI status code to text
  39. *
  40. * @v efirc EFI status code
  41. * @ret text EFI status code text
  42. */
  43. static const char * efi_status ( EFI_STATUS efirc ) {
  44. static char buf[ 19 /* "0xXXXXXXXXXXXXXXXX" + NUL */ ];
  45. switch ( efirc ) {
  46. case EFI_SUCCESS : return "0";
  47. case EFI_LOAD_ERROR : return "LOAD_ERROR";
  48. case EFI_INVALID_PARAMETER : return "INVALID_PARAMETER";
  49. case EFI_UNSUPPORTED : return "UNSUPPORTED";
  50. case EFI_BAD_BUFFER_SIZE : return "BAD_BUFFER_SIZE";
  51. case EFI_BUFFER_TOO_SMALL : return "BUFFER_TOO_SMALL";
  52. case EFI_NOT_READY : return "NOT_READY";
  53. case EFI_DEVICE_ERROR : return "DEVICE_ERROR";
  54. case EFI_WRITE_PROTECTED : return "WRITE_PROTECTED";
  55. case EFI_OUT_OF_RESOURCES : return "OUT_OF_RESOURCES";
  56. case EFI_VOLUME_CORRUPTED : return "VOLUME_CORRUPTED";
  57. case EFI_VOLUME_FULL : return "VOLUME_FULL";
  58. case EFI_NO_MEDIA : return "NO_MEDIA";
  59. case EFI_MEDIA_CHANGED : return "MEDIA_CHANGED";
  60. case EFI_NOT_FOUND : return "NOT_FOUND";
  61. case EFI_ACCESS_DENIED : return "ACCESS_DENIED";
  62. case EFI_NO_RESPONSE : return "NO_RESPONSE";
  63. case EFI_NO_MAPPING : return "NO_MAPPING";
  64. case EFI_TIMEOUT : return "TIMEOUT";
  65. case EFI_NOT_STARTED : return "NOT_STARTED";
  66. case EFI_ALREADY_STARTED : return "ALREADY_STARTED";
  67. case EFI_ABORTED : return "ABORTED";
  68. case EFI_ICMP_ERROR : return "ICMP_ERROR";
  69. case EFI_TFTP_ERROR : return "TFTP_ERROR";
  70. case EFI_PROTOCOL_ERROR : return "PROTOCOL_ERROR";
  71. case EFI_INCOMPATIBLE_VERSION : return "INCOMPATIBLE_VERSION";
  72. case EFI_SECURITY_VIOLATION : return "SECURITY_VIOLATION";
  73. case EFI_CRC_ERROR : return "CRC_ERROR";
  74. case EFI_END_OF_MEDIA : return "END_OF_MEDIA";
  75. case EFI_END_OF_FILE : return "END_OF_FILE";
  76. case EFI_INVALID_LANGUAGE : return "INVALID_LANGUAGE";
  77. case EFI_COMPROMISED_DATA : return "COMPROMISED_DATA";
  78. case EFI_WARN_UNKNOWN_GLYPH : return "WARN_UNKNOWN_GLYPH";
  79. case EFI_WARN_DELETE_FAILURE : return "WARN_DELETE_FAILURE";
  80. case EFI_WARN_WRITE_FAILURE : return "WARN_WRITE_FAILURE";
  81. case EFI_WARN_BUFFER_TOO_SMALL : return "WARN_BUFFER_TOO_SMALL";
  82. case EFI_WARN_STALE_DATA : return "WARN_STALE_DATA";
  83. default:
  84. snprintf ( buf, sizeof ( buf ), "%#lx",
  85. ( unsigned long ) efirc );
  86. return buf;
  87. }
  88. }
  89. /**
  90. * Wrap HandleProtocol()
  91. *
  92. */
  93. static EFI_STATUS EFIAPI
  94. efi_handle_protocol_wrapper ( EFI_HANDLE handle, EFI_GUID *protocol,
  95. VOID **interface ) {
  96. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  97. void *retaddr = __builtin_return_address ( 0 );
  98. EFI_STATUS efirc;
  99. DBGC ( colour, "HandleProtocol ( %p %s, %s, ... ) ", handle,
  100. efi_handle_devpath_text ( handle ), efi_guid_ntoa ( protocol ) );
  101. efirc = bs->HandleProtocol ( handle, protocol, interface );
  102. DBGC ( colour, "= %s ( %p ) -> %p\n",
  103. efi_status ( efirc ), *interface, retaddr );
  104. return efirc;
  105. }
  106. /**
  107. * Wrap LocateHandle()
  108. *
  109. */
  110. static EFI_STATUS EFIAPI
  111. efi_locate_handle_wrapper ( EFI_LOCATE_SEARCH_TYPE search_type,
  112. EFI_GUID *protocol, VOID *search_key,
  113. UINTN *buffer_size, EFI_HANDLE *buffer ) {
  114. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  115. void *retaddr = __builtin_return_address ( 0 );
  116. EFI_STATUS efirc;
  117. DBGC ( colour, "LocateHandle ( %d, %s, ..., %zd, ... ) ", search_type,
  118. efi_guid_ntoa ( protocol ), ( ( size_t ) *buffer_size ) );
  119. efirc = bs->LocateHandle ( search_type, protocol, search_key,
  120. buffer_size, buffer );
  121. DBGC ( colour, "= %s ( %zd ) -> %p\n",
  122. efi_status ( efirc ), ( ( size_t ) *buffer_size ), retaddr );
  123. return efirc;
  124. }
  125. /**
  126. * Wrap LocateDevicePath()
  127. *
  128. */
  129. static EFI_STATUS EFIAPI
  130. efi_locate_device_path_wrapper ( EFI_GUID *protocol,
  131. EFI_DEVICE_PATH_PROTOCOL **device_path,
  132. EFI_HANDLE *device ) {
  133. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  134. void *retaddr = __builtin_return_address ( 0 );
  135. EFI_STATUS efirc;
  136. DBGC ( colour, "LocateDevicePath ( %s, %s, ... ) ",
  137. efi_guid_ntoa ( protocol ), efi_devpath_text ( *device_path ) );
  138. efirc = bs->LocateDevicePath ( protocol, device_path, device );
  139. DBGC ( colour, "= %s ( %p, ",
  140. efi_status ( efirc ), efi_devpath_text ( *device_path ) );
  141. DBGC ( colour, "%p %s ) -> %p\n",
  142. *device, efi_handle_devpath_text ( *device ), retaddr );
  143. return efirc;
  144. }
  145. /**
  146. * Wrap OpenProtocol()
  147. *
  148. */
  149. static EFI_STATUS EFIAPI
  150. efi_open_protocol_wrapper ( EFI_HANDLE handle, EFI_GUID *protocol,
  151. VOID **interface, EFI_HANDLE agent_handle,
  152. EFI_HANDLE controller_handle, UINT32 attributes ) {
  153. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  154. void *retaddr = __builtin_return_address ( 0 );
  155. EFI_STATUS efirc;
  156. DBGC ( colour, "OpenProtocol ( %p %s, %s, ..., ", handle,
  157. efi_handle_devpath_text ( handle ), efi_guid_ntoa ( protocol ) );
  158. DBGC ( colour, "%p %s, ", agent_handle,
  159. efi_handle_devpath_text ( agent_handle ) );
  160. DBGC ( colour, "%p %s, %#x ) ", controller_handle,
  161. efi_handle_devpath_text ( controller_handle ), attributes );
  162. efirc = bs->OpenProtocol ( handle, protocol, interface, agent_handle,
  163. controller_handle, attributes );
  164. DBGC ( colour, "= %s ( %p ) -> %p\n",
  165. efi_status ( efirc ), *interface, retaddr );
  166. return efirc;
  167. }
  168. /**
  169. * Wrap LocateProtocol()
  170. *
  171. */
  172. static EFI_STATUS EFIAPI
  173. efi_locate_protocol_wrapper ( EFI_GUID *protocol, VOID *registration,
  174. VOID **interface ) {
  175. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  176. void *retaddr = __builtin_return_address ( 0 );
  177. EFI_STATUS efirc;
  178. DBGC ( colour, "LocateProtocol ( %s, %p, ... ) ",
  179. efi_guid_ntoa ( protocol ), registration );
  180. efirc = bs->LocateProtocol ( protocol, registration, interface );
  181. DBGC ( colour, "= %s ( %p ) -> %p\n",
  182. efi_status ( efirc ), *interface, retaddr );
  183. return efirc;
  184. }
  185. /**
  186. * Wrap the calls made by a loaded image
  187. *
  188. * @v handle Image handle
  189. * @v loaded Loaded image protocol
  190. */
  191. void efi_wrap ( EFI_HANDLE handle, EFI_LOADED_IMAGE_PROTOCOL *loaded ) {
  192. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  193. /* Do nothing unless debugging is enabled */
  194. if ( ! DBG_LOG )
  195. return;
  196. /* Populate table wrappers */
  197. memcpy ( &efi_systab_wrapper, efi_systab,
  198. sizeof ( efi_systab_wrapper ) );
  199. memcpy ( &efi_bs_wrapper, bs, sizeof ( efi_bs_wrapper ) );
  200. efi_systab_wrapper.BootServices = &efi_bs_wrapper;
  201. efi_bs_wrapper.HandleProtocol = efi_handle_protocol_wrapper;
  202. efi_bs_wrapper.LocateHandle = efi_locate_handle_wrapper;
  203. efi_bs_wrapper.LocateDevicePath = efi_locate_device_path_wrapper;
  204. efi_bs_wrapper.OpenProtocol = efi_open_protocol_wrapper;
  205. efi_bs_wrapper.LocateProtocol = efi_locate_protocol_wrapper;
  206. /* Provide system table wrapper to image */
  207. loaded->SystemTable = &efi_systab_wrapper;
  208. DBGC ( colour, "Wrapped image %p %s at base %p\n", handle,
  209. efi_handle_devpath_text ( handle ), loaded->ImageBase );
  210. DBGC ( colour, "Parent image %p %s\n", loaded->ParentHandle,
  211. efi_handle_devpath_text ( loaded->ParentHandle ) );
  212. DBGC ( colour, "Device %p %s ", loaded->DeviceHandle,
  213. efi_handle_devpath_text ( loaded->DeviceHandle ) );
  214. DBGC ( colour, "file %s\n", efi_devpath_text ( loaded->FilePath ) );
  215. }