drv0.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * Copyright (C) 2013 David Decotigny <[email protected]>
  3. *
  4. * Sample EFI shell session, together with drv0_use.efi:
  5. *
  6. * # Loading first instance:
  7. *
  8. * fs0:\> load drv0.efi
  9. * Driver instance loaded successfully.
  10. * load: Image fs0:\drv0.efi loaded at 2FD7C000 - Success
  11. *
  12. * # Testing 1st instance:
  13. *
  14. * fs0:\> drv0_use.efi
  15. * Playing with driver instance 0...
  16. * Hello Sample UEFI Driver!
  17. * Hello was called 1 time(s).
  18. *
  19. * fs0:\> drv0_use.efi
  20. * Playing with driver instance 0...
  21. * Hello Sample UEFI Driver!
  22. * Hello was called 2 time(s).
  23. *
  24. * # Loading another instance:
  25. *
  26. * fs0:\> load drv0.efi
  27. * Driver instance loaded successfully.
  28. * load: Image fs0:\drv0.efi loaded at 2FD6D000 - Success
  29. *
  30. * # Using both instances:
  31. *
  32. * fs0:\> drv0_use.efi
  33. * Playing with driver instance 0...
  34. * Hello Sample UEFI Driver!
  35. * Hello was called 3 time(s).
  36. * Playing with driver instance 1...
  37. * Hello Sample UEFI Driver!
  38. * Hello was called 1 time(s).
  39. *
  40. * fs0:\> drv0_use.efi
  41. * Playing with driver instance 0...
  42. * Hello Sample UEFI Driver!
  43. * Hello was called 4 time(s).
  44. * Playing with driver instance 1...
  45. * Hello Sample UEFI Driver!
  46. * Hello was called 2 time(s).
  47. *
  48. * # Removing 1st instance:
  49. *
  50. * fs0:\> dh
  51. * Handle dump
  52. * 1: Image(DxeCore)
  53. * [...]
  54. * 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
  55. * 7A: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
  56. *
  57. * fs0:\> unload 79
  58. * 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
  59. * Unload driver image (y/n)? y
  60. * Driver instance unloaded.
  61. * unload: Success
  62. *
  63. * # Only 2nd instance remaining:
  64. *
  65. * fs0:\> drv0_use.efi
  66. * Playing with driver instance 0...
  67. * Hello Sample UEFI Driver!
  68. * Hello was called 3 time(s).
  69. *
  70. * # Removing 2nd/last instance:
  71. *
  72. * fs0:\> dh
  73. * Handle dump
  74. * 1: Image(DxeCore)
  75. * [...]
  76. * 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
  77. *
  78. * fs0:\> unload 79
  79. * 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
  80. * Unload driver image (y/n)? y
  81. * Driver instance unloaded.
  82. * unload: Success
  83. *
  84. * # Expect error: no other drv0 instance left
  85. *
  86. * fs0:\> drv0_use.efi
  87. * Error looking up handles for proto: 14
  88. */
  89. #include <efi.h>
  90. #include <efilib.h>
  91. #include "drv0.h"
  92. static const EFI_GUID GnuEfiAppsDrv0ProtocolGuid
  93. = GNU_EFI_APPS_DRV0_PROTOCOL_GUID;
  94. static struct {
  95. GNU_EFI_APPS_DRV0_PROTOCOL Proto;
  96. UINTN Counter;
  97. } InternalGnuEfiAppsDrv0ProtocolData;
  98. static
  99. EFI_STATUS
  100. EFI_FUNCTION
  101. Drv0SayHello(
  102. IN struct _GNU_EFI_APPS_DRV0_PROTOCOL *This,
  103. IN const CHAR16 *HelloWho
  104. )
  105. {
  106. if (! HelloWho)
  107. return EFI_INVALID_PARAMETER;
  108. Print(L"Hello %s!\n", HelloWho);
  109. InternalGnuEfiAppsDrv0ProtocolData.Counter ++;
  110. return EFI_SUCCESS;
  111. }
  112. static
  113. EFI_STATUS
  114. EFI_FUNCTION
  115. Drv0GetNumberOfHello(
  116. IN struct _GNU_EFI_APPS_DRV0_PROTOCOL *This,
  117. OUT UINTN *NumberOfHello
  118. )
  119. {
  120. if (! NumberOfHello)
  121. return EFI_INVALID_PARAMETER;
  122. *NumberOfHello = InternalGnuEfiAppsDrv0ProtocolData.Counter;
  123. return EFI_SUCCESS;
  124. }
  125. static
  126. EFI_STATUS
  127. EFI_FUNCTION
  128. Drv0Unload(IN EFI_HANDLE ImageHandle)
  129. {
  130. LibUninstallProtocolInterfaces(ImageHandle,
  131. &GnuEfiAppsDrv0ProtocolGuid,
  132. &InternalGnuEfiAppsDrv0ProtocolData.Proto,
  133. NULL);
  134. Print(L"Driver instance unloaded.\n", ImageHandle);
  135. return EFI_SUCCESS;
  136. }
  137. EFI_STATUS
  138. efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SysTab)
  139. {
  140. EFI_STATUS Status;
  141. EFI_LOADED_IMAGE *LoadedImage = NULL;
  142. InitializeLib(ImageHandle, SysTab);
  143. /* Initialize global protocol definition + data */
  144. InternalGnuEfiAppsDrv0ProtocolData.Proto.SayHello
  145. = (GNU_EFI_APPS_DRV0_SAY_HELLO) Drv0SayHello;
  146. InternalGnuEfiAppsDrv0ProtocolData.Proto.GetNumberOfHello
  147. = (GNU_EFI_APPS_DRV0_GET_NUMBER_OF_HELLO) Drv0GetNumberOfHello;
  148. InternalGnuEfiAppsDrv0ProtocolData.Counter = 0;
  149. /* Grab handle to this image: we'll attach our proto instance to it */
  150. Status = uefi_call_wrapper(BS->OpenProtocol, 6,
  151. ImageHandle, &LoadedImageProtocol,
  152. &LoadedImage, ImageHandle,
  153. NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
  154. if (EFI_ERROR(Status)) {
  155. Print(L"Could not open loaded image protocol: %d\n", Status);
  156. return Status;
  157. }
  158. /* Attach our proto to the current driver image */
  159. Status = LibInstallProtocolInterfaces(
  160. &ImageHandle, &GnuEfiAppsDrv0ProtocolGuid,
  161. &InternalGnuEfiAppsDrv0ProtocolData.Proto, NULL);
  162. if (EFI_ERROR(Status)) {
  163. Print(L"Error registering driver instance: %d\n", Status);
  164. return Status;
  165. }
  166. /* Register Unload callback, used to unregister current protocol
  167. * instance from system */
  168. LoadedImage->Unload = (EFI_IMAGE_UNLOAD)Drv0Unload;
  169. Print(L"Driver instance loaded successfully.\n");
  170. return EFI_SUCCESS; /* at this point, this instance stays resident
  171. * until image is unloaded, eg. with shell's unload,
  172. * ExitBootServices() */
  173. }