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