Dispatcher.c revision 8a7d75b0625cffee0c67b85afe56763f93d86481
128a00297189c323096aae8e2975de94e8549613cyshang/*++
228a00297189c323096aae8e2975de94e8549613cyshang
328a00297189c323096aae8e2975de94e8549613cyshangCopyright (c) 2006, Intel Corporation
428a00297189c323096aae8e2975de94e8549613cyshangAll rights reserved. This program and the accompanying materials
528a00297189c323096aae8e2975de94e8549613cyshangare licensed and made available under the terms and conditions of the BSD License
628a00297189c323096aae8e2975de94e8549613cyshangwhich accompanies this distribution.  The full text of the license may be found at
728a00297189c323096aae8e2975de94e8549613cyshanghttp://opensource.org/licenses/bsd-license.php
828a00297189c323096aae8e2975de94e8549613cyshang
928a00297189c323096aae8e2975de94e8549613cyshangTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
1028a00297189c323096aae8e2975de94e8549613cyshangWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
1128a00297189c323096aae8e2975de94e8549613cyshang
1228a00297189c323096aae8e2975de94e8549613cyshangModule Name:
1328a00297189c323096aae8e2975de94e8549613cyshang
1428a00297189c323096aae8e2975de94e8549613cyshang  Dispatcher.c
1528a00297189c323096aae8e2975de94e8549613cyshang
1628a00297189c323096aae8e2975de94e8549613cyshangAbstract:
1728a00297189c323096aae8e2975de94e8549613cyshang
1828a00297189c323096aae8e2975de94e8549613cyshang  Tiano DXE Dispatcher.
1928a00297189c323096aae8e2975de94e8549613cyshang
2028a00297189c323096aae8e2975de94e8549613cyshang  Step #1 - When a FV protocol is added to the system every driver in the FV
2128a00297189c323096aae8e2975de94e8549613cyshang            is added to the mDiscoveredList. The SOR, Before, and After Depex are
2228a00297189c323096aae8e2975de94e8549613cyshang            pre-processed as drivers are added to the mDiscoveredList. If an Apriori
2328a00297189c323096aae8e2975de94e8549613cyshang            file exists in the FV those drivers are addeded to the
2428a00297189c323096aae8e2975de94e8549613cyshang            mScheduledQueue. The mFvHandleList is used to make sure a
2528a00297189c323096aae8e2975de94e8549613cyshang            FV is only processed once.
2628a00297189c323096aae8e2975de94e8549613cyshang
2728a00297189c323096aae8e2975de94e8549613cyshang  Step #2 - Dispatch. Remove driver from the mScheduledQueue and load and
2828a00297189c323096aae8e2975de94e8549613cyshang            start it. After mScheduledQueue is drained check the
2928a00297189c323096aae8e2975de94e8549613cyshang            mDiscoveredList to see if any item has a Depex that is ready to
3028a00297189c323096aae8e2975de94e8549613cyshang            be placed on the mScheduledQueue.
3128a00297189c323096aae8e2975de94e8549613cyshang
3228a00297189c323096aae8e2975de94e8549613cyshang  Step #3 - Adding to the mScheduledQueue requires that you process Before
3328a00297189c323096aae8e2975de94e8549613cyshang            and After dependencies. This is done recursively as the call to add
3428a00297189c323096aae8e2975de94e8549613cyshang            to the mScheduledQueue checks for Before and recursively adds
3528a00297189c323096aae8e2975de94e8549613cyshang            all Befores. It then addes the item that was passed in and then
3628a00297189c323096aae8e2975de94e8549613cyshang            processess the After dependecies by recursively calling the routine.
3728a00297189c323096aae8e2975de94e8549613cyshang
3828a00297189c323096aae8e2975de94e8549613cyshang  Dispatcher Rules:
3928a00297189c323096aae8e2975de94e8549613cyshang  The rules for the dispatcher are in chapter 10 of the DXE CIS. Figure 10-3
4028a00297189c323096aae8e2975de94e8549613cyshang  is the state diagram for the DXE dispatcher
4128a00297189c323096aae8e2975de94e8549613cyshang
4228a00297189c323096aae8e2975de94e8549613cyshang  Depex - Dependency Expresion.
4328a00297189c323096aae8e2975de94e8549613cyshang  SOR   - Schedule On Request - Don't schedule if this bit is set.
4428a00297189c323096aae8e2975de94e8549613cyshang
4528a00297189c323096aae8e2975de94e8549613cyshang--*/
4628a00297189c323096aae8e2975de94e8549613cyshang
4728a00297189c323096aae8e2975de94e8549613cyshang#include <DxeMain.h>
4828a00297189c323096aae8e2975de94e8549613cyshang
4928a00297189c323096aae8e2975de94e8549613cyshang//
5028a00297189c323096aae8e2975de94e8549613cyshang// The Driver List contains one copy of every driver that has been discovered.
5128a00297189c323096aae8e2975de94e8549613cyshang// Items are never removed from the driver list. List of EFI_CORE_DRIVER_ENTRY
5228a00297189c323096aae8e2975de94e8549613cyshang//
5328a00297189c323096aae8e2975de94e8549613cyshangLIST_ENTRY  mDiscoveredList = INITIALIZE_LIST_HEAD_VARIABLE (mDiscoveredList);
5428a00297189c323096aae8e2975de94e8549613cyshang
5528a00297189c323096aae8e2975de94e8549613cyshang//
5628a00297189c323096aae8e2975de94e8549613cyshang// Queue of drivers that are ready to dispatch. This queue is a subset of the
5728a00297189c323096aae8e2975de94e8549613cyshang// mDiscoveredList.list of EFI_CORE_DRIVER_ENTRY.
5828a00297189c323096aae8e2975de94e8549613cyshang//
5928a00297189c323096aae8e2975de94e8549613cyshangLIST_ENTRY  mScheduledQueue = INITIALIZE_LIST_HEAD_VARIABLE (mScheduledQueue);
6028a00297189c323096aae8e2975de94e8549613cyshang
6128a00297189c323096aae8e2975de94e8549613cyshang//
6228a00297189c323096aae8e2975de94e8549613cyshang// List of handles who's Fv's have been parsed and added to the mFwDriverList.
6328a00297189c323096aae8e2975de94e8549613cyshang//
6428a00297189c323096aae8e2975de94e8549613cyshangLIST_ENTRY  mFvHandleList = INITIALIZE_LIST_HEAD_VARIABLE (mFvHandleList);           // list of KNOWN_HANDLE
6528a00297189c323096aae8e2975de94e8549613cyshang
6628a00297189c323096aae8e2975de94e8549613cyshang//
6728a00297189c323096aae8e2975de94e8549613cyshang// Lock for mDiscoveredList, mScheduledQueue, gDispatcherRunning.
6828a00297189c323096aae8e2975de94e8549613cyshang//
6928a00297189c323096aae8e2975de94e8549613cyshangEFI_LOCK  mDispatcherLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL);
7028a00297189c323096aae8e2975de94e8549613cyshang
7128a00297189c323096aae8e2975de94e8549613cyshang
7228a00297189c323096aae8e2975de94e8549613cyshang//
7328a00297189c323096aae8e2975de94e8549613cyshang// Flag for the DXE Dispacher.  TRUE if dispatcher is execuing.
7428a00297189c323096aae8e2975de94e8549613cyshang//
7528a00297189c323096aae8e2975de94e8549613cyshangBOOLEAN  gDispatcherRunning = FALSE;
7628a00297189c323096aae8e2975de94e8549613cyshang
7728a00297189c323096aae8e2975de94e8549613cyshang//
7828a00297189c323096aae8e2975de94e8549613cyshang// Module globals to manage the FwVol registration notification event
7928a00297189c323096aae8e2975de94e8549613cyshang//
8028a00297189c323096aae8e2975de94e8549613cyshangEFI_EVENT       mFwVolEvent;
8128a00297189c323096aae8e2975de94e8549613cyshangVOID            *mFwVolEventRegistration;
8228a00297189c323096aae8e2975de94e8549613cyshang
8328a00297189c323096aae8e2975de94e8549613cyshang//
8428a00297189c323096aae8e2975de94e8549613cyshang// List of file types supported by dispatcher
8528a00297189c323096aae8e2975de94e8549613cyshang//
8628a00297189c323096aae8e2975de94e8549613cyshangstatic EFI_FV_FILETYPE mDxeFileTypes[] = {
8728a00297189c323096aae8e2975de94e8549613cyshang  EFI_FV_FILETYPE_DRIVER,
8828a00297189c323096aae8e2975de94e8549613cyshang  EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER,
8928a00297189c323096aae8e2975de94e8549613cyshang  EFI_FV_FILETYPE_DXE_CORE,
9028a00297189c323096aae8e2975de94e8549613cyshang  EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
9128a00297189c323096aae8e2975de94e8549613cyshang};
9228a00297189c323096aae8e2975de94e8549613cyshang
9328a00297189c323096aae8e2975de94e8549613cyshangtypedef struct {
9428a00297189c323096aae8e2975de94e8549613cyshang  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH   File;
9528a00297189c323096aae8e2975de94e8549613cyshang  EFI_DEVICE_PATH_PROTOCOL            End;
9628a00297189c323096aae8e2975de94e8549613cyshang} FV_FILEPATH_DEVICE_PATH;
9728a00297189c323096aae8e2975de94e8549613cyshang
9828a00297189c323096aae8e2975de94e8549613cyshangFV_FILEPATH_DEVICE_PATH mFvDevicePath;
9928a00297189c323096aae8e2975de94e8549613cyshang
10028a00297189c323096aae8e2975de94e8549613cyshang
10128a00297189c323096aae8e2975de94e8549613cyshang//
10228a00297189c323096aae8e2975de94e8549613cyshang// Function Prototypes
10328a00297189c323096aae8e2975de94e8549613cyshang//
10428a00297189c323096aae8e2975de94e8549613cyshangSTATIC
10528a00297189c323096aae8e2975de94e8549613cyshangVOID
10628a00297189c323096aae8e2975de94e8549613cyshangCoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
10728a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_CORE_DRIVER_ENTRY   *InsertedDriverEntry
10828a00297189c323096aae8e2975de94e8549613cyshang  );
10928a00297189c323096aae8e2975de94e8549613cyshang
11028a00297189c323096aae8e2975de94e8549613cyshangSTATIC
11128a00297189c323096aae8e2975de94e8549613cyshangVOID
11228a00297189c323096aae8e2975de94e8549613cyshangEFIAPI
11328a00297189c323096aae8e2975de94e8549613cyshangCoreFwVolEventProtocolNotify (
11428a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_EVENT       Event,
11528a00297189c323096aae8e2975de94e8549613cyshang  IN  VOID            *Context
11628a00297189c323096aae8e2975de94e8549613cyshang  );
11728a00297189c323096aae8e2975de94e8549613cyshang
11828a00297189c323096aae8e2975de94e8549613cyshangSTATIC
11928a00297189c323096aae8e2975de94e8549613cyshangEFI_DEVICE_PATH_PROTOCOL *
12028a00297189c323096aae8e2975de94e8549613cyshangCoreFvToDevicePath (
1210c2b5da80e9551286cd02a92d91090290ae2d816qwang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
12228a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                      FvHandle,
12328a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID                        *DriverName
12428a00297189c323096aae8e2975de94e8549613cyshang  );
12528a00297189c323096aae8e2975de94e8549613cyshang
12628a00297189c323096aae8e2975de94e8549613cyshangSTATIC
12728a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS
12828a00297189c323096aae8e2975de94e8549613cyshangCoreAddToDriverList (
1290c2b5da80e9551286cd02a92d91090290ae2d816qwang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
13028a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                    FvHandle,
13128a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID                      *DriverName
13228a00297189c323096aae8e2975de94e8549613cyshang  );
13328a00297189c323096aae8e2975de94e8549613cyshang
13428a00297189c323096aae8e2975de94e8549613cyshangSTATIC
13528a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS
13628a00297189c323096aae8e2975de94e8549613cyshangCoreProcessFvImageFile (
1370c2b5da80e9551286cd02a92d91090290ae2d816qwang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
13828a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                      FvHandle,
13928a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID                        *DriverName
14028a00297189c323096aae8e2975de94e8549613cyshang  );
14128a00297189c323096aae8e2975de94e8549613cyshang
14228a00297189c323096aae8e2975de94e8549613cyshangSTATIC
14328a00297189c323096aae8e2975de94e8549613cyshangVOID
14428a00297189c323096aae8e2975de94e8549613cyshangCoreAcquireDispatcherLock (
14528a00297189c323096aae8e2975de94e8549613cyshang  VOID
14628a00297189c323096aae8e2975de94e8549613cyshang  )
14728a00297189c323096aae8e2975de94e8549613cyshang/*++
14828a00297189c323096aae8e2975de94e8549613cyshang
14928a00297189c323096aae8e2975de94e8549613cyshangRoutine Description:
15028a00297189c323096aae8e2975de94e8549613cyshang
15128a00297189c323096aae8e2975de94e8549613cyshang  Enter critical section by gaining lock on mDispatcherLock
15228a00297189c323096aae8e2975de94e8549613cyshang
15328a00297189c323096aae8e2975de94e8549613cyshangArguments:
15428a00297189c323096aae8e2975de94e8549613cyshang
15528a00297189c323096aae8e2975de94e8549613cyshang  None
15628a00297189c323096aae8e2975de94e8549613cyshang
15728a00297189c323096aae8e2975de94e8549613cyshangReturns:
15828a00297189c323096aae8e2975de94e8549613cyshang
15928a00297189c323096aae8e2975de94e8549613cyshang  None
16028a00297189c323096aae8e2975de94e8549613cyshang
16128a00297189c323096aae8e2975de94e8549613cyshang--*/
16228a00297189c323096aae8e2975de94e8549613cyshang
16328a00297189c323096aae8e2975de94e8549613cyshang{
16428a00297189c323096aae8e2975de94e8549613cyshang  CoreAcquireLock (&mDispatcherLock);
16528a00297189c323096aae8e2975de94e8549613cyshang}
16628a00297189c323096aae8e2975de94e8549613cyshang
16728a00297189c323096aae8e2975de94e8549613cyshangSTATIC
16828a00297189c323096aae8e2975de94e8549613cyshangVOID
16928a00297189c323096aae8e2975de94e8549613cyshangCoreReleaseDispatcherLock (
17028a00297189c323096aae8e2975de94e8549613cyshang  VOID
17128a00297189c323096aae8e2975de94e8549613cyshang  )
17228a00297189c323096aae8e2975de94e8549613cyshang/*++
17328a00297189c323096aae8e2975de94e8549613cyshang
17428a00297189c323096aae8e2975de94e8549613cyshangRoutine Description:
17528a00297189c323096aae8e2975de94e8549613cyshang
17628a00297189c323096aae8e2975de94e8549613cyshang  Exit critical section by releasing lock on mDispatcherLock
17728a00297189c323096aae8e2975de94e8549613cyshang
17828a00297189c323096aae8e2975de94e8549613cyshangArguments:
17928a00297189c323096aae8e2975de94e8549613cyshang
18028a00297189c323096aae8e2975de94e8549613cyshang  None
18128a00297189c323096aae8e2975de94e8549613cyshang
18228a00297189c323096aae8e2975de94e8549613cyshangReturns:
18328a00297189c323096aae8e2975de94e8549613cyshang
18428a00297189c323096aae8e2975de94e8549613cyshang  None
18528a00297189c323096aae8e2975de94e8549613cyshang
18628a00297189c323096aae8e2975de94e8549613cyshang--*/
18728a00297189c323096aae8e2975de94e8549613cyshang{
18828a00297189c323096aae8e2975de94e8549613cyshang  CoreReleaseLock (&mDispatcherLock);
18928a00297189c323096aae8e2975de94e8549613cyshang}
19028a00297189c323096aae8e2975de94e8549613cyshang
19128a00297189c323096aae8e2975de94e8549613cyshangSTATIC
19228a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS
19328a00297189c323096aae8e2975de94e8549613cyshangCoreGetDepexSectionAndPreProccess (
19428a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_CORE_DRIVER_ENTRY   *DriverEntry
19528a00297189c323096aae8e2975de94e8549613cyshang  )
19628a00297189c323096aae8e2975de94e8549613cyshang/*++
19728a00297189c323096aae8e2975de94e8549613cyshang
19828a00297189c323096aae8e2975de94e8549613cyshangRoutine Description:
19928a00297189c323096aae8e2975de94e8549613cyshang
20028a00297189c323096aae8e2975de94e8549613cyshang  Read Depex and pre-process the Depex for Before and After. If Section Extraction
20128a00297189c323096aae8e2975de94e8549613cyshang  protocol returns an error via ReadSection defer the reading of the Depex.
20228a00297189c323096aae8e2975de94e8549613cyshang
20328a00297189c323096aae8e2975de94e8549613cyshangArguments:
20428a00297189c323096aae8e2975de94e8549613cyshang
20528a00297189c323096aae8e2975de94e8549613cyshang  DriverEntry - Driver to work on.
20628a00297189c323096aae8e2975de94e8549613cyshang
20728a00297189c323096aae8e2975de94e8549613cyshangReturns:
20828a00297189c323096aae8e2975de94e8549613cyshang
20928a00297189c323096aae8e2975de94e8549613cyshang  EFI_SUCCESS - Depex read and preprossesed
21028a00297189c323096aae8e2975de94e8549613cyshang
21128a00297189c323096aae8e2975de94e8549613cyshang  EFI_PROTOCOL_ERROR - The section extraction protocol returned an error and
21228a00297189c323096aae8e2975de94e8549613cyshang                        Depex reading needs to be retried.
21328a00297189c323096aae8e2975de94e8549613cyshang
21428a00297189c323096aae8e2975de94e8549613cyshang  Other Error - DEPEX not found.
21528a00297189c323096aae8e2975de94e8549613cyshang
21628a00297189c323096aae8e2975de94e8549613cyshang--*/
21728a00297189c323096aae8e2975de94e8549613cyshang{
21828a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                    Status;
21928a00297189c323096aae8e2975de94e8549613cyshang  EFI_SECTION_TYPE              SectionType;
22028a00297189c323096aae8e2975de94e8549613cyshang  UINT32                        AuthenticationStatus;
2210c2b5da80e9551286cd02a92d91090290ae2d816qwang  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
22228a00297189c323096aae8e2975de94e8549613cyshang
22328a00297189c323096aae8e2975de94e8549613cyshang
22428a00297189c323096aae8e2975de94e8549613cyshang  Fv = DriverEntry->Fv;
22528a00297189c323096aae8e2975de94e8549613cyshang
22628a00297189c323096aae8e2975de94e8549613cyshang  //
22728a00297189c323096aae8e2975de94e8549613cyshang  // Grab Depex info, it will never be free'ed.
22828a00297189c323096aae8e2975de94e8549613cyshang  //
22928a00297189c323096aae8e2975de94e8549613cyshang  SectionType         = EFI_SECTION_DXE_DEPEX;
23028a00297189c323096aae8e2975de94e8549613cyshang  Status = Fv->ReadSection (
23128a00297189c323096aae8e2975de94e8549613cyshang                DriverEntry->Fv,
23228a00297189c323096aae8e2975de94e8549613cyshang                &DriverEntry->FileName,
23328a00297189c323096aae8e2975de94e8549613cyshang                SectionType,
23428a00297189c323096aae8e2975de94e8549613cyshang                0,
23528a00297189c323096aae8e2975de94e8549613cyshang                &DriverEntry->Depex,
23628a00297189c323096aae8e2975de94e8549613cyshang                (UINTN *)&DriverEntry->DepexSize,
23728a00297189c323096aae8e2975de94e8549613cyshang                &AuthenticationStatus
23828a00297189c323096aae8e2975de94e8549613cyshang                );
23928a00297189c323096aae8e2975de94e8549613cyshang  if (EFI_ERROR (Status)) {
24028a00297189c323096aae8e2975de94e8549613cyshang    if (Status == EFI_PROTOCOL_ERROR) {
24128a00297189c323096aae8e2975de94e8549613cyshang      //
24228a00297189c323096aae8e2975de94e8549613cyshang      // The section extraction protocol failed so set protocol error flag
24328a00297189c323096aae8e2975de94e8549613cyshang      //
24428a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->DepexProtocolError = TRUE;
24528a00297189c323096aae8e2975de94e8549613cyshang    } else {
24628a00297189c323096aae8e2975de94e8549613cyshang      //
2478a7d75b0625cffee0c67b85afe56763f93d86481qhuang      // If no Depex assume UEFI 2.0 driver model
24828a00297189c323096aae8e2975de94e8549613cyshang      //
24928a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Depex = NULL;
25028a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Dependent = TRUE;
25128a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->DepexProtocolError = FALSE;
25228a00297189c323096aae8e2975de94e8549613cyshang    }
25328a00297189c323096aae8e2975de94e8549613cyshang  } else {
25428a00297189c323096aae8e2975de94e8549613cyshang    //
25528a00297189c323096aae8e2975de94e8549613cyshang    // Set Before, After, and Unrequested state information based on Depex
25628a00297189c323096aae8e2975de94e8549613cyshang    // Driver will be put in Dependent or Unrequested state
25728a00297189c323096aae8e2975de94e8549613cyshang    //
25828a00297189c323096aae8e2975de94e8549613cyshang    CorePreProcessDepex (DriverEntry);
25928a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry->DepexProtocolError = FALSE;
26028a00297189c323096aae8e2975de94e8549613cyshang  }
26128a00297189c323096aae8e2975de94e8549613cyshang
26228a00297189c323096aae8e2975de94e8549613cyshang  return Status;
26328a00297189c323096aae8e2975de94e8549613cyshang}
26428a00297189c323096aae8e2975de94e8549613cyshang
26528a00297189c323096aae8e2975de94e8549613cyshangEFI_DXESERVICE
26628a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS
26728a00297189c323096aae8e2975de94e8549613cyshangEFIAPI
26828a00297189c323096aae8e2975de94e8549613cyshangCoreSchedule (
26928a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE  FirmwareVolumeHandle,
27028a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID    *DriverName
27128a00297189c323096aae8e2975de94e8549613cyshang  )
27228a00297189c323096aae8e2975de94e8549613cyshang/*++
27328a00297189c323096aae8e2975de94e8549613cyshang
27428a00297189c323096aae8e2975de94e8549613cyshangRoutine Description:
27528a00297189c323096aae8e2975de94e8549613cyshang
27628a00297189c323096aae8e2975de94e8549613cyshang  Check every driver and locate a matching one. If the driver is found, the Unrequested
27728a00297189c323096aae8e2975de94e8549613cyshang  state flag is cleared.
27828a00297189c323096aae8e2975de94e8549613cyshang
27928a00297189c323096aae8e2975de94e8549613cyshangArguments:
28028a00297189c323096aae8e2975de94e8549613cyshang
28128a00297189c323096aae8e2975de94e8549613cyshang  FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware
28228a00297189c323096aae8e2975de94e8549613cyshang                         file specified by DriverName.
28328a00297189c323096aae8e2975de94e8549613cyshang
28428a00297189c323096aae8e2975de94e8549613cyshang  DriverName           - The Driver name to put in the Dependent state.
28528a00297189c323096aae8e2975de94e8549613cyshang
28628a00297189c323096aae8e2975de94e8549613cyshangReturns:
28728a00297189c323096aae8e2975de94e8549613cyshang
28828a00297189c323096aae8e2975de94e8549613cyshang  EFI_SUCCESS   - The DriverName was found and it's SOR bit was cleared
28928a00297189c323096aae8e2975de94e8549613cyshang
29028a00297189c323096aae8e2975de94e8549613cyshang  EFI_NOT_FOUND - The DriverName does not exist or it's SOR bit was not set.
29128a00297189c323096aae8e2975de94e8549613cyshang
29228a00297189c323096aae8e2975de94e8549613cyshang--*/
29328a00297189c323096aae8e2975de94e8549613cyshang{
29428a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY            *Link;
29528a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY *DriverEntry;
29628a00297189c323096aae8e2975de94e8549613cyshang
29728a00297189c323096aae8e2975de94e8549613cyshang  //
29828a00297189c323096aae8e2975de94e8549613cyshang  // Check every driver
29928a00297189c323096aae8e2975de94e8549613cyshang  //
30028a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
30128a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
30228a00297189c323096aae8e2975de94e8549613cyshang    if (DriverEntry->FvHandle == FirmwareVolumeHandle &&
30328a00297189c323096aae8e2975de94e8549613cyshang        DriverEntry->Unrequested &&
30428a00297189c323096aae8e2975de94e8549613cyshang        CompareGuid (DriverName, &DriverEntry->FileName)) {
30528a00297189c323096aae8e2975de94e8549613cyshang      //
30628a00297189c323096aae8e2975de94e8549613cyshang      // Move the driver from the Unrequested to the Dependent state
30728a00297189c323096aae8e2975de94e8549613cyshang      //
30828a00297189c323096aae8e2975de94e8549613cyshang      CoreAcquireDispatcherLock ();
30928a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Unrequested  = FALSE;
31028a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Dependent    = TRUE;
31128a00297189c323096aae8e2975de94e8549613cyshang      CoreReleaseDispatcherLock ();
31228a00297189c323096aae8e2975de94e8549613cyshang
31328a00297189c323096aae8e2975de94e8549613cyshang      return EFI_SUCCESS;
31428a00297189c323096aae8e2975de94e8549613cyshang    }
31528a00297189c323096aae8e2975de94e8549613cyshang  }
31628a00297189c323096aae8e2975de94e8549613cyshang  return EFI_NOT_FOUND;
31728a00297189c323096aae8e2975de94e8549613cyshang}
31828a00297189c323096aae8e2975de94e8549613cyshang
31928a00297189c323096aae8e2975de94e8549613cyshang
32028a00297189c323096aae8e2975de94e8549613cyshangEFI_DXESERVICE
32128a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS
32228a00297189c323096aae8e2975de94e8549613cyshangEFIAPI
32328a00297189c323096aae8e2975de94e8549613cyshangCoreTrust (
32428a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE  FirmwareVolumeHandle,
32528a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID    *DriverName
32628a00297189c323096aae8e2975de94e8549613cyshang  )
32728a00297189c323096aae8e2975de94e8549613cyshang/*++
32828a00297189c323096aae8e2975de94e8549613cyshang
32928a00297189c323096aae8e2975de94e8549613cyshangRoutine Description:
33028a00297189c323096aae8e2975de94e8549613cyshang
33128a00297189c323096aae8e2975de94e8549613cyshang  Convert a driver from the Untrused back to the Scheduled state
33228a00297189c323096aae8e2975de94e8549613cyshang
33328a00297189c323096aae8e2975de94e8549613cyshangArguments:
33428a00297189c323096aae8e2975de94e8549613cyshang
33528a00297189c323096aae8e2975de94e8549613cyshang  FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware
33628a00297189c323096aae8e2975de94e8549613cyshang                         file specified by DriverName.
33728a00297189c323096aae8e2975de94e8549613cyshang
33828a00297189c323096aae8e2975de94e8549613cyshang  DriverName           - The Driver name to put in the Scheduled state
33928a00297189c323096aae8e2975de94e8549613cyshang
34028a00297189c323096aae8e2975de94e8549613cyshangReturns:
34128a00297189c323096aae8e2975de94e8549613cyshang
34228a00297189c323096aae8e2975de94e8549613cyshang  EFI_SUCCESS   - The file was found in the untrusted state, and it was promoted
34328a00297189c323096aae8e2975de94e8549613cyshang                  to the trusted state.
34428a00297189c323096aae8e2975de94e8549613cyshang
34528a00297189c323096aae8e2975de94e8549613cyshang  EFI_NOT_FOUND - The file was not found in the untrusted state.
34628a00297189c323096aae8e2975de94e8549613cyshang
34728a00297189c323096aae8e2975de94e8549613cyshang--*/
34828a00297189c323096aae8e2975de94e8549613cyshang{
34928a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY            *Link;
35028a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY *DriverEntry;
35128a00297189c323096aae8e2975de94e8549613cyshang
35228a00297189c323096aae8e2975de94e8549613cyshang  //
35328a00297189c323096aae8e2975de94e8549613cyshang  // Check every driver
35428a00297189c323096aae8e2975de94e8549613cyshang  //
35528a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
35628a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
35728a00297189c323096aae8e2975de94e8549613cyshang    if (DriverEntry->FvHandle == FirmwareVolumeHandle &&
35828a00297189c323096aae8e2975de94e8549613cyshang        DriverEntry->Untrusted &&
35928a00297189c323096aae8e2975de94e8549613cyshang        CompareGuid (DriverName, &DriverEntry->FileName)) {
36028a00297189c323096aae8e2975de94e8549613cyshang      //
36128a00297189c323096aae8e2975de94e8549613cyshang      // Transition driver from Untrusted to Scheduled state.
36228a00297189c323096aae8e2975de94e8549613cyshang      //
36328a00297189c323096aae8e2975de94e8549613cyshang      CoreAcquireDispatcherLock ();
36428a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Untrusted = FALSE;
36528a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Scheduled = TRUE;
36628a00297189c323096aae8e2975de94e8549613cyshang      InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
36728a00297189c323096aae8e2975de94e8549613cyshang      CoreReleaseDispatcherLock ();
36828a00297189c323096aae8e2975de94e8549613cyshang
36928a00297189c323096aae8e2975de94e8549613cyshang      return EFI_SUCCESS;
37028a00297189c323096aae8e2975de94e8549613cyshang    }
37128a00297189c323096aae8e2975de94e8549613cyshang  }
37228a00297189c323096aae8e2975de94e8549613cyshang  return EFI_NOT_FOUND;
37328a00297189c323096aae8e2975de94e8549613cyshang}
37428a00297189c323096aae8e2975de94e8549613cyshang
37528a00297189c323096aae8e2975de94e8549613cyshang
37628a00297189c323096aae8e2975de94e8549613cyshangEFI_DXESERVICE
37728a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS
37828a00297189c323096aae8e2975de94e8549613cyshangEFIAPI
37928a00297189c323096aae8e2975de94e8549613cyshangCoreDispatcher (
38028a00297189c323096aae8e2975de94e8549613cyshang  VOID
38128a00297189c323096aae8e2975de94e8549613cyshang  )
38228a00297189c323096aae8e2975de94e8549613cyshang/*++
38328a00297189c323096aae8e2975de94e8549613cyshang
38428a00297189c323096aae8e2975de94e8549613cyshangRoutine Description:
38528a00297189c323096aae8e2975de94e8549613cyshang
38628a00297189c323096aae8e2975de94e8549613cyshang  This is the main Dispatcher for DXE and it exits when there are no more
38728a00297189c323096aae8e2975de94e8549613cyshang  drivers to run. Drain the mScheduledQueue and load and start a PE
38828a00297189c323096aae8e2975de94e8549613cyshang  image for each driver. Search the mDiscoveredList to see if any driver can
38928a00297189c323096aae8e2975de94e8549613cyshang  be placed on the mScheduledQueue. If no drivers are placed on the
39028a00297189c323096aae8e2975de94e8549613cyshang  mScheduledQueue exit the function. On exit it is assumed the Bds()
39128a00297189c323096aae8e2975de94e8549613cyshang  will be called, and when the Bds() exits the Dispatcher will be called
39228a00297189c323096aae8e2975de94e8549613cyshang  again.
39328a00297189c323096aae8e2975de94e8549613cyshang
39428a00297189c323096aae8e2975de94e8549613cyshangArguments:
39528a00297189c323096aae8e2975de94e8549613cyshang
39628a00297189c323096aae8e2975de94e8549613cyshang  NONE
39728a00297189c323096aae8e2975de94e8549613cyshang
39828a00297189c323096aae8e2975de94e8549613cyshangReturns:
39928a00297189c323096aae8e2975de94e8549613cyshang
40028a00297189c323096aae8e2975de94e8549613cyshang  EFI_ALREADY_STARTED - The DXE Dispatcher is already running
40128a00297189c323096aae8e2975de94e8549613cyshang
40228a00297189c323096aae8e2975de94e8549613cyshang  EFI_NOT_FOUND       - No DXE Drivers were dispatched
40328a00297189c323096aae8e2975de94e8549613cyshang
40428a00297189c323096aae8e2975de94e8549613cyshang  EFI_SUCCESS         - One or more DXE Drivers were dispatched
40528a00297189c323096aae8e2975de94e8549613cyshang
40628a00297189c323096aae8e2975de94e8549613cyshang--*/
40728a00297189c323096aae8e2975de94e8549613cyshang{
40828a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                      Status;
40928a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                      ReturnStatus;
41028a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY                      *Link;
41128a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY           *DriverEntry;
41228a00297189c323096aae8e2975de94e8549613cyshang  BOOLEAN                         ReadyToRun;
41328a00297189c323096aae8e2975de94e8549613cyshang
41428a00297189c323096aae8e2975de94e8549613cyshang  if (gDispatcherRunning) {
41528a00297189c323096aae8e2975de94e8549613cyshang    //
41628a00297189c323096aae8e2975de94e8549613cyshang    // If the dispatcher is running don't let it be restarted.
41728a00297189c323096aae8e2975de94e8549613cyshang    //
41828a00297189c323096aae8e2975de94e8549613cyshang    return EFI_ALREADY_STARTED;
41928a00297189c323096aae8e2975de94e8549613cyshang  }
42028a00297189c323096aae8e2975de94e8549613cyshang
42128a00297189c323096aae8e2975de94e8549613cyshang  gDispatcherRunning = TRUE;
42228a00297189c323096aae8e2975de94e8549613cyshang
42328a00297189c323096aae8e2975de94e8549613cyshang
42428a00297189c323096aae8e2975de94e8549613cyshang  ReturnStatus = EFI_NOT_FOUND;
42528a00297189c323096aae8e2975de94e8549613cyshang  do {
42628a00297189c323096aae8e2975de94e8549613cyshang    //
42728a00297189c323096aae8e2975de94e8549613cyshang    // Drain the Scheduled Queue
42828a00297189c323096aae8e2975de94e8549613cyshang    //
42928a00297189c323096aae8e2975de94e8549613cyshang    while (!IsListEmpty (&mScheduledQueue)) {
43028a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry = CR (
43128a00297189c323096aae8e2975de94e8549613cyshang                      mScheduledQueue.ForwardLink,
43228a00297189c323096aae8e2975de94e8549613cyshang                      EFI_CORE_DRIVER_ENTRY,
43328a00297189c323096aae8e2975de94e8549613cyshang                      ScheduledLink,
43428a00297189c323096aae8e2975de94e8549613cyshang                      EFI_CORE_DRIVER_ENTRY_SIGNATURE
43528a00297189c323096aae8e2975de94e8549613cyshang                      );
43628a00297189c323096aae8e2975de94e8549613cyshang
43728a00297189c323096aae8e2975de94e8549613cyshang      //
43828a00297189c323096aae8e2975de94e8549613cyshang      // Load the DXE Driver image into memory. If the Driver was transitioned from
43928a00297189c323096aae8e2975de94e8549613cyshang      // Untrused to Scheduled it would have already been loaded so we may need to
44028a00297189c323096aae8e2975de94e8549613cyshang      // skip the LoadImage
44128a00297189c323096aae8e2975de94e8549613cyshang      //
44228a00297189c323096aae8e2975de94e8549613cyshang      if (DriverEntry->ImageHandle == NULL) {
44328a00297189c323096aae8e2975de94e8549613cyshang        Status = CoreLoadImage (
44428a00297189c323096aae8e2975de94e8549613cyshang                        FALSE,
44528a00297189c323096aae8e2975de94e8549613cyshang                        gDxeCoreImageHandle,
44628a00297189c323096aae8e2975de94e8549613cyshang                        DriverEntry->FvFileDevicePath,
44728a00297189c323096aae8e2975de94e8549613cyshang                        NULL,
44828a00297189c323096aae8e2975de94e8549613cyshang                        0,
44928a00297189c323096aae8e2975de94e8549613cyshang                        &DriverEntry->ImageHandle
45028a00297189c323096aae8e2975de94e8549613cyshang                        );
45128a00297189c323096aae8e2975de94e8549613cyshang
45228a00297189c323096aae8e2975de94e8549613cyshang        //
45328a00297189c323096aae8e2975de94e8549613cyshang        // Update the driver state to reflect that it's been loaded
45428a00297189c323096aae8e2975de94e8549613cyshang        //
45528a00297189c323096aae8e2975de94e8549613cyshang        if (EFI_ERROR (Status)) {
45628a00297189c323096aae8e2975de94e8549613cyshang          CoreAcquireDispatcherLock ();
45728a00297189c323096aae8e2975de94e8549613cyshang
45828a00297189c323096aae8e2975de94e8549613cyshang          if (Status == EFI_SECURITY_VIOLATION) {
45928a00297189c323096aae8e2975de94e8549613cyshang            //
46028a00297189c323096aae8e2975de94e8549613cyshang            // Take driver from Scheduled to Untrused state
46128a00297189c323096aae8e2975de94e8549613cyshang            //
46228a00297189c323096aae8e2975de94e8549613cyshang            DriverEntry->Untrusted = TRUE;
46328a00297189c323096aae8e2975de94e8549613cyshang          } else {
46428a00297189c323096aae8e2975de94e8549613cyshang            //
46528a00297189c323096aae8e2975de94e8549613cyshang            // The DXE Driver could not be loaded, and do not attempt to load or start it again.
46628a00297189c323096aae8e2975de94e8549613cyshang            // Take driver from Scheduled to Initialized.
46728a00297189c323096aae8e2975de94e8549613cyshang            //
46828a00297189c323096aae8e2975de94e8549613cyshang            // This case include the Never Trusted state if EFI_ACCESS_DENIED is returned
46928a00297189c323096aae8e2975de94e8549613cyshang            //
47028a00297189c323096aae8e2975de94e8549613cyshang            DriverEntry->Initialized  = TRUE;
47128a00297189c323096aae8e2975de94e8549613cyshang          }
47228a00297189c323096aae8e2975de94e8549613cyshang
47328a00297189c323096aae8e2975de94e8549613cyshang          DriverEntry->Scheduled = FALSE;
47428a00297189c323096aae8e2975de94e8549613cyshang          RemoveEntryList (&DriverEntry->ScheduledLink);
47528a00297189c323096aae8e2975de94e8549613cyshang
47628a00297189c323096aae8e2975de94e8549613cyshang          CoreReleaseDispatcherLock ();
47728a00297189c323096aae8e2975de94e8549613cyshang
47828a00297189c323096aae8e2975de94e8549613cyshang          //
47928a00297189c323096aae8e2975de94e8549613cyshang          // If it's an error don't try the StartImage
48028a00297189c323096aae8e2975de94e8549613cyshang          //
48128a00297189c323096aae8e2975de94e8549613cyshang          continue;
48228a00297189c323096aae8e2975de94e8549613cyshang        }
48328a00297189c323096aae8e2975de94e8549613cyshang      }
48428a00297189c323096aae8e2975de94e8549613cyshang
48528a00297189c323096aae8e2975de94e8549613cyshang      CoreAcquireDispatcherLock ();
48628a00297189c323096aae8e2975de94e8549613cyshang
48728a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Scheduled    = FALSE;
48828a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Initialized  = TRUE;
48928a00297189c323096aae8e2975de94e8549613cyshang      RemoveEntryList (&DriverEntry->ScheduledLink);
49028a00297189c323096aae8e2975de94e8549613cyshang
49128a00297189c323096aae8e2975de94e8549613cyshang      CoreReleaseDispatcherLock ();
49228a00297189c323096aae8e2975de94e8549613cyshang
49328a00297189c323096aae8e2975de94e8549613cyshang      CoreReportProgressCodeSpecific (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN, DriverEntry->ImageHandle);
49428a00297189c323096aae8e2975de94e8549613cyshang      Status = CoreStartImage (DriverEntry->ImageHandle, NULL, NULL);
49528a00297189c323096aae8e2975de94e8549613cyshang      CoreReportProgressCodeSpecific (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END, DriverEntry->ImageHandle);
49628a00297189c323096aae8e2975de94e8549613cyshang
49728a00297189c323096aae8e2975de94e8549613cyshang      ReturnStatus = EFI_SUCCESS;
49828a00297189c323096aae8e2975de94e8549613cyshang    }
49928a00297189c323096aae8e2975de94e8549613cyshang
50028a00297189c323096aae8e2975de94e8549613cyshang    //
50128a00297189c323096aae8e2975de94e8549613cyshang    // Search DriverList for items to place on Scheduled Queue
50228a00297189c323096aae8e2975de94e8549613cyshang    //
50328a00297189c323096aae8e2975de94e8549613cyshang    ReadyToRun = FALSE;
50428a00297189c323096aae8e2975de94e8549613cyshang    for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
50528a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry = CR (Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
50628a00297189c323096aae8e2975de94e8549613cyshang
50728a00297189c323096aae8e2975de94e8549613cyshang      if (DriverEntry->DepexProtocolError){
50828a00297189c323096aae8e2975de94e8549613cyshang        //
50928a00297189c323096aae8e2975de94e8549613cyshang        // If Section Extraction Protocol did not let the Depex be read before retry the read
51028a00297189c323096aae8e2975de94e8549613cyshang        //
51128a00297189c323096aae8e2975de94e8549613cyshang        Status = CoreGetDepexSectionAndPreProccess (DriverEntry);
51228a00297189c323096aae8e2975de94e8549613cyshang      }
51328a00297189c323096aae8e2975de94e8549613cyshang
51428a00297189c323096aae8e2975de94e8549613cyshang      if (DriverEntry->Dependent) {
51528a00297189c323096aae8e2975de94e8549613cyshang        if (CoreIsSchedulable (DriverEntry)) {
51628a00297189c323096aae8e2975de94e8549613cyshang          CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
51728a00297189c323096aae8e2975de94e8549613cyshang          ReadyToRun = TRUE;
51828a00297189c323096aae8e2975de94e8549613cyshang        }
51928a00297189c323096aae8e2975de94e8549613cyshang      }
52028a00297189c323096aae8e2975de94e8549613cyshang    }
52128a00297189c323096aae8e2975de94e8549613cyshang  } while (ReadyToRun);
52228a00297189c323096aae8e2975de94e8549613cyshang
52328a00297189c323096aae8e2975de94e8549613cyshang  gDispatcherRunning = FALSE;
52428a00297189c323096aae8e2975de94e8549613cyshang
52528a00297189c323096aae8e2975de94e8549613cyshang  return ReturnStatus;
52628a00297189c323096aae8e2975de94e8549613cyshang}
52728a00297189c323096aae8e2975de94e8549613cyshang
52828a00297189c323096aae8e2975de94e8549613cyshangSTATIC
52928a00297189c323096aae8e2975de94e8549613cyshangVOID
53028a00297189c323096aae8e2975de94e8549613cyshangCoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
53128a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_CORE_DRIVER_ENTRY   *InsertedDriverEntry
53228a00297189c323096aae8e2975de94e8549613cyshang  )
53328a00297189c323096aae8e2975de94e8549613cyshang/*++
53428a00297189c323096aae8e2975de94e8549613cyshang
53528a00297189c323096aae8e2975de94e8549613cyshangRoutine Description:
53628a00297189c323096aae8e2975de94e8549613cyshang
53728a00297189c323096aae8e2975de94e8549613cyshang  Insert InsertedDriverEntry onto the mScheduledQueue. To do this you
53828a00297189c323096aae8e2975de94e8549613cyshang  must add any driver with a before dependency on InsertedDriverEntry first.
53928a00297189c323096aae8e2975de94e8549613cyshang  You do this by recursively calling this routine. After all the Befores are
54028a00297189c323096aae8e2975de94e8549613cyshang  processed you can add InsertedDriverEntry to the mScheduledQueue.
54128a00297189c323096aae8e2975de94e8549613cyshang  Then you can add any driver with an After dependency on InsertedDriverEntry
54228a00297189c323096aae8e2975de94e8549613cyshang  by recursively calling this routine.
54328a00297189c323096aae8e2975de94e8549613cyshang
54428a00297189c323096aae8e2975de94e8549613cyshangArguments:
54528a00297189c323096aae8e2975de94e8549613cyshang
54628a00297189c323096aae8e2975de94e8549613cyshang  InsertedDriverEntry - The driver to insert on the ScheduledLink Queue
54728a00297189c323096aae8e2975de94e8549613cyshang
54828a00297189c323096aae8e2975de94e8549613cyshangReturns:
54928a00297189c323096aae8e2975de94e8549613cyshang
55028a00297189c323096aae8e2975de94e8549613cyshang  NONE
55128a00297189c323096aae8e2975de94e8549613cyshang
55228a00297189c323096aae8e2975de94e8549613cyshang--*/
55328a00297189c323096aae8e2975de94e8549613cyshang{
55428a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY            *Link;
55528a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY *DriverEntry;
55628a00297189c323096aae8e2975de94e8549613cyshang
55728a00297189c323096aae8e2975de94e8549613cyshang  //
55828a00297189c323096aae8e2975de94e8549613cyshang  // Process Before Dependency
55928a00297189c323096aae8e2975de94e8549613cyshang  //
56028a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
56128a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
56228a00297189c323096aae8e2975de94e8549613cyshang    if (DriverEntry->Before && DriverEntry->Dependent) {
56328a00297189c323096aae8e2975de94e8549613cyshang      if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
56428a00297189c323096aae8e2975de94e8549613cyshang        //
56528a00297189c323096aae8e2975de94e8549613cyshang        // Recursively process BEFORE
56628a00297189c323096aae8e2975de94e8549613cyshang        //
56728a00297189c323096aae8e2975de94e8549613cyshang        CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
56828a00297189c323096aae8e2975de94e8549613cyshang      }
56928a00297189c323096aae8e2975de94e8549613cyshang    }
57028a00297189c323096aae8e2975de94e8549613cyshang  }
57128a00297189c323096aae8e2975de94e8549613cyshang
57228a00297189c323096aae8e2975de94e8549613cyshang  //
57328a00297189c323096aae8e2975de94e8549613cyshang  // Convert driver from Dependent to Scheduled state
57428a00297189c323096aae8e2975de94e8549613cyshang  //
57528a00297189c323096aae8e2975de94e8549613cyshang  CoreAcquireDispatcherLock ();
57628a00297189c323096aae8e2975de94e8549613cyshang
57728a00297189c323096aae8e2975de94e8549613cyshang  InsertedDriverEntry->Dependent = FALSE;
57828a00297189c323096aae8e2975de94e8549613cyshang  InsertedDriverEntry->Scheduled = TRUE;
57928a00297189c323096aae8e2975de94e8549613cyshang  InsertTailList (&mScheduledQueue, &InsertedDriverEntry->ScheduledLink);
58028a00297189c323096aae8e2975de94e8549613cyshang
58128a00297189c323096aae8e2975de94e8549613cyshang  CoreReleaseDispatcherLock ();
58228a00297189c323096aae8e2975de94e8549613cyshang
58328a00297189c323096aae8e2975de94e8549613cyshang  //
58428a00297189c323096aae8e2975de94e8549613cyshang  // Process After Dependency
58528a00297189c323096aae8e2975de94e8549613cyshang  //
58628a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
58728a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
58828a00297189c323096aae8e2975de94e8549613cyshang    if (DriverEntry->After && DriverEntry->Dependent) {
58928a00297189c323096aae8e2975de94e8549613cyshang      if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
59028a00297189c323096aae8e2975de94e8549613cyshang        //
59128a00297189c323096aae8e2975de94e8549613cyshang        // Recursively process AFTER
59228a00297189c323096aae8e2975de94e8549613cyshang        //
59328a00297189c323096aae8e2975de94e8549613cyshang        CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
59428a00297189c323096aae8e2975de94e8549613cyshang      }
59528a00297189c323096aae8e2975de94e8549613cyshang    }
59628a00297189c323096aae8e2975de94e8549613cyshang  }
59728a00297189c323096aae8e2975de94e8549613cyshang}
59828a00297189c323096aae8e2975de94e8549613cyshang
59928a00297189c323096aae8e2975de94e8549613cyshangSTATIC
60028a00297189c323096aae8e2975de94e8549613cyshangBOOLEAN
60128a00297189c323096aae8e2975de94e8549613cyshangFvHasBeenProcessed (
60228a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE      FvHandle
60328a00297189c323096aae8e2975de94e8549613cyshang  )
60428a00297189c323096aae8e2975de94e8549613cyshang/*++
60528a00297189c323096aae8e2975de94e8549613cyshang
60628a00297189c323096aae8e2975de94e8549613cyshangRoutine Description:
60728a00297189c323096aae8e2975de94e8549613cyshang
60828a00297189c323096aae8e2975de94e8549613cyshang  Return TRUE if the Fv has been processed, FALSE if not.
60928a00297189c323096aae8e2975de94e8549613cyshang
61028a00297189c323096aae8e2975de94e8549613cyshangArguments:
61128a00297189c323096aae8e2975de94e8549613cyshang
61228a00297189c323096aae8e2975de94e8549613cyshang  FvHandle - The handle of a FV that's being tested
61328a00297189c323096aae8e2975de94e8549613cyshang
61428a00297189c323096aae8e2975de94e8549613cyshangReturns:
61528a00297189c323096aae8e2975de94e8549613cyshang
61628a00297189c323096aae8e2975de94e8549613cyshang  TRUE  - Fv protocol on FvHandle has been processed
61728a00297189c323096aae8e2975de94e8549613cyshang
61828a00297189c323096aae8e2975de94e8549613cyshang  FALSE - Fv protocol on FvHandle has not yet been processed
61928a00297189c323096aae8e2975de94e8549613cyshang
62028a00297189c323096aae8e2975de94e8549613cyshang--*/
62128a00297189c323096aae8e2975de94e8549613cyshang{
62228a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY      *Link;
62328a00297189c323096aae8e2975de94e8549613cyshang  KNOWN_HANDLE    *KnownHandle;
62428a00297189c323096aae8e2975de94e8549613cyshang
62528a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) {
62628a00297189c323096aae8e2975de94e8549613cyshang    KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE);
62728a00297189c323096aae8e2975de94e8549613cyshang    if (KnownHandle->Handle == FvHandle) {
62828a00297189c323096aae8e2975de94e8549613cyshang      return TRUE;
62928a00297189c323096aae8e2975de94e8549613cyshang    }
63028a00297189c323096aae8e2975de94e8549613cyshang  }
63128a00297189c323096aae8e2975de94e8549613cyshang  return FALSE;
63228a00297189c323096aae8e2975de94e8549613cyshang}
63328a00297189c323096aae8e2975de94e8549613cyshang
63428a00297189c323096aae8e2975de94e8549613cyshangSTATIC
63528a00297189c323096aae8e2975de94e8549613cyshangVOID
63628a00297189c323096aae8e2975de94e8549613cyshangFvIsBeingProcesssed (
63728a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE    FvHandle
63828a00297189c323096aae8e2975de94e8549613cyshang  )
63928a00297189c323096aae8e2975de94e8549613cyshang/*++
64028a00297189c323096aae8e2975de94e8549613cyshang
64128a00297189c323096aae8e2975de94e8549613cyshangRoutine Description:
64228a00297189c323096aae8e2975de94e8549613cyshang
64328a00297189c323096aae8e2975de94e8549613cyshang  Remember that Fv protocol on FvHandle has had it's drivers placed on the
64428a00297189c323096aae8e2975de94e8549613cyshang  mDiscoveredList. This fucntion adds entries on the mFvHandleList. Items are
64528a00297189c323096aae8e2975de94e8549613cyshang  never removed/freed from the mFvHandleList.
64628a00297189c323096aae8e2975de94e8549613cyshang
64728a00297189c323096aae8e2975de94e8549613cyshangArguments:
64828a00297189c323096aae8e2975de94e8549613cyshang
64928a00297189c323096aae8e2975de94e8549613cyshang  FvHandle - The handle of a FV that has been processed
65028a00297189c323096aae8e2975de94e8549613cyshang
65128a00297189c323096aae8e2975de94e8549613cyshangReturns:
65228a00297189c323096aae8e2975de94e8549613cyshang
65328a00297189c323096aae8e2975de94e8549613cyshang  None
65428a00297189c323096aae8e2975de94e8549613cyshang
65528a00297189c323096aae8e2975de94e8549613cyshang--*/
65628a00297189c323096aae8e2975de94e8549613cyshang{
65728a00297189c323096aae8e2975de94e8549613cyshang  KNOWN_HANDLE  *KnownHandle;
65828a00297189c323096aae8e2975de94e8549613cyshang
65928a00297189c323096aae8e2975de94e8549613cyshang  KnownHandle = CoreAllocateBootServicesPool (sizeof (KNOWN_HANDLE));
66028a00297189c323096aae8e2975de94e8549613cyshang  ASSERT (KnownHandle != NULL);
66128a00297189c323096aae8e2975de94e8549613cyshang
66228a00297189c323096aae8e2975de94e8549613cyshang  KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE;
66328a00297189c323096aae8e2975de94e8549613cyshang  KnownHandle->Handle = FvHandle;
66428a00297189c323096aae8e2975de94e8549613cyshang  InsertTailList (&mFvHandleList, &KnownHandle->Link);
66528a00297189c323096aae8e2975de94e8549613cyshang}
66628a00297189c323096aae8e2975de94e8549613cyshang
66728a00297189c323096aae8e2975de94e8549613cyshang
66828a00297189c323096aae8e2975de94e8549613cyshang
66928a00297189c323096aae8e2975de94e8549613cyshangSTATIC
67028a00297189c323096aae8e2975de94e8549613cyshangEFI_DEVICE_PATH_PROTOCOL *
67128a00297189c323096aae8e2975de94e8549613cyshangCoreFvToDevicePath (
6720c2b5da80e9551286cd02a92d91090290ae2d816qwang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
67328a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                      FvHandle,
67428a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID                        *DriverName
67528a00297189c323096aae8e2975de94e8549613cyshang  )
67628a00297189c323096aae8e2975de94e8549613cyshang/*++
67728a00297189c323096aae8e2975de94e8549613cyshang
67828a00297189c323096aae8e2975de94e8549613cyshangRoutine Description:
67928a00297189c323096aae8e2975de94e8549613cyshang
68028a00297189c323096aae8e2975de94e8549613cyshang  Convert FvHandle and DriverName into an EFI device path
68128a00297189c323096aae8e2975de94e8549613cyshang
68228a00297189c323096aae8e2975de94e8549613cyshangArguments:
68328a00297189c323096aae8e2975de94e8549613cyshang
68428a00297189c323096aae8e2975de94e8549613cyshang  Fv         - Fv protocol, needed to read Depex info out of FLASH.
68528a00297189c323096aae8e2975de94e8549613cyshang
68628a00297189c323096aae8e2975de94e8549613cyshang  FvHandle   - Handle for Fv, needed in the EFI_CORE_DRIVER_ENTRY so that the
68728a00297189c323096aae8e2975de94e8549613cyshang               PE image can be read out of the FV at a later time.
68828a00297189c323096aae8e2975de94e8549613cyshang
68928a00297189c323096aae8e2975de94e8549613cyshang  DriverName - Name of driver to add to mDiscoveredList.
69028a00297189c323096aae8e2975de94e8549613cyshang
69128a00297189c323096aae8e2975de94e8549613cyshangReturns:
69228a00297189c323096aae8e2975de94e8549613cyshang
69328a00297189c323096aae8e2975de94e8549613cyshang  Pointer to device path constructed from FvHandle and DriverName
69428a00297189c323096aae8e2975de94e8549613cyshang
69528a00297189c323096aae8e2975de94e8549613cyshang--*/
69628a00297189c323096aae8e2975de94e8549613cyshang{
69728a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                          Status;
69828a00297189c323096aae8e2975de94e8549613cyshang  EFI_DEVICE_PATH_PROTOCOL            *FvDevicePath;
69928a00297189c323096aae8e2975de94e8549613cyshang  EFI_DEVICE_PATH_PROTOCOL            *FileNameDevicePath;
70028a00297189c323096aae8e2975de94e8549613cyshang
70128a00297189c323096aae8e2975de94e8549613cyshang  //
70228a00297189c323096aae8e2975de94e8549613cyshang  // Remember the device path of the FV
70328a00297189c323096aae8e2975de94e8549613cyshang  //
70428a00297189c323096aae8e2975de94e8549613cyshang  Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
70528a00297189c323096aae8e2975de94e8549613cyshang  if (EFI_ERROR (Status)) {
70628a00297189c323096aae8e2975de94e8549613cyshang    FileNameDevicePath = NULL;
70728a00297189c323096aae8e2975de94e8549613cyshang  } else {
70828a00297189c323096aae8e2975de94e8549613cyshang    //
70928a00297189c323096aae8e2975de94e8549613cyshang    // Build a device path to the file in the FV to pass into gBS->LoadImage
71028a00297189c323096aae8e2975de94e8549613cyshang    //
71128a00297189c323096aae8e2975de94e8549613cyshang    EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, DriverName);
71228a00297189c323096aae8e2975de94e8549613cyshang    mFvDevicePath.End.Type = EFI_END_ENTIRE_DEVICE_PATH;
71328a00297189c323096aae8e2975de94e8549613cyshang    mFvDevicePath.End.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
71428a00297189c323096aae8e2975de94e8549613cyshang    SetDevicePathNodeLength (&mFvDevicePath.End, sizeof (EFI_DEVICE_PATH_PROTOCOL));
71528a00297189c323096aae8e2975de94e8549613cyshang
71628a00297189c323096aae8e2975de94e8549613cyshang    FileNameDevicePath = CoreAppendDevicePath (
71728a00297189c323096aae8e2975de94e8549613cyshang                            FvDevicePath,
71828a00297189c323096aae8e2975de94e8549613cyshang                            (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
71928a00297189c323096aae8e2975de94e8549613cyshang                            );
72028a00297189c323096aae8e2975de94e8549613cyshang  }
72128a00297189c323096aae8e2975de94e8549613cyshang
72228a00297189c323096aae8e2975de94e8549613cyshang  return FileNameDevicePath;
72328a00297189c323096aae8e2975de94e8549613cyshang}
72428a00297189c323096aae8e2975de94e8549613cyshang
72528a00297189c323096aae8e2975de94e8549613cyshang
72628a00297189c323096aae8e2975de94e8549613cyshang
72728a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS
72828a00297189c323096aae8e2975de94e8549613cyshangCoreAddToDriverList (
7290c2b5da80e9551286cd02a92d91090290ae2d816qwang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
73028a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                      FvHandle,
73128a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID                        *DriverName
73228a00297189c323096aae8e2975de94e8549613cyshang  )
73328a00297189c323096aae8e2975de94e8549613cyshang/*++
73428a00297189c323096aae8e2975de94e8549613cyshang
73528a00297189c323096aae8e2975de94e8549613cyshangRoutine Description:
73628a00297189c323096aae8e2975de94e8549613cyshang
73728a00297189c323096aae8e2975de94e8549613cyshang  Add an entry to the mDiscoveredList. Allocate memory to store the DriverEntry,
73828a00297189c323096aae8e2975de94e8549613cyshang  and initilize any state variables. Read the Depex from the FV and store it
73928a00297189c323096aae8e2975de94e8549613cyshang  in DriverEntry. Pre-process the Depex to set the SOR, Before and After state.
74028a00297189c323096aae8e2975de94e8549613cyshang  The Discovered list is never free'ed and contains booleans that represent the
74128a00297189c323096aae8e2975de94e8549613cyshang  other possible DXE driver states.
74228a00297189c323096aae8e2975de94e8549613cyshang
74328a00297189c323096aae8e2975de94e8549613cyshangArguments:
74428a00297189c323096aae8e2975de94e8549613cyshang
74528a00297189c323096aae8e2975de94e8549613cyshang  Fv         - Fv protocol, needed to read Depex info out of FLASH.
74628a00297189c323096aae8e2975de94e8549613cyshang
74728a00297189c323096aae8e2975de94e8549613cyshang  FvHandle   - Handle for Fv, needed in the EFI_CORE_DRIVER_ENTRY so that the
74828a00297189c323096aae8e2975de94e8549613cyshang               PE image can be read out of the FV at a later time.
74928a00297189c323096aae8e2975de94e8549613cyshang
75028a00297189c323096aae8e2975de94e8549613cyshang  DriverName - Name of driver to add to mDiscoveredList.
75128a00297189c323096aae8e2975de94e8549613cyshang
75228a00297189c323096aae8e2975de94e8549613cyshangReturns:
75328a00297189c323096aae8e2975de94e8549613cyshang
75428a00297189c323096aae8e2975de94e8549613cyshang  EFI_SUCCESS - If driver was added to the mDiscoveredList.
75528a00297189c323096aae8e2975de94e8549613cyshang
75628a00297189c323096aae8e2975de94e8549613cyshang  EFI_ALREADY_STARTED - The driver has already been started. Only one DriverName
75728a00297189c323096aae8e2975de94e8549613cyshang                        may be active in the system at any one time.
75828a00297189c323096aae8e2975de94e8549613cyshang
75928a00297189c323096aae8e2975de94e8549613cyshang--*/
76028a00297189c323096aae8e2975de94e8549613cyshang{
76128a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY               *DriverEntry;
76228a00297189c323096aae8e2975de94e8549613cyshang
76328a00297189c323096aae8e2975de94e8549613cyshang
76428a00297189c323096aae8e2975de94e8549613cyshang  //
76528a00297189c323096aae8e2975de94e8549613cyshang  // Create the Driver Entry for the list. ZeroPool initializes lots of variables to
76628a00297189c323096aae8e2975de94e8549613cyshang  // NULL or FALSE.
76728a00297189c323096aae8e2975de94e8549613cyshang  //
76828a00297189c323096aae8e2975de94e8549613cyshang  DriverEntry = CoreAllocateZeroBootServicesPool (sizeof (EFI_CORE_DRIVER_ENTRY));
76928a00297189c323096aae8e2975de94e8549613cyshang  ASSERT (DriverEntry != NULL);
77028a00297189c323096aae8e2975de94e8549613cyshang
77128a00297189c323096aae8e2975de94e8549613cyshang  DriverEntry->Signature        = EFI_CORE_DRIVER_ENTRY_SIGNATURE;
77228a00297189c323096aae8e2975de94e8549613cyshang  CopyMem (&DriverEntry->FileName, DriverName, sizeof (EFI_GUID));
77328a00297189c323096aae8e2975de94e8549613cyshang  DriverEntry->FvHandle         = FvHandle;
77428a00297189c323096aae8e2975de94e8549613cyshang  DriverEntry->Fv               = Fv;
77528a00297189c323096aae8e2975de94e8549613cyshang  DriverEntry->FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName);
77628a00297189c323096aae8e2975de94e8549613cyshang
77728a00297189c323096aae8e2975de94e8549613cyshang  CoreGetDepexSectionAndPreProccess (DriverEntry);
77828a00297189c323096aae8e2975de94e8549613cyshang
77928a00297189c323096aae8e2975de94e8549613cyshang  CoreAcquireDispatcherLock ();
78028a00297189c323096aae8e2975de94e8549613cyshang
78128a00297189c323096aae8e2975de94e8549613cyshang  InsertTailList (&mDiscoveredList, &DriverEntry->Link);
78228a00297189c323096aae8e2975de94e8549613cyshang
78328a00297189c323096aae8e2975de94e8549613cyshang  CoreReleaseDispatcherLock ();
78428a00297189c323096aae8e2975de94e8549613cyshang
78528a00297189c323096aae8e2975de94e8549613cyshang  return EFI_SUCCESS;
78628a00297189c323096aae8e2975de94e8549613cyshang}
78728a00297189c323096aae8e2975de94e8549613cyshang
788bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwangSTATIC
789bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwangBOOLEAN
790bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwangFvFoundInHobFv2 (
791bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  IN  EFI_HANDLE                      FvHandle,
792bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  IN  CONST EFI_GUID                  *DriverName
793bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  )
794bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang/*++
795bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
796bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwangRoutine Description:
797bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
798bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  Check if a FV Image type file (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) is
799bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  described by a EFI_HOB_FIRMWARE_VOLUME2 Hob.
800bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
801bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwangArguments:
802bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
803bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  FvHandle    - The handle which FVB protocol installed on.
804bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  DriverName  - The driver guid specified.
805bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
806bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwangReturns:
807bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
808bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  TRUE    - This file is found in a EFI_HOB_FIRMWARE_VOLUME2 Hob.
809bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
810bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  FALSE   - Not found.
811bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
812bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
813bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang--*/
814bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang{
815bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  EFI_PEI_HOB_POINTERS                HobFv2;
816bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
817bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  HobFv2.Raw = GetHobList ();
818bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
819bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {
820bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang    if (CompareGuid (DriverName, &HobFv2.FirmwareVolume2->FileName)) {
821b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return TRUE;
822bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang    }
823bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang    HobFv2.Raw = GET_NEXT_HOB (HobFv2);
824bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  }
825bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
826bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  return FALSE;
827bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang}
82828a00297189c323096aae8e2975de94e8549613cyshang
82928a00297189c323096aae8e2975de94e8549613cyshang
83028a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS
83128a00297189c323096aae8e2975de94e8549613cyshangCoreProcessFvImageFile (
8320c2b5da80e9551286cd02a92d91090290ae2d816qwang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
83328a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                      FvHandle,
83428a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID                        *DriverName
83528a00297189c323096aae8e2975de94e8549613cyshang  )
83628a00297189c323096aae8e2975de94e8549613cyshang/*++
83728a00297189c323096aae8e2975de94e8549613cyshang
83828a00297189c323096aae8e2975de94e8549613cyshangRoutine Description:
83928a00297189c323096aae8e2975de94e8549613cyshang
84028a00297189c323096aae8e2975de94e8549613cyshang  Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.
84128a00297189c323096aae8e2975de94e8549613cyshang
84228a00297189c323096aae8e2975de94e8549613cyshangArguments:
84328a00297189c323096aae8e2975de94e8549613cyshang
84428a00297189c323096aae8e2975de94e8549613cyshang  Fv          - The FIRMWARE_VOLUME protocol installed on the FV.
84528a00297189c323096aae8e2975de94e8549613cyshang  FvHandle    - The handle which FVB protocol installed on.
84628a00297189c323096aae8e2975de94e8549613cyshang  DriverName  - The driver guid specified.
84728a00297189c323096aae8e2975de94e8549613cyshang
84828a00297189c323096aae8e2975de94e8549613cyshangReturns:
84928a00297189c323096aae8e2975de94e8549613cyshang
85028a00297189c323096aae8e2975de94e8549613cyshang  EFI_OUT_OF_RESOURCES    - No enough memory or other resource.
85128a00297189c323096aae8e2975de94e8549613cyshang
85228a00297189c323096aae8e2975de94e8549613cyshang  EFI_VOLUME_CORRUPTED    - Corrupted volume.
85328a00297189c323096aae8e2975de94e8549613cyshang
85428a00297189c323096aae8e2975de94e8549613cyshang  EFI_SUCCESS             - Function successfully returned.
85528a00297189c323096aae8e2975de94e8549613cyshang
85628a00297189c323096aae8e2975de94e8549613cyshang
85728a00297189c323096aae8e2975de94e8549613cyshang--*/
85828a00297189c323096aae8e2975de94e8549613cyshang{
85928a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                          Status;
86028a00297189c323096aae8e2975de94e8549613cyshang  EFI_SECTION_TYPE                    SectionType;
86128a00297189c323096aae8e2975de94e8549613cyshang  UINT32                              AuthenticationStatus;
86228a00297189c323096aae8e2975de94e8549613cyshang  VOID                                *Buffer;
86328a00297189c323096aae8e2975de94e8549613cyshang  UINTN                               BufferSize;
86428a00297189c323096aae8e2975de94e8549613cyshang
86528a00297189c323096aae8e2975de94e8549613cyshang  //
86628a00297189c323096aae8e2975de94e8549613cyshang  // Read the first (and only the first) firmware volume section
86728a00297189c323096aae8e2975de94e8549613cyshang  //
86828a00297189c323096aae8e2975de94e8549613cyshang  SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;
86928a00297189c323096aae8e2975de94e8549613cyshang  Buffer      = NULL;
87028a00297189c323096aae8e2975de94e8549613cyshang  BufferSize  = 0;
87128a00297189c323096aae8e2975de94e8549613cyshang  Status = Fv->ReadSection (
87228a00297189c323096aae8e2975de94e8549613cyshang                Fv,
87328a00297189c323096aae8e2975de94e8549613cyshang                DriverName,
87428a00297189c323096aae8e2975de94e8549613cyshang                SectionType,
87528a00297189c323096aae8e2975de94e8549613cyshang                0,
87628a00297189c323096aae8e2975de94e8549613cyshang                &Buffer,
87728a00297189c323096aae8e2975de94e8549613cyshang                &BufferSize,
87828a00297189c323096aae8e2975de94e8549613cyshang                &AuthenticationStatus
87928a00297189c323096aae8e2975de94e8549613cyshang                );
88028a00297189c323096aae8e2975de94e8549613cyshang  if (!EFI_ERROR (Status)) {
88128a00297189c323096aae8e2975de94e8549613cyshang    //
88228a00297189c323096aae8e2975de94e8549613cyshang    // Produce a FVB protocol for the file
88328a00297189c323096aae8e2975de94e8549613cyshang    //
88428a00297189c323096aae8e2975de94e8549613cyshang    Status = ProduceFVBProtocolOnBuffer (
88528a00297189c323096aae8e2975de94e8549613cyshang              (EFI_PHYSICAL_ADDRESS) (UINTN) Buffer,
88628a00297189c323096aae8e2975de94e8549613cyshang              (UINT64)BufferSize,
88728a00297189c323096aae8e2975de94e8549613cyshang              FvHandle,
88828a00297189c323096aae8e2975de94e8549613cyshang              NULL
88928a00297189c323096aae8e2975de94e8549613cyshang              );
89028a00297189c323096aae8e2975de94e8549613cyshang  }
89128a00297189c323096aae8e2975de94e8549613cyshang
89228a00297189c323096aae8e2975de94e8549613cyshang  if (EFI_ERROR (Status) && (Buffer != NULL)) {
89328a00297189c323096aae8e2975de94e8549613cyshang  //
89428a00297189c323096aae8e2975de94e8549613cyshang  // ReadSection or Produce FVB failed, Free data buffer
89528a00297189c323096aae8e2975de94e8549613cyshang  //
89628a00297189c323096aae8e2975de94e8549613cyshang  CoreFreePool (Buffer);
89728a00297189c323096aae8e2975de94e8549613cyshang
89828a00297189c323096aae8e2975de94e8549613cyshang  }
89928a00297189c323096aae8e2975de94e8549613cyshang
90028a00297189c323096aae8e2975de94e8549613cyshang  return Status;
90128a00297189c323096aae8e2975de94e8549613cyshang}
90228a00297189c323096aae8e2975de94e8549613cyshang
90328a00297189c323096aae8e2975de94e8549613cyshangSTATIC
90428a00297189c323096aae8e2975de94e8549613cyshangVOID
90528a00297189c323096aae8e2975de94e8549613cyshangEFIAPI
90628a00297189c323096aae8e2975de94e8549613cyshangCoreFwVolEventProtocolNotify (
90728a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_EVENT       Event,
90828a00297189c323096aae8e2975de94e8549613cyshang  IN  VOID            *Context
90928a00297189c323096aae8e2975de94e8549613cyshang  )
91028a00297189c323096aae8e2975de94e8549613cyshang/*++
91128a00297189c323096aae8e2975de94e8549613cyshang
91228a00297189c323096aae8e2975de94e8549613cyshangRoutine Description:
91328a00297189c323096aae8e2975de94e8549613cyshang
91428a00297189c323096aae8e2975de94e8549613cyshang  Event notification that is fired every time a FV dispatch protocol is added.
91528a00297189c323096aae8e2975de94e8549613cyshang  More than one protocol may have been added when this event is fired, so you
91628a00297189c323096aae8e2975de94e8549613cyshang  must loop on CoreLocateHandle () to see how many protocols were added and
91728a00297189c323096aae8e2975de94e8549613cyshang  do the following to each FV:
91828a00297189c323096aae8e2975de94e8549613cyshang
91928a00297189c323096aae8e2975de94e8549613cyshang  If the Fv has already been processed, skip it. If the Fv has not been
92028a00297189c323096aae8e2975de94e8549613cyshang  processed then mark it as being processed, as we are about to process it.
92128a00297189c323096aae8e2975de94e8549613cyshang
92228a00297189c323096aae8e2975de94e8549613cyshang  Read the Fv and add any driver in the Fv to the mDiscoveredList.The
92328a00297189c323096aae8e2975de94e8549613cyshang  mDiscoveredList is never free'ed and contains variables that define
92428a00297189c323096aae8e2975de94e8549613cyshang  the other states the DXE driver transitions to..
92528a00297189c323096aae8e2975de94e8549613cyshang
92628a00297189c323096aae8e2975de94e8549613cyshang  While you are at it read the A Priori file into memory.
92728a00297189c323096aae8e2975de94e8549613cyshang  Place drivers in the A Priori list onto the mScheduledQueue.
92828a00297189c323096aae8e2975de94e8549613cyshang
92928a00297189c323096aae8e2975de94e8549613cyshangArguments:
93028a00297189c323096aae8e2975de94e8549613cyshang
93128a00297189c323096aae8e2975de94e8549613cyshang  Event   - The Event that is being processed, not used.
93228a00297189c323096aae8e2975de94e8549613cyshang
93328a00297189c323096aae8e2975de94e8549613cyshang  Context - Event Context, not used.
93428a00297189c323096aae8e2975de94e8549613cyshang
93528a00297189c323096aae8e2975de94e8549613cyshangReturns:
93628a00297189c323096aae8e2975de94e8549613cyshang
93728a00297189c323096aae8e2975de94e8549613cyshang  None
93828a00297189c323096aae8e2975de94e8549613cyshang
93928a00297189c323096aae8e2975de94e8549613cyshang--*/
94028a00297189c323096aae8e2975de94e8549613cyshang{
94128a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                    Status;
94228a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                    GetNextFileStatus;
94328a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                    SecurityStatus;
9440c2b5da80e9551286cd02a92d91090290ae2d816qwang  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
94528a00297189c323096aae8e2975de94e8549613cyshang  EFI_DEVICE_PATH_PROTOCOL      *FvDevicePath;
94628a00297189c323096aae8e2975de94e8549613cyshang  EFI_HANDLE                    FvHandle;
94728a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         BufferSize;
94828a00297189c323096aae8e2975de94e8549613cyshang  EFI_GUID                      NameGuid;
94928a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         Key;
95028a00297189c323096aae8e2975de94e8549613cyshang  EFI_FV_FILETYPE               Type;
95128a00297189c323096aae8e2975de94e8549613cyshang  EFI_FV_FILE_ATTRIBUTES        Attributes;
95228a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         Size;
95328a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY         *DriverEntry;
95428a00297189c323096aae8e2975de94e8549613cyshang  EFI_GUID                      *AprioriFile;
95528a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         AprioriEntryCount;
95628a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         Index;
95728a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY                    *Link;
95828a00297189c323096aae8e2975de94e8549613cyshang  UINT32                        AuthenticationStatus;
95928a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         SizeOfBuffer;
96028a00297189c323096aae8e2975de94e8549613cyshang
96128a00297189c323096aae8e2975de94e8549613cyshang
96228a00297189c323096aae8e2975de94e8549613cyshang  while (TRUE) {
96328a00297189c323096aae8e2975de94e8549613cyshang    BufferSize = sizeof (EFI_HANDLE);
96428a00297189c323096aae8e2975de94e8549613cyshang    Status = CoreLocateHandle (
96528a00297189c323096aae8e2975de94e8549613cyshang                    ByRegisterNotify,
96628a00297189c323096aae8e2975de94e8549613cyshang                    NULL,
96728a00297189c323096aae8e2975de94e8549613cyshang                    mFwVolEventRegistration,
96828a00297189c323096aae8e2975de94e8549613cyshang                    &BufferSize,
96928a00297189c323096aae8e2975de94e8549613cyshang                    &FvHandle
97028a00297189c323096aae8e2975de94e8549613cyshang                    );
97128a00297189c323096aae8e2975de94e8549613cyshang    if (EFI_ERROR (Status)) {
97228a00297189c323096aae8e2975de94e8549613cyshang      //
97328a00297189c323096aae8e2975de94e8549613cyshang      // If no more notification events exit
97428a00297189c323096aae8e2975de94e8549613cyshang      //
97528a00297189c323096aae8e2975de94e8549613cyshang      return;
97628a00297189c323096aae8e2975de94e8549613cyshang    }
97728a00297189c323096aae8e2975de94e8549613cyshang
97828a00297189c323096aae8e2975de94e8549613cyshang    if (FvHasBeenProcessed (FvHandle)) {
97928a00297189c323096aae8e2975de94e8549613cyshang      //
98028a00297189c323096aae8e2975de94e8549613cyshang      // This Fv has already been processed so lets skip it!
98128a00297189c323096aae8e2975de94e8549613cyshang      //
98228a00297189c323096aae8e2975de94e8549613cyshang      continue;
98328a00297189c323096aae8e2975de94e8549613cyshang    }
98428a00297189c323096aae8e2975de94e8549613cyshang
98528a00297189c323096aae8e2975de94e8549613cyshang    Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeDispatchProtocolGuid, (VOID **)&Fv);
98628a00297189c323096aae8e2975de94e8549613cyshang    if (EFI_ERROR (Status)) {
98728a00297189c323096aae8e2975de94e8549613cyshang      //
98828a00297189c323096aae8e2975de94e8549613cyshang      // If no dispatch protocol then skip, but do not marked as being processed as it
98928a00297189c323096aae8e2975de94e8549613cyshang      // may show up later.
99028a00297189c323096aae8e2975de94e8549613cyshang      //
99128a00297189c323096aae8e2975de94e8549613cyshang      continue;
99228a00297189c323096aae8e2975de94e8549613cyshang    }
99328a00297189c323096aae8e2975de94e8549613cyshang
99428a00297189c323096aae8e2975de94e8549613cyshang    //
99528a00297189c323096aae8e2975de94e8549613cyshang    // Since we are about to process this Fv mark it as processed.
99628a00297189c323096aae8e2975de94e8549613cyshang    //
99728a00297189c323096aae8e2975de94e8549613cyshang    FvIsBeingProcesssed (FvHandle);
99828a00297189c323096aae8e2975de94e8549613cyshang
99928a00297189c323096aae8e2975de94e8549613cyshang
10000c2b5da80e9551286cd02a92d91090290ae2d816qwang    Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);
100128a00297189c323096aae8e2975de94e8549613cyshang    if (EFI_ERROR (Status)) {
100228a00297189c323096aae8e2975de94e8549613cyshang      //
100328a00297189c323096aae8e2975de94e8549613cyshang      // The Handle has a FirmwareVolumeDispatch protocol and should also contiain
100428a00297189c323096aae8e2975de94e8549613cyshang      // a FirmwareVolume protocol thus we should never get here.
100528a00297189c323096aae8e2975de94e8549613cyshang      //
100628a00297189c323096aae8e2975de94e8549613cyshang      ASSERT (FALSE);
100728a00297189c323096aae8e2975de94e8549613cyshang      continue;
100828a00297189c323096aae8e2975de94e8549613cyshang    }
100928a00297189c323096aae8e2975de94e8549613cyshang
101028a00297189c323096aae8e2975de94e8549613cyshang    Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
101128a00297189c323096aae8e2975de94e8549613cyshang    if (EFI_ERROR (Status)) {
101228a00297189c323096aae8e2975de94e8549613cyshang      //
101328a00297189c323096aae8e2975de94e8549613cyshang      // The Firmware volume doesn't have device path, can't be dispatched.
101428a00297189c323096aae8e2975de94e8549613cyshang      //
101528a00297189c323096aae8e2975de94e8549613cyshang      continue;
101628a00297189c323096aae8e2975de94e8549613cyshang    }
101728a00297189c323096aae8e2975de94e8549613cyshang
101828a00297189c323096aae8e2975de94e8549613cyshang    //
101928a00297189c323096aae8e2975de94e8549613cyshang    // Evaluate the authentication status of the Firmware Volume through
102028a00297189c323096aae8e2975de94e8549613cyshang    // Security Architectural Protocol
102128a00297189c323096aae8e2975de94e8549613cyshang    //
102228a00297189c323096aae8e2975de94e8549613cyshang    if (gSecurity != NULL) {
102328a00297189c323096aae8e2975de94e8549613cyshang      SecurityStatus = gSecurity->FileAuthenticationState (
102428a00297189c323096aae8e2975de94e8549613cyshang                                    gSecurity,
102528a00297189c323096aae8e2975de94e8549613cyshang                                    0,
102628a00297189c323096aae8e2975de94e8549613cyshang                                    FvDevicePath
102728a00297189c323096aae8e2975de94e8549613cyshang                                    );
102828a00297189c323096aae8e2975de94e8549613cyshang      if (SecurityStatus != EFI_SUCCESS) {
102928a00297189c323096aae8e2975de94e8549613cyshang        //
103028a00297189c323096aae8e2975de94e8549613cyshang        // Security check failed. The firmware volume should not be used for any purpose.
103128a00297189c323096aae8e2975de94e8549613cyshang        //
103228a00297189c323096aae8e2975de94e8549613cyshang        continue;
103328a00297189c323096aae8e2975de94e8549613cyshang      }
103428a00297189c323096aae8e2975de94e8549613cyshang    }
103528a00297189c323096aae8e2975de94e8549613cyshang
103628a00297189c323096aae8e2975de94e8549613cyshang    //
103728a00297189c323096aae8e2975de94e8549613cyshang    // Discover Drivers in FV and add them to the Discovered Driver List.
103828a00297189c323096aae8e2975de94e8549613cyshang    // Process EFI_FV_FILETYPE_DRIVER type and then EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
103928a00297189c323096aae8e2975de94e8549613cyshang    //  EFI_FV_FILETYPE_DXE_CORE is processed to produce a Loaded Image protocol for the core
104028a00297189c323096aae8e2975de94e8549613cyshang    //  EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE is processed to create a Fvb
104128a00297189c323096aae8e2975de94e8549613cyshang    //
104228a00297189c323096aae8e2975de94e8549613cyshang    for (Index = 0; Index < sizeof (mDxeFileTypes)/sizeof (EFI_FV_FILETYPE); Index++) {
104328a00297189c323096aae8e2975de94e8549613cyshang      //
104428a00297189c323096aae8e2975de94e8549613cyshang      // Initialize the search key
104528a00297189c323096aae8e2975de94e8549613cyshang      //
104628a00297189c323096aae8e2975de94e8549613cyshang      Key = 0;
104728a00297189c323096aae8e2975de94e8549613cyshang      do {
104828a00297189c323096aae8e2975de94e8549613cyshang        Type = mDxeFileTypes[Index];
104928a00297189c323096aae8e2975de94e8549613cyshang        GetNextFileStatus = Fv->GetNextFile (
105028a00297189c323096aae8e2975de94e8549613cyshang                                  Fv,
105128a00297189c323096aae8e2975de94e8549613cyshang                                  &Key,
105228a00297189c323096aae8e2975de94e8549613cyshang                                  &Type,
105328a00297189c323096aae8e2975de94e8549613cyshang                                  &NameGuid,
105428a00297189c323096aae8e2975de94e8549613cyshang                                  &Attributes,
105528a00297189c323096aae8e2975de94e8549613cyshang                                  &Size
105628a00297189c323096aae8e2975de94e8549613cyshang                                  );
105728a00297189c323096aae8e2975de94e8549613cyshang        if (!EFI_ERROR (GetNextFileStatus)) {
105828a00297189c323096aae8e2975de94e8549613cyshang          if (Type == EFI_FV_FILETYPE_DXE_CORE) {
105928a00297189c323096aae8e2975de94e8549613cyshang            //
106028a00297189c323096aae8e2975de94e8549613cyshang            // If this is the DXE core fill in it's DevicePath & DeviceHandle
106128a00297189c323096aae8e2975de94e8549613cyshang            //
106228a00297189c323096aae8e2975de94e8549613cyshang            if (gDxeCoreLoadedImage->FilePath == NULL) {
106328a00297189c323096aae8e2975de94e8549613cyshang              if (CompareGuid (&NameGuid, gDxeCoreFileName)) {
106428a00297189c323096aae8e2975de94e8549613cyshang                //
106528a00297189c323096aae8e2975de94e8549613cyshang                // Maybe One specail Fv cantains only one DXE_CORE module, so its device path must
106628a00297189c323096aae8e2975de94e8549613cyshang                // be initialized completely.
106728a00297189c323096aae8e2975de94e8549613cyshang                //
106828a00297189c323096aae8e2975de94e8549613cyshang                EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid);
106928a00297189c323096aae8e2975de94e8549613cyshang                mFvDevicePath.End.Type = EFI_END_ENTIRE_DEVICE_PATH;
107028a00297189c323096aae8e2975de94e8549613cyshang                mFvDevicePath.End.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
107128a00297189c323096aae8e2975de94e8549613cyshang                SetDevicePathNodeLength (&mFvDevicePath.End, sizeof (EFI_DEVICE_PATH_PROTOCOL));
107228a00297189c323096aae8e2975de94e8549613cyshang
107328a00297189c323096aae8e2975de94e8549613cyshang                gDxeCoreLoadedImage->FilePath = CoreDuplicateDevicePath (
107428a00297189c323096aae8e2975de94e8549613cyshang                                                  (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
107528a00297189c323096aae8e2975de94e8549613cyshang                                                  );
107628a00297189c323096aae8e2975de94e8549613cyshang                gDxeCoreLoadedImage->DeviceHandle = FvHandle;
107728a00297189c323096aae8e2975de94e8549613cyshang              }
107828a00297189c323096aae8e2975de94e8549613cyshang            }
107928a00297189c323096aae8e2975de94e8549613cyshang          } else if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
108028a00297189c323096aae8e2975de94e8549613cyshang            //
1081bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang            // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
1082bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang            // been extracted.
1083bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang            //
1084bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang            if (FvFoundInHobFv2 (FvHandle, &NameGuid)) {
1085bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang              continue;
1086bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang            }
1087bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
1088bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang            //
108928a00297189c323096aae8e2975de94e8549613cyshang            // Found a firmware volume image. Produce a firmware volume block
109028a00297189c323096aae8e2975de94e8549613cyshang            // protocol for it so it gets dispatched from. This is usually a
109128a00297189c323096aae8e2975de94e8549613cyshang            // capsule.
109228a00297189c323096aae8e2975de94e8549613cyshang            //
109328a00297189c323096aae8e2975de94e8549613cyshang            CoreProcessFvImageFile (Fv, FvHandle, &NameGuid);
109428a00297189c323096aae8e2975de94e8549613cyshang          } else {
109528a00297189c323096aae8e2975de94e8549613cyshang            //
109628a00297189c323096aae8e2975de94e8549613cyshang            // Transition driver from Undiscovered to Discovered state
109728a00297189c323096aae8e2975de94e8549613cyshang            //
109828a00297189c323096aae8e2975de94e8549613cyshang            CoreAddToDriverList (Fv, FvHandle, &NameGuid);
109928a00297189c323096aae8e2975de94e8549613cyshang          }
110028a00297189c323096aae8e2975de94e8549613cyshang        }
110128a00297189c323096aae8e2975de94e8549613cyshang      } while (!EFI_ERROR (GetNextFileStatus));
110228a00297189c323096aae8e2975de94e8549613cyshang    }
110328a00297189c323096aae8e2975de94e8549613cyshang
110428a00297189c323096aae8e2975de94e8549613cyshang    //
110528a00297189c323096aae8e2975de94e8549613cyshang    // Read the array of GUIDs from the Apriori file if it is present in the firmware volume
110628a00297189c323096aae8e2975de94e8549613cyshang    //
110728a00297189c323096aae8e2975de94e8549613cyshang    AprioriFile = NULL;
110828a00297189c323096aae8e2975de94e8549613cyshang    Status = Fv->ReadSection (
110928a00297189c323096aae8e2975de94e8549613cyshang                  Fv,
111028a00297189c323096aae8e2975de94e8549613cyshang                  &gAprioriGuid,
111128a00297189c323096aae8e2975de94e8549613cyshang                  EFI_SECTION_RAW,
111228a00297189c323096aae8e2975de94e8549613cyshang                  0,
111328a00297189c323096aae8e2975de94e8549613cyshang                  (VOID **)&AprioriFile,
111428a00297189c323096aae8e2975de94e8549613cyshang                  &SizeOfBuffer,
111528a00297189c323096aae8e2975de94e8549613cyshang                  &AuthenticationStatus
111628a00297189c323096aae8e2975de94e8549613cyshang                  );
111728a00297189c323096aae8e2975de94e8549613cyshang    if (!EFI_ERROR (Status)) {
111828a00297189c323096aae8e2975de94e8549613cyshang      AprioriEntryCount = SizeOfBuffer / sizeof (EFI_GUID);
111928a00297189c323096aae8e2975de94e8549613cyshang    } else {
112028a00297189c323096aae8e2975de94e8549613cyshang      AprioriEntryCount = 0;
112128a00297189c323096aae8e2975de94e8549613cyshang    }
112228a00297189c323096aae8e2975de94e8549613cyshang
112328a00297189c323096aae8e2975de94e8549613cyshang    //
112428a00297189c323096aae8e2975de94e8549613cyshang    // Put drivers on Apriori List on the Scheduled queue. The Discovered List includes
112528a00297189c323096aae8e2975de94e8549613cyshang    // drivers not in the current FV and these must be skipped since the a priori list
112628a00297189c323096aae8e2975de94e8549613cyshang    // is only valid for the FV that it resided in.
112728a00297189c323096aae8e2975de94e8549613cyshang    //
112828a00297189c323096aae8e2975de94e8549613cyshang    CoreAcquireDispatcherLock ();
112928a00297189c323096aae8e2975de94e8549613cyshang
113028a00297189c323096aae8e2975de94e8549613cyshang    for (Index = 0; Index < AprioriEntryCount; Index++) {
113128a00297189c323096aae8e2975de94e8549613cyshang      for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
113228a00297189c323096aae8e2975de94e8549613cyshang        DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
113328a00297189c323096aae8e2975de94e8549613cyshang        if (CompareGuid (&DriverEntry->FileName, &AprioriFile[Index]) &&
113428a00297189c323096aae8e2975de94e8549613cyshang            (FvHandle == DriverEntry->FvHandle)) {
113528a00297189c323096aae8e2975de94e8549613cyshang          DriverEntry->Dependent = FALSE;
113628a00297189c323096aae8e2975de94e8549613cyshang          DriverEntry->Scheduled = TRUE;
113728a00297189c323096aae8e2975de94e8549613cyshang          InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
113828a00297189c323096aae8e2975de94e8549613cyshang          break;
113928a00297189c323096aae8e2975de94e8549613cyshang        }
114028a00297189c323096aae8e2975de94e8549613cyshang      }
114128a00297189c323096aae8e2975de94e8549613cyshang    }
114228a00297189c323096aae8e2975de94e8549613cyshang
114328a00297189c323096aae8e2975de94e8549613cyshang    CoreReleaseDispatcherLock ();
114428a00297189c323096aae8e2975de94e8549613cyshang
114528a00297189c323096aae8e2975de94e8549613cyshang    //
114628a00297189c323096aae8e2975de94e8549613cyshang    // Free data allocated by Fv->ReadSection ()
114728a00297189c323096aae8e2975de94e8549613cyshang    //
114828a00297189c323096aae8e2975de94e8549613cyshang    CoreFreePool (AprioriFile);
114928a00297189c323096aae8e2975de94e8549613cyshang  }
115028a00297189c323096aae8e2975de94e8549613cyshang}
115128a00297189c323096aae8e2975de94e8549613cyshang
115228a00297189c323096aae8e2975de94e8549613cyshang
115328a00297189c323096aae8e2975de94e8549613cyshangVOID
115428a00297189c323096aae8e2975de94e8549613cyshangCoreInitializeDispatcher (
115528a00297189c323096aae8e2975de94e8549613cyshang  VOID
115628a00297189c323096aae8e2975de94e8549613cyshang  )
115728a00297189c323096aae8e2975de94e8549613cyshang/*++
115828a00297189c323096aae8e2975de94e8549613cyshang
115928a00297189c323096aae8e2975de94e8549613cyshangRoutine Description:
116028a00297189c323096aae8e2975de94e8549613cyshang
116128a00297189c323096aae8e2975de94e8549613cyshang  Initialize the dispatcher. Initialize the notification function that runs when
116228a00297189c323096aae8e2975de94e8549613cyshang  a FV protocol is added to the system.
116328a00297189c323096aae8e2975de94e8549613cyshang
116428a00297189c323096aae8e2975de94e8549613cyshangArguments:
116528a00297189c323096aae8e2975de94e8549613cyshang
116628a00297189c323096aae8e2975de94e8549613cyshang  NONE
116728a00297189c323096aae8e2975de94e8549613cyshang
116828a00297189c323096aae8e2975de94e8549613cyshangReturns:
116928a00297189c323096aae8e2975de94e8549613cyshang
117028a00297189c323096aae8e2975de94e8549613cyshang  NONE
117128a00297189c323096aae8e2975de94e8549613cyshang
117228a00297189c323096aae8e2975de94e8549613cyshang--*/
117328a00297189c323096aae8e2975de94e8549613cyshang{
117428a00297189c323096aae8e2975de94e8549613cyshang  mFwVolEvent = CoreCreateProtocolNotifyEvent (
11750c2b5da80e9551286cd02a92d91090290ae2d816qwang                  &gEfiFirmwareVolume2ProtocolGuid,
117628a00297189c323096aae8e2975de94e8549613cyshang                  TPL_CALLBACK,
117728a00297189c323096aae8e2975de94e8549613cyshang                  CoreFwVolEventProtocolNotify,
117828a00297189c323096aae8e2975de94e8549613cyshang                  NULL,
117928a00297189c323096aae8e2975de94e8549613cyshang                  &mFwVolEventRegistration,
118028a00297189c323096aae8e2975de94e8549613cyshang                  TRUE
118128a00297189c323096aae8e2975de94e8549613cyshang                  );
118228a00297189c323096aae8e2975de94e8549613cyshang}
118328a00297189c323096aae8e2975de94e8549613cyshang
118428a00297189c323096aae8e2975de94e8549613cyshang//
118528a00297189c323096aae8e2975de94e8549613cyshang// Function only used in debug builds
118628a00297189c323096aae8e2975de94e8549613cyshang//
118728a00297189c323096aae8e2975de94e8549613cyshangVOID
118828a00297189c323096aae8e2975de94e8549613cyshangCoreDisplayDiscoveredNotDispatched (
118928a00297189c323096aae8e2975de94e8549613cyshang  VOID
119028a00297189c323096aae8e2975de94e8549613cyshang  )
119128a00297189c323096aae8e2975de94e8549613cyshang/*++
119228a00297189c323096aae8e2975de94e8549613cyshang
119328a00297189c323096aae8e2975de94e8549613cyshangRoutine Description:
119428a00297189c323096aae8e2975de94e8549613cyshang
119528a00297189c323096aae8e2975de94e8549613cyshang  Traverse the discovered list for any drivers that were discovered but not loaded
119628a00297189c323096aae8e2975de94e8549613cyshang  because the dependency experessions evaluated to false
119728a00297189c323096aae8e2975de94e8549613cyshang
119828a00297189c323096aae8e2975de94e8549613cyshangArguments:
119928a00297189c323096aae8e2975de94e8549613cyshang
120028a00297189c323096aae8e2975de94e8549613cyshang  NONE
120128a00297189c323096aae8e2975de94e8549613cyshang
120228a00297189c323096aae8e2975de94e8549613cyshangReturns:
120328a00297189c323096aae8e2975de94e8549613cyshang
120428a00297189c323096aae8e2975de94e8549613cyshang  NONE
120528a00297189c323096aae8e2975de94e8549613cyshang
120628a00297189c323096aae8e2975de94e8549613cyshang--*/
120728a00297189c323096aae8e2975de94e8549613cyshang{
120828a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY                    *Link;
120928a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY         *DriverEntry;
121028a00297189c323096aae8e2975de94e8549613cyshang
121128a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mDiscoveredList.ForwardLink;Link !=&mDiscoveredList; Link = Link->ForwardLink) {
121228a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
121328a00297189c323096aae8e2975de94e8549613cyshang    if (DriverEntry->Dependent) {
121428a00297189c323096aae8e2975de94e8549613cyshang      DEBUG ((EFI_D_LOAD, "Driver %g was discovered but not loaded!!\n", &DriverEntry->FileName));
121528a00297189c323096aae8e2975de94e8549613cyshang    }
121628a00297189c323096aae8e2975de94e8549613cyshang  }
121728a00297189c323096aae8e2975de94e8549613cyshang}
1218