8.3 Allocating private context data structures

Private context data structures are allocated in the Start() function of the Driver Binding Protocol. The service that is typically used to allocate the private context data structures is the UEFI Boot Service AllocatePool(). The following example shows the generic template for allocating and zeroing a private context data structure in the Start() function of the Driver Binding Protocol. In this example, the UEFI Boot Service SetMem() is used to fill the allocated buffer with zeros. This code example shows only a fragment from the Start() function. Chapter 9 of this guide covers the services that are produced by the Driver Binding Protocol in more detail. The code examples that follow show how the implementation of Start() can be simplified by using the EDK II library MemoryAllocationLib.

Example 115-Allocation of a private context data structure
#include <Uefi.h>
#include <Protocol/DriverBinding.h>
#include <Protocol/DevicePath.h>
#include <Library/UefiBootServicesTableLib.h>

EFI_STATUS
EFIAPI
<<DriverName>>DriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath   OPTIONAL
  )
{
  EFI_STATUS  Status;
  <<DRIVER_NAME>>_PRIVATE_DATA Private;

  //
  // Allocate the private context data structure
  //
  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  sizeof ( <<DRIVER_NAME>>_PRIVATE_DATA),
                  (VOID **)&Private
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Clear the contents of the allocated buffer
  //
  gBS->SetMem (Private,sizeof(<<DRIVER_NAME>>_PRIVATE_DATA),0);
}

The example below shows the same generic template for the Start() function above except that it uses the EDK II library MemoryAllocationLib to allocate and zero the private context data structure.

Example 116-Library allocation of private context data structure
#include <Uefi.h>
#include <Protocol/DriverBinding.h>
#include <Protocol/DevicePath.h>
#include <Library/MemoryAllocationLib.h>

EFI_STATUS
EFIAPI
<<DriverName>>DriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath   OPTIONAL
  )
{
  <<DRIVER_NAME>>_PRIVATE_DATA Private;

  //
  // Allocate and zero the private context data structure
  //
  Private = AllocateZeroPool (sizeof ( <<DRIVER_NAME>>_PRIVATE_DATA));
  if (Private == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
}

The following example shows a code fragment from the DiskIoDxe driver in the MdeModulePkg that allocates and initializes the private context data structure from a template structure. A template structure is an instance of the private context structure with most of the fields pre-initialized. This style produces UEFI Drivers that execute faster and produce smaller executables than UEFI Drivers that initialize each field of the private context data structure in the Start() function.

Example 117-Disk I/O allocation of private context data structure
#include <Uefi.h>
#include <Protocol/DriverBinding.h>
#include <Protocol/DevicePath.h>
#include <Protocol/DiskIo.h>
#include <Library/MemoryAllocationLib.h>

//
// Template for DiskIo private data structure.
// The pointer to BlockIo protocol interface is assigned dynamically.
//
DISK_IO_PRIVATE_DATA gDiskIoPrivateDataTemplate = {
  DISK_IO_PRIVATE_DATA_SIGNATURE,
  {
    EFI_DISK_IO_PROTOCOL_REVISION,
    DiskIoReadDisk,
    DiskIoWriteDisk
  },
  NULL
};

EFI_STATUS
EFIAPI
DiskIoDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath   OPTIONAL
  )
{
  EFI_STATUS            Status;
  DISK_IO_PRIVATE_DATA  *Private;

  //
  // Initialize the Disk IO device instance.
  //
  Private = AllocateCopyPool (
              sizeof (DISK_IO_PRIVATE_DATA),
              &gDiskIoPrivateDataTemplate
              );
  if (Private == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }
}