Dispatcher.c revision cd5ebaa06dca3e6ef3c464081e6defe00d358c69
1162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** @file
2797a9d6791a7529c20c7b10f2843e9f38ed5a6a5klu  DXE Dispatcher.
328a00297189c323096aae8e2975de94e8549613cyshang
428a00297189c323096aae8e2975de94e8549613cyshang  Step #1 - When a FV protocol is added to the system every driver in the FV
5022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang            is added to the mDiscoveredList. The SOR, Before, and After Depex are
6022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang            pre-processed as drivers are added to the mDiscoveredList. If an Apriori
7022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang            file exists in the FV those drivers are addeded to the
8022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang            mScheduledQueue. The mFvHandleList is used to make sure a
928a00297189c323096aae8e2975de94e8549613cyshang            FV is only processed once.
1028a00297189c323096aae8e2975de94e8549613cyshang
1128a00297189c323096aae8e2975de94e8549613cyshang  Step #2 - Dispatch. Remove driver from the mScheduledQueue and load and
12022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang            start it. After mScheduledQueue is drained check the
13022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang            mDiscoveredList to see if any item has a Depex that is ready to
1428a00297189c323096aae8e2975de94e8549613cyshang            be placed on the mScheduledQueue.
1528a00297189c323096aae8e2975de94e8549613cyshang
16022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  Step #3 - Adding to the mScheduledQueue requires that you process Before
1728a00297189c323096aae8e2975de94e8549613cyshang            and After dependencies. This is done recursively as the call to add
18022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang            to the mScheduledQueue checks for Before and recursively adds
19022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang            all Befores. It then addes the item that was passed in and then
2028a00297189c323096aae8e2975de94e8549613cyshang            processess the After dependecies by recursively calling the routine.
2128a00297189c323096aae8e2975de94e8549613cyshang
2228a00297189c323096aae8e2975de94e8549613cyshang  Dispatcher Rules:
23022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  The rules for the dispatcher are in chapter 10 of the DXE CIS. Figure 10-3
2428a00297189c323096aae8e2975de94e8549613cyshang  is the state diagram for the DXE dispatcher
2528a00297189c323096aae8e2975de94e8549613cyshang
2628a00297189c323096aae8e2975de94e8549613cyshang  Depex - Dependency Expresion.
2728a00297189c323096aae8e2975de94e8549613cyshang  SOR   - Schedule On Request - Don't schedule if this bit is set.
2828a00297189c323096aae8e2975de94e8549613cyshang
29cd5ebaa06dca3e6ef3c464081e6defe00d358c69hhtianCopyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
30cd5ebaa06dca3e6ef3c464081e6defe00d358c69hhtianThis program and the accompanying materials
3123c98c9417908188207408afa3f6901b8aca826aqhuangare licensed and made available under the terms and conditions of the BSD License
3223c98c9417908188207408afa3f6901b8aca826aqhuangwhich accompanies this distribution.  The full text of the license may be found at
3323c98c9417908188207408afa3f6901b8aca826aqhuanghttp://opensource.org/licenses/bsd-license.php
3423c98c9417908188207408afa3f6901b8aca826aqhuang
3523c98c9417908188207408afa3f6901b8aca826aqhuangTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
3623c98c9417908188207408afa3f6901b8aca826aqhuangWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
37797a9d6791a7529c20c7b10f2843e9f38ed5a6a5klu
38797a9d6791a7529c20c7b10f2843e9f38ed5a6a5klu**/
3928a00297189c323096aae8e2975de94e8549613cyshang
409c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang#include "DxeMain.h"
4128a00297189c323096aae8e2975de94e8549613cyshang
4228a00297189c323096aae8e2975de94e8549613cyshang//
4328a00297189c323096aae8e2975de94e8549613cyshang// The Driver List contains one copy of every driver that has been discovered.
4428a00297189c323096aae8e2975de94e8549613cyshang// Items are never removed from the driver list. List of EFI_CORE_DRIVER_ENTRY
4528a00297189c323096aae8e2975de94e8549613cyshang//
46022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangLIST_ENTRY  mDiscoveredList = INITIALIZE_LIST_HEAD_VARIABLE (mDiscoveredList);
4728a00297189c323096aae8e2975de94e8549613cyshang
4828a00297189c323096aae8e2975de94e8549613cyshang//
4928a00297189c323096aae8e2975de94e8549613cyshang// Queue of drivers that are ready to dispatch. This queue is a subset of the
5028a00297189c323096aae8e2975de94e8549613cyshang// mDiscoveredList.list of EFI_CORE_DRIVER_ENTRY.
5128a00297189c323096aae8e2975de94e8549613cyshang//
5228a00297189c323096aae8e2975de94e8549613cyshangLIST_ENTRY  mScheduledQueue = INITIALIZE_LIST_HEAD_VARIABLE (mScheduledQueue);
5328a00297189c323096aae8e2975de94e8549613cyshang
5428a00297189c323096aae8e2975de94e8549613cyshang//
5528a00297189c323096aae8e2975de94e8549613cyshang// List of handles who's Fv's have been parsed and added to the mFwDriverList.
5628a00297189c323096aae8e2975de94e8549613cyshang//
5728a00297189c323096aae8e2975de94e8549613cyshangLIST_ENTRY  mFvHandleList = INITIALIZE_LIST_HEAD_VARIABLE (mFvHandleList);           // list of KNOWN_HANDLE
5828a00297189c323096aae8e2975de94e8549613cyshang
5928a00297189c323096aae8e2975de94e8549613cyshang//
6028a00297189c323096aae8e2975de94e8549613cyshang// Lock for mDiscoveredList, mScheduledQueue, gDispatcherRunning.
6128a00297189c323096aae8e2975de94e8549613cyshang//
6228a00297189c323096aae8e2975de94e8549613cyshangEFI_LOCK  mDispatcherLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL);
6328a00297189c323096aae8e2975de94e8549613cyshang
6428a00297189c323096aae8e2975de94e8549613cyshang
6528a00297189c323096aae8e2975de94e8549613cyshang//
6628a00297189c323096aae8e2975de94e8549613cyshang// Flag for the DXE Dispacher.  TRUE if dispatcher is execuing.
6728a00297189c323096aae8e2975de94e8549613cyshang//
6828a00297189c323096aae8e2975de94e8549613cyshangBOOLEAN  gDispatcherRunning = FALSE;
6928a00297189c323096aae8e2975de94e8549613cyshang
7028a00297189c323096aae8e2975de94e8549613cyshang//
7128a00297189c323096aae8e2975de94e8549613cyshang// Module globals to manage the FwVol registration notification event
7228a00297189c323096aae8e2975de94e8549613cyshang//
7328a00297189c323096aae8e2975de94e8549613cyshangEFI_EVENT       mFwVolEvent;
7428a00297189c323096aae8e2975de94e8549613cyshangVOID            *mFwVolEventRegistration;
7528a00297189c323096aae8e2975de94e8549613cyshang
7628a00297189c323096aae8e2975de94e8549613cyshang//
7728a00297189c323096aae8e2975de94e8549613cyshang// List of file types supported by dispatcher
7828a00297189c323096aae8e2975de94e8549613cyshang//
79022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_FV_FILETYPE mDxeFileTypes[] = {
80022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  EFI_FV_FILETYPE_DRIVER,
81202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  EFI_FV_FILETYPE_COMBINED_SMM_DXE,
82022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER,
8328a00297189c323096aae8e2975de94e8549613cyshang  EFI_FV_FILETYPE_DXE_CORE,
8428a00297189c323096aae8e2975de94e8549613cyshang  EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
8528a00297189c323096aae8e2975de94e8549613cyshang};
8628a00297189c323096aae8e2975de94e8549613cyshang
8728a00297189c323096aae8e2975de94e8549613cyshangtypedef struct {
8828a00297189c323096aae8e2975de94e8549613cyshang  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH   File;
8928a00297189c323096aae8e2975de94e8549613cyshang  EFI_DEVICE_PATH_PROTOCOL            End;
9028a00297189c323096aae8e2975de94e8549613cyshang} FV_FILEPATH_DEVICE_PATH;
9128a00297189c323096aae8e2975de94e8549613cyshang
9228a00297189c323096aae8e2975de94e8549613cyshangFV_FILEPATH_DEVICE_PATH mFvDevicePath;
9328a00297189c323096aae8e2975de94e8549613cyshang
9428a00297189c323096aae8e2975de94e8549613cyshang
9528a00297189c323096aae8e2975de94e8549613cyshang//
9628a00297189c323096aae8e2975de94e8549613cyshang// Function Prototypes
9728a00297189c323096aae8e2975de94e8549613cyshang//
98162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
99162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Insert InsertedDriverEntry onto the mScheduledQueue. To do this you
100162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  must add any driver with a before dependency on InsertedDriverEntry first.
101162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  You do this by recursively calling this routine. After all the Befores are
102162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  processed you can add InsertedDriverEntry to the mScheduledQueue.
103162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Then you can add any driver with an After dependency on InsertedDriverEntry
104162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  by recursively calling this routine.
105162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
106162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @param  InsertedDriverEntry   The driver to insert on the ScheduledLink Queue
107162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
108162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
10928a00297189c323096aae8e2975de94e8549613cyshangVOID
11028a00297189c323096aae8e2975de94e8549613cyshangCoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
11128a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_CORE_DRIVER_ENTRY   *InsertedDriverEntry
11228a00297189c323096aae8e2975de94e8549613cyshang  );
113022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
114162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
115162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Event notification that is fired every time a FV dispatch protocol is added.
116162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  More than one protocol may have been added when this event is fired, so you
117162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  must loop on CoreLocateHandle () to see how many protocols were added and
118162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  do the following to each FV:
119162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  If the Fv has already been processed, skip it. If the Fv has not been
120162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  processed then mark it as being processed, as we are about to process it.
121162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Read the Fv and add any driver in the Fv to the mDiscoveredList.The
122162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  mDiscoveredList is never free'ed and contains variables that define
123162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  the other states the DXE driver transitions to..
124162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  While you are at it read the A Priori file into memory.
125162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Place drivers in the A Priori list onto the mScheduledQueue.
126162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
127022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Event                 The Event that is being processed, not used.
128162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @param  Context               Event Context, not used.
129162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
130162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
13128a00297189c323096aae8e2975de94e8549613cyshangVOID
13228a00297189c323096aae8e2975de94e8549613cyshangEFIAPI
13328a00297189c323096aae8e2975de94e8549613cyshangCoreFwVolEventProtocolNotify (
13428a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_EVENT       Event,
13528a00297189c323096aae8e2975de94e8549613cyshang  IN  VOID            *Context
13628a00297189c323096aae8e2975de94e8549613cyshang  );
13728a00297189c323096aae8e2975de94e8549613cyshang
138162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
139022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  Convert FvHandle and DriverName into an EFI device path
140162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
141022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Fv                    Fv protocol, needed to read Depex info out of
142022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                FLASH.
143022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FvHandle              Handle for Fv, needed in the
144022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                EFI_CORE_DRIVER_ENTRY so that the PE image can be
145022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                read out of the FV at a later time.
146022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            Name of driver to add to mDiscoveredList.
147162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
148162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @return Pointer to device path constructed from FvHandle and DriverName
149162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
150162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
15128a00297189c323096aae8e2975de94e8549613cyshangEFI_DEVICE_PATH_PROTOCOL *
15228a00297189c323096aae8e2975de94e8549613cyshangCoreFvToDevicePath (
1530c2b5da80e9551286cd02a92d91090290ae2d816qwang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
15428a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                      FvHandle,
15528a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID                        *DriverName
15628a00297189c323096aae8e2975de94e8549613cyshang  );
15728a00297189c323096aae8e2975de94e8549613cyshang
158162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
159162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Add an entry to the mDiscoveredList. Allocate memory to store the DriverEntry,
160162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  and initilize any state variables. Read the Depex from the FV and store it
161162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  in DriverEntry. Pre-process the Depex to set the SOR, Before and After state.
162162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  The Discovered list is never free'ed and contains booleans that represent the
163162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  other possible DXE driver states.
164162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
165022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Fv                    Fv protocol, needed to read Depex info out of
166022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                FLASH.
167022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FvHandle              Handle for Fv, needed in the
168022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                EFI_CORE_DRIVER_ENTRY so that the PE image can be
169022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                read out of the FV at a later time.
170022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            Name of driver to add to mDiscoveredList.
171162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
172022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_SUCCESS           If driver was added to the mDiscoveredList.
173022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_ALREADY_STARTED   The driver has already been started. Only one
174022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                DriverName may be active in the system at any one
175162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang                                time.
176162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
177162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
17828a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS
17928a00297189c323096aae8e2975de94e8549613cyshangCoreAddToDriverList (
18023c98c9417908188207408afa3f6901b8aca826aqhuang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
18123c98c9417908188207408afa3f6901b8aca826aqhuang  IN  EFI_HANDLE                      FvHandle,
18223c98c9417908188207408afa3f6901b8aca826aqhuang  IN  EFI_GUID                        *DriverName
18328a00297189c323096aae8e2975de94e8549613cyshang  );
18428a00297189c323096aae8e2975de94e8549613cyshang
185162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
186162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.
187162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
188022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Fv                    The FIRMWARE_VOLUME protocol installed on the FV.
189022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FvHandle              The handle which FVB protocol installed on.
190022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            The driver guid specified.
191162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
192022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_OUT_OF_RESOURCES  No enough memory or other resource.
193022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_VOLUME_CORRUPTED  Corrupted volume.
194162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @retval EFI_SUCCESS           Function successfully returned.
195162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
196162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
197022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_STATUS
19828a00297189c323096aae8e2975de94e8549613cyshangCoreProcessFvImageFile (
1990c2b5da80e9551286cd02a92d91090290ae2d816qwang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
20028a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                      FvHandle,
20128a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID                        *DriverName
20228a00297189c323096aae8e2975de94e8549613cyshang  );
20328a00297189c323096aae8e2975de94e8549613cyshang
204162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
205162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
206162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Enter critical section by gaining lock on mDispatcherLock.
207162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
208162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
20928a00297189c323096aae8e2975de94e8549613cyshangVOID
21028a00297189c323096aae8e2975de94e8549613cyshangCoreAcquireDispatcherLock (
21128a00297189c323096aae8e2975de94e8549613cyshang  VOID
21228a00297189c323096aae8e2975de94e8549613cyshang  )
21328a00297189c323096aae8e2975de94e8549613cyshang{
21428a00297189c323096aae8e2975de94e8549613cyshang  CoreAcquireLock (&mDispatcherLock);
21528a00297189c323096aae8e2975de94e8549613cyshang}
21628a00297189c323096aae8e2975de94e8549613cyshang
217162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
218162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
219162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Exit critical section by releasing lock on mDispatcherLock.
220162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
221162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
22228a00297189c323096aae8e2975de94e8549613cyshangVOID
22328a00297189c323096aae8e2975de94e8549613cyshangCoreReleaseDispatcherLock (
22428a00297189c323096aae8e2975de94e8549613cyshang  VOID
22528a00297189c323096aae8e2975de94e8549613cyshang  )
22628a00297189c323096aae8e2975de94e8549613cyshang{
22728a00297189c323096aae8e2975de94e8549613cyshang  CoreReleaseLock (&mDispatcherLock);
22828a00297189c323096aae8e2975de94e8549613cyshang}
22928a00297189c323096aae8e2975de94e8549613cyshang
23028a00297189c323096aae8e2975de94e8549613cyshang
231162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
23228a00297189c323096aae8e2975de94e8549613cyshang  Read Depex and pre-process the Depex for Before and After. If Section Extraction
23328a00297189c323096aae8e2975de94e8549613cyshang  protocol returns an error via ReadSection defer the reading of the Depex.
23428a00297189c323096aae8e2975de94e8549613cyshang
235022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverEntry           Driver to work on.
23628a00297189c323096aae8e2975de94e8549613cyshang
237022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_SUCCESS           Depex read and preprossesed
238022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_PROTOCOL_ERROR    The section extraction protocol returned an error
239022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                and  Depex reading needs to be retried.
240162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @retval Error                 DEPEX not found.
24128a00297189c323096aae8e2975de94e8549613cyshang
242162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
243162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFI_STATUS
244162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreGetDepexSectionAndPreProccess (
245162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_CORE_DRIVER_ENTRY   *DriverEntry
246162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
24728a00297189c323096aae8e2975de94e8549613cyshang{
24828a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                    Status;
24928a00297189c323096aae8e2975de94e8549613cyshang  EFI_SECTION_TYPE              SectionType;
25028a00297189c323096aae8e2975de94e8549613cyshang  UINT32                        AuthenticationStatus;
2510c2b5da80e9551286cd02a92d91090290ae2d816qwang  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
25228a00297189c323096aae8e2975de94e8549613cyshang
253022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
25428a00297189c323096aae8e2975de94e8549613cyshang  Fv = DriverEntry->Fv;
25528a00297189c323096aae8e2975de94e8549613cyshang
25628a00297189c323096aae8e2975de94e8549613cyshang  //
25728a00297189c323096aae8e2975de94e8549613cyshang  // Grab Depex info, it will never be free'ed.
25828a00297189c323096aae8e2975de94e8549613cyshang  //
25928a00297189c323096aae8e2975de94e8549613cyshang  SectionType         = EFI_SECTION_DXE_DEPEX;
26028a00297189c323096aae8e2975de94e8549613cyshang  Status = Fv->ReadSection (
261022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                DriverEntry->Fv,
26228a00297189c323096aae8e2975de94e8549613cyshang                &DriverEntry->FileName,
263022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                SectionType,
264022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                0,
265022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                &DriverEntry->Depex,
26628a00297189c323096aae8e2975de94e8549613cyshang                (UINTN *)&DriverEntry->DepexSize,
26728a00297189c323096aae8e2975de94e8549613cyshang                &AuthenticationStatus
26828a00297189c323096aae8e2975de94e8549613cyshang                );
26928a00297189c323096aae8e2975de94e8549613cyshang  if (EFI_ERROR (Status)) {
27028a00297189c323096aae8e2975de94e8549613cyshang    if (Status == EFI_PROTOCOL_ERROR) {
27128a00297189c323096aae8e2975de94e8549613cyshang      //
27228a00297189c323096aae8e2975de94e8549613cyshang      // The section extraction protocol failed so set protocol error flag
27328a00297189c323096aae8e2975de94e8549613cyshang      //
27428a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->DepexProtocolError = TRUE;
27528a00297189c323096aae8e2975de94e8549613cyshang    } else {
27628a00297189c323096aae8e2975de94e8549613cyshang      //
2778a7d75b0625cffee0c67b85afe56763f93d86481qhuang      // If no Depex assume UEFI 2.0 driver model
27828a00297189c323096aae8e2975de94e8549613cyshang      //
27928a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Depex = NULL;
28028a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Dependent = TRUE;
28128a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->DepexProtocolError = FALSE;
28228a00297189c323096aae8e2975de94e8549613cyshang    }
28328a00297189c323096aae8e2975de94e8549613cyshang  } else {
28428a00297189c323096aae8e2975de94e8549613cyshang    //
28528a00297189c323096aae8e2975de94e8549613cyshang    // Set Before, After, and Unrequested state information based on Depex
28628a00297189c323096aae8e2975de94e8549613cyshang    // Driver will be put in Dependent or Unrequested state
28728a00297189c323096aae8e2975de94e8549613cyshang    //
28828a00297189c323096aae8e2975de94e8549613cyshang    CorePreProcessDepex (DriverEntry);
28928a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry->DepexProtocolError = FALSE;
290022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  }
29128a00297189c323096aae8e2975de94e8549613cyshang
29228a00297189c323096aae8e2975de94e8549613cyshang  return Status;
29328a00297189c323096aae8e2975de94e8549613cyshang}
29428a00297189c323096aae8e2975de94e8549613cyshang
295162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
296162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
297162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Check every driver and locate a matching one. If the driver is found, the Unrequested
298162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  state flag is cleared.
299162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
300022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FirmwareVolumeHandle  The handle of the Firmware Volume that contains
301022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                the firmware  file specified by DriverName.
302022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            The Driver name to put in the Dependent state.
303162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
304022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_SUCCESS           The DriverName was found and it's SOR bit was
305022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                cleared
306022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_NOT_FOUND         The DriverName does not exist or it's SOR bit was
307022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                not set.
308162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
309162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
31028a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS
31128a00297189c323096aae8e2975de94e8549613cyshangEFIAPI
31228a00297189c323096aae8e2975de94e8549613cyshangCoreSchedule (
31328a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE  FirmwareVolumeHandle,
31428a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID    *DriverName
31528a00297189c323096aae8e2975de94e8549613cyshang  )
31628a00297189c323096aae8e2975de94e8549613cyshang{
31728a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY            *Link;
31828a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY *DriverEntry;
31928a00297189c323096aae8e2975de94e8549613cyshang
32028a00297189c323096aae8e2975de94e8549613cyshang  //
32128a00297189c323096aae8e2975de94e8549613cyshang  // Check every driver
32228a00297189c323096aae8e2975de94e8549613cyshang  //
32328a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
32428a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
32528a00297189c323096aae8e2975de94e8549613cyshang    if (DriverEntry->FvHandle == FirmwareVolumeHandle &&
326022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang        DriverEntry->Unrequested &&
32728a00297189c323096aae8e2975de94e8549613cyshang        CompareGuid (DriverName, &DriverEntry->FileName)) {
32828a00297189c323096aae8e2975de94e8549613cyshang      //
32928a00297189c323096aae8e2975de94e8549613cyshang      // Move the driver from the Unrequested to the Dependent state
33028a00297189c323096aae8e2975de94e8549613cyshang      //
33128a00297189c323096aae8e2975de94e8549613cyshang      CoreAcquireDispatcherLock ();
33228a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Unrequested  = FALSE;
33328a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Dependent    = TRUE;
33428a00297189c323096aae8e2975de94e8549613cyshang      CoreReleaseDispatcherLock ();
335022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
33628a00297189c323096aae8e2975de94e8549613cyshang      return EFI_SUCCESS;
33728a00297189c323096aae8e2975de94e8549613cyshang    }
33828a00297189c323096aae8e2975de94e8549613cyshang  }
339022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  return EFI_NOT_FOUND;
34028a00297189c323096aae8e2975de94e8549613cyshang}
34128a00297189c323096aae8e2975de94e8549613cyshang
34228a00297189c323096aae8e2975de94e8549613cyshang
343162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
344162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
345e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  Convert a driver from the Untrused back to the Scheduled state.
346162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
347022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FirmwareVolumeHandle  The handle of the Firmware Volume that contains
348022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                the firmware  file specified by DriverName.
349022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            The Driver name to put in the Scheduled state
350162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
351022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_SUCCESS           The file was found in the untrusted state, and it
352022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                was promoted  to the trusted state.
353022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_NOT_FOUND         The file was not found in the untrusted state.
354162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
355162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
35628a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS
35728a00297189c323096aae8e2975de94e8549613cyshangEFIAPI
35828a00297189c323096aae8e2975de94e8549613cyshangCoreTrust (
35928a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE  FirmwareVolumeHandle,
36028a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID    *DriverName
36128a00297189c323096aae8e2975de94e8549613cyshang  )
36228a00297189c323096aae8e2975de94e8549613cyshang{
36328a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY            *Link;
36428a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY *DriverEntry;
36528a00297189c323096aae8e2975de94e8549613cyshang
36628a00297189c323096aae8e2975de94e8549613cyshang  //
36728a00297189c323096aae8e2975de94e8549613cyshang  // Check every driver
36828a00297189c323096aae8e2975de94e8549613cyshang  //
36928a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
37028a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
37128a00297189c323096aae8e2975de94e8549613cyshang    if (DriverEntry->FvHandle == FirmwareVolumeHandle &&
372022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang        DriverEntry->Untrusted &&
37328a00297189c323096aae8e2975de94e8549613cyshang        CompareGuid (DriverName, &DriverEntry->FileName)) {
37428a00297189c323096aae8e2975de94e8549613cyshang      //
37528a00297189c323096aae8e2975de94e8549613cyshang      // Transition driver from Untrusted to Scheduled state.
37628a00297189c323096aae8e2975de94e8549613cyshang      //
37728a00297189c323096aae8e2975de94e8549613cyshang      CoreAcquireDispatcherLock ();
37828a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Untrusted = FALSE;
37928a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Scheduled = TRUE;
38028a00297189c323096aae8e2975de94e8549613cyshang      InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
38128a00297189c323096aae8e2975de94e8549613cyshang      CoreReleaseDispatcherLock ();
382022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
38328a00297189c323096aae8e2975de94e8549613cyshang      return EFI_SUCCESS;
38428a00297189c323096aae8e2975de94e8549613cyshang    }
38528a00297189c323096aae8e2975de94e8549613cyshang  }
386022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  return EFI_NOT_FOUND;
38728a00297189c323096aae8e2975de94e8549613cyshang}
38828a00297189c323096aae8e2975de94e8549613cyshang
38928a00297189c323096aae8e2975de94e8549613cyshang
390202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang/**
391202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  An empty function to pass error checking of CreateEventEx ().
392202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang
393202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  @param  Event                 Event whose notification function is being invoked.
394202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  @param  Context               Pointer to the notification function's context,
395202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang                                which is implementation-dependent.
396202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang
397202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang**/
398202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuangVOID
399202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuangEFIAPI
400202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuangEmptyFuntion (
401202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  IN EFI_EVENT                Event,
402202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  IN VOID                     *Context
403202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  )
404202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang{
405202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  return;
406202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang}
40728a00297189c323096aae8e2975de94e8549613cyshang
408162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
409162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  This is the main Dispatcher for DXE and it exits when there are no more
41028a00297189c323096aae8e2975de94e8549613cyshang  drivers to run. Drain the mScheduledQueue and load and start a PE
411162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  image for each driver. Search the mDiscoveredList to see if any driver can
41228a00297189c323096aae8e2975de94e8549613cyshang  be placed on the mScheduledQueue. If no drivers are placed on the
41328a00297189c323096aae8e2975de94e8549613cyshang  mScheduledQueue exit the function. On exit it is assumed the Bds()
414162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  will be called, and when the Bds() exits the Dispatcher will be called
41528a00297189c323096aae8e2975de94e8549613cyshang  again.
41628a00297189c323096aae8e2975de94e8549613cyshang
417022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_ALREADY_STARTED   The DXE Dispatcher is already running
418022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_NOT_FOUND         No DXE Drivers were dispatched
419022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_SUCCESS           One or more DXE Drivers were dispatched
42028a00297189c323096aae8e2975de94e8549613cyshang
421162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
422162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFI_STATUS
423162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFIAPI
424162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreDispatcher (
425162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  VOID
426162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
42728a00297189c323096aae8e2975de94e8549613cyshang{
42828a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                      Status;
42928a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                      ReturnStatus;
43028a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY                      *Link;
43128a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY           *DriverEntry;
43228a00297189c323096aae8e2975de94e8549613cyshang  BOOLEAN                         ReadyToRun;
433202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  EFI_EVENT                       DxeDispatchEvent;
434202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang
43528a00297189c323096aae8e2975de94e8549613cyshang
43628a00297189c323096aae8e2975de94e8549613cyshang  if (gDispatcherRunning) {
43728a00297189c323096aae8e2975de94e8549613cyshang    //
43828a00297189c323096aae8e2975de94e8549613cyshang    // If the dispatcher is running don't let it be restarted.
43928a00297189c323096aae8e2975de94e8549613cyshang    //
44028a00297189c323096aae8e2975de94e8549613cyshang    return EFI_ALREADY_STARTED;
44128a00297189c323096aae8e2975de94e8549613cyshang  }
44228a00297189c323096aae8e2975de94e8549613cyshang
44328a00297189c323096aae8e2975de94e8549613cyshang  gDispatcherRunning = TRUE;
44428a00297189c323096aae8e2975de94e8549613cyshang
445202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  Status = CoreCreateEventEx (
446202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang             EVT_NOTIFY_SIGNAL,
447202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang             TPL_NOTIFY,
448202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang             EmptyFuntion,
449202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang             NULL,
450202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang             &gEfiEventDxeDispatchGuid,
451202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang             &DxeDispatchEvent
452202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang             );
453202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  if (EFI_ERROR (Status)) {
454202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang    return Status;
455202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  }
45628a00297189c323096aae8e2975de94e8549613cyshang
45728a00297189c323096aae8e2975de94e8549613cyshang  ReturnStatus = EFI_NOT_FOUND;
45828a00297189c323096aae8e2975de94e8549613cyshang  do {
45928a00297189c323096aae8e2975de94e8549613cyshang    //
46028a00297189c323096aae8e2975de94e8549613cyshang    // Drain the Scheduled Queue
46128a00297189c323096aae8e2975de94e8549613cyshang    //
46228a00297189c323096aae8e2975de94e8549613cyshang    while (!IsListEmpty (&mScheduledQueue)) {
46328a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry = CR (
46428a00297189c323096aae8e2975de94e8549613cyshang                      mScheduledQueue.ForwardLink,
46528a00297189c323096aae8e2975de94e8549613cyshang                      EFI_CORE_DRIVER_ENTRY,
46628a00297189c323096aae8e2975de94e8549613cyshang                      ScheduledLink,
46728a00297189c323096aae8e2975de94e8549613cyshang                      EFI_CORE_DRIVER_ENTRY_SIGNATURE
46828a00297189c323096aae8e2975de94e8549613cyshang                      );
46928a00297189c323096aae8e2975de94e8549613cyshang
47028a00297189c323096aae8e2975de94e8549613cyshang      //
47128a00297189c323096aae8e2975de94e8549613cyshang      // Load the DXE Driver image into memory. If the Driver was transitioned from
47228a00297189c323096aae8e2975de94e8549613cyshang      // Untrused to Scheduled it would have already been loaded so we may need to
47328a00297189c323096aae8e2975de94e8549613cyshang      // skip the LoadImage
47428a00297189c323096aae8e2975de94e8549613cyshang      //
47528a00297189c323096aae8e2975de94e8549613cyshang      if (DriverEntry->ImageHandle == NULL) {
4769490351076d0e95f46aa177e7643fceb953bbcb8jljusten        DEBUG ((DEBUG_INFO, "Loading driver %g\n", &DriverEntry->FileName));
47728a00297189c323096aae8e2975de94e8549613cyshang        Status = CoreLoadImage (
478022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                        FALSE,
479022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                        gDxeCoreImageHandle,
48028a00297189c323096aae8e2975de94e8549613cyshang                        DriverEntry->FvFileDevicePath,
481022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                        NULL,
482022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                        0,
48328a00297189c323096aae8e2975de94e8549613cyshang                        &DriverEntry->ImageHandle
48428a00297189c323096aae8e2975de94e8549613cyshang                        );
48528a00297189c323096aae8e2975de94e8549613cyshang
48628a00297189c323096aae8e2975de94e8549613cyshang        //
48728a00297189c323096aae8e2975de94e8549613cyshang        // Update the driver state to reflect that it's been loaded
48828a00297189c323096aae8e2975de94e8549613cyshang        //
48928a00297189c323096aae8e2975de94e8549613cyshang        if (EFI_ERROR (Status)) {
49028a00297189c323096aae8e2975de94e8549613cyshang          CoreAcquireDispatcherLock ();
49128a00297189c323096aae8e2975de94e8549613cyshang
49228a00297189c323096aae8e2975de94e8549613cyshang          if (Status == EFI_SECURITY_VIOLATION) {
49328a00297189c323096aae8e2975de94e8549613cyshang            //
49428a00297189c323096aae8e2975de94e8549613cyshang            // Take driver from Scheduled to Untrused state
49528a00297189c323096aae8e2975de94e8549613cyshang            //
49628a00297189c323096aae8e2975de94e8549613cyshang            DriverEntry->Untrusted = TRUE;
49728a00297189c323096aae8e2975de94e8549613cyshang          } else {
49828a00297189c323096aae8e2975de94e8549613cyshang            //
49928a00297189c323096aae8e2975de94e8549613cyshang            // The DXE Driver could not be loaded, and do not attempt to load or start it again.
500022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang            // Take driver from Scheduled to Initialized.
50128a00297189c323096aae8e2975de94e8549613cyshang            //
50228a00297189c323096aae8e2975de94e8549613cyshang            // This case include the Never Trusted state if EFI_ACCESS_DENIED is returned
50328a00297189c323096aae8e2975de94e8549613cyshang            //
50428a00297189c323096aae8e2975de94e8549613cyshang            DriverEntry->Initialized  = TRUE;
50528a00297189c323096aae8e2975de94e8549613cyshang          }
50628a00297189c323096aae8e2975de94e8549613cyshang
50728a00297189c323096aae8e2975de94e8549613cyshang          DriverEntry->Scheduled = FALSE;
50828a00297189c323096aae8e2975de94e8549613cyshang          RemoveEntryList (&DriverEntry->ScheduledLink);
509022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
51028a00297189c323096aae8e2975de94e8549613cyshang          CoreReleaseDispatcherLock ();
511022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
51228a00297189c323096aae8e2975de94e8549613cyshang          //
51328a00297189c323096aae8e2975de94e8549613cyshang          // If it's an error don't try the StartImage
51428a00297189c323096aae8e2975de94e8549613cyshang          //
51528a00297189c323096aae8e2975de94e8549613cyshang          continue;
51628a00297189c323096aae8e2975de94e8549613cyshang        }
51728a00297189c323096aae8e2975de94e8549613cyshang      }
51828a00297189c323096aae8e2975de94e8549613cyshang
51928a00297189c323096aae8e2975de94e8549613cyshang      CoreAcquireDispatcherLock ();
52028a00297189c323096aae8e2975de94e8549613cyshang
52128a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Scheduled    = FALSE;
52228a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Initialized  = TRUE;
52328a00297189c323096aae8e2975de94e8549613cyshang      RemoveEntryList (&DriverEntry->ScheduledLink);
524022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
52528a00297189c323096aae8e2975de94e8549613cyshang      CoreReleaseDispatcherLock ();
52628a00297189c323096aae8e2975de94e8549613cyshang
5272680a308013ecbad9a68599286ee05ddb7afa471qhuang
5282680a308013ecbad9a68599286ee05ddb7afa471qhuang      REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
5292680a308013ecbad9a68599286ee05ddb7afa471qhuang        EFI_PROGRESS_CODE,
530f9876ecf8a296a8e0d4ad8d22ed5ff12ecc11f65xli        (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN),
5312680a308013ecbad9a68599286ee05ddb7afa471qhuang        &DriverEntry->ImageHandle,
5322680a308013ecbad9a68599286ee05ddb7afa471qhuang        sizeof (DriverEntry->ImageHandle)
533797a9d6791a7529c20c7b10f2843e9f38ed5a6a5klu        );
5342680a308013ecbad9a68599286ee05ddb7afa471qhuang
53528a00297189c323096aae8e2975de94e8549613cyshang      Status = CoreStartImage (DriverEntry->ImageHandle, NULL, NULL);
5362680a308013ecbad9a68599286ee05ddb7afa471qhuang
5372680a308013ecbad9a68599286ee05ddb7afa471qhuang      REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
5382680a308013ecbad9a68599286ee05ddb7afa471qhuang        EFI_PROGRESS_CODE,
539f9876ecf8a296a8e0d4ad8d22ed5ff12ecc11f65xli        (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END),
5402680a308013ecbad9a68599286ee05ddb7afa471qhuang        &DriverEntry->ImageHandle,
5412680a308013ecbad9a68599286ee05ddb7afa471qhuang        sizeof (DriverEntry->ImageHandle)
542797a9d6791a7529c20c7b10f2843e9f38ed5a6a5klu        );
54328a00297189c323096aae8e2975de94e8549613cyshang
54428a00297189c323096aae8e2975de94e8549613cyshang      ReturnStatus = EFI_SUCCESS;
54528a00297189c323096aae8e2975de94e8549613cyshang    }
54628a00297189c323096aae8e2975de94e8549613cyshang
54728a00297189c323096aae8e2975de94e8549613cyshang    //
54828a00297189c323096aae8e2975de94e8549613cyshang    // Search DriverList for items to place on Scheduled Queue
54928a00297189c323096aae8e2975de94e8549613cyshang    //
55028a00297189c323096aae8e2975de94e8549613cyshang    ReadyToRun = FALSE;
55128a00297189c323096aae8e2975de94e8549613cyshang    for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
55228a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry = CR (Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
55328a00297189c323096aae8e2975de94e8549613cyshang
55428a00297189c323096aae8e2975de94e8549613cyshang      if (DriverEntry->DepexProtocolError){
55528a00297189c323096aae8e2975de94e8549613cyshang        //
55628a00297189c323096aae8e2975de94e8549613cyshang        // If Section Extraction Protocol did not let the Depex be read before retry the read
55728a00297189c323096aae8e2975de94e8549613cyshang        //
55828a00297189c323096aae8e2975de94e8549613cyshang        Status = CoreGetDepexSectionAndPreProccess (DriverEntry);
559022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang      }
56028a00297189c323096aae8e2975de94e8549613cyshang
56128a00297189c323096aae8e2975de94e8549613cyshang      if (DriverEntry->Dependent) {
56228a00297189c323096aae8e2975de94e8549613cyshang        if (CoreIsSchedulable (DriverEntry)) {
563022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang          CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
56428a00297189c323096aae8e2975de94e8549613cyshang          ReadyToRun = TRUE;
565022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang        }
56628a00297189c323096aae8e2975de94e8549613cyshang      }
56728a00297189c323096aae8e2975de94e8549613cyshang    }
568202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang
569202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang    //
570202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang    // Now DXE Dispatcher finished one round of dispatch, signal an event group
571202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang    // so that SMM Dispatcher get chance to dispatch SMM Drivers which depend
572202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang    // on UEFI protocols
573202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang    //
574202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang    if (!EFI_ERROR (ReturnStatus)) {
575202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang      CoreSignalEvent (DxeDispatchEvent);
576202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang    }
57728a00297189c323096aae8e2975de94e8549613cyshang  } while (ReadyToRun);
57828a00297189c323096aae8e2975de94e8549613cyshang
579202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  //
580202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  // Close DXE dispatch Event
581202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  //
582202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  CoreCloseEvent (DxeDispatchEvent);
583202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang
58428a00297189c323096aae8e2975de94e8549613cyshang  gDispatcherRunning = FALSE;
58528a00297189c323096aae8e2975de94e8549613cyshang
58628a00297189c323096aae8e2975de94e8549613cyshang  return ReturnStatus;
58728a00297189c323096aae8e2975de94e8549613cyshang}
58828a00297189c323096aae8e2975de94e8549613cyshang
58928a00297189c323096aae8e2975de94e8549613cyshang
590162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
591162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Insert InsertedDriverEntry onto the mScheduledQueue. To do this you
59228a00297189c323096aae8e2975de94e8549613cyshang  must add any driver with a before dependency on InsertedDriverEntry first.
59328a00297189c323096aae8e2975de94e8549613cyshang  You do this by recursively calling this routine. After all the Befores are
594162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  processed you can add InsertedDriverEntry to the mScheduledQueue.
595162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Then you can add any driver with an After dependency on InsertedDriverEntry
59628a00297189c323096aae8e2975de94e8549613cyshang  by recursively calling this routine.
59728a00297189c323096aae8e2975de94e8549613cyshang
598162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @param  InsertedDriverEntry   The driver to insert on the ScheduledLink Queue
59928a00297189c323096aae8e2975de94e8549613cyshang
600162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
601162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangVOID
602162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
603162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_CORE_DRIVER_ENTRY   *InsertedDriverEntry
604162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
60528a00297189c323096aae8e2975de94e8549613cyshang{
60628a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY            *Link;
60728a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY *DriverEntry;
60828a00297189c323096aae8e2975de94e8549613cyshang
60928a00297189c323096aae8e2975de94e8549613cyshang  //
61028a00297189c323096aae8e2975de94e8549613cyshang  // Process Before Dependency
61128a00297189c323096aae8e2975de94e8549613cyshang  //
61228a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
61328a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
61428a00297189c323096aae8e2975de94e8549613cyshang    if (DriverEntry->Before && DriverEntry->Dependent) {
61528a00297189c323096aae8e2975de94e8549613cyshang      if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
61628a00297189c323096aae8e2975de94e8549613cyshang        //
61728a00297189c323096aae8e2975de94e8549613cyshang        // Recursively process BEFORE
61828a00297189c323096aae8e2975de94e8549613cyshang        //
61928a00297189c323096aae8e2975de94e8549613cyshang        CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
62028a00297189c323096aae8e2975de94e8549613cyshang      }
62128a00297189c323096aae8e2975de94e8549613cyshang    }
62228a00297189c323096aae8e2975de94e8549613cyshang  }
62328a00297189c323096aae8e2975de94e8549613cyshang
62428a00297189c323096aae8e2975de94e8549613cyshang  //
62528a00297189c323096aae8e2975de94e8549613cyshang  // Convert driver from Dependent to Scheduled state
62628a00297189c323096aae8e2975de94e8549613cyshang  //
62728a00297189c323096aae8e2975de94e8549613cyshang  CoreAcquireDispatcherLock ();
62828a00297189c323096aae8e2975de94e8549613cyshang
62928a00297189c323096aae8e2975de94e8549613cyshang  InsertedDriverEntry->Dependent = FALSE;
63028a00297189c323096aae8e2975de94e8549613cyshang  InsertedDriverEntry->Scheduled = TRUE;
63128a00297189c323096aae8e2975de94e8549613cyshang  InsertTailList (&mScheduledQueue, &InsertedDriverEntry->ScheduledLink);
632022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
63328a00297189c323096aae8e2975de94e8549613cyshang  CoreReleaseDispatcherLock ();
63428a00297189c323096aae8e2975de94e8549613cyshang
63528a00297189c323096aae8e2975de94e8549613cyshang  //
63628a00297189c323096aae8e2975de94e8549613cyshang  // Process After Dependency
63728a00297189c323096aae8e2975de94e8549613cyshang  //
63828a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
63928a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
64028a00297189c323096aae8e2975de94e8549613cyshang    if (DriverEntry->After && DriverEntry->Dependent) {
64128a00297189c323096aae8e2975de94e8549613cyshang      if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
64228a00297189c323096aae8e2975de94e8549613cyshang        //
64328a00297189c323096aae8e2975de94e8549613cyshang        // Recursively process AFTER
64428a00297189c323096aae8e2975de94e8549613cyshang        //
64528a00297189c323096aae8e2975de94e8549613cyshang        CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
64628a00297189c323096aae8e2975de94e8549613cyshang      }
64728a00297189c323096aae8e2975de94e8549613cyshang    }
64828a00297189c323096aae8e2975de94e8549613cyshang  }
64928a00297189c323096aae8e2975de94e8549613cyshang}
65028a00297189c323096aae8e2975de94e8549613cyshang
65128a00297189c323096aae8e2975de94e8549613cyshang
652162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
65328a00297189c323096aae8e2975de94e8549613cyshang  Return TRUE if the Fv has been processed, FALSE if not.
65428a00297189c323096aae8e2975de94e8549613cyshang
655022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FvHandle              The handle of a FV that's being tested
65628a00297189c323096aae8e2975de94e8549613cyshang
657022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval TRUE                  Fv protocol on FvHandle has been processed
658e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  @retval FALSE                 Fv protocol on FvHandle has not yet been processed
65928a00297189c323096aae8e2975de94e8549613cyshang
660162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
661162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangBOOLEAN
662162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangFvHasBeenProcessed (
663162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_HANDLE      FvHandle
664162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
66528a00297189c323096aae8e2975de94e8549613cyshang{
66628a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY      *Link;
66728a00297189c323096aae8e2975de94e8549613cyshang  KNOWN_HANDLE    *KnownHandle;
66828a00297189c323096aae8e2975de94e8549613cyshang
66928a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) {
67028a00297189c323096aae8e2975de94e8549613cyshang    KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE);
67128a00297189c323096aae8e2975de94e8549613cyshang    if (KnownHandle->Handle == FvHandle) {
67228a00297189c323096aae8e2975de94e8549613cyshang      return TRUE;
67328a00297189c323096aae8e2975de94e8549613cyshang    }
67428a00297189c323096aae8e2975de94e8549613cyshang  }
67528a00297189c323096aae8e2975de94e8549613cyshang  return FALSE;
67628a00297189c323096aae8e2975de94e8549613cyshang}
67728a00297189c323096aae8e2975de94e8549613cyshang
67828a00297189c323096aae8e2975de94e8549613cyshang
679162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
68028a00297189c323096aae8e2975de94e8549613cyshang  Remember that Fv protocol on FvHandle has had it's drivers placed on the
68128a00297189c323096aae8e2975de94e8549613cyshang  mDiscoveredList. This fucntion adds entries on the mFvHandleList. Items are
68228a00297189c323096aae8e2975de94e8549613cyshang  never removed/freed from the mFvHandleList.
68328a00297189c323096aae8e2975de94e8549613cyshang
684162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @param  FvHandle              The handle of a FV that has been processed
68528a00297189c323096aae8e2975de94e8549613cyshang
686162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
687162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangVOID
688162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangFvIsBeingProcesssed (
689162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_HANDLE    FvHandle
690162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
69128a00297189c323096aae8e2975de94e8549613cyshang{
69228a00297189c323096aae8e2975de94e8549613cyshang  KNOWN_HANDLE  *KnownHandle;
69328a00297189c323096aae8e2975de94e8549613cyshang
6949c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang  KnownHandle = AllocatePool (sizeof (KNOWN_HANDLE));
69528a00297189c323096aae8e2975de94e8549613cyshang  ASSERT (KnownHandle != NULL);
69628a00297189c323096aae8e2975de94e8549613cyshang
69728a00297189c323096aae8e2975de94e8549613cyshang  KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE;
69828a00297189c323096aae8e2975de94e8549613cyshang  KnownHandle->Handle = FvHandle;
69928a00297189c323096aae8e2975de94e8549613cyshang  InsertTailList (&mFvHandleList, &KnownHandle->Link);
70028a00297189c323096aae8e2975de94e8549613cyshang}
70128a00297189c323096aae8e2975de94e8549613cyshang
70228a00297189c323096aae8e2975de94e8549613cyshang
70328a00297189c323096aae8e2975de94e8549613cyshang
704162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
705162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
706162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Convert FvHandle and DriverName into an EFI device path
707162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
708022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Fv                    Fv protocol, needed to read Depex info out of
709022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                FLASH.
710022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FvHandle              Handle for Fv, needed in the
711022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                EFI_CORE_DRIVER_ENTRY so that the PE image can be
712022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                read out of the FV at a later time.
713022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            Name of driver to add to mDiscoveredList.
714162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
715162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @return Pointer to device path constructed from FvHandle and DriverName
716162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
717162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
71828a00297189c323096aae8e2975de94e8549613cyshangEFI_DEVICE_PATH_PROTOCOL *
71928a00297189c323096aae8e2975de94e8549613cyshangCoreFvToDevicePath (
7200c2b5da80e9551286cd02a92d91090290ae2d816qwang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
72128a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                      FvHandle,
72228a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID                        *DriverName
72328a00297189c323096aae8e2975de94e8549613cyshang  )
72428a00297189c323096aae8e2975de94e8549613cyshang{
72528a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                          Status;
72628a00297189c323096aae8e2975de94e8549613cyshang  EFI_DEVICE_PATH_PROTOCOL            *FvDevicePath;
72728a00297189c323096aae8e2975de94e8549613cyshang  EFI_DEVICE_PATH_PROTOCOL            *FileNameDevicePath;
72828a00297189c323096aae8e2975de94e8549613cyshang
72928a00297189c323096aae8e2975de94e8549613cyshang  //
73028a00297189c323096aae8e2975de94e8549613cyshang  // Remember the device path of the FV
73128a00297189c323096aae8e2975de94e8549613cyshang  //
73228a00297189c323096aae8e2975de94e8549613cyshang  Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
73328a00297189c323096aae8e2975de94e8549613cyshang  if (EFI_ERROR (Status)) {
73428a00297189c323096aae8e2975de94e8549613cyshang    FileNameDevicePath = NULL;
73528a00297189c323096aae8e2975de94e8549613cyshang  } else {
73628a00297189c323096aae8e2975de94e8549613cyshang    //
73728a00297189c323096aae8e2975de94e8549613cyshang    // Build a device path to the file in the FV to pass into gBS->LoadImage
73828a00297189c323096aae8e2975de94e8549613cyshang    //
73928a00297189c323096aae8e2975de94e8549613cyshang    EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, DriverName);
7401232b21473646661a4ac1ae4b7bf5113d4613e83klu    SetDevicePathEndNode (&mFvDevicePath.End);
74128a00297189c323096aae8e2975de94e8549613cyshang
7429c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang    FileNameDevicePath = AppendDevicePath (
743022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                            FvDevicePath,
74428a00297189c323096aae8e2975de94e8549613cyshang                            (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
74528a00297189c323096aae8e2975de94e8549613cyshang                            );
74628a00297189c323096aae8e2975de94e8549613cyshang  }
74728a00297189c323096aae8e2975de94e8549613cyshang
74828a00297189c323096aae8e2975de94e8549613cyshang  return FileNameDevicePath;
74928a00297189c323096aae8e2975de94e8549613cyshang}
75028a00297189c323096aae8e2975de94e8549613cyshang
75128a00297189c323096aae8e2975de94e8549613cyshang
75228a00297189c323096aae8e2975de94e8549613cyshang
753162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
754162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Add an entry to the mDiscoveredList. Allocate memory to store the DriverEntry,
75528a00297189c323096aae8e2975de94e8549613cyshang  and initilize any state variables. Read the Depex from the FV and store it
75628a00297189c323096aae8e2975de94e8549613cyshang  in DriverEntry. Pre-process the Depex to set the SOR, Before and After state.
75728a00297189c323096aae8e2975de94e8549613cyshang  The Discovered list is never free'ed and contains booleans that represent the
75828a00297189c323096aae8e2975de94e8549613cyshang  other possible DXE driver states.
75928a00297189c323096aae8e2975de94e8549613cyshang
760022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Fv                    Fv protocol, needed to read Depex info out of
761022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                FLASH.
762022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FvHandle              Handle for Fv, needed in the
763022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                EFI_CORE_DRIVER_ENTRY so that the PE image can be
764022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                read out of the FV at a later time.
765022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            Name of driver to add to mDiscoveredList.
76628a00297189c323096aae8e2975de94e8549613cyshang
767022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_SUCCESS           If driver was added to the mDiscoveredList.
768022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_ALREADY_STARTED   The driver has already been started. Only one
769022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                DriverName may be active in the system at any one
770162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang                                time.
77128a00297189c323096aae8e2975de94e8549613cyshang
772162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
773162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFI_STATUS
774162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreAddToDriverList (
775162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
776162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_HANDLE                      FvHandle,
777162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_GUID                        *DriverName
778162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
77928a00297189c323096aae8e2975de94e8549613cyshang{
78028a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY               *DriverEntry;
78128a00297189c323096aae8e2975de94e8549613cyshang
782022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
78328a00297189c323096aae8e2975de94e8549613cyshang  //
784022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  // Create the Driver Entry for the list. ZeroPool initializes lots of variables to
78528a00297189c323096aae8e2975de94e8549613cyshang  // NULL or FALSE.
78628a00297189c323096aae8e2975de94e8549613cyshang  //
7879c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang  DriverEntry = AllocateZeroPool (sizeof (EFI_CORE_DRIVER_ENTRY));
78828a00297189c323096aae8e2975de94e8549613cyshang  ASSERT (DriverEntry != NULL);
78928a00297189c323096aae8e2975de94e8549613cyshang
79028a00297189c323096aae8e2975de94e8549613cyshang  DriverEntry->Signature        = EFI_CORE_DRIVER_ENTRY_SIGNATURE;
791e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  CopyGuid (&DriverEntry->FileName, DriverName);
79228a00297189c323096aae8e2975de94e8549613cyshang  DriverEntry->FvHandle         = FvHandle;
79328a00297189c323096aae8e2975de94e8549613cyshang  DriverEntry->Fv               = Fv;
79428a00297189c323096aae8e2975de94e8549613cyshang  DriverEntry->FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName);
79528a00297189c323096aae8e2975de94e8549613cyshang
79628a00297189c323096aae8e2975de94e8549613cyshang  CoreGetDepexSectionAndPreProccess (DriverEntry);
797022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
79828a00297189c323096aae8e2975de94e8549613cyshang  CoreAcquireDispatcherLock ();
799022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
80028a00297189c323096aae8e2975de94e8549613cyshang  InsertTailList (&mDiscoveredList, &DriverEntry->Link);
80128a00297189c323096aae8e2975de94e8549613cyshang
80228a00297189c323096aae8e2975de94e8549613cyshang  CoreReleaseDispatcherLock ();
80328a00297189c323096aae8e2975de94e8549613cyshang
80428a00297189c323096aae8e2975de94e8549613cyshang  return EFI_SUCCESS;
80528a00297189c323096aae8e2975de94e8549613cyshang}
80628a00297189c323096aae8e2975de94e8549613cyshang
807bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
808162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
809bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  Check if a FV Image type file (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) is
810bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  described by a EFI_HOB_FIRMWARE_VOLUME2 Hob.
811bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
812022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FvHandle              The handle which FVB protocol installed on.
813022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            The driver guid specified.
814bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
815022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval TRUE                  This file is found in a EFI_HOB_FIRMWARE_VOLUME2
816022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                Hob.
817162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @retval FALSE                 Not found.
818bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
819162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
820162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangBOOLEAN
821162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangFvFoundInHobFv2 (
822162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_HANDLE                      FvHandle,
823162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  CONST EFI_GUID                  *DriverName
824162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
825bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang{
826bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  EFI_PEI_HOB_POINTERS                HobFv2;
827022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
828bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  HobFv2.Raw = GetHobList ();
829022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
830bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {
831bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang    if (CompareGuid (DriverName, &HobFv2.FirmwareVolume2->FileName)) {
832b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return TRUE;
833bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang    }
834bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang    HobFv2.Raw = GET_NEXT_HOB (HobFv2);
835bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  }
836bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
837bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  return FALSE;
838bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang}
83928a00297189c323096aae8e2975de94e8549613cyshang
84028a00297189c323096aae8e2975de94e8549613cyshang
841162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
842162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
843162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.
844162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
845022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Fv                    The FIRMWARE_VOLUME protocol installed on the FV.
846022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FvHandle              The handle which FVB protocol installed on.
847022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            The driver guid specified.
848162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
849022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_OUT_OF_RESOURCES  No enough memory or other resource.
850022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_VOLUME_CORRUPTED  Corrupted volume.
851162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @retval EFI_SUCCESS           Function successfully returned.
852162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
853162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
854022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_STATUS
85528a00297189c323096aae8e2975de94e8549613cyshangCoreProcessFvImageFile (
8560c2b5da80e9551286cd02a92d91090290ae2d816qwang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
85728a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                      FvHandle,
85828a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID                        *DriverName
85928a00297189c323096aae8e2975de94e8549613cyshang  )
86028a00297189c323096aae8e2975de94e8549613cyshang{
86128a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                          Status;
86228a00297189c323096aae8e2975de94e8549613cyshang  EFI_SECTION_TYPE                    SectionType;
86328a00297189c323096aae8e2975de94e8549613cyshang  UINT32                              AuthenticationStatus;
86428a00297189c323096aae8e2975de94e8549613cyshang  VOID                                *Buffer;
86538837959db04259d0dbfc1ab906330961d5f9d8elgao  VOID                                *AlignedBuffer;
86628a00297189c323096aae8e2975de94e8549613cyshang  UINTN                               BufferSize;
86738837959db04259d0dbfc1ab906330961d5f9d8elgao  EFI_FIRMWARE_VOLUME_HEADER          *FvHeader;
868022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  UINT32                              FvAlignment;
86928a00297189c323096aae8e2975de94e8549613cyshang
87028a00297189c323096aae8e2975de94e8549613cyshang  //
87128a00297189c323096aae8e2975de94e8549613cyshang  // Read the first (and only the first) firmware volume section
87228a00297189c323096aae8e2975de94e8549613cyshang  //
873e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  SectionType   = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;
874e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  FvHeader      = NULL;
875e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  FvAlignment   = 0;
876e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  Buffer        = NULL;
877e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  BufferSize    = 0;
87838837959db04259d0dbfc1ab906330961d5f9d8elgao  AlignedBuffer = NULL;
87928a00297189c323096aae8e2975de94e8549613cyshang  Status = Fv->ReadSection (
880022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                 Fv,
881022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                 DriverName,
882022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                 SectionType,
883022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                 0,
884022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                 &Buffer,
885e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang                 &BufferSize,
886e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang                 &AuthenticationStatus
887e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang                 );
88828a00297189c323096aae8e2975de94e8549613cyshang  if (!EFI_ERROR (Status)) {
88928a00297189c323096aae8e2975de94e8549613cyshang    //
89038837959db04259d0dbfc1ab906330961d5f9d8elgao    // FvImage should be at its required alignment.
89128a00297189c323096aae8e2975de94e8549613cyshang    //
89238837959db04259d0dbfc1ab906330961d5f9d8elgao    FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;
8936d9a0f280d49fd1000fa685ee1392f45ff998e69lgao    //
8946d9a0f280d49fd1000fa685ee1392f45ff998e69lgao    // Get FvHeader alignment
8956d9a0f280d49fd1000fa685ee1392f45ff998e69lgao    //
89638837959db04259d0dbfc1ab906330961d5f9d8elgao    FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);
89738837959db04259d0dbfc1ab906330961d5f9d8elgao    //
8986d9a0f280d49fd1000fa685ee1392f45ff998e69lgao    // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.
899022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang    //
90038837959db04259d0dbfc1ab906330961d5f9d8elgao    if (FvAlignment < 8) {
90138837959db04259d0dbfc1ab906330961d5f9d8elgao      FvAlignment = 8;
90238837959db04259d0dbfc1ab906330961d5f9d8elgao    }
903e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang    //
904e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang    // Allocate the aligned buffer for the FvImage.
905e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang    //
906b2c5e194a80f85c733a57814dece83a4b816f07blgao    AlignedBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment);
90738837959db04259d0dbfc1ab906330961d5f9d8elgao    if (AlignedBuffer == NULL) {
90838837959db04259d0dbfc1ab906330961d5f9d8elgao      Status = EFI_OUT_OF_RESOURCES;
90938837959db04259d0dbfc1ab906330961d5f9d8elgao    } else {
91038837959db04259d0dbfc1ab906330961d5f9d8elgao      //
91138837959db04259d0dbfc1ab906330961d5f9d8elgao      // Move FvImage into the aligned buffer and release the original buffer.
91238837959db04259d0dbfc1ab906330961d5f9d8elgao      //
91338837959db04259d0dbfc1ab906330961d5f9d8elgao      CopyMem (AlignedBuffer, Buffer, BufferSize);
91438837959db04259d0dbfc1ab906330961d5f9d8elgao      CoreFreePool (Buffer);
91538837959db04259d0dbfc1ab906330961d5f9d8elgao      Buffer = NULL;
91638837959db04259d0dbfc1ab906330961d5f9d8elgao      //
91738837959db04259d0dbfc1ab906330961d5f9d8elgao      // Produce a FVB protocol for the file
91838837959db04259d0dbfc1ab906330961d5f9d8elgao      //
91938837959db04259d0dbfc1ab906330961d5f9d8elgao      Status = ProduceFVBProtocolOnBuffer (
92038837959db04259d0dbfc1ab906330961d5f9d8elgao                (EFI_PHYSICAL_ADDRESS) (UINTN) AlignedBuffer,
92138837959db04259d0dbfc1ab906330961d5f9d8elgao                (UINT64)BufferSize,
92238837959db04259d0dbfc1ab906330961d5f9d8elgao                FvHandle,
92338837959db04259d0dbfc1ab906330961d5f9d8elgao                NULL
92438837959db04259d0dbfc1ab906330961d5f9d8elgao                );
92538837959db04259d0dbfc1ab906330961d5f9d8elgao    }
92628a00297189c323096aae8e2975de94e8549613cyshang  }
92728a00297189c323096aae8e2975de94e8549613cyshang
928022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  if (EFI_ERROR (Status)) {
92938837959db04259d0dbfc1ab906330961d5f9d8elgao    //
93038837959db04259d0dbfc1ab906330961d5f9d8elgao    // ReadSection or Produce FVB failed, Free data buffer
93138837959db04259d0dbfc1ab906330961d5f9d8elgao    //
93238837959db04259d0dbfc1ab906330961d5f9d8elgao    if (Buffer != NULL) {
9339c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang      FreePool (Buffer);
93438837959db04259d0dbfc1ab906330961d5f9d8elgao    }
935022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
93638837959db04259d0dbfc1ab906330961d5f9d8elgao    if (AlignedBuffer != NULL) {
937b2c5e194a80f85c733a57814dece83a4b816f07blgao      FreeAlignedPages (AlignedBuffer, EFI_SIZE_TO_PAGES (BufferSize));
93838837959db04259d0dbfc1ab906330961d5f9d8elgao    }
93928a00297189c323096aae8e2975de94e8549613cyshang  }
94028a00297189c323096aae8e2975de94e8549613cyshang
94128a00297189c323096aae8e2975de94e8549613cyshang  return Status;
94228a00297189c323096aae8e2975de94e8549613cyshang}
94328a00297189c323096aae8e2975de94e8549613cyshang
94428a00297189c323096aae8e2975de94e8549613cyshang
945162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
946162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Event notification that is fired every time a FV dispatch protocol is added.
94728a00297189c323096aae8e2975de94e8549613cyshang  More than one protocol may have been added when this event is fired, so you
94828a00297189c323096aae8e2975de94e8549613cyshang  must loop on CoreLocateHandle () to see how many protocols were added and
94928a00297189c323096aae8e2975de94e8549613cyshang  do the following to each FV:
950162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  If the Fv has already been processed, skip it. If the Fv has not been
95128a00297189c323096aae8e2975de94e8549613cyshang  processed then mark it as being processed, as we are about to process it.
952162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Read the Fv and add any driver in the Fv to the mDiscoveredList.The
95328a00297189c323096aae8e2975de94e8549613cyshang  mDiscoveredList is never free'ed and contains variables that define
954162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  the other states the DXE driver transitions to..
95528a00297189c323096aae8e2975de94e8549613cyshang  While you are at it read the A Priori file into memory.
95628a00297189c323096aae8e2975de94e8549613cyshang  Place drivers in the A Priori list onto the mScheduledQueue.
95728a00297189c323096aae8e2975de94e8549613cyshang
958022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Event                 The Event that is being processed, not used.
959162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @param  Context               Event Context, not used.
96028a00297189c323096aae8e2975de94e8549613cyshang
961162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
962162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangVOID
963162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFIAPI
964162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreFwVolEventProtocolNotify (
965162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_EVENT       Event,
966162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  VOID            *Context
967162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
96828a00297189c323096aae8e2975de94e8549613cyshang{
96928a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                    Status;
97028a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                    GetNextFileStatus;
97128a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                    SecurityStatus;
9720c2b5da80e9551286cd02a92d91090290ae2d816qwang  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
97328a00297189c323096aae8e2975de94e8549613cyshang  EFI_DEVICE_PATH_PROTOCOL      *FvDevicePath;
97428a00297189c323096aae8e2975de94e8549613cyshang  EFI_HANDLE                    FvHandle;
97528a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         BufferSize;
97628a00297189c323096aae8e2975de94e8549613cyshang  EFI_GUID                      NameGuid;
97728a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         Key;
97828a00297189c323096aae8e2975de94e8549613cyshang  EFI_FV_FILETYPE               Type;
97928a00297189c323096aae8e2975de94e8549613cyshang  EFI_FV_FILE_ATTRIBUTES        Attributes;
98028a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         Size;
98128a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY         *DriverEntry;
98228a00297189c323096aae8e2975de94e8549613cyshang  EFI_GUID                      *AprioriFile;
98328a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         AprioriEntryCount;
98428a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         Index;
98528a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY                    *Link;
98628a00297189c323096aae8e2975de94e8549613cyshang  UINT32                        AuthenticationStatus;
98728a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         SizeOfBuffer;
98828a00297189c323096aae8e2975de94e8549613cyshang
98928a00297189c323096aae8e2975de94e8549613cyshang
99028a00297189c323096aae8e2975de94e8549613cyshang  while (TRUE) {
99128a00297189c323096aae8e2975de94e8549613cyshang    BufferSize = sizeof (EFI_HANDLE);
99228a00297189c323096aae8e2975de94e8549613cyshang    Status = CoreLocateHandle (
993e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang               ByRegisterNotify,
994e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang               NULL,
995e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang               mFwVolEventRegistration,
996e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang               &BufferSize,
997e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang               &FvHandle
998e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang               );
99928a00297189c323096aae8e2975de94e8549613cyshang    if (EFI_ERROR (Status)) {
100028a00297189c323096aae8e2975de94e8549613cyshang      //
100128a00297189c323096aae8e2975de94e8549613cyshang      // If no more notification events exit
100228a00297189c323096aae8e2975de94e8549613cyshang      //
100328a00297189c323096aae8e2975de94e8549613cyshang      return;
100428a00297189c323096aae8e2975de94e8549613cyshang    }
100528a00297189c323096aae8e2975de94e8549613cyshang
100628a00297189c323096aae8e2975de94e8549613cyshang    if (FvHasBeenProcessed (FvHandle)) {
100728a00297189c323096aae8e2975de94e8549613cyshang      //
100828a00297189c323096aae8e2975de94e8549613cyshang      // This Fv has already been processed so lets skip it!
100928a00297189c323096aae8e2975de94e8549613cyshang      //
101028a00297189c323096aae8e2975de94e8549613cyshang      continue;
101128a00297189c323096aae8e2975de94e8549613cyshang    }
101228a00297189c323096aae8e2975de94e8549613cyshang
101328a00297189c323096aae8e2975de94e8549613cyshang    //
101428a00297189c323096aae8e2975de94e8549613cyshang    // Since we are about to process this Fv mark it as processed.
101528a00297189c323096aae8e2975de94e8549613cyshang    //
101628a00297189c323096aae8e2975de94e8549613cyshang    FvIsBeingProcesssed (FvHandle);
101728a00297189c323096aae8e2975de94e8549613cyshang
10180c2b5da80e9551286cd02a92d91090290ae2d816qwang    Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);
1019d2fbaaab17945b59ca66bcd2f72e26ba3361e1d0rsun    if (EFI_ERROR (Status) || Fv == NULL) {
102028a00297189c323096aae8e2975de94e8549613cyshang      //
1021cd539d485db6356c59271e031b8fb05a4a6a66a9mdkinney      // FvHandle must have Firmware Volume2 protocol thus we should never get here.
102228a00297189c323096aae8e2975de94e8549613cyshang      //
102328a00297189c323096aae8e2975de94e8549613cyshang      ASSERT (FALSE);
102428a00297189c323096aae8e2975de94e8549613cyshang      continue;
102528a00297189c323096aae8e2975de94e8549613cyshang    }
1026022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
102728a00297189c323096aae8e2975de94e8549613cyshang    Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
102828a00297189c323096aae8e2975de94e8549613cyshang    if (EFI_ERROR (Status)) {
102928a00297189c323096aae8e2975de94e8549613cyshang      //
103028a00297189c323096aae8e2975de94e8549613cyshang      // The Firmware volume doesn't have device path, can't be dispatched.
103128a00297189c323096aae8e2975de94e8549613cyshang      //
103228a00297189c323096aae8e2975de94e8549613cyshang      continue;
103328a00297189c323096aae8e2975de94e8549613cyshang    }
1034022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
103528a00297189c323096aae8e2975de94e8549613cyshang    //
1036022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang    // Evaluate the authentication status of the Firmware Volume through
103728a00297189c323096aae8e2975de94e8549613cyshang    // Security Architectural Protocol
103828a00297189c323096aae8e2975de94e8549613cyshang    //
103928a00297189c323096aae8e2975de94e8549613cyshang    if (gSecurity != NULL) {
104028a00297189c323096aae8e2975de94e8549613cyshang      SecurityStatus = gSecurity->FileAuthenticationState (
1041022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                    gSecurity,
1042022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                    0,
104328a00297189c323096aae8e2975de94e8549613cyshang                                    FvDevicePath
104428a00297189c323096aae8e2975de94e8549613cyshang                                    );
104528a00297189c323096aae8e2975de94e8549613cyshang      if (SecurityStatus != EFI_SUCCESS) {
104628a00297189c323096aae8e2975de94e8549613cyshang        //
104728a00297189c323096aae8e2975de94e8549613cyshang        // Security check failed. The firmware volume should not be used for any purpose.
104828a00297189c323096aae8e2975de94e8549613cyshang        //
104928a00297189c323096aae8e2975de94e8549613cyshang        continue;
105028a00297189c323096aae8e2975de94e8549613cyshang      }
1051022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang    }
1052022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
105328a00297189c323096aae8e2975de94e8549613cyshang    //
1054022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang    // Discover Drivers in FV and add them to the Discovered Driver List.
1055022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang    // Process EFI_FV_FILETYPE_DRIVER type and then EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
105628a00297189c323096aae8e2975de94e8549613cyshang    //  EFI_FV_FILETYPE_DXE_CORE is processed to produce a Loaded Image protocol for the core
105728a00297189c323096aae8e2975de94e8549613cyshang    //  EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE is processed to create a Fvb
105828a00297189c323096aae8e2975de94e8549613cyshang    //
1059e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang    for (Index = 0; Index < sizeof (mDxeFileTypes) / sizeof (EFI_FV_FILETYPE); Index++) {
106028a00297189c323096aae8e2975de94e8549613cyshang      //
106128a00297189c323096aae8e2975de94e8549613cyshang      // Initialize the search key
106228a00297189c323096aae8e2975de94e8549613cyshang      //
106328a00297189c323096aae8e2975de94e8549613cyshang      Key = 0;
106428a00297189c323096aae8e2975de94e8549613cyshang      do {
106528a00297189c323096aae8e2975de94e8549613cyshang        Type = mDxeFileTypes[Index];
106628a00297189c323096aae8e2975de94e8549613cyshang        GetNextFileStatus = Fv->GetNextFile (
1067022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                  Fv,
106828a00297189c323096aae8e2975de94e8549613cyshang                                  &Key,
1069022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                  &Type,
1070022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                  &NameGuid,
1071022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                  &Attributes,
107228a00297189c323096aae8e2975de94e8549613cyshang                                  &Size
107328a00297189c323096aae8e2975de94e8549613cyshang                                  );
107428a00297189c323096aae8e2975de94e8549613cyshang        if (!EFI_ERROR (GetNextFileStatus)) {
107528a00297189c323096aae8e2975de94e8549613cyshang          if (Type == EFI_FV_FILETYPE_DXE_CORE) {
107628a00297189c323096aae8e2975de94e8549613cyshang            //
107728a00297189c323096aae8e2975de94e8549613cyshang            // If this is the DXE core fill in it's DevicePath & DeviceHandle
107828a00297189c323096aae8e2975de94e8549613cyshang            //
107928a00297189c323096aae8e2975de94e8549613cyshang            if (gDxeCoreLoadedImage->FilePath == NULL) {
108028a00297189c323096aae8e2975de94e8549613cyshang              if (CompareGuid (&NameGuid, gDxeCoreFileName)) {
108128a00297189c323096aae8e2975de94e8549613cyshang                //
108228a00297189c323096aae8e2975de94e8549613cyshang                // Maybe One specail Fv cantains only one DXE_CORE module, so its device path must
108328a00297189c323096aae8e2975de94e8549613cyshang                // be initialized completely.
108428a00297189c323096aae8e2975de94e8549613cyshang                //
108528a00297189c323096aae8e2975de94e8549613cyshang                EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid);
10861232b21473646661a4ac1ae4b7bf5113d4613e83klu                SetDevicePathEndNode (&mFvDevicePath.End);
108728a00297189c323096aae8e2975de94e8549613cyshang
10889c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang                gDxeCoreLoadedImage->FilePath = DuplicateDevicePath (
108928a00297189c323096aae8e2975de94e8549613cyshang                                                  (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
109028a00297189c323096aae8e2975de94e8549613cyshang                                                  );
109128a00297189c323096aae8e2975de94e8549613cyshang                gDxeCoreLoadedImage->DeviceHandle = FvHandle;
109228a00297189c323096aae8e2975de94e8549613cyshang              }
109328a00297189c323096aae8e2975de94e8549613cyshang            }
109428a00297189c323096aae8e2975de94e8549613cyshang          } else if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
109528a00297189c323096aae8e2975de94e8549613cyshang            //
1096022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang            // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
1097bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang            // been extracted.
1098bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang            //
1099bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang            if (FvFoundInHobFv2 (FvHandle, &NameGuid)) {
1100bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang              continue;
1101bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang            }
1102bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang            //
110328a00297189c323096aae8e2975de94e8549613cyshang            // Found a firmware volume image. Produce a firmware volume block
1104022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang            // protocol for it so it gets dispatched from. This is usually a
110528a00297189c323096aae8e2975de94e8549613cyshang            // capsule.
110628a00297189c323096aae8e2975de94e8549613cyshang            //
110728a00297189c323096aae8e2975de94e8549613cyshang            CoreProcessFvImageFile (Fv, FvHandle, &NameGuid);
110828a00297189c323096aae8e2975de94e8549613cyshang          } else {
110928a00297189c323096aae8e2975de94e8549613cyshang            //
111028a00297189c323096aae8e2975de94e8549613cyshang            // Transition driver from Undiscovered to Discovered state
111128a00297189c323096aae8e2975de94e8549613cyshang            //
111228a00297189c323096aae8e2975de94e8549613cyshang            CoreAddToDriverList (Fv, FvHandle, &NameGuid);
111328a00297189c323096aae8e2975de94e8549613cyshang          }
111428a00297189c323096aae8e2975de94e8549613cyshang        }
111528a00297189c323096aae8e2975de94e8549613cyshang      } while (!EFI_ERROR (GetNextFileStatus));
111628a00297189c323096aae8e2975de94e8549613cyshang    }
1117022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
111828a00297189c323096aae8e2975de94e8549613cyshang    //
111928a00297189c323096aae8e2975de94e8549613cyshang    // Read the array of GUIDs from the Apriori file if it is present in the firmware volume
112028a00297189c323096aae8e2975de94e8549613cyshang    //
112128a00297189c323096aae8e2975de94e8549613cyshang    AprioriFile = NULL;
112228a00297189c323096aae8e2975de94e8549613cyshang    Status = Fv->ReadSection (
112328a00297189c323096aae8e2975de94e8549613cyshang                  Fv,
112428a00297189c323096aae8e2975de94e8549613cyshang                  &gAprioriGuid,
112528a00297189c323096aae8e2975de94e8549613cyshang                  EFI_SECTION_RAW,
112628a00297189c323096aae8e2975de94e8549613cyshang                  0,
112728a00297189c323096aae8e2975de94e8549613cyshang                  (VOID **)&AprioriFile,
112828a00297189c323096aae8e2975de94e8549613cyshang                  &SizeOfBuffer,
112928a00297189c323096aae8e2975de94e8549613cyshang                  &AuthenticationStatus
113028a00297189c323096aae8e2975de94e8549613cyshang                  );
113128a00297189c323096aae8e2975de94e8549613cyshang    if (!EFI_ERROR (Status)) {
113228a00297189c323096aae8e2975de94e8549613cyshang      AprioriEntryCount = SizeOfBuffer / sizeof (EFI_GUID);
113328a00297189c323096aae8e2975de94e8549613cyshang    } else {
113428a00297189c323096aae8e2975de94e8549613cyshang      AprioriEntryCount = 0;
113528a00297189c323096aae8e2975de94e8549613cyshang    }
113628a00297189c323096aae8e2975de94e8549613cyshang
113728a00297189c323096aae8e2975de94e8549613cyshang    //
113828a00297189c323096aae8e2975de94e8549613cyshang    // Put drivers on Apriori List on the Scheduled queue. The Discovered List includes
113928a00297189c323096aae8e2975de94e8549613cyshang    // drivers not in the current FV and these must be skipped since the a priori list
114028a00297189c323096aae8e2975de94e8549613cyshang    // is only valid for the FV that it resided in.
114128a00297189c323096aae8e2975de94e8549613cyshang    //
114228a00297189c323096aae8e2975de94e8549613cyshang    CoreAcquireDispatcherLock ();
1143022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
114428a00297189c323096aae8e2975de94e8549613cyshang    for (Index = 0; Index < AprioriEntryCount; Index++) {
114528a00297189c323096aae8e2975de94e8549613cyshang      for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
114628a00297189c323096aae8e2975de94e8549613cyshang        DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
114728a00297189c323096aae8e2975de94e8549613cyshang        if (CompareGuid (&DriverEntry->FileName, &AprioriFile[Index]) &&
114828a00297189c323096aae8e2975de94e8549613cyshang            (FvHandle == DriverEntry->FvHandle)) {
114928a00297189c323096aae8e2975de94e8549613cyshang          DriverEntry->Dependent = FALSE;
115028a00297189c323096aae8e2975de94e8549613cyshang          DriverEntry->Scheduled = TRUE;
115128a00297189c323096aae8e2975de94e8549613cyshang          InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
115228a00297189c323096aae8e2975de94e8549613cyshang          break;
115328a00297189c323096aae8e2975de94e8549613cyshang        }
115428a00297189c323096aae8e2975de94e8549613cyshang      }
115528a00297189c323096aae8e2975de94e8549613cyshang    }
115628a00297189c323096aae8e2975de94e8549613cyshang
115728a00297189c323096aae8e2975de94e8549613cyshang    CoreReleaseDispatcherLock ();
115828a00297189c323096aae8e2975de94e8549613cyshang
115928a00297189c323096aae8e2975de94e8549613cyshang    //
1160022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang    // Free data allocated by Fv->ReadSection ()
116128a00297189c323096aae8e2975de94e8549613cyshang    //
1162022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang    CoreFreePool (AprioriFile);
116328a00297189c323096aae8e2975de94e8549613cyshang  }
116428a00297189c323096aae8e2975de94e8549613cyshang}
116528a00297189c323096aae8e2975de94e8549613cyshang
116628a00297189c323096aae8e2975de94e8549613cyshang
116728a00297189c323096aae8e2975de94e8549613cyshang
1168162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
116928a00297189c323096aae8e2975de94e8549613cyshang  Initialize the dispatcher. Initialize the notification function that runs when
1170e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  an FV2 protocol is added to the system.
117128a00297189c323096aae8e2975de94e8549613cyshang
1172162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
1173162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangVOID
1174162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreInitializeDispatcher (
1175162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  VOID
1176162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
117728a00297189c323096aae8e2975de94e8549613cyshang{
11787899b7971577075095266cc2af2010f2827e4096qhuang  mFwVolEvent = EfiCreateProtocolNotifyEvent (
1179022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                  &gEfiFirmwareVolume2ProtocolGuid,
118028a00297189c323096aae8e2975de94e8549613cyshang                  TPL_CALLBACK,
118128a00297189c323096aae8e2975de94e8549613cyshang                  CoreFwVolEventProtocolNotify,
118228a00297189c323096aae8e2975de94e8549613cyshang                  NULL,
11837899b7971577075095266cc2af2010f2827e4096qhuang                  &mFwVolEventRegistration
118428a00297189c323096aae8e2975de94e8549613cyshang                  );
118528a00297189c323096aae8e2975de94e8549613cyshang}
118628a00297189c323096aae8e2975de94e8549613cyshang
118728a00297189c323096aae8e2975de94e8549613cyshang//
118828a00297189c323096aae8e2975de94e8549613cyshang// Function only used in debug builds
118928a00297189c323096aae8e2975de94e8549613cyshang//
1190162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
1191162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
1192162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Traverse the discovered list for any drivers that were discovered but not loaded
1193162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  because the dependency experessions evaluated to false.
1194162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
1195162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
119628a00297189c323096aae8e2975de94e8549613cyshangVOID
119728a00297189c323096aae8e2975de94e8549613cyshangCoreDisplayDiscoveredNotDispatched (
119828a00297189c323096aae8e2975de94e8549613cyshang  VOID
119928a00297189c323096aae8e2975de94e8549613cyshang  )
120028a00297189c323096aae8e2975de94e8549613cyshang{
120128a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY                    *Link;
120228a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY         *DriverEntry;
120328a00297189c323096aae8e2975de94e8549613cyshang
120428a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mDiscoveredList.ForwardLink;Link !=&mDiscoveredList; Link = Link->ForwardLink) {
120528a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
120628a00297189c323096aae8e2975de94e8549613cyshang    if (DriverEntry->Dependent) {
1207162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang      DEBUG ((DEBUG_LOAD, "Driver %g was discovered but not loaded!!\n", &DriverEntry->FileName));
120828a00297189c323096aae8e2975de94e8549613cyshang    }
120928a00297189c323096aae8e2975de94e8549613cyshang  }
121028a00297189c323096aae8e2975de94e8549613cyshang}
1211