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
andDXE_SERVICES_REVISION
values along with the size of theDXE_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;
}