summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
diff options
context:
space:
mode:
Diffstat (limited to 'EdkModulePkg/Core/Dxe/Dispatcher/Dispatcher.c')
-rw-r--r--EdkModulePkg/Core/Dxe/Dispatcher/Dispatcher.c1170
1 files changed, 0 insertions, 1170 deletions
diff --git a/EdkModulePkg/Core/Dxe/Dispatcher/Dispatcher.c b/EdkModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
deleted file mode 100644
index 9792a16485..0000000000
--- a/EdkModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
+++ /dev/null
@@ -1,1170 +0,0 @@
-/*++
-
-Copyright (c) 2006, 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.
-
-Module Name:
-
- Dispatcher.c
-
-Abstract:
-
- Tiano 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
- 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
- be placed on the mScheduledQueue.
-
- 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
- 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
- is the state diagram for the DXE dispatcher
-
- Depex - Dependency Expresion.
- SOR - Schedule On Request - Don't schedule if this bit is set.
-
---*/
-
-#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);
-
-//
-// Queue of drivers that are ready to dispatch. This queue is a subset of the
-// mDiscoveredList.list of EFI_CORE_DRIVER_ENTRY.
-//
-LIST_ENTRY mScheduledQueue = INITIALIZE_LIST_HEAD_VARIABLE (mScheduledQueue);
-
-//
-// List of handles who's Fv's have been parsed and added to the mFwDriverList.
-//
-LIST_ENTRY mFvHandleList = INITIALIZE_LIST_HEAD_VARIABLE (mFvHandleList); // list of KNOWN_HANDLE
-
-//
-// Lock for mDiscoveredList, mScheduledQueue, gDispatcherRunning.
-//
-EFI_LOCK mDispatcherLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL);
-
-
-//
-// Flag for the DXE Dispacher. TRUE if dispatcher is execuing.
-//
-BOOLEAN gDispatcherRunning = FALSE;
-
-//
-// Module globals to manage the FwVol registration notification event
-//
-EFI_EVENT mFwVolEvent;
-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_DXE_CORE,
- EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
-};
-
-typedef struct {
- MEDIA_FW_VOL_FILEPATH_DEVICE_PATH File;
- EFI_DEVICE_PATH_PROTOCOL End;
-} FV_FILEPATH_DEVICE_PATH;
-
-FV_FILEPATH_DEVICE_PATH mFvDevicePath;
-
-
-//
-// Function Prototypes
-//
-STATIC
-VOID
-CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
- IN EFI_CORE_DRIVER_ENTRY *InsertedDriverEntry
- );
-
-STATIC
-VOID
-EFIAPI
-CoreFwVolEventProtocolNotify (
- IN EFI_EVENT Event,
- IN VOID *Context
- );
-
-STATIC
-EFI_DEVICE_PATH_PROTOCOL *
-CoreFvToDevicePath (
- IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv,
- IN EFI_HANDLE FvHandle,
- IN EFI_GUID *DriverName
- );
-
-STATIC
-EFI_STATUS
-CoreAddToDriverList (
- IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv,
- IN EFI_HANDLE FvHandle,
- IN EFI_GUID *DriverName
- );
-
-STATIC
-EFI_STATUS
-CoreProcessFvImageFile (
- IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv,
- IN EFI_HANDLE FvHandle,
- IN EFI_GUID *DriverName
- );
-
-STATIC
-VOID
-CoreAcquireDispatcherLock (
- VOID
- )
-/*++
-
-Routine Description:
-
- Enter critical section by gaining lock on mDispatcherLock
-
-Arguments:
-
- None
-
-Returns:
-
- None
-
---*/
-
-{
- CoreAcquireLock (&mDispatcherLock);
-}
-
-STATIC
-VOID
-CoreReleaseDispatcherLock (
- VOID
- )
-/*++
-
-Routine Description:
-
- Exit critical section by releasing lock on mDispatcherLock
-
-Arguments:
-
- None
-
-Returns:
-
- None
-
---*/
-{
- CoreReleaseLock (&mDispatcherLock);
-}
-
-STATIC
-EFI_STATUS
-CoreGetDepexSectionAndPreProccess (
- IN EFI_CORE_DRIVER_ENTRY *DriverEntry
- )
-/*++
-
-Routine Description:
-
- 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.
-
-Arguments:
-
- DriverEntry - Driver to work on.
-
-Returns:
-
- EFI_SUCCESS - Depex read and preprossesed
-
- EFI_PROTOCOL_ERROR - The section extraction protocol returned an error and
- Depex reading needs to be retried.
-
- Other Error - DEPEX not found.
-
---*/
-{
- EFI_STATUS Status;
- EFI_SECTION_TYPE SectionType;
- UINT32 AuthenticationStatus;
- EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
-
-
- Fv = DriverEntry->Fv;
-
- //
- // Grab Depex info, it will never be free'ed.
- //
- SectionType = EFI_SECTION_DXE_DEPEX;
- Status = Fv->ReadSection (
- DriverEntry->Fv,
- &DriverEntry->FileName,
- SectionType,
- 0,
- &DriverEntry->Depex,
- (UINTN *)&DriverEntry->DepexSize,
- &AuthenticationStatus
- );
- if (EFI_ERROR (Status)) {
- if (Status == EFI_PROTOCOL_ERROR) {
- //
- // The section extraction protocol failed so set protocol error flag
- //
- DriverEntry->DepexProtocolError = TRUE;
- } else {
- //
- // If no Depex assume EFI 1.1 driver model
- //
- DriverEntry->Depex = NULL;
- DriverEntry->Dependent = TRUE;
- DriverEntry->DepexProtocolError = FALSE;
- }
- } else {
- //
- // Set Before, After, and Unrequested state information based on Depex
- // Driver will be put in Dependent or Unrequested state
- //
- CorePreProcessDepex (DriverEntry);
- DriverEntry->DepexProtocolError = FALSE;
- }
-
- return Status;
-}
-
-EFI_DXESERVICE
-EFI_STATUS
-EFIAPI
-CoreSchedule (
- IN EFI_HANDLE FirmwareVolumeHandle,
- IN EFI_GUID *DriverName
- )
-/*++
-
-Routine Description:
-
- Check every driver and locate a matching one. If the driver is found, the Unrequested
- state flag is cleared.
-
-Arguments:
-
- FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware
- file specified by DriverName.
-
- DriverName - The Driver name to put in the Dependent state.
-
-Returns:
-
- EFI_SUCCESS - The DriverName was found and it's SOR bit was cleared
-
- EFI_NOT_FOUND - The DriverName does not exist or it's SOR bit was not set.
-
---*/
-{
- LIST_ENTRY *Link;
- EFI_CORE_DRIVER_ENTRY *DriverEntry;
-
- //
- // Check every driver
- //
- 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 &&
- CompareGuid (DriverName, &DriverEntry->FileName)) {
- //
- // Move the driver from the Unrequested to the Dependent state
- //
- CoreAcquireDispatcherLock ();
- DriverEntry->Unrequested = FALSE;
- DriverEntry->Dependent = TRUE;
- CoreReleaseDispatcherLock ();
-
- return EFI_SUCCESS;
- }
- }
- return EFI_NOT_FOUND;
-}
-
-
-EFI_DXESERVICE
-EFI_STATUS
-EFIAPI
-CoreTrust (
- IN EFI_HANDLE FirmwareVolumeHandle,
- IN EFI_GUID *DriverName
- )
-/*++
-
-Routine Description:
-
- Convert a driver from the Untrused back to the Scheduled state
-
-Arguments:
-
- FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware
- file specified by DriverName.
-
- DriverName - The Driver name to put in the Scheduled state
-
-Returns:
-
- EFI_SUCCESS - The file was found in the untrusted state, and it was promoted
- to the trusted state.
-
- EFI_NOT_FOUND - The file was not found in the untrusted state.
-
---*/
-{
- LIST_ENTRY *Link;
- EFI_CORE_DRIVER_ENTRY *DriverEntry;
-
- //
- // Check every driver
- //
- 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 &&
- CompareGuid (DriverName, &DriverEntry->FileName)) {
- //
- // Transition driver from Untrusted to Scheduled state.
- //
- CoreAcquireDispatcherLock ();
- DriverEntry->Untrusted = FALSE;
- DriverEntry->Scheduled = TRUE;
- InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
- CoreReleaseDispatcherLock ();
-
- return EFI_SUCCESS;
- }
- }
- return EFI_NOT_FOUND;
-}
-
-
-EFI_DXESERVICE
-EFI_STATUS
-EFIAPI
-CoreDispatcher (
- VOID
- )
-/*++
-
-Routine Description:
-
- 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
- image for each driver. Search the mDiscoveredList to see if any driver can
- be placed on the mScheduledQueue. If no drivers are placed on the
- mScheduledQueue exit the function. On exit it is assumed the Bds()
- will be called, and when the Bds() exits the Dispatcher will be called
- again.
-
-Arguments:
-
- NONE
-
-Returns:
-
- EFI_ALREADY_STARTED - The DXE Dispatcher is already running
-
- EFI_NOT_FOUND - No DXE Drivers were dispatched
-
- EFI_SUCCESS - One or more DXE Drivers were dispatched
-
---*/
-{
- EFI_STATUS Status;
- EFI_STATUS ReturnStatus;
- LIST_ENTRY *Link;
- EFI_CORE_DRIVER_ENTRY *DriverEntry;
- BOOLEAN ReadyToRun;
-
- if (gDispatcherRunning) {
- //
- // If the dispatcher is running don't let it be restarted.
- //
- return EFI_ALREADY_STARTED;
- }
-
- gDispatcherRunning = TRUE;
-
-
- ReturnStatus = EFI_NOT_FOUND;
- do {
- //
- // Drain the Scheduled Queue
- //
- while (!IsListEmpty (&mScheduledQueue)) {
- DriverEntry = CR (
- mScheduledQueue.ForwardLink,
- EFI_CORE_DRIVER_ENTRY,
- ScheduledLink,
- EFI_CORE_DRIVER_ENTRY_SIGNATURE
- );
-
- //
- // Load the DXE Driver image into memory. If the Driver was transitioned from
- // Untrused to Scheduled it would have already been loaded so we may need to
- // skip the LoadImage
- //
- if (DriverEntry->ImageHandle == NULL) {
- Status = CoreLoadImage (
- FALSE,
- gDxeCoreImageHandle,
- DriverEntry->FvFileDevicePath,
- NULL,
- 0,
- &DriverEntry->ImageHandle
- );
-
- //
- // Update the driver state to reflect that it's been loaded
- //
- if (EFI_ERROR (Status)) {
- CoreAcquireDispatcherLock ();
-
- if (Status == EFI_SECURITY_VIOLATION) {
- //
- // Take driver from Scheduled to Untrused state
- //
- DriverEntry->Untrusted = TRUE;
- } else {
- //
- // The DXE Driver could not be loaded, and do not attempt to load or start it again.
- // Take driver from Scheduled to Initialized.
- //
- // This case include the Never Trusted state if EFI_ACCESS_DENIED is returned
- //
- DriverEntry->Initialized = TRUE;
- }
-
- DriverEntry->Scheduled = FALSE;
- RemoveEntryList (&DriverEntry->ScheduledLink);
-
- CoreReleaseDispatcherLock ();
-
- //
- // If it's an error don't try the StartImage
- //
- continue;
- }
- }
-
- CoreAcquireDispatcherLock ();
-
- DriverEntry->Scheduled = FALSE;
- DriverEntry->Initialized = TRUE;
- RemoveEntryList (&DriverEntry->ScheduledLink);
-
- CoreReleaseDispatcherLock ();
-
-
- CoreReportProgressCodeSpecific (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN, DriverEntry->ImageHandle);
- Status = CoreStartImage (DriverEntry->ImageHandle, NULL, NULL);
- CoreReportProgressCodeSpecific (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END, DriverEntry->ImageHandle);
-
- ReturnStatus = EFI_SUCCESS;
- }
-
- //
- // Search DriverList for items to place on Scheduled Queue
- //
- ReadyToRun = FALSE;
- for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
- DriverEntry = CR (Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
-
- if (DriverEntry->DepexProtocolError){
- //
- // 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);
- ReadyToRun = TRUE;
- }
- }
- }
- } while (ReadyToRun);
-
- gDispatcherRunning = FALSE;
-
- return ReturnStatus;
-}
-
-STATIC
-VOID
-CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
- IN EFI_CORE_DRIVER_ENTRY *InsertedDriverEntry
- )
-/*++
-
-Routine Description:
-
- Insert InsertedDriverEntry onto the mScheduledQueue. To do this you
- must add any driver with a before dependency on InsertedDriverEntry first.
- You do this by recursively calling this routine. After all the Befores are
- processed you can add InsertedDriverEntry to the mScheduledQueue.
- Then you can add any driver with an After dependency on InsertedDriverEntry
- by recursively calling this routine.
-
-Arguments:
-
- InsertedDriverEntry - The driver to insert on the ScheduledLink Queue
-
-Returns:
-
- NONE
-
---*/
-{
- LIST_ENTRY *Link;
- EFI_CORE_DRIVER_ENTRY *DriverEntry;
-
- //
- // Process Before Dependency
- //
- 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 (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
- //
- // Recursively process BEFORE
- //
- CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
- }
- }
- }
-
- //
- // Convert driver from Dependent to Scheduled state
- //
- CoreAcquireDispatcherLock ();
-
- InsertedDriverEntry->Dependent = FALSE;
- InsertedDriverEntry->Scheduled = TRUE;
- InsertTailList (&mScheduledQueue, &InsertedDriverEntry->ScheduledLink);
-
- CoreReleaseDispatcherLock ();
-
- //
- // Process After Dependency
- //
- 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 (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
- //
- // Recursively process AFTER
- //
- CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
- }
- }
- }
-}
-
-STATIC
-BOOLEAN
-FvHasBeenProcessed (
- IN EFI_HANDLE FvHandle
- )
-/*++
-
-Routine Description:
-
- Return TRUE if the Fv has been processed, FALSE if not.
-
-Arguments:
-
- FvHandle - The handle of a FV that's being tested
-
-Returns:
-
- TRUE - Fv protocol on FvHandle has been processed
-
- FALSE - Fv protocol on FvHandle has not yet been processed
-
---*/
-{
- LIST_ENTRY *Link;
- KNOWN_HANDLE *KnownHandle;
-
- for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) {
- KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE);
- if (KnownHandle->Handle == FvHandle) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-STATIC
-VOID
-FvIsBeingProcesssed (
- IN EFI_HANDLE FvHandle
- )
-/*++
-
-Routine Description:
-
- 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.
-
-Arguments:
-
- FvHandle - The handle of a FV that has been processed
-
-Returns:
-
- None
-
---*/
-{
- KNOWN_HANDLE *KnownHandle;
-
- KnownHandle = CoreAllocateBootServicesPool (sizeof (KNOWN_HANDLE));
- ASSERT (KnownHandle != NULL);
-
- KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE;
- KnownHandle->Handle = FvHandle;
- InsertTailList (&mFvHandleList, &KnownHandle->Link);
-}
-
-
-
-STATIC
-EFI_DEVICE_PATH_PROTOCOL *
-CoreFvToDevicePath (
- IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv,
- IN EFI_HANDLE FvHandle,
- IN EFI_GUID *DriverName
- )
-/*++
-
-Routine Description:
-
- Convert FvHandle and DriverName into an EFI device path
-
-Arguments:
-
- Fv - Fv protocol, needed to read Depex info out of FLASH.
-
- 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.
-
- DriverName - Name of driver to add to mDiscoveredList.
-
-Returns:
-
- Pointer to device path constructed from FvHandle and DriverName
-
---*/
-{
- EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *FvDevicePath;
- EFI_DEVICE_PATH_PROTOCOL *FileNameDevicePath;
-
- //
- // Remember the device path of the FV
- //
- Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
- if (EFI_ERROR (Status)) {
- FileNameDevicePath = NULL;
- } else {
- //
- // 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));
-
- FileNameDevicePath = CoreAppendDevicePath (
- FvDevicePath,
- (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
- );
- }
-
- return FileNameDevicePath;
-}
-
-
-
-EFI_STATUS
-CoreAddToDriverList (
- IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv,
- IN EFI_HANDLE FvHandle,
- IN EFI_GUID *DriverName
- )
-/*++
-
-Routine Description:
-
- 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
- in DriverEntry. Pre-process the Depex to set the SOR, Before and After state.
- The Discovered list is never free'ed and contains booleans that represent the
- other possible DXE driver states.
-
-Arguments:
-
- Fv - Fv protocol, needed to read Depex info out of FLASH.
-
- 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.
-
- DriverName - Name of driver to add to mDiscoveredList.
-
-Returns:
-
- EFI_SUCCESS - If driver was added to the mDiscoveredList.
-
- EFI_ALREADY_STARTED - The driver has already been started. Only one DriverName
- may be active in the system at any one time.
-
---*/
-{
- EFI_CORE_DRIVER_ENTRY *DriverEntry;
-
-
- //
- // Create the Driver Entry for the list. ZeroPool initializes lots of variables to
- // NULL or FALSE.
- //
- DriverEntry = CoreAllocateZeroBootServicesPool (sizeof (EFI_CORE_DRIVER_ENTRY));
- ASSERT (DriverEntry != NULL);
-
- DriverEntry->Signature = EFI_CORE_DRIVER_ENTRY_SIGNATURE;
- CopyMem (&DriverEntry->FileName, DriverName, sizeof (EFI_GUID));
- DriverEntry->FvHandle = FvHandle;
- DriverEntry->Fv = Fv;
- DriverEntry->FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName);
-
- CoreGetDepexSectionAndPreProccess (DriverEntry);
-
- CoreAcquireDispatcherLock ();
-
- InsertTailList (&mDiscoveredList, &DriverEntry->Link);
-
- CoreReleaseDispatcherLock ();
-
- return EFI_SUCCESS;
-}
-
-
-
-EFI_STATUS
-CoreProcessFvImageFile (
- IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv,
- IN EFI_HANDLE FvHandle,
- IN EFI_GUID *DriverName
- )
-/*++
-
-Routine Description:
-
- Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.
-
-Arguments:
-
- Fv - The FIRMWARE_VOLUME protocol installed on the FV.
- FvHandle - The handle which FVB protocol installed on.
- DriverName - The driver guid specified.
-
-Returns:
-
- EFI_OUT_OF_RESOURCES - No enough memory or other resource.
-
- EFI_VOLUME_CORRUPTED - Corrupted volume.
-
- EFI_SUCCESS - Function successfully returned.
-
-
---*/
-{
- EFI_STATUS Status;
- EFI_SECTION_TYPE SectionType;
- UINT32 AuthenticationStatus;
- VOID *Buffer;
- UINTN BufferSize;
-
- //
- // Read the first (and only the first) firmware volume section
- //
- SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;
- Buffer = NULL;
- BufferSize = 0;
- Status = Fv->ReadSection (
- Fv,
- DriverName,
- SectionType,
- 0,
- &Buffer,
- &BufferSize,
- &AuthenticationStatus
- );
- if (!EFI_ERROR (Status)) {
- //
- // Produce a FVB protocol for the file
- //
- Status = ProduceFVBProtocolOnBuffer (
- (EFI_PHYSICAL_ADDRESS) (UINTN) Buffer,
- (UINT64)BufferSize,
- FvHandle,
- NULL
- );
- }
-
- if (EFI_ERROR (Status) && (Buffer != NULL)) {
- //
- // ReadSection or Produce FVB failed, Free data buffer
- //
- CoreFreePool (Buffer);
-
- }
-
- return Status;
-}
-
-STATIC
-VOID
-EFIAPI
-CoreFwVolEventProtocolNotify (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-/*++
-
-Routine Description:
-
- Event notification that is fired every time a FV dispatch protocol is added.
- More than one protocol may have been added when this event is fired, so you
- must loop on CoreLocateHandle () to see how many protocols were added and
- do the following to each FV:
-
- If the Fv has already been processed, skip it. If the Fv has not been
- processed then mark it as being processed, as we are about to process it.
-
- Read the Fv and add any driver in the Fv to the mDiscoveredList.The
- mDiscoveredList is never free'ed and contains variables that define
- the other states the DXE driver transitions to..
-
- While you are at it read the A Priori file into memory.
- Place drivers in the A Priori list onto the mScheduledQueue.
-
-Arguments:
-
- Event - The Event that is being processed, not used.
-
- Context - Event Context, not used.
-
-Returns:
-
- None
-
---*/
-{
- EFI_STATUS Status;
- EFI_STATUS GetNextFileStatus;
- EFI_STATUS SecurityStatus;
- EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
- EFI_DEVICE_PATH_PROTOCOL *FvDevicePath;
- EFI_HANDLE FvHandle;
- UINTN BufferSize;
- EFI_GUID NameGuid;
- UINTN Key;
- EFI_FV_FILETYPE Type;
- EFI_FV_FILE_ATTRIBUTES Attributes;
- UINTN Size;
- EFI_CORE_DRIVER_ENTRY *DriverEntry;
- EFI_GUID *AprioriFile;
- UINTN AprioriEntryCount;
- UINTN Index;
- LIST_ENTRY *Link;
- UINT32 AuthenticationStatus;
- UINTN SizeOfBuffer;
-
-
- while (TRUE) {
- BufferSize = sizeof (EFI_HANDLE);
- Status = CoreLocateHandle (
- ByRegisterNotify,
- NULL,
- mFwVolEventRegistration,
- &BufferSize,
- &FvHandle
- );
- if (EFI_ERROR (Status)) {
- //
- // If no more notification events exit
- //
- return;
- }
-
- if (FvHasBeenProcessed (FvHandle)) {
- //
- // This Fv has already been processed so lets skip it!
- //
- continue;
- }
-
- Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeDispatchProtocolGuid, (VOID **)&Fv);
- if (EFI_ERROR (Status)) {
- //
- // If no dispatch protocol then skip, but do not marked as being processed as it
- // may show up later.
- //
- continue;
- }
-
- //
- // Since we are about to process this Fv mark it as processed.
- //
- FvIsBeingProcesssed (FvHandle);
-
-
- Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeProtocolGuid, (VOID **)&Fv);
- if (EFI_ERROR (Status)) {
- //
- // The Handle has a FirmwareVolumeDispatch protocol and should also contiain
- // a FirmwareVolume protocol thus we should never get here.
- //
- ASSERT (FALSE);
- continue;
- }
-
- Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
- if (EFI_ERROR (Status)) {
- //
- // The Firmware volume doesn't have device path, can't be dispatched.
- //
- continue;
- }
-
- //
- // Evaluate the authentication status of the Firmware Volume through
- // Security Architectural Protocol
- //
- if (gSecurity != NULL) {
- SecurityStatus = gSecurity->FileAuthenticationState (
- gSecurity,
- 0,
- FvDevicePath
- );
- if (SecurityStatus != EFI_SUCCESS) {
- //
- // Security check failed. The firmware volume should not be used for any purpose.
- //
- continue;
- }
- }
-
- //
- // Discover Drivers in FV and add them to the Discovered Driver List.
- // Process EFI_FV_FILETYPE_DRIVER type and then EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
- // EFI_FV_FILETYPE_DXE_CORE is processed to produce a Loaded Image protocol for the core
- // EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE is processed to create a Fvb
- //
- for (Index = 0; Index < sizeof (mDxeFileTypes)/sizeof (EFI_FV_FILETYPE); Index++) {
- //
- // Initialize the search key
- //
- Key = 0;
- do {
- Type = mDxeFileTypes[Index];
- GetNextFileStatus = Fv->GetNextFile (
- Fv,
- &Key,
- &Type,
- &NameGuid,
- &Attributes,
- &Size
- );
- if (!EFI_ERROR (GetNextFileStatus)) {
- if (Type == EFI_FV_FILETYPE_DXE_CORE) {
- //
- // If this is the DXE core fill in it's DevicePath & DeviceHandle
- //
- if (gDxeCoreLoadedImage->FilePath == NULL) {
- if (CompareGuid (&NameGuid, gDxeCoreFileName)) {
- //
- // Maybe One specail Fv cantains only one DXE_CORE module, so its device path must
- // 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));
-
- gDxeCoreLoadedImage->FilePath = CoreDuplicateDevicePath (
- (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
- );
- gDxeCoreLoadedImage->DeviceHandle = FvHandle;
- }
- }
- } else if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
- //
- // Found a firmware volume image. Produce a firmware volume block
- // protocol for it so it gets dispatched from. This is usually a
- // capsule.
- //
- CoreProcessFvImageFile (Fv, FvHandle, &NameGuid);
- } else {
- //
- // Transition driver from Undiscovered to Discovered state
- //
- CoreAddToDriverList (Fv, FvHandle, &NameGuid);
- }
- }
- } while (!EFI_ERROR (GetNextFileStatus));
- }
-
- //
- // Read the array of GUIDs from the Apriori file if it is present in the firmware volume
- //
- AprioriFile = NULL;
- Status = Fv->ReadSection (
- Fv,
- &gAprioriGuid,
- EFI_SECTION_RAW,
- 0,
- (VOID **)&AprioriFile,
- &SizeOfBuffer,
- &AuthenticationStatus
- );
- if (!EFI_ERROR (Status)) {
- AprioriEntryCount = SizeOfBuffer / sizeof (EFI_GUID);
- } else {
- AprioriEntryCount = 0;
- }
-
- //
- // Put drivers on Apriori List on the Scheduled queue. The Discovered List includes
- // drivers not in the current FV and these must be skipped since the a priori list
- // is only valid for the FV that it resided in.
- //
- CoreAcquireDispatcherLock ();
-
- for (Index = 0; Index < AprioriEntryCount; Index++) {
- for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
- DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
- if (CompareGuid (&DriverEntry->FileName, &AprioriFile[Index]) &&
- (FvHandle == DriverEntry->FvHandle)) {
- DriverEntry->Dependent = FALSE;
- DriverEntry->Scheduled = TRUE;
- InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
- break;
- }
- }
- }
-
- CoreReleaseDispatcherLock ();
-
- //
- // Free data allocated by Fv->ReadSection ()
- //
- CoreFreePool (AprioriFile);
- }
-}
-
-
-VOID
-CoreInitializeDispatcher (
- VOID
- )
-/*++
-
-Routine Description:
-
- Initialize the dispatcher. Initialize the notification function that runs when
- a FV protocol is added to the system.
-
-Arguments:
-
- NONE
-
-Returns:
-
- NONE
-
---*/
-{
- mFwVolEvent = CoreCreateProtocolNotifyEvent (
- &gEfiFirmwareVolumeProtocolGuid,
- TPL_CALLBACK,
- CoreFwVolEventProtocolNotify,
- NULL,
- &mFwVolEventRegistration,
- TRUE
- );
-}
-
-//
-// Function only used in debug builds
-//
-VOID
-CoreDisplayDiscoveredNotDispatched (
- VOID
- )
-/*++
-
-Routine Description:
-
- Traverse the discovered list for any drivers that were discovered but not loaded
- because the dependency experessions evaluated to false
-
-Arguments:
-
- NONE
-
-Returns:
-
- NONE
-
---*/
-{
- LIST_ENTRY *Link;
- EFI_CORE_DRIVER_ENTRY *DriverEntry;
-
- for (Link = mDiscoveredList.ForwardLink;Link !=&mDiscoveredList; Link = Link->ForwardLink) {
- DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
- if (DriverEntry->Dependent) {
- DEBUG ((EFI_D_LOAD, "Driver %g was discovered but not loaded!!\n", &DriverEntry->FileName));
- }
- }
-}