dispatcher.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,192 行 · 第 1/3 页
C
1,192 行
DriverEntry->FvHandle = FvHandle;
DriverEntry->Fv = Fv;
DriverEntry->FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName);
CoreGetDepexSectionAndPreProccess (DriverEntry);
CoreAcquireDispatcherLock ();
InsertTailList (&mDiscoveredList, &DriverEntry->Link);
CoreReleaseDispatcherLock ();
return EFI_SUCCESS;
}
EFI_STATUS
CoreProcessFvImageFile (
IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv,
IN EFI_HANDLE FvHandle,
IN EFI_GUID *DriverName
)
/*++
Routine Description:
Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.
Arguments:
Fv - The FIRMWARE_VOLUME protocol installed on the FV.
FvHandle - The handle which FVB protocol installed on.
DriverName - The driver guid specified.
Returns:
EFI_OUT_OF_RESOURCES - No enough memory or other resource.
EFI_VOLUME_CORRUPTED - Corrupted volume.
EFI_SUCCESS - Function successfully returned.
--*/
{
EFI_STATUS Status;
EFI_SECTION_TYPE SectionType;
UINT32 AuthenticationStatus;
VOID *Buffer;
UINTN BufferSize;
//
// Read the first (and only the first) firmware volume section
//
SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;
Buffer = NULL;
BufferSize = 0;
Status = Fv->ReadSection (
Fv,
DriverName,
SectionType,
0,
&Buffer,
&BufferSize,
&AuthenticationStatus
);
if (!EFI_ERROR (Status)) {
//
// Produce a FVB protocol for the file
//
Status = ProduceFVBProtocolOnBuffer (
(EFI_PHYSICAL_ADDRESS) (UINTN) Buffer,
(UINT64)BufferSize,
FvHandle,
NULL
);
}
if (EFI_ERROR (Status) && (Buffer != NULL)) {
//
// ReadSection or Produce FVB failed, Free data buffer
//
gBS->FreePool (Buffer);
}
return Status;
}
VOID
EFIAPI
CoreFwVolEventProtocolNotify (
IN EFI_EVENT Event,
IN VOID *Context
)
/*++
Routine Description:
Event notification that is fired every time a FV dispatch protocol is added.
More than one protocol may have been added when this event is fired, so you
must loop on CoreLocateHandle () to see how many protocols were added and
do the following to each FV:
If the Fv has already been processed, skip it. If the Fv has not been
processed then mark it as being processed, as we are about to process it.
Read the Fv and add any driver in the Fv to the mDiscoveredList.The
mDiscoveredList is never free'ed and contains variables that define
the other states the DXE driver transitions to..
While you are at it read the A Priori file into memory.
Place drivers in the A Priori list onto the mScheduledQueue.
Arguments:
Event - The Event that is being processed, not used.
Context - Event Context, not used.
Returns:
None
--*/
{
EFI_STATUS Status;
EFI_STATUS GetNextFileStatus;
EFI_STATUS SecurityStatus;
EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
EFI_DEVICE_PATH_PROTOCOL *FvDevicePath;
EFI_HANDLE FvHandle;
UINTN BufferSize;
EFI_GUID NameGuid;
UINTN Key;
EFI_FV_FILETYPE Type;
EFI_FV_FILE_ATTRIBUTES Attributes;
UINTN Size;
EFI_CORE_DRIVER_ENTRY *DriverEntry;
EFI_GUID *AprioriFile;
UINTN AprioriEntryCount;
UINTN Index;
EFI_LIST_ENTRY *Link;
UINT32 AuthenticationStatus;
UINTN SizeOfBuffer;
while (TRUE) {
BufferSize = sizeof (EFI_HANDLE);
Status = CoreLocateHandle (
ByRegisterNotify,
NULL,
mFwVolEventRegistration,
&BufferSize,
&FvHandle
);
if (EFI_ERROR (Status)) {
//
// If no more notification events exit
//
return;
}
if (FvHasBeenProcessed (FvHandle)) {
//
// This Fv has already been processed so lets skip it!
//
continue;
}
Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeDispatchProtocolGuid, &Fv);
if (EFI_ERROR (Status)) {
//
// If no dispatch protocol then skip, but do not marked as being processed as it
// may show up later.
//
continue;
}
//
// Since we are about to process this Fv mark it as processed.
//
FvIsBeingProcesssed (FvHandle);
Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeProtocolGuid, &Fv);
if (EFI_ERROR (Status)) {
//
// The Handle has a FirmwareVolumeDispatch protocol and should also contiain
// a FirmwareVolume protocol thus we should never get here.
//
ASSERT (FALSE);
continue;
}
Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, &FvDevicePath);
if (EFI_ERROR (Status)) {
//
// The Firmware volume doesn't have device path, can't be dispatched.
//
continue;
}
//
// Evaluate the authentication status of the Firmware Volume through
// Security Architectural Protocol
//
if (gSecurity != NULL) {
SecurityStatus = gSecurity->FileAuthenticationState (
gSecurity,
0,
FvDevicePath
);
if (SecurityStatus != EFI_SUCCESS) {
//
// Security check failed. The firmware volume should not be used for any purpose.
//
continue;
}
}
//
// Discover Drivers in FV and add them to the Discovered Driver List.
// Process EFI_FV_FILETYPE_DRIVER type and then EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
// EFI_FV_FILETYPE_DXE_CORE is processed to produce a Loaded Image protocol for the core
// EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE is processed to create a Fvb
//
for (Index = 0; Index < sizeof (mDxeFileTypes)/sizeof (EFI_FV_FILETYPE); Index++) {
//
// Initialize the search key
//
Key = 0;
do {
Type = mDxeFileTypes[Index];
GetNextFileStatus = Fv->GetNextFile (
Fv,
&Key,
&Type,
&NameGuid,
&Attributes,
&Size
);
if (!EFI_ERROR (GetNextFileStatus)) {
if (Type == EFI_FV_FILETYPE_DXE_CORE) {
//
// If this is the DXE core fill in it's DevicePath & DeviceHandle
//
if (gDxeCoreLoadedImage->FilePath == NULL) {
if (EfiCompareGuid (&NameGuid, gDxeCoreFileName)) {
CoreInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid);
mFvDevicePath.End.Type = EFI_END_ENTIRE_DEVICE_PATH;
mFvDevicePath.End.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
SetDevicePathNodeLength (&mFvDevicePath.End, sizeof (EFI_DEVICE_PATH_PROTOCOL));
gDxeCoreLoadedImage->FilePath = CoreDuplicateDevicePath (
(EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
);
gDxeCoreLoadedImage->DeviceHandle = FvHandle;
}
}
} else if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
//
// Found a firmware volume image. Produce a firmware volume block
// protocol for it so it gets dispatched from. This is usually a
// capsule.
//
CoreProcessFvImageFile (Fv, FvHandle, &NameGuid);
} else {
//
// Transition driver from Undiscovered to Discovered state
//
CoreAddToDriverList (Fv, FvHandle, &NameGuid);
}
}
} while (!EFI_ERROR (GetNextFileStatus));
}
//
// Read the array of GUIDs from the Apriori file if it is present in the firmware volume
//
AprioriFile = NULL;
Status = Fv->ReadSection (
Fv,
&gAprioriGuid,
EFI_SECTION_RAW,
0,
&AprioriFile,
&SizeOfBuffer,
&AuthenticationStatus
);
if (!EFI_ERROR (Status)) {
AprioriEntryCount = SizeOfBuffer / sizeof (EFI_GUID);
} else {
AprioriEntryCount = 0;
}
//
// Put drivers on Apriori List on the Scheduled queue. The Discovered List includes
// drivers not in the current FV and these must be skipped since the a priori list
// is only valid for the FV that it resided in.
//
CoreAcquireDispatcherLock ();
for (Index = 0; Index < AprioriEntryCount; Index++) {
for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
if (EfiCompareGuid (&DriverEntry->FileName, &AprioriFile[Index]) &&
(FvHandle == DriverEntry->FvHandle)) {
DriverEntry->Dependent = FALSE;
DriverEntry->Scheduled = TRUE;
InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
break;
}
}
}
CoreReleaseDispatcherLock ();
//
// Free data allocated by Fv->ReadSection ()
//
gBS->FreePool (AprioriFile);
}
}
VOID
CoreInitializeDispatcher (
VOID
)
/*++
Routine Description:
Initialize the dispatcher. Initialize the notification function that runs when
a FV protocol is added to the system.
Arguments:
NONE
Returns:
NONE
--*/
{
mFwVolEvent = CoreCreateProtocolNotifyEvent (
&gEfiFirmwareVolumeProtocolGuid,
EFI_TPL_CALLBACK,
CoreFwVolEventProtocolNotify,
NULL,
&mFwVolEventRegistration,
TRUE
);
}
//
// Function only used in debug buils
//
DEBUG_CODE (
VOID
CoreDisplayDiscoveredNotDispatched (
VOID
)
/*++
Routine Description:
Traverse the discovered list for any drivers that were discovered but not loaded
because the dependency experessions evaluated to false
Arguments:
NONE
Returns:
NONE
--*/
{
EFI_LIST_ENTRY *Link;
EFI_CORE_DRIVER_ENTRY *DriverEntry;
for (Link = mDiscoveredList.ForwardLink;Link !=&mDiscoveredList; Link = Link->ForwardLink) {
DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
if (DriverEntry->Dependent) {
DEBUG ((EFI_D_LOAD, "Driver %g was discovered but not loaded!!\n", &DriverEntry->FileName));
}
}
}
)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?