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 ); }