4. UEFI System Table

4.1. DXE Services Table

4.1.1. DXE_SERVICES

Summary

Contains a table header and pointers to all of the DXE-specific services.

//
// DXE Services Table
//
#define DXE_SERVICES_SIGNATURE 0x565245535f455844
#define DXE_SERVICES_REVISION PI_SPECIFICATION_VERSION

typedef struct {
  EFI_TABLE_HEADER                  Hdr;

  //
  // Global Coherency               Domain Services
  //
  EFI_ADD_MEMORY_SPACE              AddMemorySpace;
  EFI_ALLOCATE_MEMORY_SPACE         AllocateMemorySpace;
  EFI_FREE_MEMORY_SPACE             FreeMemorySpace;
  EFI_REMOVE_MEMORY_SPACE           RemoveMemorySpace;
  EFI_GET_MEMORY_SPACE_DESCRIPTOR   GetMemorySpaceDescriptor;
  EFI_SET_MEMORY_SPACE_ATTRIBUTES   SetMemorySpaceAttributes;
  EFI_GET_MEMORY_SPACE_MAP          GetMemorySpaceMap;
  EFI_ADD_IO_SPACE                  AddIoSpace;
  EFI_ALLOCATE_IO_SPACE             AllocateIoSpace;
  EFI_FREE_IO_SPACE                 FreeIoSpace;
  EFI_REMOVE_IO_SPACE               RemoveIoSpace;
  EFI_GET_IO_SPACE_DESCRIPTOR       GetIoSpaceDescriptor;
  EFI_GET_IO_SPACE_MAP              GetIoSpaceMap;

  //
  // Dispatcher Services
  //
  EFI_DISPATCH                      Dispatch;
  EFI_SCHEDULE                      Schedule;
  EFI_TRUST                         Trust;


  //
  // Service to process a single firmware volume found in
  // a capsule
  //
  EFI_PROCESS_FIRMWARE_VOLUME       ProcessFirmwareVolume;
  //
  // Extensions to Global Coherency Domain Services
  //
  EFI_SET_MEMORY_SPACE_CAPABILITIES SetMemorySpaceCapabilities;
} DXE_SERVICES;

Parameters

Hdr

The table header for the DXE Services Table. This header contains the DXE_SERVICES_SIGNATURE and DXE_SERVICES_REVISION values along with the size of the DXE_SERVICES_TABLE structure and a 32-bit CRC to verify that the contents of the DXE Services Table are valid.

AddMemorySpace

Adds reserved memory, system memory, or memory-mapped I/O resources to the global coherency domain of the processor. See the AddMemorySpace() function description in this document.

AllocateMemorySpace

Allocates nonexistent memory, reserved memory, system memory, or memory-mapped I/O resources from the global coherency domain of the processor. See the AllocateMemorySpace() function description in this document.

FreeMemorySpace

Frees nonexistent memory, reserved memory, system memory, or memory-mapped I/O resources from the global coherency domain of the processor. See the FreeMemorySpace() function description in this document.

RemoveMemorySpace

Removes reserved memory, system memory, or memory-mapped I/O resources from the global coherency domain of the processor. See the RemoveMemorySpace() function description in this document.

GetMemorySpaceDescriptor

Retrieves the descriptor for a memory region containing a specified address. See the GetMemorySpaceDescriptor() function description in this document.

SetMemorySpaceAttributes

Modifies the attributes for a memory region in the global coherency domain of the processor. See the SetMemorySpaceAttributes() function description in this document.

GetMemorySpaceMap

Returns a map of the memory resources in the global coherency domain of the processor. See the GetMemorySpaceMap() function description in this document.

AddIoSpace

Adds reserved I/O or I/O resources to the global coherency domain of the processor. See the AddIoSpace() function description in this document.

AllocateIoSpace

Allocates nonexistent I/O, reserved I/O, or I/O resources from the global coherency domain of the processor. See the AllocateIoSpace() function description in this document.

FreeIoSpace

Frees nonexistent I/O, reserved I/O, or I/O resources from the global coherency domain of the processor. See the FreeIoSpace() function description in this document.

RemoveIoSpace

Removes reserved I/O or I/O resources from the global coherency domain of the processor. See the RemoveIoSpace() function description in this document.

GetIoSpaceDescriptor

Retrieves the descriptor for an I/O region containing a specified address. See the GetIoSpaceDescriptor() function description in this document.

GetIoSpaceMap

Returns a map of the I/O resources in the global coherency domain of the processor. See the GetIoSpaceMap() function description in this document.

Dispatch

Loads and executed DXE drivers from firmware volumes. See the Dispatch() function description in this document.

Schedule

Clears the Schedule on Request (SOR) flag for a component that is stored in a firmware volume. See the Schedule() function description in this document.

Trust

Promotes a file stored in a firmware volume from the untrusted to the trusted state. See the Trust() function description in this document.

ProcessFirmwareVolume

Creates a firmware volume handle for a firmware volume that is present in system memory. See the ProcessFirmwareVolume() function description in this document.

SetMemorySpaceCapabilities

Modifies the capabilities for a memory region in the global coherency domain of the processor. See the SetMemorySpaceCapabilities() function description in this document.

Description

The UEFI DXE Services Table contains a table header and pointers to all of the DXE-specific services. Except for the table header, all elements in the DXE Services Tables are prototypes of function pointers to functions as defined in Services - DXE Services.

4.2. UEFI Image Entry Point Examples

4.2.1. UEFI Application Example

The following example shows the UEFI image entry point for an UEFI application. This application makes use of the UEFI System Table, UEFI Boot Services Table, UEFI Runtime Services Table, and DXE Services Table.

EFI_GUID gEfiDxeServicesTableGuid = DXE_SERVICES_TABLE_GUID;

EFI_SYSTEM_TABLE      *gST;
EFI_BOOT_SERVICES     *gBS;
EFI_RUNTIME_SERVICES  *gRT;
DXE_SERVICES          *gDS;

EfiApplicationEntryPoint(
  IN EFI_HANDLE       ImageHandle,
  IN EFI_SYSTEM_TABLE *SystemTable
  )
{
  UINTN                           Index;
  BOOLEAN                         Result;
  EFI_STATUS                      Status;
  EFI_TIME                        *Time;
  UINTN                           NumberOfDescriptors;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemorySpaceDescriptor;

  gST = SystemTable;
  gBS = gST->BootServices;
  gRT = gST->RuntimeServices;

  gDS = NULL;
  for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
    Result = EfiCompareGuid (
                &gEfiDxeServicesTableGuid,
                &(gST->ConfigurationTable[Index].VendorGuid)
                );
    if (Result) {
      gDS = gST->ConfigurationTable[Index].VendorTable;
    }
  }
  if (gDS == NULL) {
    return EFI_NOT_FOUND;
  }

  //
  // Use UEFI System Table to print “Hello World” to the active console
  // output device.
  //
  Status = gST->ConOut->OutputString (gST->ConOut, L”Hello
  World\n\r”);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Use UEFI Boot Services Table to allocate a buffer to store the
  // current time and date.
  //
  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  sizeof (EFI_TIME),
                  (VOID **)&Time
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Use the UEFI Runtime Services Table to get the current
  // time and date.
  //
  Status = gRT->GetTime (&Time, NULL)
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Use UEFI Boot Services to free the buffer that was used to store
  // the current time and date.
  //
  Status = gBS->FreePool (Time);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Use the DXE Services Table to get the current GCD Memory Space Map
  //
  Status = gDS->GetMemorySpaceMap (
                  &NumberOfDescriptors,
                  &MemorySpaceMap
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Use UEFI Boot Services to free the buffer that was used to store
  // the GCD Memory Space Map.
  //
  Status = gBS->FreePool (MemorySpaceMap);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return Status;
}

4.2.2. Non-UEFI Driver Model Example (Resident in Memory)

The following example shows the UEFI image entry point for an UEFI driver that does not follow the UEFI Driver Model. Because this driver returns EFI_SUCCESS, it will stay resident in memory after it exits.

EFI_GUID gEfiDxeServicesTableGuid = DXE_SERVICES_TABLE_GUID;

EFI_SYSTEM_TABLE        *gST;
EFI_BOOT_SERVICES       *gBS;
EFI_RUNTIME_SERVICES    *gRT;
DXE_SERVICES            *gDS;

EfiDriverEntryPoint(
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
  UINTN     Index;
  BOOLEAN   Result;

  gST = SystemTable;
  gBS = gST->BootServices;
  gRT = gST->RuntimeServices;

  gDS = NULL;
  for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
    Result = EfiCompareGuid (
                &gEfiDxeServicesTableGuid,
                &(gST->ConfigurationTable[Index].VendorGuid)
                );
    if (Result) {
      gDS = gST->ConfigurationTable[Index].VendorTable;
    }
  }
  if (gDS == NULL) {
    return EFI_REQUEST_UNLOAD_IMAGE;
  }

  //
  // Implement driver initialization here.
  //

  return EFI_SUCCESS;
}

4.2.3. Non-UEFI Driver Model Example (Nonresident inMemory)

The following example shows the UEFI image entry point for an UEFI driver that also does not follow the UEFI Driver Model. Because this driver returns the error code EFI_REQUEST_UNLOAD_IMAGE , it will not stay resident in memory after it exits.

EFI_GUID gEfiDxeServicesTableGuid = DXE_SERVICES_TABLE_GUID;

EFI_SYSTEM_TABLE          *gST;
EFI_BOOT_SERVICES         *gBS;
EFI_RUNTIME_SERVICES      *gRT;
DXE_SERVICES              *gDS;

EfiDriverEntryPoint(
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )

{
  UINTN     Index;
  BOOLEAN   Result;

  gST = SystemTable;
  gBS = gST->BootServices;
  gRT = gST->RuntimeServices;

  gDS = NULL;
  for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
    Result = EfiCompareGuid (
                &gEfiDxeServicesTableGuid,
                &(gST->ConfigurationTable[Index].VendorGuid)
                );
    if (Result) {
      gDS = gST->ConfigurationTable[Index].VendorTable;
    }
  }
  if (gDS == NULL) {
    return EFI_REQUEST_UNLOAD_IMAGE;
  }

  //
  // Implement driver initialization here.
  //

  return EFI_REQUEST_UNLOAD_IMAGE;
}

4.2.4. UEFI Driver Model Example

The following is an UEFI Driver Model example that shows the driver initialization routine for the ABC device controller that is on the XYZ bus. The EFI_DRIVER_BINDING_PROTOCOL is defined in Chapter 9 of the UEFI 2.0 specification. The function prototypes for the AbcSupported() , AbcStart() , and AbcStop() functions are defined in Section 9.1 of the UEFI 2.0 specification. This function saves the driver’s image handle and a pointer to the UEFI Boot Services Table in global variables, so that the other functions in the same driver can have access to these values. It then creates an instance of the EFI_DRIVER_BINDING_PROTOCOL and installs it onto the driver’s image handle.

extern EFI_GUID                     gEfiDriverBindingProtocolGuid;
EFI_BOOT_SERVICES                   *gBS;
static EFI_DRIVER_BINDING_PROTOCOL  mAbcDriverBinding = {
  AbcSupported,
  AbcStart,
  AbcStop,
  0x10,
  NULL,
  NULL
};

AbcEntryPoint(
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )

{
  EFI_STATUS Status;

  gBS = SystemTable->BootServices;

  mAbcDriverBinding->ImageHandle = ImageHandle;
  mAbcDriverBinding->DriverBindingHandle = ImageHandle;

  Status = gBS->InstallMultipleProtocolInterfaces(
                  &mAbcDriverBinding->DriverBindingHandle,
                  &gEfiDriverBindingProtocolGuid, &mAbcDriverBinding,
                  NULL
                  );
  return Status;
}

4.2.5. UEFI Driver Model Example (Unloadable)

The following is the same UEFI Driver Model example as in the UEFI Driver Model Example, except that it also includes the code required to allow the driver to be unloaded through the boot service Unload() . Any protocols installed or memory allocated in AbcEntryPoint() must be uninstalled or freed in the AbcUnload() . The AbcUnload() function first checks to see how many controllers this driver is currently managing. If the number of controllers is greater than zero, then this driver cannot be unloaded at this time, so an error is returned.

extern EFI_GUID                     gEfiLoadedImageProtocolGuid;
extern EFI_GUID                     gEfiDriverBindingProtocolGuid;
EFI_BOOT_SERVICES                   *gBS;
static EFI_DRIVER_BINDING_PROTOCOL  mAbcDriverBinding = {
  AbcSupported,
  AbcStart,
  AbcStop,
  1,
  NULL,
  NULL
};

EFI_STATUS
AbcUnload (
  IN EFI_HANDLE ImageHandle
  );

AbcEntryPoint(
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )

{
  EFI_STATUS                  Status;
  EFI_LOADED_IMAGE_PROTOCOL   *LoadedImage;

  gBS = SystemTable->BootServices;

  Status = gBS->OpenProtocol (
                  ImageHandle,
                  &gEfiLoadedImageProtocolGuid,
                  &LoadedImage,
                  ImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  LoadedImage->Unload = AbcUnload;

  mAbcDriverBinding->ImageHandle = ImageHandle;
  mAbcDriverBinding->DriverBindingHandle = ImageHandle;

  Status = gBS->InstallMultipleProtocolInterfaces(
                  &mAbcDriverBinding->DriverBindingHandle,
                  &gEfiDriverBindingProtocolGuid, &mAbcDriverBinding,
                  NULL
                  );
  return Status;
}

EFI_STATUS
AbcUnload (
  IN EFI_HANDLE ImageHandle
)

{
  EFI_STATUS  Status;
  UINTN       Count;
  Status = LibGetManagedControllerHandles (ImageHandle, &Count, NULL);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (Count > 0) {
    return EFI_ACCESS_DENIED;
  }

  Status = gBS->UninstallMultipleProtocolInterfaces (
                  ImageHandle,
                  &gEfiDriverBindingProtocolGuid, &mAbcDriverBinding,
                  NULL
                  );
  return Status;
}

4.2.6. UEFI Driver Model Example (Multiple Instances)

The following is the same as the first UEFI Driver Model example, except that it produces three EFI_DRIVER_BINDING_PROTOCOL instances. The first one is installed onto the driver’s image handle. The other two are installed onto newly created handles.

extern EFI_GUID                     gEfiDriverBindingProtocolGuid;
EFI_BOOT_SERVICES                   *gBS;

static EFI_DRIVER_BINDING_PROTOCOL  mAbcDriverBindingA = {
  AbcSupportedA,
  AbcStartA,
  AbcStopA,
  1,
  NULL,
  NULL
};

static EFI_DRIVER_BINDING_PROTOCOL  mAbcDriverBindingB = {
  AbcSupportedB,
  AbcStartB,
  AbcStopB,
  1,
  NULL,
  NULL
};

static EFI_DRIVER_BINDING_PROTOCOL  mAbcDriverBindingC = {
  AbcSupportedC,
  AbcStartC,
  AbcStopC,
  1,
  NULL,
  NULL
};

AbcEntryPoint(
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )

{
  EFI_STATUS Status;

  gBS = SystemTable->BootServices;

  //
  // Install mAbcDriverBindingA onto ImageHandle
  //
  mAbcDriverBindingA->ImageHandle         = ImageHandle;
  mAbcDriverBindingA->DriverBindingHandle = ImageHandle;

  Status = gBS->InstallMultipleProtocolInterfaces(
                  &mAbcDriverBindingA->DriverBindingHandle,
                  &gEfiDriverBindingProtocolGuid, &mAbcDriverBindingA,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Install mAbcDriverBindingB onto a newly created handle
  //
  mAbcDriverBindingB->ImageHandle         = ImageHandle;
  mAbcDriverBindingB->DriverBindingHandle = NULL;

  Status = gBS->InstallMultipleProtocolInterfaces(
                  &mAbcDriverBindingB->DriverBindingHandle,
                  &gEfiDriverBindingProtocolGuid, &mAbcDriverBindingB,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Install mAbcDriverBindingC onto a newly created handle
  //
  mAbcDriverBindingC->ImageHandle         = ImageHandle;
  mAbcDriverBindingC->DriverBindingHandle = NULL;

  Status = gBS->InstallMultipleProtocolInterfaces(
                  &mAbcDriverBindingC->DriverBindingHandle,
                  &gEfiDriverBindingProtocolGuid, &mAbcDriverBindingC,
                  NULL
                  );

  return Status;
}