2 * Copyright (C) 2013 David Decotigny <decot@googlers.com>
4 * Sample EFI shell session, together with drv0_use.efi:
6 * # Loading first instance:
9 * Driver instance loaded successfully.
10 * load: Image fs0:\drv0.efi loaded at 2FD7C000 - Success
12 * # Testing 1st instance:
15 * Playing with driver instance 0...
16 * Hello Sample UEFI Driver!
17 * Hello was called 1 time(s).
20 * Playing with driver instance 0...
21 * Hello Sample UEFI Driver!
22 * Hello was called 2 time(s).
24 * # Loading another instance:
26 * fs0:\> load drv0.efi
27 * Driver instance loaded successfully.
28 * load: Image fs0:\drv0.efi loaded at 2FD6D000 - Success
30 * # Using both instances:
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).
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).
48 * # Removing 1st instance:
54 * 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
55 * 7A: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
58 * 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
59 * Unload driver image (y/n)? y
60 * Driver instance unloaded.
63 * # Only 2nd instance remaining:
66 * Playing with driver instance 0...
67 * Hello Sample UEFI Driver!
68 * Hello was called 3 time(s).
70 * # Removing 2nd/last instance:
76 * 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
79 * 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
80 * Unload driver image (y/n)? y
81 * Driver instance unloaded.
84 * # Expect error: no other drv0 instance left
87 * Error looking up handles for proto: 14
95 static const EFI_GUID GnuEfiAppsDrv0ProtocolGuid
96 = GNU_EFI_APPS_DRV0_PROTOCOL_GUID;
99 GNU_EFI_APPS_DRV0_PROTOCOL Proto;
101 } InternalGnuEfiAppsDrv0ProtocolData;
108 IN struct _GNU_EFI_APPS_DRV0_PROTOCOL *This,
109 IN const CHAR16 *HelloWho
113 return EFI_INVALID_PARAMETER;
115 Print(L"Hello %s!\n", HelloWho);
116 InternalGnuEfiAppsDrv0ProtocolData.Counter ++;
124 Drv0GetNumberOfHello(
125 IN struct _GNU_EFI_APPS_DRV0_PROTOCOL *This,
126 OUT UINTN *NumberOfHello
130 return EFI_INVALID_PARAMETER;
132 *NumberOfHello = InternalGnuEfiAppsDrv0ProtocolData.Counter;
140 Drv0Unload(IN EFI_HANDLE ImageHandle)
142 LibUninstallProtocolInterfaces(ImageHandle,
143 &GnuEfiAppsDrv0ProtocolGuid,
144 &InternalGnuEfiAppsDrv0ProtocolData.Proto,
146 Print(L"Driver instance unloaded.\n", ImageHandle);
152 efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SysTab)
155 EFI_LOADED_IMAGE *LoadedImage = NULL;
157 InitializeLib(ImageHandle, SysTab);
159 /* Initialize global protocol definition + data */
160 InternalGnuEfiAppsDrv0ProtocolData.Proto.SayHello
161 = (GNU_EFI_APPS_DRV0_SAY_HELLO) Drv0SayHello;
162 InternalGnuEfiAppsDrv0ProtocolData.Proto.GetNumberOfHello
163 = (GNU_EFI_APPS_DRV0_GET_NUMBER_OF_HELLO) Drv0GetNumberOfHello;
164 InternalGnuEfiAppsDrv0ProtocolData.Counter = 0;
166 /* Grab handle to this image: we'll attach our proto instance to it */
167 Status = uefi_call_wrapper(BS->OpenProtocol, 6,
168 ImageHandle, &LoadedImageProtocol,
169 &LoadedImage, ImageHandle,
170 NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
171 if (EFI_ERROR(Status)) {
172 Print(L"Could not open loaded image protocol: %d\n", Status);
176 /* Attach our proto to the current driver image */
177 Status = LibInstallProtocolInterfaces(
178 &ImageHandle, &GnuEfiAppsDrv0ProtocolGuid,
179 &InternalGnuEfiAppsDrv0ProtocolData.Proto, NULL);
180 if (EFI_ERROR(Status)) {
181 Print(L"Error registering driver instance: %d\n", Status);
185 /* Register Unload callback, used to unregister current protocol
186 * instance from system */
187 LoadedImage->Unload = (EFI_IMAGE_UNLOAD)Drv0Unload;
189 Print(L"Driver instance loaded successfully.\n");
190 return EFI_SUCCESS; /* at this point, this instance stays resident
191 * until image is unloaded, eg. with shell's unload,
192 * ExitBootServices() */