9. DXE Foundation

9.1. Introduction

The DXE Foundation is designed to be completely portable with no processor, chipset, or platform dependencies. This lack of dependencies is accomplished by designing in several features:

  • The DXE Foundation depends only upon a HOB list for its initial state.

    This means that the DXE Foundation does not depend on any services from a previous phase, so all the prior phases can be unloaded once the HOB list is passed to the DXE Foundation.

  • The DXE Foundation does not contain any hard-coded addresses.

    This means that the DXE Foundation can be loaded anywhere in physical memory, and it can function correctly no matter where physical memory or where Firmware Volumes (FVs) are located in the processor’s physical address space.

  • The DXE Foundation does not contain any processor-specific, chipset-specific, or platform-specific information.

    Instead, the DXE Foundation is abstracted from the system hardware through a set of DXE Architectural Protocol interfaces. These architectural protocol interfaces are produced by a set of DXE drivers that are invoked by the DXE Dispatcher.

The DXE Foundation must produce the UEFI System Table and its associated set of UEFI Boot Services and UEFI Runtime Services. The DXE Foundation also contains the DXE Dispatcher whose main purpose is to discover and execute DXE drivers stored in FVs. The execution order of DXE drivers is determined by a combination of the optional a priori file and the set of dependency expressions that are associated with the DXE drivers. The FV file format allows dependency expressions to be packaged with the executable DXE driver image. DXE drivers utilize a PE/COFF image format, so the DXE Dispatcher must also contain a PE/COFF loader to load and execute DXE drivers.

The GetMemoryMap() implementation must include all GCD map entries of types EfiGcdMemoryTypeReserved and EfiGcdMemoryTypeMemoryMappedIo into the UEFI memory map.

9.2. Hand-Off Block (HOB) List

The Hand-Off Block (HOB) list contains all the information that the DXE Foundation requires to produce its memory-based services. The HOB list contains the following:

  • Information on the boot mode and the memory that was allocated in the previous phase.

  • A description of the system memory that was initialized by the previous phase along with information about the firmware devices that were discovered in the previous phase.

The firmware device information includes the system memory locations of the firmware devices and system memory locations of the firmware volumes that are contained within those firmware devices. The firmware volumes may contain DXE drivers, and the DXE Dispatcher is responsible for loading and executing the DXE drivers that are discovered in those firmware volumes.

The I/O resources and memory-mapped I/O resources that were discovered in the previous phase.

The HOB list must be treated as a read-only data structure. It conveys the state of the system at the time the DXE Foundation is started. The DXE Foundation and DXE drivers should never modify the contents of the HOB list.

HOB List shows an example HOB list. The first HOB list entry is always the Phase Handoff Information Table (PHIT) HOB that contains the boot mode and a description of the memory regions used by the previous phase. The rest of the HOB list entries can appear in any order. This example shows the various HOB types that are supported. The most important ones to the DXE Foundation are the HOBs that describe system memory and the firmware volumes. A HOB list is terminated by an end of list HOB. There is one additional HOB type that is not shown. This is a GUIDed HOB that allows a module from the previous phase to pass private data to a DXE driver. Only the DXE driver that recognizes the GUID value in the GUIDed HOB will be able to understand the data in the GUIDed HOB. The DXE Foundation does not consume any GUIDed HOBs. The HOB entries are all designed to be position independent. This allows the DXE Foundation to relocate the HOB list to a different location if the DXE Foundation does not like where the previous phase placed the HOB list in memory.

See HOB Translations for more information on HOB types.

_images/V2_DXE_Foundation-2.png

Fig. 9.1 HOB List

9.3. DXE Foundation Data Structures

The DXE Foundation produces the UEFI System Table, and the UEFI System Table is consumed by every DXE driver and executable image invoked by the DXE Dispatcher and BDS. It contains all the information required for these components to utilize the services provided by the DXE Foundation and the services provided by any previously loaded DXE driver. UEFI System Table and Related Components shows the various components that are available through the UEFI System Table.

The DXE Foundation produces the UEFI Boot Services, UEFI Runtime Services, and DXE Services with the aide of the DXE Architectural Protocols. The UEFI System Table also provides access to all the active console devices in the platform and the set of UEFI Configuration Tables. The UEFI Configuration Tables are an extensible list of tables that describe the configuration of the platform. Today, this includes pointers to tables such as DXE Services, the HOB list, ACPI table, SMBIOS table, and the SAL System Table. This list may be expanded in the future as new table types are defined. Also, through the use of the Protocol Handle Services in the UEFI Boot Services Table, any executable image can access the handle database and any of the protocol interfaces that have been registered by DXE drivers.

When the transition to the OS runtime is performed, the handle database, active consoles, UEFI Boot Services, DXE Services, and services provided by boot service DXE drivers are terminated. This frees up memory for use by the OS. This only leaves the UEFI System Table, UEFI Runtime Services Table, and the UEFI Configuration Tables available in the OS runtime environment. There is also the option of converting all of the UEFI Runtime Services from a physical address space to an OS-specific virtual address space. This address space conversion may be performed only once.

9.4. Required DXE Foundation Components

DXE Foundation Components shows the components that a DXE Foundation must contain. A detailed description of these components follows.

_images/V2_DXE_Foundation-4.png

Fig. 9.3 DXE Foundation Components

A DXE Foundation must have the following components:

  • An implementation of the UEFI Boot Services. UEFI Boot Services Dependencies describes which services can be made available based on the HOB list alone and which services depend on the presence of architectural protocols.

  • An implementation of the DXE Services. DXE Services Dependencies describes which services can be made available based on the HOB list alone and which services depend on the presence of architectural protocols.

  • A HOB Parser that consumes the HOB list specified by HobStart and initializes the UEFI memory map, GCD memory space map, and GCD I/O space map. See section if for details on the translation from HOBs to the maps maintained by the DXE Foundation

  • An implementation if a DXE Dispatcher that includes a dependency expression evaluator. See DXE Dispatcher for a detailed description of this component.

  • A Firmware Volume driver that produces the EFI_FIRMWARE_VOLUME2_PROTOCOL for every firmware volume described in the HOB list. This component is used by the DXE Dispatcher to search for a priori files and DXE drivers in firmware volumes. See the Platform Initialization Specification , Volume 3, for the definition of the Firmware Volume Protocol.

  • An instance of the EFI_DECOMPRESS_PROTOCOL . See the UEFI 2.0 specification for the detailed requirements for this component. This component is required by the DXE Dispatcher to read compressed sections from DXE drivers stored in firmware volumes. It is expected that most DXE drivers will utilize compressed sections to reduce the size of firmware volumes.

  • The DXE Dispatcher uses the Boot Service StartImage() to invoke a DXE driver. The Boot Services StartImage() and Exit() work together to hand control to a DXE driver and return control to the DXE Foundation. Since the Boot Service Exit() can be called for anywhere inside a DXE driver, the Boot Service Exit() is required to rebalance the stack, so it is in the same state it was in when the Boot Service Start() was called. This is typically implemented using the processor-specific functions called SetJump() and LongJump() . Since the DXE Foundation must use the Boot Services StartImage() and Exit() to invoke DXE drivers, the routines SetJump() and LongJump() are required by the DXE Foundation.

  • A PE/COFF loader that supports PE32+ image types. This PE/COFF loader is used to implement the UEFI Boot Service LoadImage() . The DXE Dispatcher uses the Boot Service LoadImage() to load DXE drivers into system memory. If the processor that the DXE Foundation is compiled for requires an instruction cache when an image is loaded into system memory, then an instruction cache flush routine is also required in the DXE Foundation.

  • The phase that executed prior to DXE will initialize a stack for the DXE Foundation to use. This stack is described in the HOB list. If the size of this stack does not meet the DXE Foundation’s minimum stack size requirement or the stack is not located in memory region that is suitable to the DXE Foundation, then the DXE Foundation will have to allocate a new stack that does meet the minimum size and location requirements. As a result, the DXE Foundation must contain a stack switching routine for the processor type that the DXE Foundation is compiled.

9.5. Handing Control to DXE Dispatcher

The DXE Foundation must complete the following tasks before handing control to the DXE Dispatcher. The order that these tasks are performed is implementation dependent.

  • Use the HOB list to initialize the GCD memory space map, the GCD I/O space map, and UEFI memory map.

  • Allocate the UEFI Boot Services Table from EFI_BOOT_SERVICES_MEMORY and initialize the services that only require system memory to function correctly. The remaining UEFI Boot Services must be filled in with a service that returns EFI_NOT_AVAILABLE_YET .

  • Allocate the DXE Services Table from EFI_BOOT_SERVICES_MEMORY and initialize the services that only require system memory to function correctly. The remaining DXE Services must be filled in with a service that returns EFI_NOT_AVAILABLE_YET .

  • Allocate the UEFI Runtime Services Table from EFI_RUNTIME_SERVICES_MEMORY and initialize all the services to a service that returns EFI_NOT_AVAILABLE_YET .

  • Allocate the UEFI System Table from EFI_RUNTIME_SERVICES_MEMORY and initialize all the fields.

  • Build an image handle and EFI_LOADED_IMAGE_PROTOCOL instance for the DXE Foundation itself and add it to the handle database.

  • If the HOB list is not in a suitable location in memory, then relocate the HOB list to a more suitable location.

  • Add the DXE Services Table to the UEFI Configuration Table.

  • Add the HOB list to the UEFI Configuration Table.

  • Create a notification event for each of the DXE Architectural Protocols. These events will be signaled when a DXE driver installs a DXE Architectural Protocol in the handle database. The DXE Foundation must have a notification function associated with each of these events, so the full complement of UEFI Boot Services, UEFI Runtime Services, and DXE Services can be produced. Each of the notification functions should compute the 32-bit CRC of the UEFI Boot Services Table, UEFI Runtime Services Table, and the DXE Services Table if the CalculateCrc32() Boot Services is available.

  • Initialize the Decompress Protocol driver that must be available before the DXE Dispatcher can process compressed sections.

  • Produce firmware volume handles for the one or more firmware volumes that are described in the HOB list.

Once these tasks have been completed, the DXE Foundation is ready to load and execute DXE drivers stored in firmware volumes. This execution is done by handing control to the DXE Dispatcher. Once the DXE Dispatcher has finished dispatching all the DXE drivers that it can, control is then passed to the BDS Architectural Protocol. If for some reason, any of the DXE Architectural Protocols have not been produced by the DXE drivers, then the system is in an unusable state and the DXE Foundation must halt. Otherwise, control is handed to the BDS Architectural Protocol. The BDS Architectural Protocol is responsible for transferring control to an operating system or system utility.

9.6. DXE Foundation Entry Point

9.6.1. DXE_ENTRY_POINT

The only parameter passed to the DXE Foundation is a pointer to the HOB list. The DXE Foundation and all the DXE drivers must treat the HOB list as read-only data.

The function DXE_ENTRY_POINT is the main entry point to the DXE Foundation.

9.6.1.1. DXE_ENTRY_POINT

Summary

This function is the main entry point to the DXE Foundation.

Prototype

typedef
VOID
(EFIAPI *DXE_ENTRY_POINT) (
  IN CONST VOID  *HobStart
  );

Parameters

HobStart

A pointer to the HOB list.

Description

This function is the entry point to the DXE Foundation. The PEI phase, which executes just before DXE, is responsible for loading and invoking the DXE Foundation in system memory. The only parameter that is passed to the DXE Foundation is HobStart . This parameter is a pointer to the HOB list that describes the system state at the hand-off to the DXE Foundation. At a minimum, this system state must include the following:

  • PHIT HOB

  • CPU HOB

  • Description of system memory

  • Description of one or more firmware volumes

The DXE Foundation is also guaranteed that only one processor is running and that the processor is running with interrupts disabled. The implementation of the DXE Foundation must not make any assumptions about where the DXE Foundation will be loaded or where the stack is located. In general, the DXE Foundation should make as few assumptions about the state of the system as possible. This lack of assumptions will allow the DXE Foundation to be portable to the widest variety of system architectures.

9.7. Dependencies

9.7.1. UEFI Boot Services Dependencies

Boot Service Dependencies lists all the UEFI Boot Services and the components upon which each of these services depend. The topics that follow describe what responsibilities the DXE Foundation has in producing the services that depend on the presence of DXE Architectural Protocols.

Table 9.3 Boot Service Dependencies

Name

Dependency

CreateEvent

HOB list

CloseEvent

HOB list

SignalEvent

HOB list

WaitForEvent

HOB list

CheckEvent

HOB list

SetTimer

Timer Architectural Protocol

RaiseTPL

CPU Architectural Protocol

RestoreTPL

CPU Architectural Protocol

AllocatePages

HOB list

FreePages

HOB list

GetMemoryMap

HOB list and GetMemorySpaceMap

AllocatePool

HOB list

FreePool

HOB list

InstallProtocolInterface

HOB list

UninstallProtocolInterface

HOB list

ReinstallProtocolInterface

HOB list

RegisterProtocolNotify

HOB list

LocateHandle

HOB list

HandleProtocol

HOB list

LocateDevicePath

HOB list

OpenProtocol

HOB list

CloseProtocol

HOB list

OpenProtocolInformation

HOB list

ConnectController

HOB list

DisconnectController

HOB list

ProtocolsPerHandle

HOB list

LocateHandleBuffer

HOB list

LocateProtocol

HOB list

InstallMultipleProtocolInterfaces

HOB list

Un installMultipleProtocolInterfaces

HOB list

LoadImage

HOB list

StartImage

HOB list

UnloadImage

HOB list

EFI_IMAGE_ENTRY_POINT

HOB list

Exit

HOB list

ExitBootServices

HOB list

SetWatchDogTimer

Watchdog Architectural Protocol

Stall

Metronome Architectural Protocol Timer Architectural Protocol

CopyMem

HOB list

SetMem

HOB list

GetMemory Map

HOB list

GetMemorySpaceMap

GCD Service

GetNextMonotonicCount

Monotonic Counter Architectural Protocol

InstallConfigurationTable

HOB list

CalculateCrc32

Runtime Architectural Protocol

9.7.1.1. SetTimer()

When the DXE Foundation is notified that the EFI_TIMER_ARCH_PROTOCOL has been installed, then the Boot Service SetTimer() can be made available. The DXE Foundation can use the services of the EFI_TIMER_ARCH_PROTOCOL to initialize and hook a heartbeat timer interrupt for the DXE Foundation. The DXE Foundation can use this heartbeat timer interrupt to determine when to signal on-shot and periodic timer events. This service may be called before the EFI_TIMER_ARCH_PROTOCOL is installed. However, since a heartbeat timer is not running yet, time is essentially frozen at zero. This means that no periodic or one-shot timer events will fire until the EFI_TIMER_ARCH_PROTOCOL is installed.

9.7.1.2. RaiseTPL()

The DXE Foundation must produce the Boot Service RaiseTPL() when the memory-based services are initialized. The DXE Foundation is guaranteed to be handed control of the platform with interrupts disabled. Until the DXE Foundation installs a heartbeat timer interrupt and turns on interrupts, this Boot Service can be a very simple function that always succeeds. When the DXE Foundation is notified that the EFI_CPU_ARCH_PROTOCOL has been installed, then the full version of the Boot Service RaiseTPL() can be made available. When an attempt is made to raise the TPL level to EFI_TPL_HIGH_LEVEL or higher, then the DXE Foundation should use the services of the EFI_CPU_ARCH_PROTOCOL to disable interrupts.

9.7.1.3. RestoreTPL()

The DXE Foundation must produce the Boot Service RestoreTPL() when the memory-based services are initialized. The DXE Foundation is guaranteed to be handed control of the platform with interrupts disabled. Until the DXE Foundation installs a heartbeat timer interrupt and turns on interrupts, this Boot Service can be a very simple function that always succeeds. When the DXE Foundation is notified that the EFI_CPU_ARCH_PROTOCOL has been installed, then the full version of the Boot Service RestoreTPL() can be made available. When an attempt is made to restore the TPL level to level below EFI_TPL_HIGH_LEVEL , then the DXE Foundation should use the services of the EFI_CPU_ARCH_PROTOCOL to enable interrupts.

9.7.1.4. SetWatchdogTimer()

When the DXE Foundation is notified that the EFI_WATCHDOG_ARCH_PROTOCOL has been installed, then the Boot Service SetWatchdogTimer() can be made available. The DXE Foundation can use the services of the EFI_WATCHDOG_TIMER_ARCH_PROTOCOL to set the amount of time before the system’s watchdog timer will expire.

9.7.1.5. Stall()

When the DXE Foundation is notified that the EFI_METRONOME_ARCH_PROTOCOL has been installed, the DXE Foundation can produce a very simple version of the Boot Service Stall() . The granularity of the Boot Service Stall() will be based on the period of the EFI_METRONOME_ARCH_PROTOCOL . When the DXE Foundation is notified that the EFI_TIMER_ARCH_PROTOCOL has been installed, the DXE Foundation can possibly produce a more accurate version of the Boot Service Stall() . This all depends on the periods of the EFI_METRONOME_ARCH_PROTOCOL and the period of the EFI_TIMER_ARCH_PROTOCOL . The DXE Foundation should produce the Boot Service Stall() using the most accurate time base available.

9.7.1.6. GetNextMonotonicCount()

When the DXE Foundation is notified that the EFI_MONOTONIC_COUNTER_ARCH_PROTOCOL has been installed, then the Boot Service GetNextMonotonicCount() is available. The DXE driver that produces the EFI_MONOTONIC_COUNTER_ARCH_PROTOCOL is responsible for directly updating the GetNextMonotonicCount field of the UEFI Boot Services Table. The DXE Foundation is only responsible for updating the 32-bit CRC of the UEFI Boot Services Table.

9.7.1.7. CalculateCrc32()

When the DXE Foundation is notified that the EFI_RUNTIME_ARCH_PROTOCOL has been installed, then the Boot Service CalculateCrc32() is available. The DXE driver that produces the EFI_RUNTIME_ARCH_PROTOCOL is responsible for directly updating the CalculateCrc32 field of the UEFI Boot Services Table. The DXE Foundation is only responsible for updating the 32-bit CRC of the UEFI Boot Services Table.

9.7.1.8. GetMemoryMap()

The GetMemoryMap() implementation must include into the UEFI memory map all GCD map entries of types EfiGcdMemoryTypeReserved and EfiPersistentMemory , and all GCD map entries of type EfiGcdMemoryTypeMemoryMappedIo that have EFI_MEMORY_RUNTIME attribute set.

9.7.2. UEFI Runtime Services Dependencies

Runtime Service Dependencies lists all the UEFI Runtime Services and the components upon which each of these services depend. The topics that follow describe what responsibilities the DXE Foundation has in producing the services that depend on the presence of DXE Architectural Protocols.

Table 9.4 Runtime Service Dependencies

Name

Dependency

GetVariable

Variable Architectural Protocol

GetNextVariableName

Variable Architectural Protocol

SetVariable

Variable Architectural Protocol Variable Write Architectural Protocol

GetTime

Real Time Clock Architectural Protocol

SetTime

Real Time Clock Architectural Protocol

GetWakeupTime

Real Time Clock Architectural Protocol

SetWakeupTime

Real Time Clock Architectural Protocol

SetVirtualAddressMap

Runtime Architectural Protocol

ConvertPointer

Runtime Architectural Protocol

ResetSystem

Reset Architectural Protocol

GetNextHighMonotonicCount

Monotonic Counter Architectural Protocol

UpdateCapsule

Capsule Header Protocol

QueryCapsuleCapabilities

Capsule Header Protocol

9.7.2.1. GetVariable()

When the DXE Foundation is notified that the EFI_VARIABLE_ARCH_PROTOCOL has been installed, then the Runtime Service GetVariable() is available. The DXE driver that produces the EFI_VARIABLE_ARCH_PROTOCOL is responsible for directly updating the GetVariable field of the UEFI Runtime Services Table. The DXE Foundation is only responsible for updating the 32-bit CRC of the UEFI Runtime Services Table.

9.7.2.2. GetNextVariableName()

When the DXE Foundation is notified that the EFI_VARIABLE_ARCH_PROTOCOL has been installed, then the Runtime Service GetNextVariableName() is available. The DXE driver that produces the EFI_VARIABLE_ARCH_PROTOCOL is responsible for directly updating the GetNextVariableName field of the UEFI Runtime Services Table. The DXE Foundation is only responsible for updating the 32-bit CRC of the UEFI Runtime Services Table.

9.7.2.3. SetVariable()

When the DXE Foundation is notified that the EFI_VARIABLE_ARCH_PROTOCOL has been installed, then the Runtime Service SetVariable() is available. The DXE driver that produces the EFI_VARIABLE_ARCH_PROTOCOL is responsible for directly updating the SetVariable field of the UEFI Runtime Services Table. The DXE Foundation is only responsible for updating the 32-bit CRC of the UEFI Runtime Services Table. The EFI_VARIABLE_ARCH_PROTOCOL is required to provide read-only access to all environment variables and write access to volatile environment variables. When the DXE Foundation is notified that the EFI_VARIABLE_WRITE_ARCH_PROTOCOL has been installed, then write access to nonvolatile environment variables will also be available. If an attempt is made to call this function for a nonvolatile environment variable prior to the installation of EFI_VARIABLE_WRITE_ARCH_PROTOCOL , then EFI_NOT_AVAILABLE_YET must be returned. This allows for flexibility in the design and implementation of the variables services in a platform such that read access to environment variables can be provided very early in the DXE phase and write access to nonvolatile environment variables can be provided later in the DXE phase.

9.7.2.4. GetTime()

When the DXE Foundation is notified that the EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL has been installed, then the Runtime Service GetTime() is available. The DXE driver that produces the EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL is responsible for directly updating the GetTime field of the UEFI Runtime Services Table. The DXE Foundation is only responsible for updating the 32-bit CRC of the UEFI Runtime Services Table.

9.7.2.5. SetTime()

When the DXE Foundation is notified that the EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL has been installed, then the Runtime Service SetTime() is available. The DXE driver that produces the EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL is responsible for directly updating the SetTime field of the UEFI Runtime Services Table. The DXE Foundation is only responsible for updating the 32-bit CRC of the UEFI Runtime Services Table.

9.7.2.6. GetWakeupTime()

When the DXE Foundation is notified that the EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL has been installed, then the Runtime Service GetWakeupTime() is available. The DXE driver that produces the EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL is responsible for directly updating the GetWakeupTime field of the UEFI Runtime Services Table. The DXE Foundation is only responsible for updating the 32-bit CRC of the UEFI Runtime Services Table.

9.7.2.7. SetWakeupTime()

When the DXE Foundation is notified that the EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL has been installed, then the Runtime Service SetWakeupTime() is available. The DXE driver that produces the EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL is responsible for directly updating the SetWakeupTime field of the UEFI Runtime Services Table. The DXE Foundation is only responsible for updating the 32-bit CRC of the UEFI Runtime Services Table.

9.7.2.8. SetVirtualAddressMap()

When the DXE Foundation is notified that the EFI_RUNTIME_ARCH_PROTOCOL has been installed, then the Runtime Service SetVirtualAddressMap() is available. The DXE driver that produces the EFI_RUNTIME_ARCH_PROTOCOL is responsible for directly updating the SetVirtualAddressMap field of the UEFI Runtime Services Table. The DXE Foundation is only responsible for updating the 32-bit CRC of the UEFI Runtime Services Table.

9.7.2.9. ConvertPointer()

When the DXE Foundation is notified that the EFI_RUNTIME_ARCH_PROTOCOL has been installed, then the Runtime Service ConvertPointer() is available. The DXE driver that produces the EFI_RUNTIME_ARCH_PROTOCOL is responsible for directly updating the ConvertPointer field of the UEFI Runtime Services Table. The DXE Foundation is only responsible for updating the 32-bit CRC of the UEFI Runtime Services Table.

9.7.2.10. ResetSystem()

When the DXE Foundation is notified that the EFI_RESET_ARCH_PROTOCOL has been installed, then the Runtime Service ResetSystem() is available. The DXE driver that produces the EFI_RESET_ARCH_PROTOCOL is responsible for directly updating the Reset field of the UEFI Runtime Services Table. The DXE Foundation is only responsible for updating the 32-bit CRC of the UEFI Runtime Services Table.

9.7.2.11. GetNextHighMonotonicCount()

When the DXE Foundation is notified that the EFI_MONOTONIC_COUNTER_ARCH_PROTOCOL has been installed, then the Runtime Service GetNextHighMonotonicCount() is available. The DXE driver that produces the EFI_MONOTONIC_COUNTER_ARCH_PROTOCOL is responsible for directly updating the GetNextHighMonotonicCount field of the UEFI Runtime Services Table. The DXE Foundation is only responsible for updating the 32-bit CRC of the UEFI Runtime Services Table.

9.7.3. DXE Services Dependencies

DXE Service Dependencies lists all the DXE Services and the components upon which each of these services depend. The topics that follow describe what responsibilities the DXE Foundation has in producing the services that depend on the presence of DXE Architectural Protocols.

Table 9.5 DXE Service Dependencies

Name

Dependency

AddMemorySpace

HOB list

AllocateMemorySpace

HOB list

FreeMemorySpace

HOB list

RemoveMemorySpace

HOB list

GetMemorySpaceDescriptor

CPU Architectural Protocol

SetMemorySpaceAttributes

CPU Architectural Protocol

GetMemorySpaceMap

CPU Architectural Protocol

AddIoSpace

HOB list

AllocateIoSpace

HOB list

FreeIoSpace

HOB list

RemoveIoSpace

HOB list

GetIoSpaceDescriptor

HOB list

GetIoSpaceMap

HOB list

Schedule

HOB list

9.7.3.1. GetMemorySpaceDescriptor()

When the DXE Foundation is notified that the EFI_CPU_ARCH_PROTOCOL has been installed, then the DXE Service GetMemorySpaceDescriptor() is fully functional. This function is made available when the memory-based services are initialized. However, the Attributes field of the EFI_GCD_MEMORY_SPACE_DESCRIPTOR is not valid until the EFI_CPU_ARCH_PROTOCOL is installed.

9.7.3.2. SetMemorySpaceAttributes()

When the DXE Foundation is notified that the EFI_CPU_ARCH_PROTOCOL has been installed, then the DXE Service SetMemorySpaceAttributes() can be made available. The DXE Foundation can then use the SetMemoryAttributes() service of the EFI_CPU_ARCH_PROTOCOL to implement the DXE Service SetMemorySpaceAttributes() .

9.7.3.3. GetMemorySpaceMap()

When the DXE Foundation is notified that the EFI_CPU_ARCH_PROTOCOL has been installed, then the DXE Service GetMemorySpaceMap() is fully functional. This function is made available when the memory-based services are initialized. However, the Attributes field of the array of EFI_GCD_MEMORY_SPACE_DESCRIPTOR s is not valid until the EFI_CPU_ARCH_PROTOCOL is installed.

9.8. HOB Translations

9.8.1. HOB Translations Overview

The following topics describe how the DXE Foundation should interpret the contents of the HOB list to initialize the GCD memory space map, GCD I/O space map, and UEFI memory map. After all of the HOBs have been parsed, the Boot Service GetMemoryMap() and the DXE Services GetMemorySpaceMap() and GetIoSpaceMap() should reflect the memory resources, I/O resources, and logical memory allocations described in the HOB list.

See Volume 3 for detailed information on HOBs.

9.8.2. PHIT HOB

The Phase Handoff Information Table (PHIT) HOB describes a region of tested system memory. This region of memory contains the following:

  • HOB list

  • Some amount of free memory

  • Potentially some logical memory allocations

The PHIT HOB is used by the DXE Foundation to determine the size of the HOB list so that the DXE Foundation can relocate the HOB list to a new location in system memory. The base address of the HOB list is passed to the DXE Foundation in the parameter HobStart , and the PHIT HOB field EfiFreeMemoryBottom specifies the end of the HOB list.

Since the PHIT HOB may contain some of amount of free memory, the DXE Foundation may use this free memory region in its early initialization phase until the full complement of UEFI memory services are available.

See Volume 3 for the definition of this HOB type.

9.8.3. CPU HOB

The CPU HOB contains the field SizeOfMemorySpaceMap . This field is used to initialize the GCD memory space map. The SizeOfMemorySpaceMap field defines the number of address bits that the processor can use to address memory resources. The DXE Foundation must create the primordial GCD memory space map entry of type EfiGcdMemoryTypeNonExistent for the region from 0 to (1 << SizeOfMemorySpaceMap) . All future GCD memory space operations must be performed within this memory region.

The CPU HOB also contains the field SizeOfIoSpaceMap . This field is used to initialize the GCD I/O space map. The SizeOfIoSpaceMap field defines the number of address bits that the processor can use to address I/O resources. The DXE Foundation must create the primordial GCD I/O space map entry of type EfiGcdIoTypeNonExistent for the region from 0 to (1 << SizeOfIoSpaceMap). All future GCD I/O space operations must be performed within this I/O region.

See Volume 3 for the definition of this HOB type.

9.8.4. Resource Descriptor HOBs

The DXE Foundation must traverse the HOB list looking for Resource Descriptor HOBs. These HOBs describe memory and I/O resources that are visible to the processor. All of the resource ranges described in these HOBs must fall in the memory and I/O ranges initialized in the GCD maps based on the contents of the CPU HOB. The DXE Foundation will use the DXE Services AddMemorySpace() and AddIoSpace() to register these memory and I/O resources in the GCD maps.

The Owner field of the Resource Descriptor HOB is ignored by the DXE Foundation. The ResourceType field and ResourceAttribute fields are used to determine the GCD memory type or GCD I/O type of the resource. The table below shows this mapping. The resource range is specified by the PhysicalStart and ResourceLength fields of the Resource Descriptor HOB.

The ResourceAttribute field also contains the caching capabilities of memory regions. If a memory region is being added to the GCD memory space map, then the ResourceAttribute field will be used to initialize the supported caching capabilities. The ResourceAttribute field is also be used to further qualify memory regions. For example, a system memory region cannot be added to the UEFI memory map if it is read protected. However, it is legal to add a firmware device memory region that is write-protected if the firmware device is a ROM.

See Volume 3 for the definition of this HOB type.

Table 9.6 Resource Descriptor HOB to GCD Type Mapping

Resource Descriptor HOB

GCD Map

Resource Type

Attributes

Memory Type

I/O Type

System Memory

Present

Reserved

System Memory

Present AND Initialized

Reserved

System Memory

Present AND Initialized AND Tested

System Memory

Memory Mapped I/O

Memory Mapped I/O

Firmware Device

Memory Mapped I/O

Memory Mapped I/O Port

Reserved

Memory Reserved

Reserved

Unaccepted Memory

Unaccepted

I/O

I/O

I/O Reserved

Reserved

9.8.5. Firmware Volume HOBs

The DXE Foundation must traverse the HOB list for Firmware Volume HOBs. There are two types of firmware volume HOBs:

  • EFI_HOB_FIRMWARE_VOLUME , which describes PI Firmware Volumes.

  • EFI_HOB_FIRMWARE_VOLUME2 which describes PI Firmware Volumes which came from a firmware file within a firmware volume.

When the DXE Foundation discovers a Firmware Volume HOB, the DXE Dispatcher verifies that the firmware volume has not been previously processed. Then a new handle must be created in the handle database, and the EFI_FIRMWARE_VOLUME2_PROTOCOL must be installed on that handle. The BaseAddress and Length fields of the Firmware Volume HOB specific the memory range that the firmware volume consumes. The DXE Service AllocateMemorySpace() is used to allocate the memory regions described in the Firmware Volume HOBs to the DXE Foundation. The UEFI Boot Service InstallProtocolInterface() is used to create new handles and install protocol interfaces.

See the Platform Initialization Specification, Volume 3, for code definitions concerning Hand-Off Blocks, the Firmware Volume Block Protocol and the Firmware Volume Protocol.

9.8.6. Memory Allocation HOBs

Memory Allocation HOBs describe logical memory allocations that occurred prior to the DXE phase. The DXE Foundation must parse the HOB list for this HOB type. When a HOB of this type is discovered, the GCD memory space map must be updated with a call to the DXE Service AllocateMemorySpace() . In addition, the UEFI memory map must be updated with logical allocation described by the MemoryType , MemoryBaseAddress , and MemoryLength fields of the Memory Allocation HOB.

Once the DXE Foundation has parsed all of the Memory Allocation HOBs, all of the unallocated system memory regions in the GCD memory space map must be allocated to the DXE Foundation with the DXE Service AllocateMemorySpace() . In addition, those same memory regions must be added to the UEFI memory map so those memory regions can be allocated and freed using the Boot Services AllocatePages() , AllocatePool() , FreePages() , and FreePool() .

See Volume 3 for the definition of this HOB type.

9.8.7. GUID Extension HOBs

The DXE Foundation does not require any GUID Extension HOBs. Implementations of the DXE Foundation may use GUID Extension HOBs but shall not require them in order to function correctly. GUID Extension HOBs contain private or implementation-specific data that is being passed from the previous execution phase to a specific DXE driver. DXE drivers may choose to parse the HOB list for GUID Extension HOBs.

See Volume 3 for the definition of this HOB type.