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 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  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. * You can also choose to distribute this program under the terms of
  20. * the Unmodified Binary Distribution Licence (as given in the file
  21. * COPYING.UBDL), provided that you have satisfied its requirements.
  22. */
  23. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. /**
  25. * @file
  26. *
  27. * EFI image wrapping
  28. *
  29. */
  30. #include <string.h>
  31. #include <stdio.h>
  32. #include <errno.h>
  33. #include <ipxe/efi/efi.h>
  34. #include <ipxe/efi/Protocol/LoadedImage.h>
  35. #include <ipxe/efi/efi_wrap.h>
  36. /** EFI system table wrapper */
  37. static EFI_SYSTEM_TABLE efi_systab_wrapper;
  38. /** EFI boot services table wrapper */
  39. static EFI_BOOT_SERVICES efi_bs_wrapper;
  40. /** Colour for debug messages */
  41. #define colour &efi_systab_wrapper
  42. /**
  43. * Convert EFI status code to text
  44. *
  45. * @v efirc EFI status code
  46. * @ret text EFI status code text
  47. */
  48. static const char * efi_status ( EFI_STATUS efirc ) {
  49. static char buf[ 19 /* "0xXXXXXXXXXXXXXXXX" + NUL */ ];
  50. switch ( efirc ) {
  51. case EFI_SUCCESS : return "0";
  52. case EFI_LOAD_ERROR : return "LOAD_ERROR";
  53. case EFI_INVALID_PARAMETER : return "INVALID_PARAMETER";
  54. case EFI_UNSUPPORTED : return "UNSUPPORTED";
  55. case EFI_BAD_BUFFER_SIZE : return "BAD_BUFFER_SIZE";
  56. case EFI_BUFFER_TOO_SMALL : return "BUFFER_TOO_SMALL";
  57. case EFI_NOT_READY : return "NOT_READY";
  58. case EFI_DEVICE_ERROR : return "DEVICE_ERROR";
  59. case EFI_WRITE_PROTECTED : return "WRITE_PROTECTED";
  60. case EFI_OUT_OF_RESOURCES : return "OUT_OF_RESOURCES";
  61. case EFI_VOLUME_CORRUPTED : return "VOLUME_CORRUPTED";
  62. case EFI_VOLUME_FULL : return "VOLUME_FULL";
  63. case EFI_NO_MEDIA : return "NO_MEDIA";
  64. case EFI_MEDIA_CHANGED : return "MEDIA_CHANGED";
  65. case EFI_NOT_FOUND : return "NOT_FOUND";
  66. case EFI_ACCESS_DENIED : return "ACCESS_DENIED";
  67. case EFI_NO_RESPONSE : return "NO_RESPONSE";
  68. case EFI_NO_MAPPING : return "NO_MAPPING";
  69. case EFI_TIMEOUT : return "TIMEOUT";
  70. case EFI_NOT_STARTED : return "NOT_STARTED";
  71. case EFI_ALREADY_STARTED : return "ALREADY_STARTED";
  72. case EFI_ABORTED : return "ABORTED";
  73. case EFI_ICMP_ERROR : return "ICMP_ERROR";
  74. case EFI_TFTP_ERROR : return "TFTP_ERROR";
  75. case EFI_PROTOCOL_ERROR : return "PROTOCOL_ERROR";
  76. case EFI_INCOMPATIBLE_VERSION : return "INCOMPATIBLE_VERSION";
  77. case EFI_SECURITY_VIOLATION : return "SECURITY_VIOLATION";
  78. case EFI_CRC_ERROR : return "CRC_ERROR";
  79. case EFI_END_OF_MEDIA : return "END_OF_MEDIA";
  80. case EFI_END_OF_FILE : return "END_OF_FILE";
  81. case EFI_INVALID_LANGUAGE : return "INVALID_LANGUAGE";
  82. case EFI_COMPROMISED_DATA : return "COMPROMISED_DATA";
  83. case EFI_WARN_UNKNOWN_GLYPH : return "WARN_UNKNOWN_GLYPH";
  84. case EFI_WARN_DELETE_FAILURE : return "WARN_DELETE_FAILURE";
  85. case EFI_WARN_WRITE_FAILURE : return "WARN_WRITE_FAILURE";
  86. case EFI_WARN_BUFFER_TOO_SMALL : return "WARN_BUFFER_TOO_SMALL";
  87. case EFI_WARN_STALE_DATA : return "WARN_STALE_DATA";
  88. default:
  89. snprintf ( buf, sizeof ( buf ), "%#lx",
  90. ( unsigned long ) efirc );
  91. return buf;
  92. }
  93. }
  94. /**
  95. * Convert EFI boolean to text
  96. *
  97. * @v boolean Boolean value
  98. * @ret text Boolean value text
  99. */
  100. static const char * efi_boolean ( BOOLEAN boolean ) {
  101. return ( boolean ? "TRUE" : "FALSE" );
  102. }
  103. /**
  104. * Wrap InstallProtocolInterface()
  105. *
  106. */
  107. static EFI_STATUS EFIAPI
  108. efi_install_protocol_interface_wrapper ( EFI_HANDLE *handle, EFI_GUID *protocol,
  109. EFI_INTERFACE_TYPE interface_type,
  110. VOID *interface ) {
  111. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  112. void *retaddr = __builtin_return_address ( 0 );
  113. EFI_STATUS efirc;
  114. DBGC ( colour, "InstallProtocolInterface ( %s, %s, %d, %p ) ",
  115. efi_handle_name ( *handle ), efi_guid_ntoa ( protocol ),
  116. interface_type, interface );
  117. efirc = bs->InstallProtocolInterface ( handle, protocol, interface_type,
  118. interface );
  119. DBGC ( colour, "= %s ( %s ) -> %p\n",
  120. efi_status ( efirc ), efi_handle_name ( *handle ), retaddr );
  121. return efirc;
  122. }
  123. /**
  124. * Wrap ReinstallProtocolInterface()
  125. *
  126. */
  127. static EFI_STATUS EFIAPI
  128. efi_reinstall_protocol_interface_wrapper ( EFI_HANDLE handle,
  129. EFI_GUID *protocol,
  130. VOID *old_interface,
  131. VOID *new_interface ) {
  132. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  133. void *retaddr = __builtin_return_address ( 0 );
  134. EFI_STATUS efirc;
  135. DBGC ( colour, "ReinstallProtocolInterface ( %s, %s, %p, %p ) ",
  136. efi_handle_name ( handle ), efi_guid_ntoa ( protocol ),
  137. old_interface, new_interface );
  138. efirc = bs->ReinstallProtocolInterface ( handle, protocol,
  139. old_interface, new_interface );
  140. DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
  141. return efirc;
  142. }
  143. /**
  144. * Wrap UninstallProtocolInterface()
  145. *
  146. */
  147. static EFI_STATUS EFIAPI
  148. efi_uninstall_protocol_interface_wrapper ( EFI_HANDLE handle,
  149. EFI_GUID *protocol,
  150. VOID *interface ) {
  151. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  152. void *retaddr = __builtin_return_address ( 0 );
  153. EFI_STATUS efirc;
  154. DBGC ( colour, "UninstallProtocolInterface ( %s, %s, %p ) ",
  155. efi_handle_name ( handle ), efi_guid_ntoa ( protocol ),
  156. interface );
  157. efirc = bs->UninstallProtocolInterface ( handle, protocol, interface );
  158. DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
  159. return efirc;
  160. }
  161. /**
  162. * Wrap HandleProtocol()
  163. *
  164. */
  165. static EFI_STATUS EFIAPI
  166. efi_handle_protocol_wrapper ( EFI_HANDLE handle, EFI_GUID *protocol,
  167. VOID **interface ) {
  168. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  169. void *retaddr = __builtin_return_address ( 0 );
  170. EFI_STATUS efirc;
  171. DBGC ( colour, "HandleProtocol ( %s, %s ) ",
  172. efi_handle_name ( handle ), efi_guid_ntoa ( protocol ) );
  173. efirc = bs->HandleProtocol ( handle, protocol, interface );
  174. DBGC ( colour, "= %s ( %p ) -> %p\n",
  175. efi_status ( efirc ), *interface, retaddr );
  176. return efirc;
  177. }
  178. /**
  179. * Wrap LocateHandle()
  180. *
  181. */
  182. static EFI_STATUS EFIAPI
  183. efi_locate_handle_wrapper ( EFI_LOCATE_SEARCH_TYPE search_type,
  184. EFI_GUID *protocol, VOID *search_key,
  185. UINTN *buffer_size, EFI_HANDLE *buffer ) {
  186. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  187. void *retaddr = __builtin_return_address ( 0 );
  188. unsigned int i;
  189. EFI_STATUS efirc;
  190. DBGC ( colour, "LocateHandle ( %s, %s, %p, %zd ) ",
  191. efi_locate_search_type_name ( search_type ),
  192. efi_guid_ntoa ( protocol ), search_key,
  193. ( ( size_t ) *buffer_size ) );
  194. efirc = bs->LocateHandle ( search_type, protocol, search_key,
  195. buffer_size, buffer );
  196. DBGC ( colour, "= %s ( %zd", efi_status ( efirc ),
  197. ( ( size_t ) *buffer_size ) );
  198. if ( efirc == 0 ) {
  199. DBGC ( colour, ", {" );
  200. for ( i = 0; i < ( *buffer_size / sizeof ( buffer[0] ) ); i++ ){
  201. DBGC ( colour, "%s%s", ( i ? ", " : " " ),
  202. efi_handle_name ( buffer[i] ) );
  203. }
  204. DBGC ( colour, " }" );
  205. }
  206. DBGC ( colour, " ) -> %p\n", retaddr );
  207. return efirc;
  208. }
  209. /**
  210. * Wrap LocateDevicePath()
  211. *
  212. */
  213. static EFI_STATUS EFIAPI
  214. efi_locate_device_path_wrapper ( EFI_GUID *protocol,
  215. EFI_DEVICE_PATH_PROTOCOL **device_path,
  216. EFI_HANDLE *device ) {
  217. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  218. void *retaddr = __builtin_return_address ( 0 );
  219. EFI_STATUS efirc;
  220. DBGC ( colour, "LocateDevicePath ( %s, %s ) ",
  221. efi_guid_ntoa ( protocol ), efi_devpath_text ( *device_path ) );
  222. efirc = bs->LocateDevicePath ( protocol, device_path, device );
  223. DBGC ( colour, "= %s ( %s, ",
  224. efi_status ( efirc ), efi_devpath_text ( *device_path ) );
  225. DBGC ( colour, "%s ) -> %p\n", efi_handle_name ( *device ), retaddr );
  226. return efirc;
  227. }
  228. /**
  229. * Wrap LoadImage()
  230. *
  231. */
  232. static EFI_STATUS EFIAPI
  233. efi_load_image_wrapper ( BOOLEAN boot_policy, EFI_HANDLE parent_image_handle,
  234. EFI_DEVICE_PATH_PROTOCOL *device_path,
  235. VOID *source_buffer, UINTN source_size,
  236. EFI_HANDLE *image_handle ) {
  237. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  238. void *retaddr = __builtin_return_address ( 0 );
  239. EFI_STATUS efirc;
  240. DBGC ( colour, "LoadImage ( %s, %s, ", efi_boolean ( boot_policy ),
  241. efi_handle_name ( parent_image_handle ) );
  242. DBGC ( colour, "%s, %p, %#llx ) ",
  243. efi_devpath_text ( device_path ), source_buffer,
  244. ( ( unsigned long long ) source_size ) );
  245. efirc = bs->LoadImage ( boot_policy, parent_image_handle, device_path,
  246. source_buffer, source_size, image_handle );
  247. DBGC ( colour, "= %s ( ", efi_status ( efirc ) );
  248. if ( efirc == 0 )
  249. DBGC ( colour, "%s ", efi_handle_name ( *image_handle ) );
  250. DBGC ( colour, ") -> %p\n", retaddr );
  251. /* Wrap the new image */
  252. if ( efirc == 0 )
  253. efi_wrap ( *image_handle );
  254. return efirc;
  255. }
  256. /**
  257. * Wrap StartImage()
  258. *
  259. */
  260. static EFI_STATUS EFIAPI
  261. efi_start_image_wrapper ( EFI_HANDLE image_handle, UINTN *exit_data_size,
  262. CHAR16 **exit_data ) {
  263. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  264. void *retaddr = __builtin_return_address ( 0 );
  265. EFI_STATUS efirc;
  266. DBGC ( colour, "StartImage ( %s ) ", efi_handle_name ( image_handle ) );
  267. efirc = bs->StartImage ( image_handle, exit_data_size, exit_data );
  268. DBGC ( colour, "= %s", efi_status ( efirc ) );
  269. if ( ( efirc != 0 ) && exit_data && *exit_data_size )
  270. DBGC ( colour, " ( \"%ls\" )", *exit_data );
  271. DBGC ( colour, " -> %p\n", retaddr );
  272. if ( ( efirc != 0 ) && exit_data && *exit_data_size )
  273. DBGC_HD ( colour, *exit_data, *exit_data_size );
  274. return efirc;
  275. }
  276. /**
  277. * Wrap Exit()
  278. *
  279. */
  280. static EFI_STATUS EFIAPI
  281. efi_exit_wrapper ( EFI_HANDLE image_handle, EFI_STATUS exit_status,
  282. UINTN exit_data_size, CHAR16 *exit_data ) {
  283. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  284. void *retaddr = __builtin_return_address ( 0 );
  285. EFI_STATUS efirc;
  286. if ( ( exit_status != 0 ) && exit_data && exit_data_size )
  287. DBGC_HD ( colour, exit_data, exit_data_size );
  288. DBGC ( colour, "Exit ( %s, %s",
  289. efi_handle_name ( image_handle ), efi_status ( exit_status ) );
  290. if ( ( exit_status != 0 ) && exit_data && exit_data_size )
  291. DBGC ( colour, ", \"%ls\"", exit_data );
  292. DBGC ( colour, " ) " );
  293. efirc = bs->Exit ( image_handle, exit_status, exit_data_size,
  294. exit_data );
  295. DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
  296. return efirc;
  297. }
  298. /**
  299. * Wrap UnloadImage()
  300. *
  301. */
  302. static EFI_STATUS EFIAPI
  303. efi_unload_image_wrapper ( EFI_HANDLE image_handle ) {
  304. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  305. void *retaddr = __builtin_return_address ( 0 );
  306. EFI_STATUS efirc;
  307. DBGC ( colour, "UnloadImage ( %s ) ",
  308. efi_handle_name ( image_handle ) );
  309. efirc = bs->UnloadImage ( image_handle );
  310. DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
  311. return efirc;
  312. }
  313. /**
  314. * Wrap ExitBootServices()
  315. *
  316. */
  317. static EFI_STATUS EFIAPI
  318. efi_exit_boot_services_wrapper ( EFI_HANDLE image_handle, UINTN map_key ) {
  319. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  320. void *retaddr = __builtin_return_address ( 0 );
  321. EFI_STATUS efirc;
  322. DBGC ( colour, "ExitBootServices ( %s, %#llx ) ",
  323. efi_handle_name ( image_handle ),
  324. ( ( unsigned long long ) map_key ) );
  325. efirc = bs->ExitBootServices ( image_handle, map_key );
  326. DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
  327. return efirc;
  328. }
  329. /**
  330. * Wrap ConnectController()
  331. *
  332. */
  333. static EFI_STATUS EFIAPI
  334. efi_connect_controller_wrapper ( EFI_HANDLE controller_handle,
  335. EFI_HANDLE *driver_image_handle,
  336. EFI_DEVICE_PATH_PROTOCOL *remaining_path,
  337. BOOLEAN recursive ) {
  338. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  339. void *retaddr = __builtin_return_address ( 0 );
  340. EFI_HANDLE *tmp;
  341. EFI_STATUS efirc;
  342. DBGC ( colour, "ConnectController ( %s, {",
  343. efi_handle_name ( controller_handle ) );
  344. if ( driver_image_handle ) {
  345. for ( tmp = driver_image_handle ; *tmp ; tmp++ ) {
  346. DBGC ( colour, "%s%s",
  347. ( ( tmp == driver_image_handle ) ? " " : ", " ),
  348. efi_handle_name ( *tmp ) );
  349. }
  350. }
  351. DBGC ( colour, " }, %s, %s ) ", efi_devpath_text ( remaining_path ),
  352. efi_boolean ( recursive ) );
  353. efirc = bs->ConnectController ( controller_handle, driver_image_handle,
  354. remaining_path, recursive );
  355. DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
  356. return efirc;
  357. }
  358. /**
  359. * Wrap DisconnectController()
  360. *
  361. */
  362. static EFI_STATUS EFIAPI
  363. efi_disconnect_controller_wrapper ( EFI_HANDLE controller_handle,
  364. EFI_HANDLE driver_image_handle,
  365. EFI_HANDLE child_handle ) {
  366. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  367. void *retaddr = __builtin_return_address ( 0 );
  368. EFI_STATUS efirc;
  369. DBGC ( colour, "DisconnectController ( %s",
  370. efi_handle_name ( controller_handle ) );
  371. DBGC ( colour, ", %s", efi_handle_name ( driver_image_handle ) );
  372. DBGC ( colour, ", %s ) ", efi_handle_name ( child_handle ) );
  373. efirc = bs->DisconnectController ( controller_handle,
  374. driver_image_handle,
  375. child_handle );
  376. DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
  377. return efirc;
  378. }
  379. /**
  380. * Wrap OpenProtocol()
  381. *
  382. */
  383. static EFI_STATUS EFIAPI
  384. efi_open_protocol_wrapper ( EFI_HANDLE handle, EFI_GUID *protocol,
  385. VOID **interface, EFI_HANDLE agent_handle,
  386. EFI_HANDLE controller_handle, UINT32 attributes ) {
  387. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  388. void *retaddr = __builtin_return_address ( 0 );
  389. EFI_STATUS efirc;
  390. DBGC ( colour, "OpenProtocol ( %s, %s, ",
  391. efi_handle_name ( handle ), efi_guid_ntoa ( protocol ) );
  392. DBGC ( colour, "%s, ", efi_handle_name ( agent_handle ) );
  393. DBGC ( colour, "%s, %s ) ", efi_handle_name ( controller_handle ),
  394. efi_open_attributes_name ( attributes ) );
  395. efirc = bs->OpenProtocol ( handle, protocol, interface, agent_handle,
  396. controller_handle, attributes );
  397. DBGC ( colour, "= %s ( %p ) -> %p\n",
  398. efi_status ( efirc ), *interface, retaddr );
  399. return efirc;
  400. }
  401. /**
  402. * Wrap CloseProtocol()
  403. *
  404. */
  405. static EFI_STATUS EFIAPI
  406. efi_close_protocol_wrapper ( EFI_HANDLE handle, EFI_GUID *protocol,
  407. EFI_HANDLE agent_handle,
  408. EFI_HANDLE controller_handle ) {
  409. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  410. void *retaddr = __builtin_return_address ( 0 );
  411. EFI_STATUS efirc;
  412. DBGC ( colour, "CloseProtocol ( %s, %s, ",
  413. efi_handle_name ( handle ), efi_guid_ntoa ( protocol ) );
  414. DBGC ( colour, "%s, ", efi_handle_name ( agent_handle ) );
  415. DBGC ( colour, "%s ) ", efi_handle_name ( controller_handle ) );
  416. efirc = bs->CloseProtocol ( handle, protocol, agent_handle,
  417. controller_handle );
  418. DBGC ( colour, "= %s -> %p\n",
  419. efi_status ( efirc ), retaddr );
  420. return efirc;
  421. }
  422. /**
  423. * Wrap ProtocolsPerHandle()
  424. *
  425. */
  426. static EFI_STATUS EFIAPI
  427. efi_protocols_per_handle_wrapper ( EFI_HANDLE handle,
  428. EFI_GUID ***protocol_buffer,
  429. UINTN *protocol_buffer_count ) {
  430. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  431. void *retaddr = __builtin_return_address ( 0 );
  432. unsigned int i;
  433. EFI_STATUS efirc;
  434. DBGC ( colour, "ProtocolsPerHandle ( %s ) ",
  435. efi_handle_name ( handle ) );
  436. efirc = bs->ProtocolsPerHandle ( handle, protocol_buffer,
  437. protocol_buffer_count );
  438. DBGC ( colour, "= %s", efi_status ( efirc ) );
  439. if ( efirc == 0 ) {
  440. DBGC ( colour, " ( {" );
  441. for ( i = 0 ; i < *protocol_buffer_count ; i++ ) {
  442. DBGC ( colour, "%s%s", ( i ? ", " : " " ),
  443. efi_guid_ntoa ( (*protocol_buffer)[i] ) );
  444. }
  445. DBGC ( colour, " } )" );
  446. }
  447. DBGC ( colour, " -> %p\n", retaddr );
  448. return efirc;
  449. }
  450. /**
  451. * Wrap LocateHandleBuffer()
  452. *
  453. */
  454. static EFI_STATUS EFIAPI
  455. efi_locate_handle_buffer_wrapper ( EFI_LOCATE_SEARCH_TYPE search_type,
  456. EFI_GUID *protocol, VOID *search_key,
  457. UINTN *no_handles, EFI_HANDLE **buffer ) {
  458. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  459. void *retaddr = __builtin_return_address ( 0 );
  460. unsigned int i;
  461. EFI_STATUS efirc;
  462. DBGC ( colour, "LocateHandleBuffer ( %s, %s, %p ) ",
  463. efi_locate_search_type_name ( search_type ),
  464. efi_guid_ntoa ( protocol ), search_key );
  465. efirc = bs->LocateHandleBuffer ( search_type, protocol, search_key,
  466. no_handles, buffer );
  467. DBGC ( colour, "= %s", efi_status ( efirc ) );
  468. if ( efirc == 0 ) {
  469. DBGC ( colour, " ( %d, {", ( ( unsigned int ) *no_handles ) );
  470. for ( i = 0 ; i < *no_handles ; i++ ) {
  471. DBGC ( colour, "%s%s", ( i ? ", " : " " ),
  472. efi_handle_name ( (*buffer)[i] ) );
  473. }
  474. DBGC ( colour, " } )" );
  475. }
  476. DBGC ( colour, " -> %p\n", retaddr );
  477. return efirc;
  478. }
  479. /**
  480. * Wrap LocateProtocol()
  481. *
  482. */
  483. static EFI_STATUS EFIAPI
  484. efi_locate_protocol_wrapper ( EFI_GUID *protocol, VOID *registration,
  485. VOID **interface ) {
  486. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  487. void *retaddr = __builtin_return_address ( 0 );
  488. EFI_STATUS efirc;
  489. DBGC ( colour, "LocateProtocol ( %s, %p ) ",
  490. efi_guid_ntoa ( protocol ), registration );
  491. efirc = bs->LocateProtocol ( protocol, registration, interface );
  492. DBGC ( colour, "= %s ( %p ) -> %p\n",
  493. efi_status ( efirc ), *interface, retaddr );
  494. return efirc;
  495. }
  496. /**
  497. * Wrap the calls made by a loaded image
  498. *
  499. * @v handle Image handle
  500. */
  501. void efi_wrap ( EFI_HANDLE handle ) {
  502. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  503. union {
  504. EFI_LOADED_IMAGE_PROTOCOL *image;
  505. void *intf;
  506. } loaded;
  507. EFI_STATUS efirc;
  508. int rc;
  509. /* Do nothing unless debugging is enabled */
  510. if ( ! DBG_LOG )
  511. return;
  512. /* Populate table wrappers */
  513. memcpy ( &efi_systab_wrapper, efi_systab,
  514. sizeof ( efi_systab_wrapper ) );
  515. memcpy ( &efi_bs_wrapper, bs, sizeof ( efi_bs_wrapper ) );
  516. efi_systab_wrapper.BootServices = &efi_bs_wrapper;
  517. efi_bs_wrapper.InstallProtocolInterface
  518. = efi_install_protocol_interface_wrapper;
  519. efi_bs_wrapper.ReinstallProtocolInterface
  520. = efi_reinstall_protocol_interface_wrapper;
  521. efi_bs_wrapper.UninstallProtocolInterface
  522. = efi_uninstall_protocol_interface_wrapper;
  523. efi_bs_wrapper.HandleProtocol = efi_handle_protocol_wrapper;
  524. efi_bs_wrapper.LocateHandle = efi_locate_handle_wrapper;
  525. efi_bs_wrapper.LocateDevicePath = efi_locate_device_path_wrapper;
  526. efi_bs_wrapper.LoadImage = efi_load_image_wrapper;
  527. efi_bs_wrapper.StartImage = efi_start_image_wrapper;
  528. efi_bs_wrapper.Exit = efi_exit_wrapper;
  529. efi_bs_wrapper.UnloadImage = efi_unload_image_wrapper;
  530. efi_bs_wrapper.ExitBootServices = efi_exit_boot_services_wrapper;
  531. efi_bs_wrapper.ConnectController
  532. = efi_connect_controller_wrapper;
  533. efi_bs_wrapper.DisconnectController
  534. = efi_disconnect_controller_wrapper;
  535. efi_bs_wrapper.OpenProtocol = efi_open_protocol_wrapper;
  536. efi_bs_wrapper.CloseProtocol = efi_close_protocol_wrapper;
  537. efi_bs_wrapper.ProtocolsPerHandle
  538. = efi_protocols_per_handle_wrapper;
  539. efi_bs_wrapper.LocateHandleBuffer
  540. = efi_locate_handle_buffer_wrapper;
  541. efi_bs_wrapper.LocateProtocol = efi_locate_protocol_wrapper;
  542. /* Open loaded image protocol */
  543. if ( ( efirc = bs->OpenProtocol ( handle,
  544. &efi_loaded_image_protocol_guid,
  545. &loaded.intf, efi_image_handle, NULL,
  546. EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
  547. rc = -EEFI ( efirc );
  548. DBGC ( colour, "WRAP %s could not get loaded image protocol: "
  549. "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
  550. return;
  551. }
  552. /* Provide system table wrapper to image */
  553. loaded.image->SystemTable = &efi_systab_wrapper;
  554. DBGC ( colour, "WRAP %s at base %p has protocols:\n",
  555. efi_handle_name ( handle ), loaded.image->ImageBase );
  556. DBGC_EFI_PROTOCOLS ( colour, handle );
  557. DBGC ( colour, "WRAP %s parent", efi_handle_name ( handle ) );
  558. DBGC ( colour, " %s\n", efi_handle_name ( loaded.image->ParentHandle ));
  559. DBGC ( colour, "WRAP %s device", efi_handle_name ( handle ) );
  560. DBGC ( colour, " %s\n", efi_handle_name ( loaded.image->DeviceHandle ));
  561. DBGC ( colour, "WRAP %s file", efi_handle_name ( handle ) );
  562. DBGC ( colour, " %s\n", efi_devpath_text ( loaded.image->FilePath ) );
  563. /* Close loaded image protocol */
  564. bs->CloseProtocol ( handle, &efi_loaded_image_protocol_guid,
  565. efi_image_handle, NULL );
  566. }