123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- /*
- * Copyright (C) 2013 David Decotigny <[email protected]>
- *
- * Sample EFI shell session, together with drv0_use.efi:
- *
- * # Loading first instance:
- *
- * fs0:\> load drv0.efi
- * Driver instance loaded successfully.
- * load: Image fs0:\drv0.efi loaded at 2FD7C000 - Success
- *
- * # Testing 1st instance:
- *
- * fs0:\> drv0_use.efi
- * Playing with driver instance 0...
- * Hello Sample UEFI Driver!
- * Hello was called 1 time(s).
- *
- * fs0:\> drv0_use.efi
- * Playing with driver instance 0...
- * Hello Sample UEFI Driver!
- * Hello was called 2 time(s).
- *
- * # Loading another instance:
- *
- * fs0:\> load drv0.efi
- * Driver instance loaded successfully.
- * load: Image fs0:\drv0.efi loaded at 2FD6D000 - Success
- *
- * # Using both instances:
- *
- * fs0:\> drv0_use.efi
- * Playing with driver instance 0...
- * Hello Sample UEFI Driver!
- * Hello was called 3 time(s).
- * Playing with driver instance 1...
- * Hello Sample UEFI Driver!
- * Hello was called 1 time(s).
- *
- * fs0:\> drv0_use.efi
- * Playing with driver instance 0...
- * Hello Sample UEFI Driver!
- * Hello was called 4 time(s).
- * Playing with driver instance 1...
- * Hello Sample UEFI Driver!
- * Hello was called 2 time(s).
- *
- * # Removing 1st instance:
- *
- * fs0:\> dh
- * Handle dump
- * 1: Image(DxeCore)
- * [...]
- * 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
- * 7A: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
- *
- * fs0:\> unload 79
- * 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
- * Unload driver image (y/n)? y
- * Driver instance unloaded.
- * unload: Success
- *
- * # Only 2nd instance remaining:
- *
- * fs0:\> drv0_use.efi
- * Playing with driver instance 0...
- * Hello Sample UEFI Driver!
- * Hello was called 3 time(s).
- *
- * # Removing 2nd/last instance:
- *
- * fs0:\> dh
- * Handle dump
- * 1: Image(DxeCore)
- * [...]
- * 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
- *
- * fs0:\> unload 79
- * 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
- * Unload driver image (y/n)? y
- * Driver instance unloaded.
- * unload: Success
- *
- * # Expect error: no other drv0 instance left
- *
- * fs0:\> drv0_use.efi
- * Error looking up handles for proto: 14
- */
- #include <efi.h>
- #include <efilib.h>
- #include "drv0.h"
- static const EFI_GUID GnuEfiAppsDrv0ProtocolGuid
- = GNU_EFI_APPS_DRV0_PROTOCOL_GUID;
- static struct {
- GNU_EFI_APPS_DRV0_PROTOCOL Proto;
- UINTN Counter;
- } InternalGnuEfiAppsDrv0ProtocolData;
- static
- EFI_STATUS
- EFI_FUNCTION
- Drv0SayHello(
- IN struct _GNU_EFI_APPS_DRV0_PROTOCOL *This,
- IN const CHAR16 *HelloWho
- )
- {
- if (! HelloWho)
- return EFI_INVALID_PARAMETER;
- Print(L"Hello %s!\n", HelloWho);
- InternalGnuEfiAppsDrv0ProtocolData.Counter ++;
- return EFI_SUCCESS;
- }
- static
- EFI_STATUS
- EFI_FUNCTION
- Drv0GetNumberOfHello(
- IN struct _GNU_EFI_APPS_DRV0_PROTOCOL *This,
- OUT UINTN *NumberOfHello
- )
- {
- if (! NumberOfHello)
- return EFI_INVALID_PARAMETER;
- *NumberOfHello = InternalGnuEfiAppsDrv0ProtocolData.Counter;
- return EFI_SUCCESS;
- }
- static
- EFI_STATUS
- EFI_FUNCTION
- Drv0Unload(IN EFI_HANDLE ImageHandle)
- {
- LibUninstallProtocolInterfaces(ImageHandle,
- &GnuEfiAppsDrv0ProtocolGuid,
- &InternalGnuEfiAppsDrv0ProtocolData.Proto,
- NULL);
- Print(L"Driver instance unloaded.\n", ImageHandle);
- return EFI_SUCCESS;
- }
- EFI_STATUS
- efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SysTab)
- {
- EFI_STATUS Status;
- EFI_LOADED_IMAGE *LoadedImage = NULL;
- InitializeLib(ImageHandle, SysTab);
- /* Initialize global protocol definition + data */
- InternalGnuEfiAppsDrv0ProtocolData.Proto.SayHello
- = (GNU_EFI_APPS_DRV0_SAY_HELLO) Drv0SayHello;
- InternalGnuEfiAppsDrv0ProtocolData.Proto.GetNumberOfHello
- = (GNU_EFI_APPS_DRV0_GET_NUMBER_OF_HELLO) Drv0GetNumberOfHello;
- InternalGnuEfiAppsDrv0ProtocolData.Counter = 0;
- /* Grab handle to this image: we'll attach our proto instance to it */
- Status = uefi_call_wrapper(BS->OpenProtocol, 6,
- ImageHandle, &LoadedImageProtocol,
- &LoadedImage, ImageHandle,
- NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
- if (EFI_ERROR(Status)) {
- Print(L"Could not open loaded image protocol: %d\n", Status);
- return Status;
- }
- /* Attach our proto to the current driver image */
- Status = LibInstallProtocolInterfaces(
- &ImageHandle, &GnuEfiAppsDrv0ProtocolGuid,
- &InternalGnuEfiAppsDrv0ProtocolData.Proto, NULL);
- if (EFI_ERROR(Status)) {
- Print(L"Error registering driver instance: %d\n", Status);
- return Status;
- }
- /* Register Unload callback, used to unregister current protocol
- * instance from system */
- LoadedImage->Unload = (EFI_IMAGE_UNLOAD)Drv0Unload;
- Print(L"Driver instance loaded successfully.\n");
- return EFI_SUCCESS; /* at this point, this instance stays resident
- * until image is unloaded, eg. with shell's unload,
- * ExitBootServices() */
- }
|