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