X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FCore%2FDxe%2FDispatcher%2FDispatcher.c;h=68f5ef5d6463385c9de692a49db72ebf435dbc3d;hp=3a4d03bd556b844c0386f810d6abfbeea28cd162;hb=22675de35c8af7c553f763dea5f7d2eb9658aada;hpb=cd539d485db6356c59271e031b8fb05a4a6a66a9 diff --git a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c index 3a4d03bd55..68f5ef5d64 100644 --- a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c +++ b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c @@ -26,8 +26,8 @@ Depex - Dependency Expresion. SOR - Schedule On Request - Don't schedule if this bit is set. -Copyright (c) 2006 - 2010, Intel Corporation.
-All rights reserved. This program and the accompanying materials +Copyright (c) 2006 - 2011, 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 @@ -168,6 +168,7 @@ CoreFvToDevicePath ( 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 @@ -179,7 +180,8 @@ 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 ); /** @@ -333,9 +335,14 @@ CoreSchedule ( DriverEntry->Dependent = TRUE; CoreReleaseDispatcherLock (); + DEBUG ((DEBUG_DISPATCH, "Schedule FFS(%g) - EFI_SUCCESS\n", DriverName)); + return EFI_SUCCESS; } } + + DEBUG ((DEBUG_DISPATCH, "Schedule FFS(%g) - EFI_NOT_FOUND\n", DriverName)); + return EFI_NOT_FOUND; } @@ -397,7 +404,7 @@ CoreTrust ( **/ VOID EFIAPI -EmptyFuntion ( +CoreEmptyCallbackFunction ( IN EFI_EVENT Event, IN VOID *Context ) @@ -445,7 +452,7 @@ CoreDispatcher ( Status = CoreCreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, - EmptyFuntion, + CoreEmptyCallbackFunction, NULL, &gEfiEventDxeDispatchGuid, &DxeDispatchEvent @@ -472,7 +479,7 @@ 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, @@ -525,25 +532,41 @@ CoreDispatcher ( CoreReleaseDispatcherLock (); - REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( - EFI_PROGRESS_CODE, - (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN), - &DriverEntry->ImageHandle, - sizeof (DriverEntry->ImageHandle) - ); - - 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) - ); + 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) + ); + + 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 // @@ -563,17 +586,14 @@ CoreDispatcher ( 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")); + } } } - - // - // 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); - } } while (ReadyToRun); // @@ -611,12 +631,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")); } } } @@ -637,12 +662,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")); } } } @@ -763,6 +793,7 @@ CoreFvToDevicePath ( 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 @@ -774,7 +805,8 @@ 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; @@ -786,6 +818,9 @@ CoreAddToDriverList ( // 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; CopyGuid (&DriverEntry->FileName, DriverName); @@ -985,7 +1020,7 @@ CoreFwVolEventProtocolNotify ( LIST_ENTRY *Link; UINT32 AuthenticationStatus; UINTN SizeOfBuffer; - + VOID *DepexBuffer; while (TRUE) { BufferSize = sizeof (EFI_HANDLE); @@ -1016,7 +1051,7 @@ CoreFwVolEventProtocolNotify ( FvIsBeingProcesssed (FvHandle); Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv); - if (EFI_ERROR (Status)) { + if (EFI_ERROR (Status) || Fv == NULL) { // // FvHandle must have Firmware Volume2 protocol thus we should never get here. // @@ -1099,17 +1134,84 @@ CoreFwVolEventProtocolNotify ( if (FvFoundInHobFv2 (FvHandle, &NameGuid)) { continue; } + // - // 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 PEI depex section. // - CoreProcessFvImageFile (Fv, FvHandle, &NameGuid); + DepexBuffer = NULL; + SizeOfBuffer = 0; + Status = Fv->ReadSection ( + Fv, + &NameGuid, + EFI_SECTION_PEI_DEPEX, + 0, + &DepexBuffer, + &SizeOfBuffer, + &AuthenticationStatus + ); + if (!EFI_ERROR (Status)) { + // + // If PEI depex section is found, this FV image will be ignored in DXE phase. + // Now, DxeCore doesn't support FV image with more one type DEPEX section. + // + FreePool (DepexBuffer); + 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 will be ignored in DXE phase. + // Now, DxeCore doesn't support FV image with more one type DEPEX section. + // + FreePool (DepexBuffer); + continue; + } + + // + // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has DXE depex section. + // + 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)); @@ -1139,23 +1241,24 @@ 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 () //