X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FCore%2FDxe%2FDispatcher%2FDispatcher.c;h=5eee71bb2cd33ce6fd10dd72c183d76db9239b4d;hp=554a07c42b88797ba3a133232e9d4e7c189bcd28;hb=e06179889586c37101e2900e7f52be9f0da12cda;hpb=162ed594438ab8d39f89b43e6d645ca24e1e1e65
diff --git a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
index 554a07c42b..5eee71bb2c 100644
--- a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
+++ b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
@@ -2,48 +2,48 @@
DXE Dispatcher.
Step #1 - When a FV protocol is added to the system every driver in the FV
- is added to the mDiscoveredList. The SOR, Before, and After Depex are
- pre-processed as drivers are added to the mDiscoveredList. If an Apriori
- file exists in the FV those drivers are addeded to the
- mScheduledQueue. The mFvHandleList is used to make sure a
+ is added to the mDiscoveredList. The SOR, Before, and After Depex are
+ pre-processed as drivers are added to the mDiscoveredList. If an Apriori
+ file exists in the FV those drivers are addeded to the
+ mScheduledQueue. The mFvHandleList is used to make sure a
FV is only processed once.
Step #2 - Dispatch. Remove driver from the mScheduledQueue and load and
- start it. After mScheduledQueue is drained check the
- mDiscoveredList to see if any item has a Depex that is ready to
+ start it. After mScheduledQueue is drained check the
+ mDiscoveredList to see if any item has a Depex that is ready to
be placed on the mScheduledQueue.
- Step #3 - Adding to the mScheduledQueue requires that you process Before
+ Step #3 - Adding to the mScheduledQueue requires that you process Before
and After dependencies. This is done recursively as the call to add
- to the mScheduledQueue checks for Before and recursively adds
- all Befores. It then addes the item that was passed in and then
+ to the mScheduledQueue checks for Before and recursively adds
+ all Befores. It then addes the item that was passed in and then
processess the After dependecies by recursively calling the routine.
Dispatcher Rules:
- The rules for the dispatcher are in chapter 10 of the DXE CIS. Figure 10-3
+ The rules for the dispatcher are in chapter 10 of the DXE CIS. Figure 10-3
is the state diagram for the DXE dispatcher
Depex - Dependency Expresion.
SOR - Schedule On Request - Don't schedule if this bit is set.
-Copyright (c) 2006 - 2008, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
-#include
+#include "DxeMain.h"
//
// The Driver List contains one copy of every driver that has been discovered.
// Items are never removed from the driver list. List of EFI_CORE_DRIVER_ENTRY
//
-LIST_ENTRY mDiscoveredList = INITIALIZE_LIST_HEAD_VARIABLE (mDiscoveredList);
+LIST_ENTRY mDiscoveredList = INITIALIZE_LIST_HEAD_VARIABLE (mDiscoveredList);
//
// Queue of drivers that are ready to dispatch. This queue is a subset of the
@@ -76,9 +76,10 @@ VOID *mFwVolEventRegistration;
//
// List of file types supported by dispatcher
//
-static EFI_FV_FILETYPE mDxeFileTypes[] = {
- EFI_FV_FILETYPE_DRIVER,
- EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER,
+EFI_FV_FILETYPE mDxeFileTypes[] = {
+ EFI_FV_FILETYPE_DRIVER,
+ EFI_FV_FILETYPE_COMBINED_SMM_DXE,
+ EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER,
EFI_FV_FILETYPE_DXE_CORE,
EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
};
@@ -90,7 +91,6 @@ typedef struct {
FV_FILEPATH_DEVICE_PATH mFvDevicePath;
-
//
// Function Prototypes
//
@@ -105,12 +105,11 @@ FV_FILEPATH_DEVICE_PATH mFvDevicePath;
@param InsertedDriverEntry The driver to insert on the ScheduledLink Queue
**/
-STATIC
VOID
CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
IN EFI_CORE_DRIVER_ENTRY *InsertedDriverEntry
);
-
+
/**
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
@@ -124,11 +123,10 @@ CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
While you are at it read the A Priori file into memory.
Place drivers in the A Priori list onto the mScheduledQueue.
- @param Event The Event that is being processed, not used.
+ @param Event The Event that is being processed, not used.
@param Context Event Context, not used.
**/
-STATIC
VOID
EFIAPI
CoreFwVolEventProtocolNotify (
@@ -139,17 +137,16 @@ CoreFwVolEventProtocolNotify (
/**
Convert FvHandle and DriverName into an EFI device path
- @param Fv Fv protocol, needed to read Depex info out of
- FLASH.
- @param FvHandle Handle for Fv, needed in the
- EFI_CORE_DRIVER_ENTRY so that the PE image can be
- read out of the FV at a later time.
- @param DriverName Name of driver to add to mDiscoveredList.
+ @param Fv Fv protocol, needed to read Depex info out of
+ FLASH.
+ @param FvHandle Handle for Fv, needed in the
+ EFI_CORE_DRIVER_ENTRY so that the PE image can be
+ read out of the FV at a later time.
+ @param DriverName Name of driver to add to mDiscoveredList.
@return Pointer to device path constructed from FvHandle and DriverName
**/
-STATIC
EFI_DEVICE_PATH_PROTOCOL *
CoreFvToDevicePath (
IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
@@ -164,41 +161,41 @@ CoreFvToDevicePath (
The Discovered list is never free'ed and contains booleans that represent the
other possible DXE driver states.
- @param Fv Fv protocol, needed to read Depex info out of
- FLASH.
- @param FvHandle Handle for Fv, needed in the
- EFI_CORE_DRIVER_ENTRY so that the PE image can be
- read out of the FV at a later time.
- @param DriverName Name of driver to add to mDiscoveredList.
-
- @retval EFI_SUCCESS If driver was added to the mDiscoveredList.
- @retval EFI_ALREADY_STARTED The driver has already been started. Only one
- DriverName may be active in the system at any one
+ @param Fv Fv protocol, needed to read Depex info out of
+ FLASH.
+ @param FvHandle Handle for Fv, needed in the
+ EFI_CORE_DRIVER_ENTRY so that the PE image can be
+ read out of the FV at a later time.
+ @param DriverName Name of driver to add to mDiscoveredList.
+ @param Type Fv File Type of file to add to mDiscoveredList.
+
+ @retval EFI_SUCCESS If driver was added to the mDiscoveredList.
+ @retval EFI_ALREADY_STARTED The driver has already been started. Only one
+ DriverName may be active in the system at any one
time.
**/
-STATIC
EFI_STATUS
CoreAddToDriverList (
- IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
- IN EFI_HANDLE FvHandle,
- IN EFI_GUID *DriverName
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
+ IN EFI_HANDLE FvHandle,
+ IN EFI_GUID *DriverName,
+ IN EFI_FV_FILETYPE Type
);
/**
Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.
- @param Fv The FIRMWARE_VOLUME protocol installed on the FV.
- @param FvHandle The handle which FVB protocol installed on.
- @param DriverName The driver guid specified.
+ @param Fv The FIRMWARE_VOLUME protocol installed on the FV.
+ @param FvHandle The handle which FVB protocol installed on.
+ @param DriverName The driver guid specified.
- @retval EFI_OUT_OF_RESOURCES No enough memory or other resource.
- @retval EFI_VOLUME_CORRUPTED Corrupted volume.
+ @retval EFI_OUT_OF_RESOURCES No enough memory or other resource.
+ @retval EFI_VOLUME_CORRUPTED Corrupted volume.
@retval EFI_SUCCESS Function successfully returned.
**/
-STATIC
-EFI_STATUS
+EFI_STATUS
CoreProcessFvImageFile (
IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
IN EFI_HANDLE FvHandle,
@@ -210,7 +207,6 @@ CoreProcessFvImageFile (
Enter critical section by gaining lock on mDispatcherLock.
**/
-STATIC
VOID
CoreAcquireDispatcherLock (
VOID
@@ -224,7 +220,6 @@ CoreAcquireDispatcherLock (
Exit critical section by releasing lock on mDispatcherLock.
**/
-STATIC
VOID
CoreReleaseDispatcherLock (
VOID
@@ -238,15 +233,14 @@ CoreReleaseDispatcherLock (
Read Depex and pre-process the Depex for Before and After. If Section Extraction
protocol returns an error via ReadSection defer the reading of the Depex.
- @param DriverEntry Driver to work on.
+ @param DriverEntry Driver to work on.
- @retval EFI_SUCCESS Depex read and preprossesed
- @retval EFI_PROTOCOL_ERROR The section extraction protocol returned an error
- and Depex reading needs to be retried.
+ @retval EFI_SUCCESS Depex read and preprossesed
+ @retval EFI_PROTOCOL_ERROR The section extraction protocol returned an error
+ and Depex reading needs to be retried.
@retval Error DEPEX not found.
**/
-STATIC
EFI_STATUS
CoreGetDepexSectionAndPreProccess (
IN EFI_CORE_DRIVER_ENTRY *DriverEntry
@@ -257,7 +251,7 @@ CoreGetDepexSectionAndPreProccess (
UINT32 AuthenticationStatus;
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
-
+
Fv = DriverEntry->Fv;
//
@@ -265,11 +259,11 @@ CoreGetDepexSectionAndPreProccess (
//
SectionType = EFI_SECTION_DXE_DEPEX;
Status = Fv->ReadSection (
- DriverEntry->Fv,
+ DriverEntry->Fv,
&DriverEntry->FileName,
- SectionType,
- 0,
- &DriverEntry->Depex,
+ SectionType,
+ 0,
+ &DriverEntry->Depex,
(UINTN *)&DriverEntry->DepexSize,
&AuthenticationStatus
);
@@ -294,7 +288,7 @@ CoreGetDepexSectionAndPreProccess (
//
CorePreProcessDepex (DriverEntry);
DriverEntry->DepexProtocolError = FALSE;
- }
+ }
return Status;
}
@@ -304,17 +298,16 @@ CoreGetDepexSectionAndPreProccess (
Check every driver and locate a matching one. If the driver is found, the Unrequested
state flag is cleared.
- @param FirmwareVolumeHandle The handle of the Firmware Volume that contains
- the firmware file specified by DriverName.
- @param DriverName The Driver name to put in the Dependent state.
+ @param FirmwareVolumeHandle The handle of the Firmware Volume that contains
+ the firmware file specified by DriverName.
+ @param DriverName The Driver name to put in the Dependent state.
- @retval EFI_SUCCESS The DriverName was found and it's SOR bit was
- cleared
- @retval EFI_NOT_FOUND The DriverName does not exist or it's SOR bit was
- not set.
+ @retval EFI_SUCCESS The DriverName was found and it's SOR bit was
+ cleared
+ @retval EFI_NOT_FOUND The DriverName does not exist or it's SOR bit was
+ not set.
**/
-EFI_DXESERVICE
EFI_STATUS
EFIAPI
CoreSchedule (
@@ -331,7 +324,7 @@ CoreSchedule (
for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
if (DriverEntry->FvHandle == FirmwareVolumeHandle &&
- DriverEntry->Unrequested &&
+ DriverEntry->Unrequested &&
CompareGuid (DriverName, &DriverEntry->FileName)) {
//
// Move the driver from the Unrequested to the Dependent state
@@ -340,28 +333,32 @@ CoreSchedule (
DriverEntry->Unrequested = FALSE;
DriverEntry->Dependent = TRUE;
CoreReleaseDispatcherLock ();
-
+
+ DEBUG ((DEBUG_DISPATCH, "Schedule FFS(%g) - EFI_SUCCESS\n", DriverName));
+
return EFI_SUCCESS;
}
}
- return EFI_NOT_FOUND;
+
+ DEBUG ((DEBUG_DISPATCH, "Schedule FFS(%g) - EFI_NOT_FOUND\n", DriverName));
+
+ return EFI_NOT_FOUND;
}
/**
- Convert a driver from the Untrused back to the Scheduled state
+ Convert a driver from the Untrused back to the Scheduled state.
- @param FirmwareVolumeHandle The handle of the Firmware Volume that contains
- the firmware file specified by DriverName.
- @param DriverName The Driver name to put in the Scheduled state
+ @param FirmwareVolumeHandle The handle of the Firmware Volume that contains
+ the firmware file specified by DriverName.
+ @param DriverName The Driver name to put in the Scheduled state
- @retval EFI_SUCCESS The file was found in the untrusted state, and it
- was promoted to the trusted state.
- @retval EFI_NOT_FOUND The file was not found in the untrusted state.
+ @retval EFI_SUCCESS The file was found in the untrusted state, and it
+ was promoted to the trusted state.
+ @retval EFI_NOT_FOUND The file was not found in the untrusted state.
**/
-EFI_DXESERVICE
EFI_STATUS
EFIAPI
CoreTrust (
@@ -378,7 +375,7 @@ CoreTrust (
for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
if (DriverEntry->FvHandle == FirmwareVolumeHandle &&
- DriverEntry->Untrusted &&
+ DriverEntry->Untrusted &&
CompareGuid (DriverName, &DriverEntry->FileName)) {
//
// Transition driver from Untrusted to Scheduled state.
@@ -388,15 +385,13 @@ CoreTrust (
DriverEntry->Scheduled = TRUE;
InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
CoreReleaseDispatcherLock ();
-
+
return EFI_SUCCESS;
}
}
- return EFI_NOT_FOUND;
+ return EFI_NOT_FOUND;
}
-
-
/**
This is the main Dispatcher for DXE and it exits when there are no more
drivers to run. Drain the mScheduledQueue and load and start a PE
@@ -406,14 +401,11 @@ CoreTrust (
will be called, and when the Bds() exits the Dispatcher will be called
again.
- NONE
-
- @retval EFI_ALREADY_STARTED The DXE Dispatcher is already running
- @retval EFI_NOT_FOUND No DXE Drivers were dispatched
- @retval EFI_SUCCESS One or more DXE Drivers were dispatched
+ @retval EFI_ALREADY_STARTED The DXE Dispatcher is already running
+ @retval EFI_NOT_FOUND No DXE Drivers were dispatched
+ @retval EFI_SUCCESS One or more DXE Drivers were dispatched
**/
-EFI_DXESERVICE
EFI_STATUS
EFIAPI
CoreDispatcher (
@@ -425,6 +417,8 @@ CoreDispatcher (
LIST_ENTRY *Link;
EFI_CORE_DRIVER_ENTRY *DriverEntry;
BOOLEAN ReadyToRun;
+ EFI_EVENT DxeDispatchEvent;
+
if (gDispatcherRunning) {
//
@@ -435,6 +429,17 @@ CoreDispatcher (
gDispatcherRunning = TRUE;
+ Status = CoreCreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ EfiEventEmptyFunction,
+ NULL,
+ &gEfiEventDxeDispatchGuid,
+ &DxeDispatchEvent
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
ReturnStatus = EFI_NOT_FOUND;
do {
@@ -454,13 +459,14 @@ CoreDispatcher (
// Untrused to Scheduled it would have already been loaded so we may need to
// skip the LoadImage
//
- if (DriverEntry->ImageHandle == NULL) {
+ if (DriverEntry->ImageHandle == NULL && !DriverEntry->IsFvImage) {
+ DEBUG ((DEBUG_INFO, "Loading driver %g\n", &DriverEntry->FileName));
Status = CoreLoadImage (
- FALSE,
- gDxeCoreImageHandle,
+ FALSE,
+ gDxeCoreImageHandle,
DriverEntry->FvFileDevicePath,
- NULL,
- 0,
+ NULL,
+ 0,
&DriverEntry->ImageHandle
);
@@ -478,7 +484,7 @@ CoreDispatcher (
} else {
//
// The DXE Driver could not be loaded, and do not attempt to load or start it again.
- // Take driver from Scheduled to Initialized.
+ // Take driver from Scheduled to Initialized.
//
// This case include the Never Trusted state if EFI_ACCESS_DENIED is returned
//
@@ -487,9 +493,9 @@ CoreDispatcher (
DriverEntry->Scheduled = FALSE;
RemoveEntryList (&DriverEntry->ScheduledLink);
-
+
CoreReleaseDispatcherLock ();
-
+
//
// If it's an error don't try the StartImage
//
@@ -502,22 +508,46 @@ CoreDispatcher (
DriverEntry->Scheduled = FALSE;
DriverEntry->Initialized = TRUE;
RemoveEntryList (&DriverEntry->ScheduledLink);
-
+
CoreReleaseDispatcherLock ();
- CoreReportProgressCodeSpecific (
- FixedPcdGet32(PcdStatusCodeValueDxeDriverBegin),
- DriverEntry->ImageHandle
- );
- Status = CoreStartImage (DriverEntry->ImageHandle, NULL, NULL);
- CoreReportProgressCodeSpecific (
- FixedPcdGet32(PcdStatusCodeValueDxeDriverEnd),
- DriverEntry->ImageHandle
- );
+
+ if (DriverEntry->IsFvImage) {
+ //
+ // Produce a firmware volume block protocol for FvImage so it gets dispatched from.
+ //
+ Status = CoreProcessFvImageFile (DriverEntry->Fv, DriverEntry->FvHandle, &DriverEntry->FileName);
+ } else {
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
+ EFI_PROGRESS_CODE,
+ (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN),
+ &DriverEntry->ImageHandle,
+ sizeof (DriverEntry->ImageHandle)
+ );
+ ASSERT (DriverEntry->ImageHandle != NULL);
+
+ Status = CoreStartImage (DriverEntry->ImageHandle, NULL, NULL);
+
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
+ EFI_PROGRESS_CODE,
+ (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END),
+ &DriverEntry->ImageHandle,
+ sizeof (DriverEntry->ImageHandle)
+ );
+ }
ReturnStatus = EFI_SUCCESS;
}
+ //
+ // Now DXE Dispatcher finished one round of dispatch, signal an event group
+ // so that SMM Dispatcher get chance to dispatch SMM Drivers which depend
+ // on UEFI protocols
+ //
+ if (!EFI_ERROR (ReturnStatus)) {
+ CoreSignalEvent (DxeDispatchEvent);
+ }
+
//
// Search DriverList for items to place on Scheduled Queue
//
@@ -530,17 +560,28 @@ CoreDispatcher (
// If Section Extraction Protocol did not let the Depex be read before retry the read
//
Status = CoreGetDepexSectionAndPreProccess (DriverEntry);
- }
+ }
if (DriverEntry->Dependent) {
if (CoreIsSchedulable (DriverEntry)) {
- CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
+ CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
ReadyToRun = TRUE;
- }
+ }
+ } else {
+ if (DriverEntry->Unrequested) {
+ DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName));
+ DEBUG ((DEBUG_DISPATCH, " SOR = Not Requested\n"));
+ DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE\n"));
+ }
}
}
} while (ReadyToRun);
+ //
+ // Close DXE dispatch Event
+ //
+ CoreCloseEvent (DxeDispatchEvent);
+
gDispatcherRunning = FALSE;
return ReturnStatus;
@@ -558,7 +599,6 @@ CoreDispatcher (
@param InsertedDriverEntry The driver to insert on the ScheduledLink Queue
**/
-STATIC
VOID
CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
IN EFI_CORE_DRIVER_ENTRY *InsertedDriverEntry
@@ -572,12 +612,17 @@ CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
//
for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
- if (DriverEntry->Before && DriverEntry->Dependent) {
+ if (DriverEntry->Before && DriverEntry->Dependent && DriverEntry != InsertedDriverEntry) {
+ DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName));
+ DEBUG ((DEBUG_DISPATCH, " BEFORE FFS(%g) = ", &DriverEntry->BeforeAfterGuid));
if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
//
// Recursively process BEFORE
//
+ DEBUG ((DEBUG_DISPATCH, "TRUE\n END\n RESULT = TRUE\n"));
CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
+ } else {
+ DEBUG ((DEBUG_DISPATCH, "FALSE\n END\n RESULT = FALSE\n"));
}
}
}
@@ -590,7 +635,7 @@ CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
InsertedDriverEntry->Dependent = FALSE;
InsertedDriverEntry->Scheduled = TRUE;
InsertTailList (&mScheduledQueue, &InsertedDriverEntry->ScheduledLink);
-
+
CoreReleaseDispatcherLock ();
//
@@ -598,12 +643,17 @@ CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
//
for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
- if (DriverEntry->After && DriverEntry->Dependent) {
+ if (DriverEntry->After && DriverEntry->Dependent && DriverEntry != InsertedDriverEntry) {
+ DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName));
+ DEBUG ((DEBUG_DISPATCH, " AFTER FFS(%g) = ", &DriverEntry->BeforeAfterGuid));
if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
//
// Recursively process AFTER
//
+ DEBUG ((DEBUG_DISPATCH, "TRUE\n END\n RESULT = TRUE\n"));
CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
+ } else {
+ DEBUG ((DEBUG_DISPATCH, "FALSE\n END\n RESULT = FALSE\n"));
}
}
}
@@ -613,14 +663,12 @@ CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
/**
Return TRUE if the Fv has been processed, FALSE if not.
- @param FvHandle The handle of a FV that's being tested
+ @param FvHandle The handle of a FV that's being tested
- @retval TRUE Fv protocol on FvHandle has been processed
- @retval FALSE Fv protocol on FvHandle has not yet been
- processed
+ @retval TRUE Fv protocol on FvHandle has been processed
+ @retval FALSE Fv protocol on FvHandle has not yet been processed
**/
-STATIC
BOOLEAN
FvHasBeenProcessed (
IN EFI_HANDLE FvHandle
@@ -641,26 +689,106 @@ FvHasBeenProcessed (
/**
Remember that Fv protocol on FvHandle has had it's drivers placed on the
- mDiscoveredList. This fucntion adds entries on the mFvHandleList. Items are
- never removed/freed from the mFvHandleList.
+ mDiscoveredList. This fucntion adds entries on the mFvHandleList if new
+ entry is different from one in mFvHandleList by checking FvImage Guid.
+ Items are never removed/freed from the mFvHandleList.
@param FvHandle The handle of a FV that has been processed
+ @return A point to new added FvHandle entry. If FvHandle with the same FvImage guid
+ has been added, NULL will return.
+
**/
-STATIC
-VOID
+KNOWN_HANDLE *
FvIsBeingProcesssed (
IN EFI_HANDLE FvHandle
)
{
- KNOWN_HANDLE *KnownHandle;
+ EFI_STATUS Status;
+ EFI_GUID FvNameGuid;
+ BOOLEAN FvNameGuidIsFound;
+ UINT32 ExtHeaderOffset;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
+ UINTN LbaOffset;
+ UINTN Index;
+ EFI_LBA LbaIndex;
+ LIST_ENTRY *Link;
+ KNOWN_HANDLE *KnownHandle;
+
+ FwVolHeader = NULL;
+
+ //
+ // Get the FirmwareVolumeBlock protocol on that handle
+ //
+ FvNameGuidIsFound = FALSE;
+ Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Get the full FV header based on FVB protocol.
+ //
+ ASSERT (Fvb != NULL);
+ Status = GetFwVolHeader (Fvb, &FwVolHeader);
+ if (!EFI_ERROR (Status)) {
+ ASSERT (FwVolHeader != NULL);
+ if (VerifyFvHeaderChecksum (FwVolHeader) && FwVolHeader->ExtHeaderOffset != 0) {
+ ExtHeaderOffset = (UINT32) FwVolHeader->ExtHeaderOffset;
+ BlockMap = FwVolHeader->BlockMap;
+ LbaIndex = 0;
+ LbaOffset = 0;
+ //
+ // Find LbaIndex and LbaOffset for FV extension header based on BlockMap.
+ //
+ while ((BlockMap->NumBlocks != 0) || (BlockMap->Length != 0)) {
+ for (Index = 0; Index < BlockMap->NumBlocks && ExtHeaderOffset >= BlockMap->Length; Index ++) {
+ ExtHeaderOffset -= BlockMap->Length;
+ LbaIndex ++;
+ }
+ //
+ // Check whether FvExtHeader is crossing the multi block range.
+ //
+ if (Index < BlockMap->NumBlocks) {
+ LbaOffset = ExtHeaderOffset;
+ break;
+ }
+ BlockMap++;
+ }
+ //
+ // Read FvNameGuid from FV extension header.
+ //
+ Status = ReadFvbData (Fvb, &LbaIndex, &LbaOffset, sizeof (FvNameGuid), (UINT8 *) &FvNameGuid);
+ if (!EFI_ERROR (Status)) {
+ FvNameGuidIsFound = TRUE;
+ }
+ }
+ CoreFreePool (FwVolHeader);
+ }
+ }
- KnownHandle = CoreAllocateBootServicesPool (sizeof (KNOWN_HANDLE));
+ if (FvNameGuidIsFound) {
+ //
+ // Check whether the FV image with the found FvNameGuid has been processed.
+ //
+ for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) {
+ KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE);
+ if (CompareGuid (&FvNameGuid, &KnownHandle->FvNameGuid)) {
+ DEBUG ((EFI_D_ERROR, "FvImage on FvHandle %p and %p has the same FvNameGuid %g.\n", FvHandle, KnownHandle->Handle, &FvNameGuid));
+ return NULL;
+ }
+ }
+ }
+
+ KnownHandle = AllocateZeroPool (sizeof (KNOWN_HANDLE));
ASSERT (KnownHandle != NULL);
KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE;
KnownHandle->Handle = FvHandle;
+ if (FvNameGuidIsFound) {
+ CopyGuid (&KnownHandle->FvNameGuid, &FvNameGuid);
+ }
InsertTailList (&mFvHandleList, &KnownHandle->Link);
+ return KnownHandle;
}
@@ -669,17 +797,16 @@ FvIsBeingProcesssed (
/**
Convert FvHandle and DriverName into an EFI device path
- @param Fv Fv protocol, needed to read Depex info out of
- FLASH.
- @param FvHandle Handle for Fv, needed in the
- EFI_CORE_DRIVER_ENTRY so that the PE image can be
- read out of the FV at a later time.
- @param DriverName Name of driver to add to mDiscoveredList.
+ @param Fv Fv protocol, needed to read Depex info out of
+ FLASH.
+ @param FvHandle Handle for Fv, needed in the
+ EFI_CORE_DRIVER_ENTRY so that the PE image can be
+ read out of the FV at a later time.
+ @param DriverName Name of driver to add to mDiscoveredList.
@return Pointer to device path constructed from FvHandle and DriverName
**/
-STATIC
EFI_DEVICE_PATH_PROTOCOL *
CoreFvToDevicePath (
IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
@@ -702,12 +829,10 @@ CoreFvToDevicePath (
// Build a device path to the file in the FV to pass into gBS->LoadImage
//
EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, DriverName);
- mFvDevicePath.End.Type = EFI_END_ENTIRE_DEVICE_PATH;
- mFvDevicePath.End.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
- SetDevicePathNodeLength (&mFvDevicePath.End, sizeof (EFI_DEVICE_PATH_PROTOCOL));
+ SetDevicePathEndNode (&mFvDevicePath.End);
- FileNameDevicePath = CoreAppendDevicePath (
- FvDevicePath,
+ FileNameDevicePath = AppendDevicePath (
+ FvDevicePath,
(EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
);
}
@@ -717,7 +842,6 @@ CoreFvToDevicePath (
-
/**
Add an entry to the mDiscoveredList. Allocate memory to store the DriverEntry,
and initilize any state variables. Read the Depex from the FV and store it
@@ -725,16 +849,17 @@ CoreFvToDevicePath (
The Discovered list is never free'ed and contains booleans that represent the
other possible DXE driver states.
- @param Fv Fv protocol, needed to read Depex info out of
- FLASH.
- @param FvHandle Handle for Fv, needed in the
- EFI_CORE_DRIVER_ENTRY so that the PE image can be
- read out of the FV at a later time.
- @param DriverName Name of driver to add to mDiscoveredList.
-
- @retval EFI_SUCCESS If driver was added to the mDiscoveredList.
- @retval EFI_ALREADY_STARTED The driver has already been started. Only one
- DriverName may be active in the system at any one
+ @param Fv Fv protocol, needed to read Depex info out of
+ FLASH.
+ @param FvHandle Handle for Fv, needed in the
+ EFI_CORE_DRIVER_ENTRY so that the PE image can be
+ read out of the FV at a later time.
+ @param DriverName Name of driver to add to mDiscoveredList.
+ @param Type Fv File Type of file to add to mDiscoveredList.
+
+ @retval EFI_SUCCESS If driver was added to the mDiscoveredList.
+ @retval EFI_ALREADY_STARTED The driver has already been started. Only one
+ DriverName may be active in the system at any one
time.
**/
@@ -742,29 +867,33 @@ EFI_STATUS
CoreAddToDriverList (
IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
IN EFI_HANDLE FvHandle,
- IN EFI_GUID *DriverName
+ IN EFI_GUID *DriverName,
+ IN EFI_FV_FILETYPE Type
)
{
EFI_CORE_DRIVER_ENTRY *DriverEntry;
-
+
//
- // Create the Driver Entry for the list. ZeroPool initializes lots of variables to
+ // Create the Driver Entry for the list. ZeroPool initializes lots of variables to
// NULL or FALSE.
//
- DriverEntry = CoreAllocateZeroBootServicesPool (sizeof (EFI_CORE_DRIVER_ENTRY));
+ DriverEntry = AllocateZeroPool (sizeof (EFI_CORE_DRIVER_ENTRY));
ASSERT (DriverEntry != NULL);
+ if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
+ DriverEntry->IsFvImage = TRUE;
+ }
DriverEntry->Signature = EFI_CORE_DRIVER_ENTRY_SIGNATURE;
- CopyMem (&DriverEntry->FileName, DriverName, sizeof (EFI_GUID));
+ CopyGuid (&DriverEntry->FileName, DriverName);
DriverEntry->FvHandle = FvHandle;
DriverEntry->Fv = Fv;
DriverEntry->FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName);
CoreGetDepexSectionAndPreProccess (DriverEntry);
-
+
CoreAcquireDispatcherLock ();
-
+
InsertTailList (&mDiscoveredList, &DriverEntry->Link);
CoreReleaseDispatcherLock ();
@@ -777,27 +906,30 @@ CoreAddToDriverList (
Check if a FV Image type file (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) is
described by a EFI_HOB_FIRMWARE_VOLUME2 Hob.
- @param FvHandle The handle which FVB protocol installed on.
- @param DriverName The driver guid specified.
+ @param FvNameGuid The FV image guid specified.
+ @param DriverName The driver guid specified.
- @retval TRUE This file is found in a EFI_HOB_FIRMWARE_VOLUME2
- Hob.
+ @retval TRUE This file is found in a EFI_HOB_FIRMWARE_VOLUME2
+ Hob.
@retval FALSE Not found.
**/
-STATIC
BOOLEAN
FvFoundInHobFv2 (
- IN EFI_HANDLE FvHandle,
+ IN CONST EFI_GUID *FvNameGuid,
IN CONST EFI_GUID *DriverName
)
{
EFI_PEI_HOB_POINTERS HobFv2;
-
+
HobFv2.Raw = GetHobList ();
-
+
while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {
- if (CompareGuid (DriverName, &HobFv2.FirmwareVolume2->FileName)) {
+ //
+ // Compare parent FvNameGuid and FileGuid both.
+ //
+ if (CompareGuid (DriverName, &HobFv2.FirmwareVolume2->FileName) &&
+ CompareGuid (FvNameGuid, &HobFv2.FirmwareVolume2->FvName)) {
return TRUE;
}
HobFv2.Raw = GET_NEXT_HOB (HobFv2);
@@ -811,16 +943,16 @@ FvFoundInHobFv2 (
/**
Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.
- @param Fv The FIRMWARE_VOLUME protocol installed on the FV.
- @param FvHandle The handle which FVB protocol installed on.
- @param DriverName The driver guid specified.
+ @param Fv The FIRMWARE_VOLUME protocol installed on the FV.
+ @param FvHandle The handle which FVB protocol installed on.
+ @param DriverName The driver guid specified.
- @retval EFI_OUT_OF_RESOURCES No enough memory or other resource.
- @retval EFI_VOLUME_CORRUPTED Corrupted volume.
+ @retval EFI_OUT_OF_RESOURCES No enough memory or other resource.
+ @retval EFI_VOLUME_CORRUPTED Corrupted volume.
@retval EFI_SUCCESS Function successfully returned.
**/
-EFI_STATUS
+EFI_STATUS
CoreProcessFvImageFile (
IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
IN EFI_HANDLE FvHandle,
@@ -834,68 +966,111 @@ CoreProcessFvImageFile (
VOID *AlignedBuffer;
UINTN BufferSize;
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
- UINT32 FvAlignment;
+ UINT32 FvAlignment;
+ EFI_DEVICE_PATH_PROTOCOL *FvFileDevicePath;
//
// Read the first (and only the first) firmware volume section
//
- SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;
- FvHeader = NULL;
- FvAlignment = 0;
- Buffer = NULL;
- BufferSize = 0;
+ SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;
+ FvHeader = NULL;
+ FvAlignment = 0;
+ Buffer = NULL;
+ BufferSize = 0;
AlignedBuffer = NULL;
Status = Fv->ReadSection (
- Fv,
- DriverName,
- SectionType,
- 0,
- &Buffer,
- &BufferSize,
- &AuthenticationStatus
- );
+ Fv,
+ DriverName,
+ SectionType,
+ 0,
+ &Buffer,
+ &BufferSize,
+ &AuthenticationStatus
+ );
if (!EFI_ERROR (Status)) {
+ //
+ // Evaluate the authentication status of the Firmware Volume through
+ // Security Architectural Protocol
+ //
+ if (gSecurity != NULL) {
+ FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName);
+ Status = gSecurity->FileAuthenticationState (
+ gSecurity,
+ AuthenticationStatus,
+ FvFileDevicePath
+ );
+ if (FvFileDevicePath != NULL) {
+ FreePool (FvFileDevicePath);
+ }
+
+ if (Status != EFI_SUCCESS) {
+ //
+ // Security check failed. The firmware volume should not be used for any purpose.
+ //
+ if (Buffer != NULL) {
+ FreePool (Buffer);
+ }
+ return Status;
+ }
+ }
+
//
// FvImage should be at its required alignment.
//
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;
- FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);
//
- // FvAlignment must be more than 8 bytes required by FvHeader structure.
- //
- if (FvAlignment < 8) {
- FvAlignment = 8;
- }
- AlignedBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment);
- if (AlignedBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- } else {
+ // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume
+ // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from
+ // its initial linked location and maintain its alignment.
+ //
+ if ((FvHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {
//
- // Move FvImage into the aligned buffer and release the original buffer.
+ // Get FvHeader alignment
//
- CopyMem (AlignedBuffer, Buffer, BufferSize);
- CoreFreePool (Buffer);
- Buffer = NULL;
+ FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);
//
- // Produce a FVB protocol for the file
+ // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.
//
- Status = ProduceFVBProtocolOnBuffer (
- (EFI_PHYSICAL_ADDRESS) (UINTN) AlignedBuffer,
- (UINT64)BufferSize,
- FvHandle,
- NULL
- );
+ if (FvAlignment < 8) {
+ FvAlignment = 8;
+ }
+ //
+ // Allocate the aligned buffer for the FvImage.
+ //
+ AlignedBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment);
+ if (AlignedBuffer == NULL) {
+ FreePool (Buffer);
+ return EFI_OUT_OF_RESOURCES;
+ } else {
+ //
+ // Move FvImage into the aligned buffer and release the original buffer.
+ //
+ CopyMem (AlignedBuffer, Buffer, BufferSize);
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) AlignedBuffer;
+ CoreFreePool (Buffer);
+ Buffer = NULL;
+ }
}
+ //
+ // Produce a FVB protocol for the file
+ //
+ Status = ProduceFVBProtocolOnBuffer (
+ (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,
+ (UINT64)BufferSize,
+ FvHandle,
+ AuthenticationStatus,
+ NULL
+ );
}
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status)) {
//
// ReadSection or Produce FVB failed, Free data buffer
//
if (Buffer != NULL) {
- CoreFreePool (Buffer);
+ FreePool (Buffer);
}
-
+
if (AlignedBuffer != NULL) {
FreeAlignedPages (AlignedBuffer, EFI_SIZE_TO_PAGES (BufferSize));
}
@@ -918,11 +1093,10 @@ CoreProcessFvImageFile (
While you are at it read the A Priori file into memory.
Place drivers in the A Priori list onto the mScheduledQueue.
- @param Event The Event that is being processed, not used.
+ @param Event The Event that is being processed, not used.
@param Context Event Context, not used.
**/
-STATIC
VOID
EFIAPI
CoreFwVolEventProtocolNotify (
@@ -932,7 +1106,6 @@ CoreFwVolEventProtocolNotify (
{
EFI_STATUS Status;
EFI_STATUS GetNextFileStatus;
- EFI_STATUS SecurityStatus;
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
EFI_DEVICE_PATH_PROTOCOL *FvDevicePath;
EFI_HANDLE FvHandle;
@@ -949,17 +1122,20 @@ CoreFwVolEventProtocolNotify (
LIST_ENTRY *Link;
UINT32 AuthenticationStatus;
UINTN SizeOfBuffer;
+ VOID *DepexBuffer;
+ KNOWN_HANDLE *KnownHandle;
+ FvHandle = NULL;
while (TRUE) {
BufferSize = sizeof (EFI_HANDLE);
Status = CoreLocateHandle (
- ByRegisterNotify,
- NULL,
- mFwVolEventRegistration,
- &BufferSize,
- &FvHandle
- );
+ ByRegisterNotify,
+ NULL,
+ mFwVolEventRegistration,
+ &BufferSize,
+ &FvHandle
+ );
if (EFI_ERROR (Status)) {
//
// If no more notification events exit
@@ -974,31 +1150,27 @@ CoreFwVolEventProtocolNotify (
continue;
}
- Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeDispatchProtocolGuid, (VOID **)&Fv);
- if (EFI_ERROR (Status)) {
+ //
+ // Since we are about to process this Fv mark it as processed.
+ //
+ KnownHandle = FvIsBeingProcesssed (FvHandle);
+ if (KnownHandle == NULL) {
//
- // If no dispatch protocol then skip, but do not marked as being processed as it
- // may show up later.
+ // The FV with the same FV name guid has already been processed.
+ // So lets skip it!
//
continue;
}
- //
- // Since we are about to process this Fv mark it as processed.
- //
- FvIsBeingProcesssed (FvHandle);
-
-
Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || Fv == NULL) {
//
- // The Handle has a FirmwareVolumeDispatch protocol and should also contiain
- // a FirmwareVolume protocol thus we should never get here.
+ // FvHandle must have Firmware Volume2 protocol thus we should never get here.
//
ASSERT (FALSE);
continue;
}
-
+
Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
if (EFI_ERROR (Status)) {
//
@@ -1006,32 +1178,14 @@ CoreFwVolEventProtocolNotify (
//
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
+ // 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++) {
+ for (Index = 0; Index < sizeof (mDxeFileTypes) / sizeof (EFI_FV_FILETYPE); Index++) {
//
// Initialize the search key
//
@@ -1039,11 +1193,11 @@ CoreFwVolEventProtocolNotify (
do {
Type = mDxeFileTypes[Index];
GetNextFileStatus = Fv->GetNextFile (
- Fv,
+ Fv,
&Key,
- &Type,
- &NameGuid,
- &Attributes,
+ &Type,
+ &NameGuid,
+ &Attributes,
&Size
);
if (!EFI_ERROR (GetNextFileStatus)) {
@@ -1058,11 +1212,9 @@ CoreFwVolEventProtocolNotify (
// be initialized completely.
//
EfiInitializeFwVolDevicepathNode (&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));
+ SetDevicePathEndNode (&mFvDevicePath.End);
- gDxeCoreLoadedImage->FilePath = CoreDuplicateDevicePath (
+ gDxeCoreLoadedImage->FilePath = DuplicateDevicePath (
(EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
);
gDxeCoreLoadedImage->DeviceHandle = FvHandle;
@@ -1070,28 +1222,72 @@ CoreFwVolEventProtocolNotify (
}
} else if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
//
- // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
+ // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
// been extracted.
//
- if (FvFoundInHobFv2 (FvHandle, &NameGuid)) {
+ if (FvFoundInHobFv2 (&KnownHandle->FvNameGuid, &NameGuid)) {
continue;
}
+
+ //
+ // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has SMM depex section.
+ //
+ DepexBuffer = NULL;
+ SizeOfBuffer = 0;
+ Status = Fv->ReadSection (
+ Fv,
+ &NameGuid,
+ EFI_SECTION_SMM_DEPEX,
+ 0,
+ &DepexBuffer,
+ &SizeOfBuffer,
+ &AuthenticationStatus
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // If SMM depex section is found, this FV image is invalid to be supported.
+ // ASSERT FALSE to report this FV image.
+ //
+ FreePool (DepexBuffer);
+ ASSERT (FALSE);
+ }
+
//
- // Found a firmware volume image. Produce a firmware volume block
- // protocol for it so it gets dispatched from. This is usually a
- // capsule.
+ // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has DXE depex section.
//
- CoreProcessFvImageFile (Fv, FvHandle, &NameGuid);
+ DepexBuffer = NULL;
+ SizeOfBuffer = 0;
+ Status = Fv->ReadSection (
+ Fv,
+ &NameGuid,
+ EFI_SECTION_DXE_DEPEX,
+ 0,
+ &DepexBuffer,
+ &SizeOfBuffer,
+ &AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // If no depex section, produce a firmware volume block protocol for it so it gets dispatched from.
+ //
+ CoreProcessFvImageFile (Fv, FvHandle, &NameGuid);
+ } else {
+ //
+ // If depex section is found, this FV image will be dispatched until its depex is evaluated to TRUE.
+ //
+ FreePool (DepexBuffer);
+ CoreAddToDriverList (Fv, FvHandle, &NameGuid, Type);
+ }
} else {
//
// Transition driver from Undiscovered to Discovered state
//
- CoreAddToDriverList (Fv, FvHandle, &NameGuid);
+ CoreAddToDriverList (Fv, FvHandle, &NameGuid, Type);
}
}
} while (!EFI_ERROR (GetNextFileStatus));
}
-
+
//
// Read the array of GUIDs from the Apriori file if it is present in the firmware volume
//
@@ -1116,27 +1312,28 @@ CoreFwVolEventProtocolNotify (
// 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 (CompareGuid (&DriverEntry->FileName, &AprioriFile[Index]) &&
(FvHandle == DriverEntry->FvHandle)) {
+ CoreAcquireDispatcherLock ();
DriverEntry->Dependent = FALSE;
DriverEntry->Scheduled = TRUE;
InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
+ CoreReleaseDispatcherLock ();
+ DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName));
+ DEBUG ((DEBUG_DISPATCH, " RESULT = TRUE (Apriori)\n"));
break;
}
}
}
- CoreReleaseDispatcherLock ();
-
//
- // Free data allocated by Fv->ReadSection ()
+ // Free data allocated by Fv->ReadSection ()
//
- CoreFreePool (AprioriFile);
+ CoreFreePool (AprioriFile);
}
}
@@ -1144,7 +1341,7 @@ CoreFwVolEventProtocolNotify (
/**
Initialize the dispatcher. Initialize the notification function that runs when
- a FV protocol is added to the system.
+ an FV2 protocol is added to the system.
**/
VOID
@@ -1152,13 +1349,12 @@ CoreInitializeDispatcher (
VOID
)
{
- mFwVolEvent = CoreCreateProtocolNotifyEvent (
- &gEfiFirmwareVolume2ProtocolGuid,
+ mFwVolEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiFirmwareVolume2ProtocolGuid,
TPL_CALLBACK,
CoreFwVolEventProtocolNotify,
NULL,
- &mFwVolEventRegistration,
- TRUE
+ &mFwVolEventRegistration
);
}