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
294e1005eca7186cbe61aaae09108f6fdf29959f22Eric DongCopyright (c) 2006 - 2014, 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
92e407ceecc7ab0df3adc91ba258a5a6c8d9484f04lgaoFV_FILEPATH_DEVICE_PATH mFvDevicePath;
93e407ceecc7ab0df3adc91ba258a5a6c8d9484f04lgao
9428a00297189c323096aae8e2975de94e8549613cyshang//
9528a00297189c323096aae8e2975de94e8549613cyshang// Function Prototypes
9628a00297189c323096aae8e2975de94e8549613cyshang//
97162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
98162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Insert InsertedDriverEntry onto the mScheduledQueue. To do this you
99162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  must add any driver with a before dependency on InsertedDriverEntry first.
100162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  You do this by recursively calling this routine. After all the Befores are
101162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  processed you can add InsertedDriverEntry to the mScheduledQueue.
102162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Then you can add any driver with an After dependency on InsertedDriverEntry
103162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  by recursively calling this routine.
104162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
105162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @param  InsertedDriverEntry   The driver to insert on the ScheduledLink Queue
106162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
107162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
10828a00297189c323096aae8e2975de94e8549613cyshangVOID
10928a00297189c323096aae8e2975de94e8549613cyshangCoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
11028a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_CORE_DRIVER_ENTRY   *InsertedDriverEntry
11128a00297189c323096aae8e2975de94e8549613cyshang  );
112022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
113162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
114162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Event notification that is fired every time a FV dispatch protocol is added.
115162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  More than one protocol may have been added when this event is fired, so you
116162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  must loop on CoreLocateHandle () to see how many protocols were added and
117162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  do the following to each FV:
118162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  If the Fv has already been processed, skip it. If the Fv has not been
119162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  processed then mark it as being processed, as we are about to process it.
120162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Read the Fv and add any driver in the Fv to the mDiscoveredList.The
121162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  mDiscoveredList is never free'ed and contains variables that define
122162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  the other states the DXE driver transitions to..
123162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  While you are at it read the A Priori file into memory.
124162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Place drivers in the A Priori list onto the mScheduledQueue.
125162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
126022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Event                 The Event that is being processed, not used.
127162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @param  Context               Event Context, not used.
128162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
129162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
13028a00297189c323096aae8e2975de94e8549613cyshangVOID
13128a00297189c323096aae8e2975de94e8549613cyshangEFIAPI
13228a00297189c323096aae8e2975de94e8549613cyshangCoreFwVolEventProtocolNotify (
13328a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_EVENT       Event,
13428a00297189c323096aae8e2975de94e8549613cyshang  IN  VOID            *Context
13528a00297189c323096aae8e2975de94e8549613cyshang  );
13628a00297189c323096aae8e2975de94e8549613cyshang
137162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
138022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  Convert FvHandle and DriverName into an EFI device path
139162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
140022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Fv                    Fv protocol, needed to read Depex info out of
141022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                FLASH.
142022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FvHandle              Handle for Fv, needed in the
143022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                EFI_CORE_DRIVER_ENTRY so that the PE image can be
144022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                read out of the FV at a later time.
145022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            Name of driver to add to mDiscoveredList.
146162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
147162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @return Pointer to device path constructed from FvHandle and DriverName
148162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
149162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
15028a00297189c323096aae8e2975de94e8549613cyshangEFI_DEVICE_PATH_PROTOCOL *
15128a00297189c323096aae8e2975de94e8549613cyshangCoreFvToDevicePath (
1520c2b5da80e9551286cd02a92d91090290ae2d816qwang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
15328a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                      FvHandle,
15428a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID                        *DriverName
15528a00297189c323096aae8e2975de94e8549613cyshang  );
15628a00297189c323096aae8e2975de94e8549613cyshang
157162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
158162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Add an entry to the mDiscoveredList. Allocate memory to store the DriverEntry,
159162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  and initilize any state variables. Read the Depex from the FV and store it
160162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  in DriverEntry. Pre-process the Depex to set the SOR, Before and After state.
161162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  The Discovered list is never free'ed and contains booleans that represent the
162162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  other possible DXE driver states.
163162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
164022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Fv                    Fv protocol, needed to read Depex info out of
165022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                FLASH.
166022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FvHandle              Handle for Fv, needed in the
167022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                EFI_CORE_DRIVER_ENTRY so that the PE image can be
168022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                read out of the FV at a later time.
169022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            Name of driver to add to mDiscoveredList.
170d3592549901814d6f542996c12505e56e26219f1lgao  @param  Type                  Fv File Type of file 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,
182d3592549901814d6f542996c12505e56e26219f1lgao  IN  EFI_GUID                        *DriverName,
183d3592549901814d6f542996c12505e56e26219f1lgao  IN  EFI_FV_FILETYPE                 Type
18428a00297189c323096aae8e2975de94e8549613cyshang  );
18528a00297189c323096aae8e2975de94e8549613cyshang
186162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
187162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.
188162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
189022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Fv                    The FIRMWARE_VOLUME protocol installed on the FV.
190022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FvHandle              The handle which FVB protocol installed on.
191022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            The driver guid specified.
192162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
193022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_OUT_OF_RESOURCES  No enough memory or other resource.
194022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_VOLUME_CORRUPTED  Corrupted volume.
195162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @retval EFI_SUCCESS           Function successfully returned.
196162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
197162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
198022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_STATUS
19928a00297189c323096aae8e2975de94e8549613cyshangCoreProcessFvImageFile (
2000c2b5da80e9551286cd02a92d91090290ae2d816qwang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
20128a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                      FvHandle,
20228a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID                        *DriverName
20328a00297189c323096aae8e2975de94e8549613cyshang  );
20428a00297189c323096aae8e2975de94e8549613cyshang
205162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
206162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
207162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Enter critical section by gaining lock on mDispatcherLock.
208162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
209162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
21028a00297189c323096aae8e2975de94e8549613cyshangVOID
21128a00297189c323096aae8e2975de94e8549613cyshangCoreAcquireDispatcherLock (
21228a00297189c323096aae8e2975de94e8549613cyshang  VOID
21328a00297189c323096aae8e2975de94e8549613cyshang  )
21428a00297189c323096aae8e2975de94e8549613cyshang{
21528a00297189c323096aae8e2975de94e8549613cyshang  CoreAcquireLock (&mDispatcherLock);
21628a00297189c323096aae8e2975de94e8549613cyshang}
21728a00297189c323096aae8e2975de94e8549613cyshang
218162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
219162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
220162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Exit critical section by releasing lock on mDispatcherLock.
221162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
222162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
22328a00297189c323096aae8e2975de94e8549613cyshangVOID
22428a00297189c323096aae8e2975de94e8549613cyshangCoreReleaseDispatcherLock (
22528a00297189c323096aae8e2975de94e8549613cyshang  VOID
22628a00297189c323096aae8e2975de94e8549613cyshang  )
22728a00297189c323096aae8e2975de94e8549613cyshang{
22828a00297189c323096aae8e2975de94e8549613cyshang  CoreReleaseLock (&mDispatcherLock);
22928a00297189c323096aae8e2975de94e8549613cyshang}
23028a00297189c323096aae8e2975de94e8549613cyshang
23128a00297189c323096aae8e2975de94e8549613cyshang
232162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
23328a00297189c323096aae8e2975de94e8549613cyshang  Read Depex and pre-process the Depex for Before and After. If Section Extraction
23428a00297189c323096aae8e2975de94e8549613cyshang  protocol returns an error via ReadSection defer the reading of the Depex.
23528a00297189c323096aae8e2975de94e8549613cyshang
236022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverEntry           Driver to work on.
23728a00297189c323096aae8e2975de94e8549613cyshang
238022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_SUCCESS           Depex read and preprossesed
239022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_PROTOCOL_ERROR    The section extraction protocol returned an error
240022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                and  Depex reading needs to be retried.
241162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @retval Error                 DEPEX not found.
24228a00297189c323096aae8e2975de94e8549613cyshang
243162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
244162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFI_STATUS
245162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreGetDepexSectionAndPreProccess (
246162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_CORE_DRIVER_ENTRY   *DriverEntry
247162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
24828a00297189c323096aae8e2975de94e8549613cyshang{
24928a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                    Status;
25028a00297189c323096aae8e2975de94e8549613cyshang  EFI_SECTION_TYPE              SectionType;
25128a00297189c323096aae8e2975de94e8549613cyshang  UINT32                        AuthenticationStatus;
2520c2b5da80e9551286cd02a92d91090290ae2d816qwang  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
25328a00297189c323096aae8e2975de94e8549613cyshang
254022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
25528a00297189c323096aae8e2975de94e8549613cyshang  Fv = DriverEntry->Fv;
25628a00297189c323096aae8e2975de94e8549613cyshang
25728a00297189c323096aae8e2975de94e8549613cyshang  //
25828a00297189c323096aae8e2975de94e8549613cyshang  // Grab Depex info, it will never be free'ed.
25928a00297189c323096aae8e2975de94e8549613cyshang  //
26028a00297189c323096aae8e2975de94e8549613cyshang  SectionType         = EFI_SECTION_DXE_DEPEX;
26128a00297189c323096aae8e2975de94e8549613cyshang  Status = Fv->ReadSection (
262022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                DriverEntry->Fv,
26328a00297189c323096aae8e2975de94e8549613cyshang                &DriverEntry->FileName,
264022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                SectionType,
265022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                0,
266022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                &DriverEntry->Depex,
26728a00297189c323096aae8e2975de94e8549613cyshang                (UINTN *)&DriverEntry->DepexSize,
26828a00297189c323096aae8e2975de94e8549613cyshang                &AuthenticationStatus
26928a00297189c323096aae8e2975de94e8549613cyshang                );
27028a00297189c323096aae8e2975de94e8549613cyshang  if (EFI_ERROR (Status)) {
27128a00297189c323096aae8e2975de94e8549613cyshang    if (Status == EFI_PROTOCOL_ERROR) {
27228a00297189c323096aae8e2975de94e8549613cyshang      //
27328a00297189c323096aae8e2975de94e8549613cyshang      // The section extraction protocol failed so set protocol error flag
27428a00297189c323096aae8e2975de94e8549613cyshang      //
27528a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->DepexProtocolError = TRUE;
27628a00297189c323096aae8e2975de94e8549613cyshang    } else {
27728a00297189c323096aae8e2975de94e8549613cyshang      //
2788a7d75b0625cffee0c67b85afe56763f93d86481qhuang      // If no Depex assume UEFI 2.0 driver model
27928a00297189c323096aae8e2975de94e8549613cyshang      //
28028a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Depex = NULL;
28128a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Dependent = TRUE;
28228a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->DepexProtocolError = FALSE;
28328a00297189c323096aae8e2975de94e8549613cyshang    }
28428a00297189c323096aae8e2975de94e8549613cyshang  } else {
28528a00297189c323096aae8e2975de94e8549613cyshang    //
28628a00297189c323096aae8e2975de94e8549613cyshang    // Set Before, After, and Unrequested state information based on Depex
28728a00297189c323096aae8e2975de94e8549613cyshang    // Driver will be put in Dependent or Unrequested state
28828a00297189c323096aae8e2975de94e8549613cyshang    //
28928a00297189c323096aae8e2975de94e8549613cyshang    CorePreProcessDepex (DriverEntry);
29028a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry->DepexProtocolError = FALSE;
291022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  }
29228a00297189c323096aae8e2975de94e8549613cyshang
29328a00297189c323096aae8e2975de94e8549613cyshang  return Status;
29428a00297189c323096aae8e2975de94e8549613cyshang}
29528a00297189c323096aae8e2975de94e8549613cyshang
296162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
297162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
298162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Check every driver and locate a matching one. If the driver is found, the Unrequested
299162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  state flag is cleared.
300162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
301022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FirmwareVolumeHandle  The handle of the Firmware Volume that contains
302022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                the firmware  file specified by DriverName.
303022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            The Driver name to put in the Dependent state.
304162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
305022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_SUCCESS           The DriverName was found and it's SOR bit was
306022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                cleared
307022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_NOT_FOUND         The DriverName does not exist or it's SOR bit was
308022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                not set.
309162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
310162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
31128a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS
31228a00297189c323096aae8e2975de94e8549613cyshangEFIAPI
31328a00297189c323096aae8e2975de94e8549613cyshangCoreSchedule (
31428a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE  FirmwareVolumeHandle,
31528a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID    *DriverName
31628a00297189c323096aae8e2975de94e8549613cyshang  )
31728a00297189c323096aae8e2975de94e8549613cyshang{
31828a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY            *Link;
31928a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY *DriverEntry;
32028a00297189c323096aae8e2975de94e8549613cyshang
32128a00297189c323096aae8e2975de94e8549613cyshang  //
32228a00297189c323096aae8e2975de94e8549613cyshang  // Check every driver
32328a00297189c323096aae8e2975de94e8549613cyshang  //
32428a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
32528a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
32628a00297189c323096aae8e2975de94e8549613cyshang    if (DriverEntry->FvHandle == FirmwareVolumeHandle &&
327022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang        DriverEntry->Unrequested &&
32828a00297189c323096aae8e2975de94e8549613cyshang        CompareGuid (DriverName, &DriverEntry->FileName)) {
32928a00297189c323096aae8e2975de94e8549613cyshang      //
33028a00297189c323096aae8e2975de94e8549613cyshang      // Move the driver from the Unrequested to the Dependent state
33128a00297189c323096aae8e2975de94e8549613cyshang      //
33228a00297189c323096aae8e2975de94e8549613cyshang      CoreAcquireDispatcherLock ();
33328a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Unrequested  = FALSE;
33428a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Dependent    = TRUE;
33528a00297189c323096aae8e2975de94e8549613cyshang      CoreReleaseDispatcherLock ();
336022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
3376a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney      DEBUG ((DEBUG_DISPATCH, "Schedule FFS(%g) - EFI_SUCCESS\n", DriverName));
3386a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney
33928a00297189c323096aae8e2975de94e8549613cyshang      return EFI_SUCCESS;
34028a00297189c323096aae8e2975de94e8549613cyshang    }
34128a00297189c323096aae8e2975de94e8549613cyshang  }
3426a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney
3436a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney  DEBUG ((DEBUG_DISPATCH, "Schedule FFS(%g) - EFI_NOT_FOUND\n", DriverName));
3446a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney
345022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  return EFI_NOT_FOUND;
34628a00297189c323096aae8e2975de94e8549613cyshang}
34728a00297189c323096aae8e2975de94e8549613cyshang
34828a00297189c323096aae8e2975de94e8549613cyshang
349162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
350162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
351e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  Convert a driver from the Untrused back to the Scheduled state.
352162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
353022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FirmwareVolumeHandle  The handle of the Firmware Volume that contains
354022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                the firmware  file specified by DriverName.
355022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            The Driver name to put in the Scheduled state
356162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
357022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_SUCCESS           The file was found in the untrusted state, and it
358022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                was promoted  to the trusted state.
359022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_NOT_FOUND         The file was not found in the untrusted state.
360162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
361162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
36228a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS
36328a00297189c323096aae8e2975de94e8549613cyshangEFIAPI
36428a00297189c323096aae8e2975de94e8549613cyshangCoreTrust (
36528a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE  FirmwareVolumeHandle,
36628a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID    *DriverName
36728a00297189c323096aae8e2975de94e8549613cyshang  )
36828a00297189c323096aae8e2975de94e8549613cyshang{
36928a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY            *Link;
37028a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY *DriverEntry;
37128a00297189c323096aae8e2975de94e8549613cyshang
37228a00297189c323096aae8e2975de94e8549613cyshang  //
37328a00297189c323096aae8e2975de94e8549613cyshang  // Check every driver
37428a00297189c323096aae8e2975de94e8549613cyshang  //
37528a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
37628a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
37728a00297189c323096aae8e2975de94e8549613cyshang    if (DriverEntry->FvHandle == FirmwareVolumeHandle &&
378022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang        DriverEntry->Untrusted &&
37928a00297189c323096aae8e2975de94e8549613cyshang        CompareGuid (DriverName, &DriverEntry->FileName)) {
38028a00297189c323096aae8e2975de94e8549613cyshang      //
38128a00297189c323096aae8e2975de94e8549613cyshang      // Transition driver from Untrusted to Scheduled state.
38228a00297189c323096aae8e2975de94e8549613cyshang      //
38328a00297189c323096aae8e2975de94e8549613cyshang      CoreAcquireDispatcherLock ();
38428a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Untrusted = FALSE;
38528a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Scheduled = TRUE;
38628a00297189c323096aae8e2975de94e8549613cyshang      InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
38728a00297189c323096aae8e2975de94e8549613cyshang      CoreReleaseDispatcherLock ();
388022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
38928a00297189c323096aae8e2975de94e8549613cyshang      return EFI_SUCCESS;
39028a00297189c323096aae8e2975de94e8549613cyshang    }
39128a00297189c323096aae8e2975de94e8549613cyshang  }
392022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  return EFI_NOT_FOUND;
39328a00297189c323096aae8e2975de94e8549613cyshang}
39428a00297189c323096aae8e2975de94e8549613cyshang
39528a00297189c323096aae8e2975de94e8549613cyshang
396202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang/**
397202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  An empty function to pass error checking of CreateEventEx ().
398202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang
399202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  @param  Event                 Event whose notification function is being invoked.
400202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  @param  Context               Pointer to the notification function's context,
401202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang                                which is implementation-dependent.
402202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang
403202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang**/
404202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuangVOID
405202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuangEFIAPI
40654cd17e9842d82dae3cd78686e05c4dc37a3540djljustenCoreEmptyCallbackFunction (
407202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  IN EFI_EVENT                Event,
408202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  IN VOID                     *Context
409202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  )
410202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang{
411202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  return;
412202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang}
41328a00297189c323096aae8e2975de94e8549613cyshang
414162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
415162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  This is the main Dispatcher for DXE and it exits when there are no more
41628a00297189c323096aae8e2975de94e8549613cyshang  drivers to run. Drain the mScheduledQueue and load and start a PE
417162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  image for each driver. Search the mDiscoveredList to see if any driver can
41828a00297189c323096aae8e2975de94e8549613cyshang  be placed on the mScheduledQueue. If no drivers are placed on the
41928a00297189c323096aae8e2975de94e8549613cyshang  mScheduledQueue exit the function. On exit it is assumed the Bds()
420162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  will be called, and when the Bds() exits the Dispatcher will be called
42128a00297189c323096aae8e2975de94e8549613cyshang  again.
42228a00297189c323096aae8e2975de94e8549613cyshang
423022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_ALREADY_STARTED   The DXE Dispatcher is already running
424022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_NOT_FOUND         No DXE Drivers were dispatched
425022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_SUCCESS           One or more DXE Drivers were dispatched
42628a00297189c323096aae8e2975de94e8549613cyshang
427162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
428162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFI_STATUS
429162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFIAPI
430162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreDispatcher (
431162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  VOID
432162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
43328a00297189c323096aae8e2975de94e8549613cyshang{
43428a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                      Status;
43528a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                      ReturnStatus;
43628a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY                      *Link;
43728a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY           *DriverEntry;
43828a00297189c323096aae8e2975de94e8549613cyshang  BOOLEAN                         ReadyToRun;
439202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  EFI_EVENT                       DxeDispatchEvent;
440202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang
44128a00297189c323096aae8e2975de94e8549613cyshang
44228a00297189c323096aae8e2975de94e8549613cyshang  if (gDispatcherRunning) {
44328a00297189c323096aae8e2975de94e8549613cyshang    //
44428a00297189c323096aae8e2975de94e8549613cyshang    // If the dispatcher is running don't let it be restarted.
44528a00297189c323096aae8e2975de94e8549613cyshang    //
44628a00297189c323096aae8e2975de94e8549613cyshang    return EFI_ALREADY_STARTED;
44728a00297189c323096aae8e2975de94e8549613cyshang  }
44828a00297189c323096aae8e2975de94e8549613cyshang
44928a00297189c323096aae8e2975de94e8549613cyshang  gDispatcherRunning = TRUE;
45028a00297189c323096aae8e2975de94e8549613cyshang
451202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  Status = CoreCreateEventEx (
452202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang             EVT_NOTIFY_SIGNAL,
453202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang             TPL_NOTIFY,
45454cd17e9842d82dae3cd78686e05c4dc37a3540djljusten             CoreEmptyCallbackFunction,
455202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang             NULL,
456202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang             &gEfiEventDxeDispatchGuid,
457202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang             &DxeDispatchEvent
458202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang             );
459202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  if (EFI_ERROR (Status)) {
460202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang    return Status;
461202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  }
46228a00297189c323096aae8e2975de94e8549613cyshang
46328a00297189c323096aae8e2975de94e8549613cyshang  ReturnStatus = EFI_NOT_FOUND;
46428a00297189c323096aae8e2975de94e8549613cyshang  do {
46528a00297189c323096aae8e2975de94e8549613cyshang    //
46628a00297189c323096aae8e2975de94e8549613cyshang    // Drain the Scheduled Queue
46728a00297189c323096aae8e2975de94e8549613cyshang    //
46828a00297189c323096aae8e2975de94e8549613cyshang    while (!IsListEmpty (&mScheduledQueue)) {
46928a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry = CR (
47028a00297189c323096aae8e2975de94e8549613cyshang                      mScheduledQueue.ForwardLink,
47128a00297189c323096aae8e2975de94e8549613cyshang                      EFI_CORE_DRIVER_ENTRY,
47228a00297189c323096aae8e2975de94e8549613cyshang                      ScheduledLink,
47328a00297189c323096aae8e2975de94e8549613cyshang                      EFI_CORE_DRIVER_ENTRY_SIGNATURE
47428a00297189c323096aae8e2975de94e8549613cyshang                      );
47528a00297189c323096aae8e2975de94e8549613cyshang
47628a00297189c323096aae8e2975de94e8549613cyshang      //
47728a00297189c323096aae8e2975de94e8549613cyshang      // Load the DXE Driver image into memory. If the Driver was transitioned from
47828a00297189c323096aae8e2975de94e8549613cyshang      // Untrused to Scheduled it would have already been loaded so we may need to
47928a00297189c323096aae8e2975de94e8549613cyshang      // skip the LoadImage
48028a00297189c323096aae8e2975de94e8549613cyshang      //
481d3592549901814d6f542996c12505e56e26219f1lgao      if (DriverEntry->ImageHandle == NULL && !DriverEntry->IsFvImage) {
4829490351076d0e95f46aa177e7643fceb953bbcb8jljusten        DEBUG ((DEBUG_INFO, "Loading driver %g\n", &DriverEntry->FileName));
48328a00297189c323096aae8e2975de94e8549613cyshang        Status = CoreLoadImage (
484022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                        FALSE,
485022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                        gDxeCoreImageHandle,
48628a00297189c323096aae8e2975de94e8549613cyshang                        DriverEntry->FvFileDevicePath,
487022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                        NULL,
488022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                        0,
48928a00297189c323096aae8e2975de94e8549613cyshang                        &DriverEntry->ImageHandle
49028a00297189c323096aae8e2975de94e8549613cyshang                        );
49128a00297189c323096aae8e2975de94e8549613cyshang
49228a00297189c323096aae8e2975de94e8549613cyshang        //
49328a00297189c323096aae8e2975de94e8549613cyshang        // Update the driver state to reflect that it's been loaded
49428a00297189c323096aae8e2975de94e8549613cyshang        //
49528a00297189c323096aae8e2975de94e8549613cyshang        if (EFI_ERROR (Status)) {
49628a00297189c323096aae8e2975de94e8549613cyshang          CoreAcquireDispatcherLock ();
49728a00297189c323096aae8e2975de94e8549613cyshang
49828a00297189c323096aae8e2975de94e8549613cyshang          if (Status == EFI_SECURITY_VIOLATION) {
49928a00297189c323096aae8e2975de94e8549613cyshang            //
50028a00297189c323096aae8e2975de94e8549613cyshang            // Take driver from Scheduled to Untrused state
50128a00297189c323096aae8e2975de94e8549613cyshang            //
50228a00297189c323096aae8e2975de94e8549613cyshang            DriverEntry->Untrusted = TRUE;
50328a00297189c323096aae8e2975de94e8549613cyshang          } else {
50428a00297189c323096aae8e2975de94e8549613cyshang            //
50528a00297189c323096aae8e2975de94e8549613cyshang            // The DXE Driver could not be loaded, and do not attempt to load or start it again.
506022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang            // Take driver from Scheduled to Initialized.
50728a00297189c323096aae8e2975de94e8549613cyshang            //
50828a00297189c323096aae8e2975de94e8549613cyshang            // This case include the Never Trusted state if EFI_ACCESS_DENIED is returned
50928a00297189c323096aae8e2975de94e8549613cyshang            //
51028a00297189c323096aae8e2975de94e8549613cyshang            DriverEntry->Initialized  = TRUE;
51128a00297189c323096aae8e2975de94e8549613cyshang          }
51228a00297189c323096aae8e2975de94e8549613cyshang
51328a00297189c323096aae8e2975de94e8549613cyshang          DriverEntry->Scheduled = FALSE;
51428a00297189c323096aae8e2975de94e8549613cyshang          RemoveEntryList (&DriverEntry->ScheduledLink);
515022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
51628a00297189c323096aae8e2975de94e8549613cyshang          CoreReleaseDispatcherLock ();
517022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
51828a00297189c323096aae8e2975de94e8549613cyshang          //
51928a00297189c323096aae8e2975de94e8549613cyshang          // If it's an error don't try the StartImage
52028a00297189c323096aae8e2975de94e8549613cyshang          //
52128a00297189c323096aae8e2975de94e8549613cyshang          continue;
52228a00297189c323096aae8e2975de94e8549613cyshang        }
52328a00297189c323096aae8e2975de94e8549613cyshang      }
52428a00297189c323096aae8e2975de94e8549613cyshang
52528a00297189c323096aae8e2975de94e8549613cyshang      CoreAcquireDispatcherLock ();
52628a00297189c323096aae8e2975de94e8549613cyshang
52728a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Scheduled    = FALSE;
52828a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry->Initialized  = TRUE;
52928a00297189c323096aae8e2975de94e8549613cyshang      RemoveEntryList (&DriverEntry->ScheduledLink);
530022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
53128a00297189c323096aae8e2975de94e8549613cyshang      CoreReleaseDispatcherLock ();
53228a00297189c323096aae8e2975de94e8549613cyshang
5332680a308013ecbad9a68599286ee05ddb7afa471qhuang
534d3592549901814d6f542996c12505e56e26219f1lgao      if (DriverEntry->IsFvImage) {
535d3592549901814d6f542996c12505e56e26219f1lgao        //
536d3592549901814d6f542996c12505e56e26219f1lgao        // Produce a firmware volume block protocol for FvImage so it gets dispatched from.
537d3592549901814d6f542996c12505e56e26219f1lgao        //
538d3592549901814d6f542996c12505e56e26219f1lgao        Status = CoreProcessFvImageFile (DriverEntry->Fv, DriverEntry->FvHandle, &DriverEntry->FileName);
539d3592549901814d6f542996c12505e56e26219f1lgao      } else {
540d3592549901814d6f542996c12505e56e26219f1lgao        REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
541d3592549901814d6f542996c12505e56e26219f1lgao          EFI_PROGRESS_CODE,
542d3592549901814d6f542996c12505e56e26219f1lgao          (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN),
543d3592549901814d6f542996c12505e56e26219f1lgao          &DriverEntry->ImageHandle,
544d3592549901814d6f542996c12505e56e26219f1lgao          sizeof (DriverEntry->ImageHandle)
545d3592549901814d6f542996c12505e56e26219f1lgao          );
546328ce03e55c2d802e1c83739d51c54bbcc92d87bydong        ASSERT (DriverEntry->ImageHandle != NULL);
547d3592549901814d6f542996c12505e56e26219f1lgao
548d3592549901814d6f542996c12505e56e26219f1lgao        Status = CoreStartImage (DriverEntry->ImageHandle, NULL, NULL);
549d3592549901814d6f542996c12505e56e26219f1lgao
550d3592549901814d6f542996c12505e56e26219f1lgao        REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
551d3592549901814d6f542996c12505e56e26219f1lgao          EFI_PROGRESS_CODE,
552d3592549901814d6f542996c12505e56e26219f1lgao          (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END),
553d3592549901814d6f542996c12505e56e26219f1lgao          &DriverEntry->ImageHandle,
554d3592549901814d6f542996c12505e56e26219f1lgao          sizeof (DriverEntry->ImageHandle)
555d3592549901814d6f542996c12505e56e26219f1lgao          );
556d3592549901814d6f542996c12505e56e26219f1lgao      }
55728a00297189c323096aae8e2975de94e8549613cyshang
55828a00297189c323096aae8e2975de94e8549613cyshang      ReturnStatus = EFI_SUCCESS;
55928a00297189c323096aae8e2975de94e8549613cyshang    }
56028a00297189c323096aae8e2975de94e8549613cyshang
56128a00297189c323096aae8e2975de94e8549613cyshang    //
5620e4483bc69aa31f1facbe62af438fa4feaf4503algao    // Now DXE Dispatcher finished one round of dispatch, signal an event group
5630e4483bc69aa31f1facbe62af438fa4feaf4503algao    // so that SMM Dispatcher get chance to dispatch SMM Drivers which depend
5640e4483bc69aa31f1facbe62af438fa4feaf4503algao    // on UEFI protocols
5650e4483bc69aa31f1facbe62af438fa4feaf4503algao    //
5660e4483bc69aa31f1facbe62af438fa4feaf4503algao    if (!EFI_ERROR (ReturnStatus)) {
5670e4483bc69aa31f1facbe62af438fa4feaf4503algao      CoreSignalEvent (DxeDispatchEvent);
5680e4483bc69aa31f1facbe62af438fa4feaf4503algao    }
5690e4483bc69aa31f1facbe62af438fa4feaf4503algao
5700e4483bc69aa31f1facbe62af438fa4feaf4503algao    //
57128a00297189c323096aae8e2975de94e8549613cyshang    // Search DriverList for items to place on Scheduled Queue
57228a00297189c323096aae8e2975de94e8549613cyshang    //
57328a00297189c323096aae8e2975de94e8549613cyshang    ReadyToRun = FALSE;
57428a00297189c323096aae8e2975de94e8549613cyshang    for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
57528a00297189c323096aae8e2975de94e8549613cyshang      DriverEntry = CR (Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
57628a00297189c323096aae8e2975de94e8549613cyshang
57728a00297189c323096aae8e2975de94e8549613cyshang      if (DriverEntry->DepexProtocolError){
57828a00297189c323096aae8e2975de94e8549613cyshang        //
57928a00297189c323096aae8e2975de94e8549613cyshang        // If Section Extraction Protocol did not let the Depex be read before retry the read
58028a00297189c323096aae8e2975de94e8549613cyshang        //
58128a00297189c323096aae8e2975de94e8549613cyshang        Status = CoreGetDepexSectionAndPreProccess (DriverEntry);
582022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang      }
58328a00297189c323096aae8e2975de94e8549613cyshang
58428a00297189c323096aae8e2975de94e8549613cyshang      if (DriverEntry->Dependent) {
58528a00297189c323096aae8e2975de94e8549613cyshang        if (CoreIsSchedulable (DriverEntry)) {
586022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang          CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
58728a00297189c323096aae8e2975de94e8549613cyshang          ReadyToRun = TRUE;
588022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang        }
5896a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney      } else {
5906a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney        if (DriverEntry->Unrequested) {
5916a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney          DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName));
5926a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney          DEBUG ((DEBUG_DISPATCH, "  SOR                                             = Not Requested\n"));
5936a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney          DEBUG ((DEBUG_DISPATCH, "  RESULT = FALSE\n"));
5946a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney        }
59528a00297189c323096aae8e2975de94e8549613cyshang      }
59628a00297189c323096aae8e2975de94e8549613cyshang    }
59728a00297189c323096aae8e2975de94e8549613cyshang  } while (ReadyToRun);
59828a00297189c323096aae8e2975de94e8549613cyshang
599202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  //
600202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  // Close DXE dispatch Event
601202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  //
602202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang  CoreCloseEvent (DxeDispatchEvent);
603202c32790fb65187a3f5dfc546d611b5f3b1f10bdavidhuang
60428a00297189c323096aae8e2975de94e8549613cyshang  gDispatcherRunning = FALSE;
60528a00297189c323096aae8e2975de94e8549613cyshang
60628a00297189c323096aae8e2975de94e8549613cyshang  return ReturnStatus;
60728a00297189c323096aae8e2975de94e8549613cyshang}
60828a00297189c323096aae8e2975de94e8549613cyshang
60928a00297189c323096aae8e2975de94e8549613cyshang
610162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
611162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Insert InsertedDriverEntry onto the mScheduledQueue. To do this you
61228a00297189c323096aae8e2975de94e8549613cyshang  must add any driver with a before dependency on InsertedDriverEntry first.
61328a00297189c323096aae8e2975de94e8549613cyshang  You do this by recursively calling this routine. After all the Befores are
614162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  processed you can add InsertedDriverEntry to the mScheduledQueue.
615162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Then you can add any driver with an After dependency on InsertedDriverEntry
61628a00297189c323096aae8e2975de94e8549613cyshang  by recursively calling this routine.
61728a00297189c323096aae8e2975de94e8549613cyshang
618162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @param  InsertedDriverEntry   The driver to insert on the ScheduledLink Queue
61928a00297189c323096aae8e2975de94e8549613cyshang
620162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
621162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangVOID
622162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
623162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_CORE_DRIVER_ENTRY   *InsertedDriverEntry
624162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
62528a00297189c323096aae8e2975de94e8549613cyshang{
62628a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY            *Link;
62728a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY *DriverEntry;
62828a00297189c323096aae8e2975de94e8549613cyshang
62928a00297189c323096aae8e2975de94e8549613cyshang  //
63028a00297189c323096aae8e2975de94e8549613cyshang  // Process Before Dependency
63128a00297189c323096aae8e2975de94e8549613cyshang  //
63228a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
63328a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
6346a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney    if (DriverEntry->Before && DriverEntry->Dependent && DriverEntry != InsertedDriverEntry) {
6356a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney      DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName));
6366a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney      DEBUG ((DEBUG_DISPATCH, "  BEFORE FFS(%g) = ", &DriverEntry->BeforeAfterGuid));
63728a00297189c323096aae8e2975de94e8549613cyshang      if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
63828a00297189c323096aae8e2975de94e8549613cyshang        //
63928a00297189c323096aae8e2975de94e8549613cyshang        // Recursively process BEFORE
64028a00297189c323096aae8e2975de94e8549613cyshang        //
6416a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney        DEBUG ((DEBUG_DISPATCH, "TRUE\n  END\n  RESULT = TRUE\n"));
64228a00297189c323096aae8e2975de94e8549613cyshang        CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
6436a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney      } else {
6446a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney        DEBUG ((DEBUG_DISPATCH, "FALSE\n  END\n  RESULT = FALSE\n"));
64528a00297189c323096aae8e2975de94e8549613cyshang      }
64628a00297189c323096aae8e2975de94e8549613cyshang    }
64728a00297189c323096aae8e2975de94e8549613cyshang  }
64828a00297189c323096aae8e2975de94e8549613cyshang
64928a00297189c323096aae8e2975de94e8549613cyshang  //
65028a00297189c323096aae8e2975de94e8549613cyshang  // Convert driver from Dependent to Scheduled state
65128a00297189c323096aae8e2975de94e8549613cyshang  //
65228a00297189c323096aae8e2975de94e8549613cyshang  CoreAcquireDispatcherLock ();
65328a00297189c323096aae8e2975de94e8549613cyshang
65428a00297189c323096aae8e2975de94e8549613cyshang  InsertedDriverEntry->Dependent = FALSE;
65528a00297189c323096aae8e2975de94e8549613cyshang  InsertedDriverEntry->Scheduled = TRUE;
65628a00297189c323096aae8e2975de94e8549613cyshang  InsertTailList (&mScheduledQueue, &InsertedDriverEntry->ScheduledLink);
657022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
65828a00297189c323096aae8e2975de94e8549613cyshang  CoreReleaseDispatcherLock ();
65928a00297189c323096aae8e2975de94e8549613cyshang
66028a00297189c323096aae8e2975de94e8549613cyshang  //
66128a00297189c323096aae8e2975de94e8549613cyshang  // Process After Dependency
66228a00297189c323096aae8e2975de94e8549613cyshang  //
66328a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
66428a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
6656a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney    if (DriverEntry->After && DriverEntry->Dependent && DriverEntry != InsertedDriverEntry) {
6666a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney      DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName));
6676a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney      DEBUG ((DEBUG_DISPATCH, "  AFTER FFS(%g) = ", &DriverEntry->BeforeAfterGuid));
66828a00297189c323096aae8e2975de94e8549613cyshang      if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
66928a00297189c323096aae8e2975de94e8549613cyshang        //
67028a00297189c323096aae8e2975de94e8549613cyshang        // Recursively process AFTER
67128a00297189c323096aae8e2975de94e8549613cyshang        //
6726a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney        DEBUG ((DEBUG_DISPATCH, "TRUE\n  END\n  RESULT = TRUE\n"));
67328a00297189c323096aae8e2975de94e8549613cyshang        CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
6746a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney      } else {
6756a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney        DEBUG ((DEBUG_DISPATCH, "FALSE\n  END\n  RESULT = FALSE\n"));
67628a00297189c323096aae8e2975de94e8549613cyshang      }
67728a00297189c323096aae8e2975de94e8549613cyshang    }
67828a00297189c323096aae8e2975de94e8549613cyshang  }
67928a00297189c323096aae8e2975de94e8549613cyshang}
68028a00297189c323096aae8e2975de94e8549613cyshang
68128a00297189c323096aae8e2975de94e8549613cyshang
682162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
68328a00297189c323096aae8e2975de94e8549613cyshang  Return TRUE if the Fv has been processed, FALSE if not.
68428a00297189c323096aae8e2975de94e8549613cyshang
685022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FvHandle              The handle of a FV that's being tested
68628a00297189c323096aae8e2975de94e8549613cyshang
687022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval TRUE                  Fv protocol on FvHandle has been processed
688e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  @retval FALSE                 Fv protocol on FvHandle has not yet been processed
68928a00297189c323096aae8e2975de94e8549613cyshang
690162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
691162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangBOOLEAN
692162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangFvHasBeenProcessed (
693162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_HANDLE      FvHandle
694162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
69528a00297189c323096aae8e2975de94e8549613cyshang{
69628a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY      *Link;
69728a00297189c323096aae8e2975de94e8549613cyshang  KNOWN_HANDLE    *KnownHandle;
69828a00297189c323096aae8e2975de94e8549613cyshang
69928a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) {
70028a00297189c323096aae8e2975de94e8549613cyshang    KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE);
70128a00297189c323096aae8e2975de94e8549613cyshang    if (KnownHandle->Handle == FvHandle) {
70228a00297189c323096aae8e2975de94e8549613cyshang      return TRUE;
70328a00297189c323096aae8e2975de94e8549613cyshang    }
70428a00297189c323096aae8e2975de94e8549613cyshang  }
70528a00297189c323096aae8e2975de94e8549613cyshang  return FALSE;
70628a00297189c323096aae8e2975de94e8549613cyshang}
70728a00297189c323096aae8e2975de94e8549613cyshang
70828a00297189c323096aae8e2975de94e8549613cyshang
709162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
71028a00297189c323096aae8e2975de94e8549613cyshang  Remember that Fv protocol on FvHandle has had it's drivers placed on the
7112fc46f86f91daf139ffb1bf20500d8254f037d2blgao  mDiscoveredList. This fucntion adds entries on the mFvHandleList if new
7122fc46f86f91daf139ffb1bf20500d8254f037d2blgao  entry is different from one in mFvHandleList by checking FvImage Guid.
7132fc46f86f91daf139ffb1bf20500d8254f037d2blgao  Items are never removed/freed from the mFvHandleList.
71428a00297189c323096aae8e2975de94e8549613cyshang
715162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @param  FvHandle              The handle of a FV that has been processed
71628a00297189c323096aae8e2975de94e8549613cyshang
7172fc46f86f91daf139ffb1bf20500d8254f037d2blgao  @return A point to new added FvHandle entry. If FvHandle with the same FvImage guid
7182fc46f86f91daf139ffb1bf20500d8254f037d2blgao          has been added, NULL will return.
7192fc46f86f91daf139ffb1bf20500d8254f037d2blgao
720162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
7212fc46f86f91daf139ffb1bf20500d8254f037d2blgaoKNOWN_HANDLE *
722162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangFvIsBeingProcesssed (
723162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_HANDLE    FvHandle
724162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
72528a00297189c323096aae8e2975de94e8549613cyshang{
7262fc46f86f91daf139ffb1bf20500d8254f037d2blgao  EFI_STATUS                            Status;
7272fc46f86f91daf139ffb1bf20500d8254f037d2blgao  EFI_GUID                              FvNameGuid;
7282fc46f86f91daf139ffb1bf20500d8254f037d2blgao  BOOLEAN                               FvNameGuidIsFound;
7292fc46f86f91daf139ffb1bf20500d8254f037d2blgao  UINT32                                ExtHeaderOffset;
7302fc46f86f91daf139ffb1bf20500d8254f037d2blgao  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *Fvb;
7312fc46f86f91daf139ffb1bf20500d8254f037d2blgao  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;
7322fc46f86f91daf139ffb1bf20500d8254f037d2blgao  EFI_FV_BLOCK_MAP_ENTRY                *BlockMap;
7332fc46f86f91daf139ffb1bf20500d8254f037d2blgao  UINTN                                 LbaOffset;
7342fc46f86f91daf139ffb1bf20500d8254f037d2blgao  UINTN                                 Index;
7352fc46f86f91daf139ffb1bf20500d8254f037d2blgao  EFI_LBA                               LbaIndex;
7362fc46f86f91daf139ffb1bf20500d8254f037d2blgao  LIST_ENTRY                            *Link;
7372fc46f86f91daf139ffb1bf20500d8254f037d2blgao  KNOWN_HANDLE                          *KnownHandle;
7382fc46f86f91daf139ffb1bf20500d8254f037d2blgao
739ac30bca0a37b0f88781ff447183970a523d1f5c3Star Zeng  FwVolHeader = NULL;
740ac30bca0a37b0f88781ff447183970a523d1f5c3Star Zeng
7412fc46f86f91daf139ffb1bf20500d8254f037d2blgao  //
7422fc46f86f91daf139ffb1bf20500d8254f037d2blgao  // Get the FirmwareVolumeBlock protocol on that handle
7432fc46f86f91daf139ffb1bf20500d8254f037d2blgao  //
7442fc46f86f91daf139ffb1bf20500d8254f037d2blgao  FvNameGuidIsFound = FALSE;
7452fc46f86f91daf139ffb1bf20500d8254f037d2blgao  Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
7462fc46f86f91daf139ffb1bf20500d8254f037d2blgao  if (!EFI_ERROR (Status)) {
7472fc46f86f91daf139ffb1bf20500d8254f037d2blgao    //
7482fc46f86f91daf139ffb1bf20500d8254f037d2blgao    // Get the full FV header based on FVB protocol.
7492fc46f86f91daf139ffb1bf20500d8254f037d2blgao    //
750bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao    ASSERT (Fvb != NULL);
7512fc46f86f91daf139ffb1bf20500d8254f037d2blgao    Status = GetFwVolHeader (Fvb, &FwVolHeader);
752bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao    if (!EFI_ERROR (Status)) {
753bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao      ASSERT (FwVolHeader != NULL);
754bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao      if (VerifyFvHeaderChecksum (FwVolHeader) && FwVolHeader->ExtHeaderOffset != 0) {
755bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao        ExtHeaderOffset = (UINT32) FwVolHeader->ExtHeaderOffset;
756bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao        BlockMap  = FwVolHeader->BlockMap;
757bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao        LbaIndex  = 0;
758bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao        LbaOffset = 0;
759bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao        //
760bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao        // Find LbaIndex and LbaOffset for FV extension header based on BlockMap.
761bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao        //
762bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao        while ((BlockMap->NumBlocks != 0) || (BlockMap->Length != 0)) {
763bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao          for (Index = 0; Index < BlockMap->NumBlocks && ExtHeaderOffset >= BlockMap->Length; Index ++) {
764bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao            ExtHeaderOffset -= BlockMap->Length;
765bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao            LbaIndex ++;
766bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao          }
767bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao          //
768bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao          // Check whether FvExtHeader is crossing the multi block range.
769bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao          //
770bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao          if (Index < BlockMap->NumBlocks) {
771bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao            LbaOffset = ExtHeaderOffset;
772bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao            break;
773bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao          }
774bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao          BlockMap++;
7752fc46f86f91daf139ffb1bf20500d8254f037d2blgao        }
7762fc46f86f91daf139ffb1bf20500d8254f037d2blgao        //
777bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao        // Read FvNameGuid from FV extension header.
7782fc46f86f91daf139ffb1bf20500d8254f037d2blgao        //
779bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao        Status = ReadFvbData (Fvb, &LbaIndex, &LbaOffset, sizeof (FvNameGuid), (UINT8 *) &FvNameGuid);
780bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao        if (!EFI_ERROR (Status)) {
781bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao          FvNameGuidIsFound = TRUE;
7822fc46f86f91daf139ffb1bf20500d8254f037d2blgao        }
7832fc46f86f91daf139ffb1bf20500d8254f037d2blgao      }
784bdc9d5a5d5b22bb96e075e04211c450f76bef595lgao      CoreFreePool (FwVolHeader);
7852fc46f86f91daf139ffb1bf20500d8254f037d2blgao    }
7862fc46f86f91daf139ffb1bf20500d8254f037d2blgao  }
7872fc46f86f91daf139ffb1bf20500d8254f037d2blgao
7882fc46f86f91daf139ffb1bf20500d8254f037d2blgao  if (FvNameGuidIsFound) {
7892fc46f86f91daf139ffb1bf20500d8254f037d2blgao    //
7902fc46f86f91daf139ffb1bf20500d8254f037d2blgao    // Check whether the FV image with the found FvNameGuid has been processed.
7912fc46f86f91daf139ffb1bf20500d8254f037d2blgao    //
7922fc46f86f91daf139ffb1bf20500d8254f037d2blgao    for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) {
7932fc46f86f91daf139ffb1bf20500d8254f037d2blgao      KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE);
7942fc46f86f91daf139ffb1bf20500d8254f037d2blgao      if (CompareGuid (&FvNameGuid, &KnownHandle->FvNameGuid)) {
7952fc46f86f91daf139ffb1bf20500d8254f037d2blgao        DEBUG ((EFI_D_ERROR, "FvImage on FvHandle %p and %p has the same FvNameGuid %g.\n", FvHandle, KnownHandle->Handle, FvNameGuid));
7962fc46f86f91daf139ffb1bf20500d8254f037d2blgao        return NULL;
7972fc46f86f91daf139ffb1bf20500d8254f037d2blgao      }
7982fc46f86f91daf139ffb1bf20500d8254f037d2blgao    }
7992fc46f86f91daf139ffb1bf20500d8254f037d2blgao  }
80028a00297189c323096aae8e2975de94e8549613cyshang
8012fc46f86f91daf139ffb1bf20500d8254f037d2blgao  KnownHandle = AllocateZeroPool (sizeof (KNOWN_HANDLE));
80228a00297189c323096aae8e2975de94e8549613cyshang  ASSERT (KnownHandle != NULL);
80328a00297189c323096aae8e2975de94e8549613cyshang
80428a00297189c323096aae8e2975de94e8549613cyshang  KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE;
80528a00297189c323096aae8e2975de94e8549613cyshang  KnownHandle->Handle = FvHandle;
8062fc46f86f91daf139ffb1bf20500d8254f037d2blgao  if (FvNameGuidIsFound) {
8072fc46f86f91daf139ffb1bf20500d8254f037d2blgao    CopyGuid (&KnownHandle->FvNameGuid, &FvNameGuid);
8082fc46f86f91daf139ffb1bf20500d8254f037d2blgao  }
80928a00297189c323096aae8e2975de94e8549613cyshang  InsertTailList (&mFvHandleList, &KnownHandle->Link);
8102fc46f86f91daf139ffb1bf20500d8254f037d2blgao  return KnownHandle;
81128a00297189c323096aae8e2975de94e8549613cyshang}
81228a00297189c323096aae8e2975de94e8549613cyshang
81328a00297189c323096aae8e2975de94e8549613cyshang
81428a00297189c323096aae8e2975de94e8549613cyshang
815162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
816162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
817162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Convert FvHandle and DriverName into an EFI device path
818162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
819022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Fv                    Fv protocol, needed to read Depex info out of
820022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                FLASH.
821022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FvHandle              Handle for Fv, needed in the
822022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                EFI_CORE_DRIVER_ENTRY so that the PE image can be
823022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                read out of the FV at a later time.
824022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            Name of driver to add to mDiscoveredList.
825162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
826162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @return Pointer to device path constructed from FvHandle and DriverName
827162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
828162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
82928a00297189c323096aae8e2975de94e8549613cyshangEFI_DEVICE_PATH_PROTOCOL *
83028a00297189c323096aae8e2975de94e8549613cyshangCoreFvToDevicePath (
8310c2b5da80e9551286cd02a92d91090290ae2d816qwang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
83228a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                      FvHandle,
83328a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID                        *DriverName
83428a00297189c323096aae8e2975de94e8549613cyshang  )
83528a00297189c323096aae8e2975de94e8549613cyshang{
83628a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                          Status;
83728a00297189c323096aae8e2975de94e8549613cyshang  EFI_DEVICE_PATH_PROTOCOL            *FvDevicePath;
83828a00297189c323096aae8e2975de94e8549613cyshang  EFI_DEVICE_PATH_PROTOCOL            *FileNameDevicePath;
83928a00297189c323096aae8e2975de94e8549613cyshang
84028a00297189c323096aae8e2975de94e8549613cyshang  //
84128a00297189c323096aae8e2975de94e8549613cyshang  // Remember the device path of the FV
84228a00297189c323096aae8e2975de94e8549613cyshang  //
84328a00297189c323096aae8e2975de94e8549613cyshang  Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
84428a00297189c323096aae8e2975de94e8549613cyshang  if (EFI_ERROR (Status)) {
84528a00297189c323096aae8e2975de94e8549613cyshang    FileNameDevicePath = NULL;
84628a00297189c323096aae8e2975de94e8549613cyshang  } else {
84728a00297189c323096aae8e2975de94e8549613cyshang    //
84828a00297189c323096aae8e2975de94e8549613cyshang    // Build a device path to the file in the FV to pass into gBS->LoadImage
84928a00297189c323096aae8e2975de94e8549613cyshang    //
85028a00297189c323096aae8e2975de94e8549613cyshang    EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, DriverName);
8511232b21473646661a4ac1ae4b7bf5113d4613e83klu    SetDevicePathEndNode (&mFvDevicePath.End);
85228a00297189c323096aae8e2975de94e8549613cyshang
8539c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang    FileNameDevicePath = AppendDevicePath (
854022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                            FvDevicePath,
85528a00297189c323096aae8e2975de94e8549613cyshang                            (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
85628a00297189c323096aae8e2975de94e8549613cyshang                            );
85728a00297189c323096aae8e2975de94e8549613cyshang  }
85828a00297189c323096aae8e2975de94e8549613cyshang
85928a00297189c323096aae8e2975de94e8549613cyshang  return FileNameDevicePath;
86028a00297189c323096aae8e2975de94e8549613cyshang}
86128a00297189c323096aae8e2975de94e8549613cyshang
86228a00297189c323096aae8e2975de94e8549613cyshang
86328a00297189c323096aae8e2975de94e8549613cyshang
864162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
865162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Add an entry to the mDiscoveredList. Allocate memory to store the DriverEntry,
86628a00297189c323096aae8e2975de94e8549613cyshang  and initilize any state variables. Read the Depex from the FV and store it
86728a00297189c323096aae8e2975de94e8549613cyshang  in DriverEntry. Pre-process the Depex to set the SOR, Before and After state.
86828a00297189c323096aae8e2975de94e8549613cyshang  The Discovered list is never free'ed and contains booleans that represent the
86928a00297189c323096aae8e2975de94e8549613cyshang  other possible DXE driver states.
87028a00297189c323096aae8e2975de94e8549613cyshang
871022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Fv                    Fv protocol, needed to read Depex info out of
872022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                FLASH.
873022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FvHandle              Handle for Fv, needed in the
874022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                EFI_CORE_DRIVER_ENTRY so that the PE image can be
875022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                read out of the FV at a later time.
876022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            Name of driver to add to mDiscoveredList.
877d3592549901814d6f542996c12505e56e26219f1lgao  @param  Type                  Fv File Type of file to add to mDiscoveredList.
87828a00297189c323096aae8e2975de94e8549613cyshang
879022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_SUCCESS           If driver was added to the mDiscoveredList.
880022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_ALREADY_STARTED   The driver has already been started. Only one
881022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                DriverName may be active in the system at any one
882162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang                                time.
88328a00297189c323096aae8e2975de94e8549613cyshang
884162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
885162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFI_STATUS
886162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreAddToDriverList (
887162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
888162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_HANDLE                      FvHandle,
889d3592549901814d6f542996c12505e56e26219f1lgao  IN  EFI_GUID                        *DriverName,
890d3592549901814d6f542996c12505e56e26219f1lgao  IN  EFI_FV_FILETYPE                 Type
891162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
89228a00297189c323096aae8e2975de94e8549613cyshang{
89328a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY               *DriverEntry;
89428a00297189c323096aae8e2975de94e8549613cyshang
895022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
89628a00297189c323096aae8e2975de94e8549613cyshang  //
897022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  // Create the Driver Entry for the list. ZeroPool initializes lots of variables to
89828a00297189c323096aae8e2975de94e8549613cyshang  // NULL or FALSE.
89928a00297189c323096aae8e2975de94e8549613cyshang  //
9009c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang  DriverEntry = AllocateZeroPool (sizeof (EFI_CORE_DRIVER_ENTRY));
90128a00297189c323096aae8e2975de94e8549613cyshang  ASSERT (DriverEntry != NULL);
902d3592549901814d6f542996c12505e56e26219f1lgao  if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
903d3592549901814d6f542996c12505e56e26219f1lgao    DriverEntry->IsFvImage = TRUE;
904d3592549901814d6f542996c12505e56e26219f1lgao  }
90528a00297189c323096aae8e2975de94e8549613cyshang
90628a00297189c323096aae8e2975de94e8549613cyshang  DriverEntry->Signature        = EFI_CORE_DRIVER_ENTRY_SIGNATURE;
907e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  CopyGuid (&DriverEntry->FileName, DriverName);
90828a00297189c323096aae8e2975de94e8549613cyshang  DriverEntry->FvHandle         = FvHandle;
90928a00297189c323096aae8e2975de94e8549613cyshang  DriverEntry->Fv               = Fv;
91028a00297189c323096aae8e2975de94e8549613cyshang  DriverEntry->FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName);
91128a00297189c323096aae8e2975de94e8549613cyshang
91228a00297189c323096aae8e2975de94e8549613cyshang  CoreGetDepexSectionAndPreProccess (DriverEntry);
913022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
91428a00297189c323096aae8e2975de94e8549613cyshang  CoreAcquireDispatcherLock ();
915022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
91628a00297189c323096aae8e2975de94e8549613cyshang  InsertTailList (&mDiscoveredList, &DriverEntry->Link);
91728a00297189c323096aae8e2975de94e8549613cyshang
91828a00297189c323096aae8e2975de94e8549613cyshang  CoreReleaseDispatcherLock ();
91928a00297189c323096aae8e2975de94e8549613cyshang
92028a00297189c323096aae8e2975de94e8549613cyshang  return EFI_SUCCESS;
92128a00297189c323096aae8e2975de94e8549613cyshang}
92228a00297189c323096aae8e2975de94e8549613cyshang
923bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
924162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
925bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  Check if a FV Image type file (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) is
926bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  described by a EFI_HOB_FIRMWARE_VOLUME2 Hob.
927bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
9282fc46f86f91daf139ffb1bf20500d8254f037d2blgao  @param  FvNameGuid            The FV image guid specified.
929022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            The driver guid specified.
930bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
931022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval TRUE                  This file is found in a EFI_HOB_FIRMWARE_VOLUME2
932022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                Hob.
933162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @retval FALSE                 Not found.
934bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
935162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
936162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangBOOLEAN
937162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangFvFoundInHobFv2 (
9382fc46f86f91daf139ffb1bf20500d8254f037d2blgao  IN  CONST EFI_GUID                  *FvNameGuid,
939162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  CONST EFI_GUID                  *DriverName
940162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
941bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang{
942bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  EFI_PEI_HOB_POINTERS                HobFv2;
943022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
944bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  HobFv2.Raw = GetHobList ();
945022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
946bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {
9472fc46f86f91daf139ffb1bf20500d8254f037d2blgao    //
9482fc46f86f91daf139ffb1bf20500d8254f037d2blgao    // Compare parent FvNameGuid and FileGuid both.
9492fc46f86f91daf139ffb1bf20500d8254f037d2blgao    //
9502fc46f86f91daf139ffb1bf20500d8254f037d2blgao    if (CompareGuid (DriverName, &HobFv2.FirmwareVolume2->FileName) &&
9512fc46f86f91daf139ffb1bf20500d8254f037d2blgao        CompareGuid (FvNameGuid, &HobFv2.FirmwareVolume2->FvName)) {
952b0d803fe3e5c55a9a0c75bc90ccf40ebbbc9ffa3klu      return TRUE;
953bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang    }
954bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang    HobFv2.Raw = GET_NEXT_HOB (HobFv2);
955bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  }
956bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang
957bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang  return FALSE;
958bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang}
95928a00297189c323096aae8e2975de94e8549613cyshang
96028a00297189c323096aae8e2975de94e8549613cyshang
961162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
962162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
963162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.
964162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
965022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Fv                    The FIRMWARE_VOLUME protocol installed on the FV.
966022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  FvHandle              The handle which FVB protocol installed on.
967022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  DriverName            The driver guid specified.
968162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
969022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_OUT_OF_RESOURCES  No enough memory or other resource.
970022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @retval EFI_VOLUME_CORRUPTED  Corrupted volume.
971162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @retval EFI_SUCCESS           Function successfully returned.
972162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
973162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
974022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_STATUS
97528a00297189c323096aae8e2975de94e8549613cyshangCoreProcessFvImageFile (
9760c2b5da80e9551286cd02a92d91090290ae2d816qwang  IN  EFI_FIRMWARE_VOLUME2_PROTOCOL   *Fv,
97728a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_HANDLE                      FvHandle,
97828a00297189c323096aae8e2975de94e8549613cyshang  IN  EFI_GUID                        *DriverName
97928a00297189c323096aae8e2975de94e8549613cyshang  )
98028a00297189c323096aae8e2975de94e8549613cyshang{
98128a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                          Status;
98228a00297189c323096aae8e2975de94e8549613cyshang  EFI_SECTION_TYPE                    SectionType;
98328a00297189c323096aae8e2975de94e8549613cyshang  UINT32                              AuthenticationStatus;
98428a00297189c323096aae8e2975de94e8549613cyshang  VOID                                *Buffer;
98538837959db04259d0dbfc1ab906330961d5f9d8elgao  VOID                                *AlignedBuffer;
98628a00297189c323096aae8e2975de94e8549613cyshang  UINTN                               BufferSize;
98738837959db04259d0dbfc1ab906330961d5f9d8elgao  EFI_FIRMWARE_VOLUME_HEADER          *FvHeader;
988022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  UINT32                              FvAlignment;
989022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng  EFI_DEVICE_PATH_PROTOCOL            *FvFileDevicePath;
99028a00297189c323096aae8e2975de94e8549613cyshang
99128a00297189c323096aae8e2975de94e8549613cyshang  //
99228a00297189c323096aae8e2975de94e8549613cyshang  // Read the first (and only the first) firmware volume section
99328a00297189c323096aae8e2975de94e8549613cyshang  //
994e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  SectionType   = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;
995e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  FvHeader      = NULL;
996e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  FvAlignment   = 0;
997e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  Buffer        = NULL;
998e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  BufferSize    = 0;
99938837959db04259d0dbfc1ab906330961d5f9d8elgao  AlignedBuffer = NULL;
100028a00297189c323096aae8e2975de94e8549613cyshang  Status = Fv->ReadSection (
1001022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                 Fv,
1002022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                 DriverName,
1003022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                 SectionType,
1004022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                 0,
1005022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                 &Buffer,
1006e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang                 &BufferSize,
1007e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang                 &AuthenticationStatus
1008e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang                 );
100928a00297189c323096aae8e2975de94e8549613cyshang  if (!EFI_ERROR (Status)) {
1010022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng     //
1011022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng    // Evaluate the authentication status of the Firmware Volume through
1012022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng    // Security Architectural Protocol
1013022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng    //
1014022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng    if (gSecurity != NULL) {
1015022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng      FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName);
1016022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng      Status = gSecurity->FileAuthenticationState (
1017022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng                            gSecurity,
1018022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng                            AuthenticationStatus,
1019022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng                            FvFileDevicePath
1020022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng                            );
1021022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng      if (FvFileDevicePath != NULL) {
1022022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng        FreePool (FvFileDevicePath);
1023022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng      }
1024022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng
1025022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng      if (Status != EFI_SUCCESS) {
1026022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng        //
1027022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng        // Security check failed. The firmware volume should not be used for any purpose.
1028022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng        //
1029022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng        if (Buffer != NULL) {
1030022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng          FreePool (Buffer);
1031022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng        }
1032022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng        return Status;
1033022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng      }
1034022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng    }
1035022ff6bbba14e86ad721de66d43e0ddb2109ff8alzeng
103628a00297189c323096aae8e2975de94e8549613cyshang    //
103738837959db04259d0dbfc1ab906330961d5f9d8elgao    // FvImage should be at its required alignment.
103828a00297189c323096aae8e2975de94e8549613cyshang    //
103938837959db04259d0dbfc1ab906330961d5f9d8elgao    FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;
10406d9a0f280d49fd1000fa685ee1392f45ff998e69lgao    //
10413837e91c58d4b626a91895b68b32cb59679787e8Star Zeng    // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume
10423837e91c58d4b626a91895b68b32cb59679787e8Star Zeng    // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from
10433837e91c58d4b626a91895b68b32cb59679787e8Star Zeng    // its initial linked location and maintain its alignment.
10446d9a0f280d49fd1000fa685ee1392f45ff998e69lgao    //
10453837e91c58d4b626a91895b68b32cb59679787e8Star Zeng    if ((FvHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {
104638837959db04259d0dbfc1ab906330961d5f9d8elgao      //
10473837e91c58d4b626a91895b68b32cb59679787e8Star Zeng      // Get FvHeader alignment
104838837959db04259d0dbfc1ab906330961d5f9d8elgao      //
10493837e91c58d4b626a91895b68b32cb59679787e8Star Zeng      FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);
105038837959db04259d0dbfc1ab906330961d5f9d8elgao      //
10513837e91c58d4b626a91895b68b32cb59679787e8Star Zeng      // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.
105238837959db04259d0dbfc1ab906330961d5f9d8elgao      //
10533837e91c58d4b626a91895b68b32cb59679787e8Star Zeng      if (FvAlignment < 8) {
10543837e91c58d4b626a91895b68b32cb59679787e8Star Zeng        FvAlignment = 8;
10553837e91c58d4b626a91895b68b32cb59679787e8Star Zeng      }
10563837e91c58d4b626a91895b68b32cb59679787e8Star Zeng      //
10573837e91c58d4b626a91895b68b32cb59679787e8Star Zeng      // Allocate the aligned buffer for the FvImage.
10583837e91c58d4b626a91895b68b32cb59679787e8Star Zeng      //
10593837e91c58d4b626a91895b68b32cb59679787e8Star Zeng      AlignedBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment);
10603837e91c58d4b626a91895b68b32cb59679787e8Star Zeng      if (AlignedBuffer == NULL) {
10613837e91c58d4b626a91895b68b32cb59679787e8Star Zeng        FreePool (Buffer);
10623837e91c58d4b626a91895b68b32cb59679787e8Star Zeng        return EFI_OUT_OF_RESOURCES;
10633837e91c58d4b626a91895b68b32cb59679787e8Star Zeng      } else {
10643837e91c58d4b626a91895b68b32cb59679787e8Star Zeng        //
10653837e91c58d4b626a91895b68b32cb59679787e8Star Zeng        // Move FvImage into the aligned buffer and release the original buffer.
10663837e91c58d4b626a91895b68b32cb59679787e8Star Zeng        //
10673837e91c58d4b626a91895b68b32cb59679787e8Star Zeng        CopyMem (AlignedBuffer, Buffer, BufferSize);
10683837e91c58d4b626a91895b68b32cb59679787e8Star Zeng        FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) AlignedBuffer;
10693837e91c58d4b626a91895b68b32cb59679787e8Star Zeng        CoreFreePool (Buffer);
10703837e91c58d4b626a91895b68b32cb59679787e8Star Zeng        Buffer = NULL;
10713837e91c58d4b626a91895b68b32cb59679787e8Star Zeng      }
107238837959db04259d0dbfc1ab906330961d5f9d8elgao    }
10733837e91c58d4b626a91895b68b32cb59679787e8Star Zeng    //
10743837e91c58d4b626a91895b68b32cb59679787e8Star Zeng    // Produce a FVB protocol for the file
10753837e91c58d4b626a91895b68b32cb59679787e8Star Zeng    //
10763837e91c58d4b626a91895b68b32cb59679787e8Star Zeng    Status = ProduceFVBProtocolOnBuffer (
10773837e91c58d4b626a91895b68b32cb59679787e8Star Zeng              (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,
10783837e91c58d4b626a91895b68b32cb59679787e8Star Zeng              (UINT64)BufferSize,
10793837e91c58d4b626a91895b68b32cb59679787e8Star Zeng              FvHandle,
10803837e91c58d4b626a91895b68b32cb59679787e8Star Zeng              AuthenticationStatus,
10813837e91c58d4b626a91895b68b32cb59679787e8Star Zeng              NULL
10823837e91c58d4b626a91895b68b32cb59679787e8Star Zeng              );
108328a00297189c323096aae8e2975de94e8549613cyshang  }
108428a00297189c323096aae8e2975de94e8549613cyshang
1085022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  if (EFI_ERROR (Status)) {
108638837959db04259d0dbfc1ab906330961d5f9d8elgao    //
108738837959db04259d0dbfc1ab906330961d5f9d8elgao    // ReadSection or Produce FVB failed, Free data buffer
108838837959db04259d0dbfc1ab906330961d5f9d8elgao    //
108938837959db04259d0dbfc1ab906330961d5f9d8elgao    if (Buffer != NULL) {
10909c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang      FreePool (Buffer);
109138837959db04259d0dbfc1ab906330961d5f9d8elgao    }
1092022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
109338837959db04259d0dbfc1ab906330961d5f9d8elgao    if (AlignedBuffer != NULL) {
1094b2c5e194a80f85c733a57814dece83a4b816f07blgao      FreeAlignedPages (AlignedBuffer, EFI_SIZE_TO_PAGES (BufferSize));
109538837959db04259d0dbfc1ab906330961d5f9d8elgao    }
109628a00297189c323096aae8e2975de94e8549613cyshang  }
109728a00297189c323096aae8e2975de94e8549613cyshang
109828a00297189c323096aae8e2975de94e8549613cyshang  return Status;
109928a00297189c323096aae8e2975de94e8549613cyshang}
110028a00297189c323096aae8e2975de94e8549613cyshang
110128a00297189c323096aae8e2975de94e8549613cyshang
1102162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
1103162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Event notification that is fired every time a FV dispatch protocol is added.
110428a00297189c323096aae8e2975de94e8549613cyshang  More than one protocol may have been added when this event is fired, so you
110528a00297189c323096aae8e2975de94e8549613cyshang  must loop on CoreLocateHandle () to see how many protocols were added and
110628a00297189c323096aae8e2975de94e8549613cyshang  do the following to each FV:
1107162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  If the Fv has already been processed, skip it. If the Fv has not been
110828a00297189c323096aae8e2975de94e8549613cyshang  processed then mark it as being processed, as we are about to process it.
1109162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Read the Fv and add any driver in the Fv to the mDiscoveredList.The
111028a00297189c323096aae8e2975de94e8549613cyshang  mDiscoveredList is never free'ed and contains variables that define
1111162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  the other states the DXE driver transitions to..
111228a00297189c323096aae8e2975de94e8549613cyshang  While you are at it read the A Priori file into memory.
111328a00297189c323096aae8e2975de94e8549613cyshang  Place drivers in the A Priori list onto the mScheduledQueue.
111428a00297189c323096aae8e2975de94e8549613cyshang
1115022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang  @param  Event                 The Event that is being processed, not used.
1116162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  @param  Context               Event Context, not used.
111728a00297189c323096aae8e2975de94e8549613cyshang
1118162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
1119162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangVOID
1120162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangEFIAPI
1121162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreFwVolEventProtocolNotify (
1122162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  EFI_EVENT       Event,
1123162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  IN  VOID            *Context
1124162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
112528a00297189c323096aae8e2975de94e8549613cyshang{
112628a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                    Status;
112728a00297189c323096aae8e2975de94e8549613cyshang  EFI_STATUS                    GetNextFileStatus;
11280c2b5da80e9551286cd02a92d91090290ae2d816qwang  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
112928a00297189c323096aae8e2975de94e8549613cyshang  EFI_DEVICE_PATH_PROTOCOL      *FvDevicePath;
113028a00297189c323096aae8e2975de94e8549613cyshang  EFI_HANDLE                    FvHandle;
113128a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         BufferSize;
113228a00297189c323096aae8e2975de94e8549613cyshang  EFI_GUID                      NameGuid;
113328a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         Key;
113428a00297189c323096aae8e2975de94e8549613cyshang  EFI_FV_FILETYPE               Type;
113528a00297189c323096aae8e2975de94e8549613cyshang  EFI_FV_FILE_ATTRIBUTES        Attributes;
113628a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         Size;
113728a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY         *DriverEntry;
113828a00297189c323096aae8e2975de94e8549613cyshang  EFI_GUID                      *AprioriFile;
113928a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         AprioriEntryCount;
114028a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         Index;
114128a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY                    *Link;
114228a00297189c323096aae8e2975de94e8549613cyshang  UINT32                        AuthenticationStatus;
114328a00297189c323096aae8e2975de94e8549613cyshang  UINTN                         SizeOfBuffer;
1144d3592549901814d6f542996c12505e56e26219f1lgao  VOID                          *DepexBuffer;
11452fc46f86f91daf139ffb1bf20500d8254f037d2blgao  KNOWN_HANDLE                  *KnownHandle;
114628a00297189c323096aae8e2975de94e8549613cyshang
11474e1005eca7186cbe61aaae09108f6fdf29959f22Eric Dong  FvHandle = NULL;
11484e1005eca7186cbe61aaae09108f6fdf29959f22Eric Dong
114928a00297189c323096aae8e2975de94e8549613cyshang  while (TRUE) {
115028a00297189c323096aae8e2975de94e8549613cyshang    BufferSize = sizeof (EFI_HANDLE);
115128a00297189c323096aae8e2975de94e8549613cyshang    Status = CoreLocateHandle (
1152e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang               ByRegisterNotify,
1153e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang               NULL,
1154e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang               mFwVolEventRegistration,
1155e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang               &BufferSize,
1156e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang               &FvHandle
1157e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang               );
115828a00297189c323096aae8e2975de94e8549613cyshang    if (EFI_ERROR (Status)) {
115928a00297189c323096aae8e2975de94e8549613cyshang      //
116028a00297189c323096aae8e2975de94e8549613cyshang      // If no more notification events exit
116128a00297189c323096aae8e2975de94e8549613cyshang      //
116228a00297189c323096aae8e2975de94e8549613cyshang      return;
116328a00297189c323096aae8e2975de94e8549613cyshang    }
116428a00297189c323096aae8e2975de94e8549613cyshang
116528a00297189c323096aae8e2975de94e8549613cyshang    if (FvHasBeenProcessed (FvHandle)) {
116628a00297189c323096aae8e2975de94e8549613cyshang      //
116728a00297189c323096aae8e2975de94e8549613cyshang      // This Fv has already been processed so lets skip it!
116828a00297189c323096aae8e2975de94e8549613cyshang      //
116928a00297189c323096aae8e2975de94e8549613cyshang      continue;
117028a00297189c323096aae8e2975de94e8549613cyshang    }
117128a00297189c323096aae8e2975de94e8549613cyshang
117228a00297189c323096aae8e2975de94e8549613cyshang    //
117328a00297189c323096aae8e2975de94e8549613cyshang    // Since we are about to process this Fv mark it as processed.
117428a00297189c323096aae8e2975de94e8549613cyshang    //
11752fc46f86f91daf139ffb1bf20500d8254f037d2blgao    KnownHandle = FvIsBeingProcesssed (FvHandle);
11762fc46f86f91daf139ffb1bf20500d8254f037d2blgao    if (KnownHandle == NULL) {
11772fc46f86f91daf139ffb1bf20500d8254f037d2blgao      //
11782fc46f86f91daf139ffb1bf20500d8254f037d2blgao      // The FV with the same FV name guid has already been processed.
11792fc46f86f91daf139ffb1bf20500d8254f037d2blgao      // So lets skip it!
11802fc46f86f91daf139ffb1bf20500d8254f037d2blgao      //
11812fc46f86f91daf139ffb1bf20500d8254f037d2blgao      continue;
11822fc46f86f91daf139ffb1bf20500d8254f037d2blgao    }
118328a00297189c323096aae8e2975de94e8549613cyshang
11840c2b5da80e9551286cd02a92d91090290ae2d816qwang    Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);
1185d2fbaaab17945b59ca66bcd2f72e26ba3361e1d0rsun    if (EFI_ERROR (Status) || Fv == NULL) {
118628a00297189c323096aae8e2975de94e8549613cyshang      //
1187cd539d485db6356c59271e031b8fb05a4a6a66a9mdkinney      // FvHandle must have Firmware Volume2 protocol thus we should never get here.
118828a00297189c323096aae8e2975de94e8549613cyshang      //
118928a00297189c323096aae8e2975de94e8549613cyshang      ASSERT (FALSE);
119028a00297189c323096aae8e2975de94e8549613cyshang      continue;
119128a00297189c323096aae8e2975de94e8549613cyshang    }
1192022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
119328a00297189c323096aae8e2975de94e8549613cyshang    Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
119428a00297189c323096aae8e2975de94e8549613cyshang    if (EFI_ERROR (Status)) {
119528a00297189c323096aae8e2975de94e8549613cyshang      //
119628a00297189c323096aae8e2975de94e8549613cyshang      // The Firmware volume doesn't have device path, can't be dispatched.
119728a00297189c323096aae8e2975de94e8549613cyshang      //
119828a00297189c323096aae8e2975de94e8549613cyshang      continue;
119928a00297189c323096aae8e2975de94e8549613cyshang    }
1200022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
120128a00297189c323096aae8e2975de94e8549613cyshang    //
1202022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang    // Discover Drivers in FV and add them to the Discovered Driver List.
1203022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang    // Process EFI_FV_FILETYPE_DRIVER type and then EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
120428a00297189c323096aae8e2975de94e8549613cyshang    //  EFI_FV_FILETYPE_DXE_CORE is processed to produce a Loaded Image protocol for the core
120528a00297189c323096aae8e2975de94e8549613cyshang    //  EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE is processed to create a Fvb
120628a00297189c323096aae8e2975de94e8549613cyshang    //
1207e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang    for (Index = 0; Index < sizeof (mDxeFileTypes) / sizeof (EFI_FV_FILETYPE); Index++) {
120828a00297189c323096aae8e2975de94e8549613cyshang      //
120928a00297189c323096aae8e2975de94e8549613cyshang      // Initialize the search key
121028a00297189c323096aae8e2975de94e8549613cyshang      //
121128a00297189c323096aae8e2975de94e8549613cyshang      Key = 0;
121228a00297189c323096aae8e2975de94e8549613cyshang      do {
121328a00297189c323096aae8e2975de94e8549613cyshang        Type = mDxeFileTypes[Index];
121428a00297189c323096aae8e2975de94e8549613cyshang        GetNextFileStatus = Fv->GetNextFile (
1215022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                  Fv,
121628a00297189c323096aae8e2975de94e8549613cyshang                                  &Key,
1217022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                  &Type,
1218022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                  &NameGuid,
1219022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                                  &Attributes,
122028a00297189c323096aae8e2975de94e8549613cyshang                                  &Size
122128a00297189c323096aae8e2975de94e8549613cyshang                                  );
122228a00297189c323096aae8e2975de94e8549613cyshang        if (!EFI_ERROR (GetNextFileStatus)) {
122328a00297189c323096aae8e2975de94e8549613cyshang          if (Type == EFI_FV_FILETYPE_DXE_CORE) {
122428a00297189c323096aae8e2975de94e8549613cyshang            //
122528a00297189c323096aae8e2975de94e8549613cyshang            // If this is the DXE core fill in it's DevicePath & DeviceHandle
122628a00297189c323096aae8e2975de94e8549613cyshang            //
122728a00297189c323096aae8e2975de94e8549613cyshang            if (gDxeCoreLoadedImage->FilePath == NULL) {
122828a00297189c323096aae8e2975de94e8549613cyshang              if (CompareGuid (&NameGuid, gDxeCoreFileName)) {
122928a00297189c323096aae8e2975de94e8549613cyshang                //
123028a00297189c323096aae8e2975de94e8549613cyshang                // Maybe One specail Fv cantains only one DXE_CORE module, so its device path must
123128a00297189c323096aae8e2975de94e8549613cyshang                // be initialized completely.
123228a00297189c323096aae8e2975de94e8549613cyshang                //
123328a00297189c323096aae8e2975de94e8549613cyshang                EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid);
12341232b21473646661a4ac1ae4b7bf5113d4613e83klu                SetDevicePathEndNode (&mFvDevicePath.End);
123528a00297189c323096aae8e2975de94e8549613cyshang
12369c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang                gDxeCoreLoadedImage->FilePath = DuplicateDevicePath (
123728a00297189c323096aae8e2975de94e8549613cyshang                                                  (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
123828a00297189c323096aae8e2975de94e8549613cyshang                                                  );
123928a00297189c323096aae8e2975de94e8549613cyshang                gDxeCoreLoadedImage->DeviceHandle = FvHandle;
124028a00297189c323096aae8e2975de94e8549613cyshang              }
124128a00297189c323096aae8e2975de94e8549613cyshang            }
124228a00297189c323096aae8e2975de94e8549613cyshang          } else if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
124328a00297189c323096aae8e2975de94e8549613cyshang            //
1244022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang            // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
1245bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang            // been extracted.
1246bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang            //
12472fc46f86f91daf139ffb1bf20500d8254f037d2blgao            if (FvFoundInHobFv2 (&KnownHandle->FvNameGuid, &NameGuid)) {
1248bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang              continue;
1249bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang            }
1250d3592549901814d6f542996c12505e56e26219f1lgao
1251d3592549901814d6f542996c12505e56e26219f1lgao            //
1252d3592549901814d6f542996c12505e56e26219f1lgao            // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has PEI depex section.
1253d3592549901814d6f542996c12505e56e26219f1lgao            //
1254d3592549901814d6f542996c12505e56e26219f1lgao            DepexBuffer  = NULL;
1255d3592549901814d6f542996c12505e56e26219f1lgao            SizeOfBuffer = 0;
1256d3592549901814d6f542996c12505e56e26219f1lgao            Status = Fv->ReadSection (
1257d3592549901814d6f542996c12505e56e26219f1lgao                           Fv,
1258d3592549901814d6f542996c12505e56e26219f1lgao                           &NameGuid,
1259d3592549901814d6f542996c12505e56e26219f1lgao                           EFI_SECTION_PEI_DEPEX,
1260d3592549901814d6f542996c12505e56e26219f1lgao                           0,
1261d3592549901814d6f542996c12505e56e26219f1lgao                           &DepexBuffer,
1262d3592549901814d6f542996c12505e56e26219f1lgao                           &SizeOfBuffer,
1263d3592549901814d6f542996c12505e56e26219f1lgao                           &AuthenticationStatus
1264d3592549901814d6f542996c12505e56e26219f1lgao                           );
1265d3592549901814d6f542996c12505e56e26219f1lgao            if (!EFI_ERROR (Status)) {
1266d3592549901814d6f542996c12505e56e26219f1lgao              //
1267d3592549901814d6f542996c12505e56e26219f1lgao              // If PEI depex section is found, this FV image will be ignored in DXE phase.
1268d3592549901814d6f542996c12505e56e26219f1lgao              // Now, DxeCore doesn't support FV image with more one type DEPEX section.
1269d3592549901814d6f542996c12505e56e26219f1lgao              //
1270d3592549901814d6f542996c12505e56e26219f1lgao              FreePool (DepexBuffer);
1271d3592549901814d6f542996c12505e56e26219f1lgao              continue;
1272d3592549901814d6f542996c12505e56e26219f1lgao            }
1273d3592549901814d6f542996c12505e56e26219f1lgao
1274bbc0f1bb24d1685a72f99a98ec1ae86e95891bb0qwang            //
1275d3592549901814d6f542996c12505e56e26219f1lgao            // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has SMM depex section.
127628a00297189c323096aae8e2975de94e8549613cyshang            //
1277d3592549901814d6f542996c12505e56e26219f1lgao            DepexBuffer  = NULL;
1278d3592549901814d6f542996c12505e56e26219f1lgao            SizeOfBuffer = 0;
1279d3592549901814d6f542996c12505e56e26219f1lgao            Status = Fv->ReadSection (
1280d3592549901814d6f542996c12505e56e26219f1lgao                           Fv,
1281d3592549901814d6f542996c12505e56e26219f1lgao                           &NameGuid,
1282d3592549901814d6f542996c12505e56e26219f1lgao                           EFI_SECTION_SMM_DEPEX,
1283d3592549901814d6f542996c12505e56e26219f1lgao                           0,
1284d3592549901814d6f542996c12505e56e26219f1lgao                           &DepexBuffer,
1285d3592549901814d6f542996c12505e56e26219f1lgao                           &SizeOfBuffer,
1286d3592549901814d6f542996c12505e56e26219f1lgao                           &AuthenticationStatus
1287d3592549901814d6f542996c12505e56e26219f1lgao                           );
1288d3592549901814d6f542996c12505e56e26219f1lgao            if (!EFI_ERROR (Status)) {
1289d3592549901814d6f542996c12505e56e26219f1lgao              //
1290d3592549901814d6f542996c12505e56e26219f1lgao              // If SMM depex section is found, this FV image will be ignored in DXE phase.
1291d3592549901814d6f542996c12505e56e26219f1lgao              // Now, DxeCore doesn't support FV image with more one type DEPEX section.
1292d3592549901814d6f542996c12505e56e26219f1lgao              //
1293d3592549901814d6f542996c12505e56e26219f1lgao              FreePool (DepexBuffer);
1294d3592549901814d6f542996c12505e56e26219f1lgao              continue;
1295d3592549901814d6f542996c12505e56e26219f1lgao            }
1296d3592549901814d6f542996c12505e56e26219f1lgao
1297d3592549901814d6f542996c12505e56e26219f1lgao            //
1298d3592549901814d6f542996c12505e56e26219f1lgao            // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has DXE depex section.
1299d3592549901814d6f542996c12505e56e26219f1lgao            //
1300d3592549901814d6f542996c12505e56e26219f1lgao            DepexBuffer  = NULL;
1301d3592549901814d6f542996c12505e56e26219f1lgao            SizeOfBuffer = 0;
1302d3592549901814d6f542996c12505e56e26219f1lgao            Status = Fv->ReadSection (
1303d3592549901814d6f542996c12505e56e26219f1lgao                           Fv,
1304d3592549901814d6f542996c12505e56e26219f1lgao                           &NameGuid,
1305d3592549901814d6f542996c12505e56e26219f1lgao                           EFI_SECTION_DXE_DEPEX,
1306d3592549901814d6f542996c12505e56e26219f1lgao                           0,
1307d3592549901814d6f542996c12505e56e26219f1lgao                           &DepexBuffer,
1308d3592549901814d6f542996c12505e56e26219f1lgao                           &SizeOfBuffer,
1309d3592549901814d6f542996c12505e56e26219f1lgao                           &AuthenticationStatus
1310d3592549901814d6f542996c12505e56e26219f1lgao                           );
1311d3592549901814d6f542996c12505e56e26219f1lgao            if (EFI_ERROR (Status)) {
1312d3592549901814d6f542996c12505e56e26219f1lgao              //
1313d3592549901814d6f542996c12505e56e26219f1lgao              // If no depex section, produce a firmware volume block protocol for it so it gets dispatched from.
1314d3592549901814d6f542996c12505e56e26219f1lgao              //
1315d3592549901814d6f542996c12505e56e26219f1lgao              CoreProcessFvImageFile (Fv, FvHandle, &NameGuid);
1316d3592549901814d6f542996c12505e56e26219f1lgao            } else {
1317d3592549901814d6f542996c12505e56e26219f1lgao              //
1318d3592549901814d6f542996c12505e56e26219f1lgao              // If depex section is found, this FV image will be dispatched until its depex is evaluated to TRUE.
1319d3592549901814d6f542996c12505e56e26219f1lgao              //
1320d3592549901814d6f542996c12505e56e26219f1lgao              FreePool (DepexBuffer);
1321d3592549901814d6f542996c12505e56e26219f1lgao              CoreAddToDriverList (Fv, FvHandle, &NameGuid, Type);
1322d3592549901814d6f542996c12505e56e26219f1lgao            }
132328a00297189c323096aae8e2975de94e8549613cyshang          } else {
132428a00297189c323096aae8e2975de94e8549613cyshang            //
132528a00297189c323096aae8e2975de94e8549613cyshang            // Transition driver from Undiscovered to Discovered state
132628a00297189c323096aae8e2975de94e8549613cyshang            //
1327d3592549901814d6f542996c12505e56e26219f1lgao            CoreAddToDriverList (Fv, FvHandle, &NameGuid, Type);
132828a00297189c323096aae8e2975de94e8549613cyshang          }
132928a00297189c323096aae8e2975de94e8549613cyshang        }
133028a00297189c323096aae8e2975de94e8549613cyshang      } while (!EFI_ERROR (GetNextFileStatus));
133128a00297189c323096aae8e2975de94e8549613cyshang    }
1332022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
133328a00297189c323096aae8e2975de94e8549613cyshang    //
133428a00297189c323096aae8e2975de94e8549613cyshang    // Read the array of GUIDs from the Apriori file if it is present in the firmware volume
133528a00297189c323096aae8e2975de94e8549613cyshang    //
133628a00297189c323096aae8e2975de94e8549613cyshang    AprioriFile = NULL;
133728a00297189c323096aae8e2975de94e8549613cyshang    Status = Fv->ReadSection (
133828a00297189c323096aae8e2975de94e8549613cyshang                  Fv,
133928a00297189c323096aae8e2975de94e8549613cyshang                  &gAprioriGuid,
134028a00297189c323096aae8e2975de94e8549613cyshang                  EFI_SECTION_RAW,
134128a00297189c323096aae8e2975de94e8549613cyshang                  0,
134228a00297189c323096aae8e2975de94e8549613cyshang                  (VOID **)&AprioriFile,
134328a00297189c323096aae8e2975de94e8549613cyshang                  &SizeOfBuffer,
134428a00297189c323096aae8e2975de94e8549613cyshang                  &AuthenticationStatus
134528a00297189c323096aae8e2975de94e8549613cyshang                  );
134628a00297189c323096aae8e2975de94e8549613cyshang    if (!EFI_ERROR (Status)) {
134728a00297189c323096aae8e2975de94e8549613cyshang      AprioriEntryCount = SizeOfBuffer / sizeof (EFI_GUID);
134828a00297189c323096aae8e2975de94e8549613cyshang    } else {
134928a00297189c323096aae8e2975de94e8549613cyshang      AprioriEntryCount = 0;
135028a00297189c323096aae8e2975de94e8549613cyshang    }
135128a00297189c323096aae8e2975de94e8549613cyshang
135228a00297189c323096aae8e2975de94e8549613cyshang    //
135328a00297189c323096aae8e2975de94e8549613cyshang    // Put drivers on Apriori List on the Scheduled queue. The Discovered List includes
135428a00297189c323096aae8e2975de94e8549613cyshang    // drivers not in the current FV and these must be skipped since the a priori list
135528a00297189c323096aae8e2975de94e8549613cyshang    // is only valid for the FV that it resided in.
135628a00297189c323096aae8e2975de94e8549613cyshang    //
1357022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang
135828a00297189c323096aae8e2975de94e8549613cyshang    for (Index = 0; Index < AprioriEntryCount; Index++) {
135928a00297189c323096aae8e2975de94e8549613cyshang      for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
136028a00297189c323096aae8e2975de94e8549613cyshang        DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
136128a00297189c323096aae8e2975de94e8549613cyshang        if (CompareGuid (&DriverEntry->FileName, &AprioriFile[Index]) &&
136228a00297189c323096aae8e2975de94e8549613cyshang            (FvHandle == DriverEntry->FvHandle)) {
13636a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney          CoreAcquireDispatcherLock ();
136428a00297189c323096aae8e2975de94e8549613cyshang          DriverEntry->Dependent = FALSE;
136528a00297189c323096aae8e2975de94e8549613cyshang          DriverEntry->Scheduled = TRUE;
136628a00297189c323096aae8e2975de94e8549613cyshang          InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
13676a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney          CoreReleaseDispatcherLock ();
13686a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney          DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName));
13696a55eea3eba088eaaad7c7f1f14580016c37406bmdkinney          DEBUG ((DEBUG_DISPATCH, "  RESULT = TRUE (Apriori)\n"));
137028a00297189c323096aae8e2975de94e8549613cyshang          break;
137128a00297189c323096aae8e2975de94e8549613cyshang        }
137228a00297189c323096aae8e2975de94e8549613cyshang      }
137328a00297189c323096aae8e2975de94e8549613cyshang    }
137428a00297189c323096aae8e2975de94e8549613cyshang
137528a00297189c323096aae8e2975de94e8549613cyshang    //
1376022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang    // Free data allocated by Fv->ReadSection ()
137728a00297189c323096aae8e2975de94e8549613cyshang    //
1378022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang    CoreFreePool (AprioriFile);
137928a00297189c323096aae8e2975de94e8549613cyshang  }
138028a00297189c323096aae8e2975de94e8549613cyshang}
138128a00297189c323096aae8e2975de94e8549613cyshang
138228a00297189c323096aae8e2975de94e8549613cyshang
138328a00297189c323096aae8e2975de94e8549613cyshang
1384162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
138528a00297189c323096aae8e2975de94e8549613cyshang  Initialize the dispatcher. Initialize the notification function that runs when
1386e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang  an FV2 protocol is added to the system.
138728a00297189c323096aae8e2975de94e8549613cyshang
1388162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
1389162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangVOID
1390162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuangCoreInitializeDispatcher (
1391162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  VOID
1392162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  )
139328a00297189c323096aae8e2975de94e8549613cyshang{
13947899b7971577075095266cc2af2010f2827e4096qhuang  mFwVolEvent = EfiCreateProtocolNotifyEvent (
1395022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang                  &gEfiFirmwareVolume2ProtocolGuid,
139628a00297189c323096aae8e2975de94e8549613cyshang                  TPL_CALLBACK,
139728a00297189c323096aae8e2975de94e8549613cyshang                  CoreFwVolEventProtocolNotify,
139828a00297189c323096aae8e2975de94e8549613cyshang                  NULL,
13997899b7971577075095266cc2af2010f2827e4096qhuang                  &mFwVolEventRegistration
140028a00297189c323096aae8e2975de94e8549613cyshang                  );
140128a00297189c323096aae8e2975de94e8549613cyshang}
140228a00297189c323096aae8e2975de94e8549613cyshang
140328a00297189c323096aae8e2975de94e8549613cyshang//
140428a00297189c323096aae8e2975de94e8549613cyshang// Function only used in debug builds
140528a00297189c323096aae8e2975de94e8549613cyshang//
1406162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
1407162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/**
1408162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  Traverse the discovered list for any drivers that were discovered but not loaded
1409162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang  because the dependency experessions evaluated to false.
1410162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang
1411162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/
141228a00297189c323096aae8e2975de94e8549613cyshangVOID
141328a00297189c323096aae8e2975de94e8549613cyshangCoreDisplayDiscoveredNotDispatched (
141428a00297189c323096aae8e2975de94e8549613cyshang  VOID
141528a00297189c323096aae8e2975de94e8549613cyshang  )
141628a00297189c323096aae8e2975de94e8549613cyshang{
141728a00297189c323096aae8e2975de94e8549613cyshang  LIST_ENTRY                    *Link;
141828a00297189c323096aae8e2975de94e8549613cyshang  EFI_CORE_DRIVER_ENTRY         *DriverEntry;
141928a00297189c323096aae8e2975de94e8549613cyshang
142028a00297189c323096aae8e2975de94e8549613cyshang  for (Link = mDiscoveredList.ForwardLink;Link !=&mDiscoveredList; Link = Link->ForwardLink) {
142128a00297189c323096aae8e2975de94e8549613cyshang    DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
142228a00297189c323096aae8e2975de94e8549613cyshang    if (DriverEntry->Dependent) {
1423162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang      DEBUG ((DEBUG_LOAD, "Driver %g was discovered but not loaded!!\n", &DriverEntry->FileName));
142428a00297189c323096aae8e2975de94e8549613cyshang    }
142528a00297189c323096aae8e2975de94e8549613cyshang  }
142628a00297189c323096aae8e2975de94e8549613cyshang}
1427