MdeModulePkg: Process Sys Prep load options in BdsDxe driver.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17403 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Ruiyu Ni 2015-05-11 06:33:45 +00:00 committed by niruiyu
parent 573b8a86d0
commit 1634214dbb
8 changed files with 1160 additions and 1027 deletions

View File

@ -27,8 +27,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// Load Option Type
//
typedef enum {
LoadOptionTypeBoot,
LoadOptionTypeDriver,
LoadOptionTypeSysPrep,
LoadOptionTypeBoot,
LoadOptionTypeMax
} EFI_BOOT_MANAGER_LOAD_OPTION_TYPE;
@ -51,6 +52,7 @@ typedef struct {
EFI_DEVICE_PATH_PROTOCOL *FilePath; // Load Option Device Path
UINT8 *OptionalData; // Load Option optional data to pass into image
UINT32 OptionalDataSize; // Load Option size of OptionalData
EFI_GUID VendorGuid;
//
// Used at runtime
@ -172,11 +174,11 @@ EfiBootManagerLoadOptionToVariable (
);
/**
This function will update the Boot####/Driver#### and the BootOrder/DriverOrder
to add a new load option.
This function will update the Boot####/Driver####/SysPrep#### and the
BootOrder/DriverOrder/SysPrepOrder to add a new load option.
@param Option Pointer to load option to add.
@param Position Position of the new load option to put in the BootOrder/DriverOrder.
@param Position Position of the new load option to put in the BootOrder/DriverOrder/SysPrepOrder.
@retval EFI_SUCCESS The load option has been successfully added.
@retval Others Error status returned by RT->SetVariable.
@ -458,17 +460,20 @@ EfiBootManagerConnectAll (
/**
This function will create all handles associate with every device
path node. If the handle associate with one device path node can not
be created successfully, then still give one chance to do the dispatch,
be created successfully, then still give chance to do the dispatch,
which load the missing drivers if possible.
@param DevicePathToConnect The device path which will be connected, it CANNOT be
@param DevicePathToConnect The device path which will be connected, it can be
a multi-instance device path
@param MatchingHandle Return the controller handle closest to the DevicePathToConnect
@retval EFI_INVALID_PARAMETER DevicePathToConnect is NULL.
@retval EFI_NOT_FOUND Failed to create all handles associate with every device path node.
@retval EFI_SUCCESS Successful to create all handles associate with every device path node.
@retval EFI_SUCCESS All handles associate with every device path node
have been created.
@retval EFI_OUT_OF_RESOURCES There is no resource to create new handles.
@retval EFI_NOT_FOUND Create the handle associate with one device path
node failed.
@retval EFI_SECURITY_VIOLATION The user has no permission to start UEFI device
drivers on the DevicePath.
**/
EFI_STATUS
EFIAPI
@ -508,8 +513,12 @@ typedef enum {
/**
This function will connect all the console devices base on the console
device variable ConIn, ConOut and ErrOut.
@retval EFI_DEVICE_ERROR All the consoles were not connected due to an error.
@retval EFI_SUCCESS Success connect any one instance of the console
device path base on the variable ConVarName.
**/
VOID
EFI_STATUS
EFIAPI
EfiBootManagerConnectAllDefaultConsoles (
VOID
@ -654,4 +663,19 @@ EfiBootManagerFreeDriverHealthInfo (
UINTN Count
);
/**
Process (load and execute) the load option.
@param LoadOption Pointer to the load option.
@retval EFI_INVALID_PARAMETER The load option type is invalid,
or the load option file path doesn't point to a valid file.
@retval EFI_UNSUPPORTED The load option type is of LoadOptionTypeBoot.
@retval EFI_SUCCESS The load option is inactive, or successfully loaded and executed.
**/
EFI_STATUS
EFIAPI
EfiBootManagerProcessLoadOption (
EFI_BOOT_MANAGER_LOAD_OPTION *LoadOption
);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -102,12 +102,13 @@ EfiBootManagerConnectAll (
a multi-instance device path
@param MatchingHandle Return the controller handle closest to the DevicePathToConnect
@retval EFI_SUCCESS All handles associate with every device path node
have been created
@retval EFI_OUT_OF_RESOURCES There is no resource to create new handles
@retval EFI_NOT_FOUND Create the handle associate with one device path
node failed
@retval EFI_SUCCESS All handles associate with every device path node
have been created.
@retval EFI_OUT_OF_RESOURCES There is no resource to create new handles.
@retval EFI_NOT_FOUND Create the handle associate with one device path
node failed.
@retval EFI_SECURITY_VIOLATION The user has no permission to start UEFI device
drivers on the DevicePath.
**/
EFI_STATUS
EFIAPI
@ -166,9 +167,8 @@ EfiBootManagerConnectDevicePath (
// Connect all drivers that apply to Handle and RemainingDevicePath,
// the Recursive flag is FALSE so only one level will be expanded.
//
// Do not check the connect status here, if the connect controller fail,
// then still give the chance to do dispatch, because partial
// RemainingDevicepath may be in the new FV
// If ConnectController fails to find a driver, then still give the chance to
// do dispatch, because partial RemainingDevicePath may be in the new FV
//
// 1. If the connect fail, RemainingDevicepath and handle will not
// change, so next time will do the dispatch, then dispatch's status
@ -177,7 +177,10 @@ EfiBootManagerConnectDevicePath (
// change, then avoid the dispatch, we have chance to continue the
// next connection
//
gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);
Status = gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);
if (Status == EFI_NOT_FOUND) {
Status = EFI_SUCCESS;
}
if (MatchingHandle != NULL) {
*MatchingHandle = Handle;
}

View File

@ -695,28 +695,42 @@ EfiBootManagerConnectAllConsoles (
/**
This function will connect all the console devices base on the console
device variable ConIn, ConOut and ErrOut.
@retval EFI_DEVICE_ERROR All the consoles were not connected due to an error.
@retval EFI_SUCCESS Success connect any one instance of the console
device path base on the variable ConVarName.
**/
VOID
EFI_STATUS
EFIAPI
EfiBootManagerConnectAllDefaultConsoles (
VOID
)
{
EFI_STATUS Status;
BOOLEAN OneConnected;
BOOLEAN SystemTableUpdated;
EfiBootManagerConnectConsoleVariable (ConOut);
OneConnected = FALSE;
Status = EfiBootManagerConnectConsoleVariable (ConOut);
if (!EFI_ERROR (Status)) {
OneConnected = TRUE;
}
PERF_START (NULL, "ConOutReady", "BDS", 1);
PERF_END (NULL, "ConOutReady", "BDS", 0);
EfiBootManagerConnectConsoleVariable (ConIn);
Status = EfiBootManagerConnectConsoleVariable (ConIn);
if (!EFI_ERROR (Status)) {
OneConnected = TRUE;
}
PERF_START (NULL, "ConInReady", "BDS", 1);
PERF_END (NULL, "ConInReady", "BDS", 0);
//
// The _ModuleEntryPoint err out var is legal.
//
EfiBootManagerConnectConsoleVariable (ErrOut);
Status = EfiBootManagerConnectConsoleVariable (ErrOut);
if (!EFI_ERROR (Status)) {
OneConnected = TRUE;
}
PERF_START (NULL, "ErrOutReady", "BDS", 1);
PERF_END (NULL, "ErrOutReady", "BDS", 0);
@ -745,4 +759,6 @@ EfiBootManagerConnectAllDefaultConsoles (
&gST->Hdr.CRC32
);
}
return OneConnected ? EFI_SUCCESS : EFI_DEVICE_ERROR;
}

File diff suppressed because it is too large Load Diff

View File

@ -120,146 +120,6 @@ BmMatchDevicePaths (
return FALSE;
}
/**
Get the headers (dos, image, optional header) from an image
@param Device SimpleFileSystem device handle
@param FileName File name for the image
@param DosHeader Pointer to dos header
@param Hdr The buffer in which to return the PE32, PE32+, or TE header.
@retval EFI_SUCCESS Successfully get the machine type.
@retval EFI_NOT_FOUND The file is not found.
@retval EFI_LOAD_ERROR File is not a valid image file.
**/
EFI_STATUS
BmGetImageHeader (
IN EFI_HANDLE Device,
IN CHAR16 *FileName,
OUT EFI_IMAGE_DOS_HEADER *DosHeader,
OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
)
{
EFI_STATUS Status;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
EFI_FILE_HANDLE Root;
EFI_FILE_HANDLE ThisFile;
UINTN BufferSize;
UINT64 FileSize;
EFI_FILE_INFO *Info;
Root = NULL;
ThisFile = NULL;
//
// Handle the file system interface to the device
//
Status = gBS->HandleProtocol (
Device,
&gEfiSimpleFileSystemProtocolGuid,
(VOID *) &Volume
);
if (EFI_ERROR (Status)) {
goto Done;
}
Status = Volume->OpenVolume (
Volume,
&Root
);
if (EFI_ERROR (Status)) {
Root = NULL;
goto Done;
}
ASSERT (Root != NULL);
Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0);
if (EFI_ERROR (Status)) {
goto Done;
}
ASSERT (ThisFile != NULL);
//
// Get file size
//
BufferSize = SIZE_OF_EFI_FILE_INFO + 200;
do {
Info = NULL;
Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info);
if (EFI_ERROR (Status)) {
goto Done;
}
Status = ThisFile->GetInfo (
ThisFile,
&gEfiFileInfoGuid,
&BufferSize,
Info
);
if (!EFI_ERROR (Status)) {
break;
}
if (Status != EFI_BUFFER_TOO_SMALL) {
FreePool (Info);
goto Done;
}
FreePool (Info);
} while (TRUE);
FileSize = Info->FileSize;
FreePool (Info);
//
// Read dos header
//
BufferSize = sizeof (EFI_IMAGE_DOS_HEADER);
Status = ThisFile->Read (ThisFile, &BufferSize, DosHeader);
if (EFI_ERROR (Status) ||
BufferSize < sizeof (EFI_IMAGE_DOS_HEADER) ||
FileSize <= DosHeader->e_lfanew ||
DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
Status = EFI_LOAD_ERROR;
goto Done;
}
//
// Move to PE signature
//
Status = ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew);
if (EFI_ERROR (Status)) {
Status = EFI_LOAD_ERROR;
goto Done;
}
//
// Read and check PE signature
//
BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
Status = ThisFile->Read (ThisFile, &BufferSize, Hdr.Pe32);
if (EFI_ERROR (Status) ||
BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) ||
Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
Status = EFI_LOAD_ERROR;
goto Done;
}
//
// Check PE32 or PE32+ magic
//
if (Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
Status = EFI_LOAD_ERROR;
goto Done;
}
Done:
if (ThisFile != NULL) {
ThisFile->Close (ThisFile);
}
if (Root != NULL) {
Root->Close (Root);
}
return Status;
}
/**
This routine adjust the memory information for different memory type and
save them into the variables for next boot.
@ -505,3 +365,22 @@ BmSetVariableAndReportStatusCodeOnError (
return Status;
}
/**
Print the device path info.
@param DevicePath The device path need to print.
**/
VOID
BmPrintDp (
EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
CHAR16 *Str;
Str = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
DEBUG ((EFI_D_INFO, "%s", Str));
if (Str != NULL) {
FreePool (Str);
}
}

View File

@ -100,6 +100,37 @@ CHAR16 *
IN EFI_HANDLE Handle
);
#define BM_OPTION_NAME_LEN sizeof ("SysPrep####")
extern CHAR16 *mBmLoadOptionName[];
typedef
VOID
(*VARIABLE_VISITOR) (
CHAR16 *Name,
EFI_GUID *Guid,
VOID *Context
);
/**
Call Visitor function for each variable in variable storage.
@param Visitor Visitor function.
@param Context The context passed to Visitor function.
**/
VOID
ForEachVariable (
VARIABLE_VISITOR Visitor,
VOID *Context
);
/**
Repair all the controllers according to the Driver Health status queried.
**/
VOID
BmRepairAllControllers (
VOID
);
#define BM_HOTKEY_SIGNATURE SIGNATURE_32 ('b', 'm', 'h', 'k')
typedef struct {
UINT32 Signature;
@ -139,7 +170,7 @@ BmLoadEfiBootOption (
/**
Get the Option Number that wasn't used.
@param OrderVariableName Could be L"BootOrder" or L"DriverOrder".
@param LoadOptionType Load option type.
@param FreeOptionNumber To receive the minimal free option number.
@retval EFI_SUCCESS The option number is found
@ -149,8 +180,8 @@ BmLoadEfiBootOption (
**/
EFI_STATUS
BmGetFreeOptionNumber (
IN CHAR16 *OrderVariableName,
OUT UINT16 *FreeOptionNumber
IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType,
OUT UINT16 *FreeOptionNumber
);
/**
@ -294,6 +325,42 @@ BmSetVariableAndReportStatusCodeOnError (
IN VOID *Data
);
/**
Get the load option by its device path.
@param FilePath The device path pointing to a load option.
It could be a short-form device path.
@param FullPath Return the full device path of the load option after
short-form device path expanding.
Caller is responsible to free it.
@param FileSize Return the load option size.
@return The load option buffer. Caller is responsible to free the memory.
**/
VOID *
BmGetLoadOptionBuffer (
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
OUT EFI_DEVICE_PATH_PROTOCOL **FullPath,
OUT UINTN *FileSize
);
/**
Return whether the PE header of the load option is valid or not.
@param[in] Type The load option type.
@param[in] FileBuffer The PE file buffer of the load option.
@param[in] FileSize The size of the load option file.
@retval TRUE The PE header of the load option is valid.
@retval FALSE The PE header of the load option is not valid.
**/
BOOLEAN
BmIsLoadOptionPeHeaderValid (
IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE Type,
IN VOID *FileBuffer,
IN UINTN FileSize
);
/**
Function compares a device path data structure to that of all the nodes of a
second device path instance.
@ -361,4 +428,14 @@ BmRepairAllControllers (
VOID
);
/**
Print the device path info.
@param DevicePath The device path need to print.
**/
VOID
BmPrintDp (
EFI_DEVICE_PATH_PROTOCOL *DevicePath
);
#endif // _INTERNAL_BM_H_

View File

@ -47,6 +47,12 @@ CHAR16 *mReadOnlyVariables[] = {
EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME
};
CHAR16 *mBdsLoadOptionName[] = {
L"Driver",
L"SysPrep",
L"Boot"
};
CHAR16 mRecoveryBoot[] = L"Recovery Boot";
/**
Event to Connect ConIn.
@ -75,7 +81,7 @@ BdsDxeOnConnectConInCallBack (
// Should not enter this case, if enter, the keyboard will not work.
// May need platfrom policy to connect keyboard.
//
DEBUG ((EFI_D_WARN, "[Bds] ASSERT Connect ConIn failed!!!\n"));
DEBUG ((EFI_D_WARN, "[Bds] Connect ConIn failed - %r!!!\n", Status));
}
}
@ -553,103 +559,55 @@ DefaultBootBehavior (
}
/**
The function will go through the driver option link list, load and start
every driver the driver option device path point to.
The function will load and start every Driver####/SysPrep####.
@param DriverOption Input driver option array.
@param DriverOptionCount Input driver option count.
@param LoadOptions Load option array.
@param LoadOptionCount Load option count.
**/
VOID
LoadDrivers (
IN EFI_BOOT_MANAGER_LOAD_OPTION *DriverOption,
IN UINTN DriverOptionCount
ProcessLoadOptions (
IN EFI_BOOT_MANAGER_LOAD_OPTION *LoadOptions,
IN UINTN LoadOptionCount
)
{
EFI_STATUS Status;
UINTN Index;
EFI_HANDLE ImageHandle;
EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
BOOLEAN ReconnectAll;
EFI_STATUS Status;
UINTN Index;
BOOLEAN ReconnectAll;
EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType;
ReconnectAll = FALSE;
LoadOptionType = LoadOptionTypeMax;
//
// Process the driver option
//
for (Index = 0; Index < DriverOptionCount; Index++) {
for (Index = 0; Index < LoadOptionCount; Index++) {
//
// If a load option is not marked as LOAD_OPTION_ACTIVE,
// the boot manager will not automatically load the option.
// All the load options in the array should be of the same type.
//
if ((DriverOption[Index].Attributes & LOAD_OPTION_ACTIVE) == 0) {
continue;
if (LoadOptionType == LoadOptionTypeMax) {
LoadOptionType = LoadOptions[Index].OptionType;
}
//
// If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,
// then all of the EFI drivers in the system will be disconnected and
// reconnected after the last driver load option is processed.
//
if ((DriverOption[Index].Attributes & LOAD_OPTION_FORCE_RECONNECT) != 0) {
ASSERT (LoadOptionType == LoadOptions[Index].OptionType);
ASSERT (LoadOptionType == LoadOptionTypeDriver || LoadOptionType == LoadOptionTypeSysPrep);
Status = EfiBootManagerProcessLoadOption (&LoadOptions[Index]);
if (!EFI_ERROR (Status) && ((LoadOptions[Index].Attributes & LOAD_OPTION_FORCE_RECONNECT) != 0)) {
ReconnectAll = TRUE;
}
//
// Make sure the driver path is connected.
//
EfiBootManagerConnectDevicePath (DriverOption[Index].FilePath, NULL);
//
// Load and start the image that Driver#### describes
//
Status = gBS->LoadImage (
FALSE,
gImageHandle,
DriverOption[Index].FilePath,
NULL,
0,
&ImageHandle
);
if (!EFI_ERROR (Status)) {
gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo);
//
// Verify whether this image is a driver, if not,
// exit it and continue to parse next load option
//
if (ImageInfo->ImageCodeType != EfiBootServicesCode && ImageInfo->ImageCodeType != EfiRuntimeServicesCode) {
gBS->Exit (ImageHandle, EFI_INVALID_PARAMETER, 0, NULL);
continue;
}
ImageInfo->LoadOptionsSize = DriverOption[Index].OptionalDataSize;
ImageInfo->LoadOptions = DriverOption[Index].OptionalData;
//
// Before calling the image, enable the Watchdog Timer for
// the 5 Minute period
//
gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
DriverOption[Index].Status = gBS->StartImage (ImageHandle, &DriverOption[Index].ExitDataSize, &DriverOption[Index].ExitData);
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Driver Return Status = %r\n", DriverOption[Index].Status));
//
// Clear the Watchdog Timer after the image returns
//
gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
}
}
//
// Process the LOAD_OPTION_FORCE_RECONNECT driver option
// If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,
// then all of the EFI drivers in the system will be disconnected and
// reconnected after the last driver load option is processed.
//
if (ReconnectAll) {
if (ReconnectAll && LoadOptionType == LoadOptionTypeDriver) {
EfiBootManagerDisconnectAll ();
EfiBootManagerConnectAll ();
}
}
/**
@ -855,9 +813,8 @@ BdsEntry (
IN EFI_BDS_ARCH_PROTOCOL *This
)
{
EFI_BOOT_MANAGER_LOAD_OPTION *DriverOption;
EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
UINTN DriverOptionCount;
EFI_BOOT_MANAGER_LOAD_OPTION *LoadOptions;
UINTN LoadOptionCount;
CHAR16 *FirmwareVendor;
EFI_EVENT HotkeyTriggered;
UINT64 OsIndication;
@ -867,8 +824,11 @@ BdsEntry (
UINT16 BootTimeOut;
EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;
UINTN Index;
EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
UINT16 *BootNext;
CHAR16 BootNextVariableName[sizeof ("Boot####")];
EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu;
BOOLEAN BootFwUi;
HotkeyTriggered = NULL;
Status = EFI_SUCCESS;
@ -939,7 +899,7 @@ BdsEntry (
// Initialize L"BootOptionSupport" EFI global variable.
// Lazy-ConIn implictly disables BDS hotkey.
//
BootOptionSupport = EFI_BOOT_OPTION_SUPPORT_APP;
BootOptionSupport = EFI_BOOT_OPTION_SUPPORT_APP | EFI_BOOT_OPTION_SUPPORT_SYSPREP;
if (!PcdGetBool (PcdConInConnectOnDemand)) {
BootOptionSupport |= EFI_BOOT_OPTION_SUPPORT_KEY;
SET_BOOT_OPTION_SUPPORT_KEY_COUNT (BootOptionSupport, 3);
@ -1010,11 +970,11 @@ BdsEntry (
EfiBootManagerStartHotkeyService (&HotkeyTriggered);
//
// Load Driver Options
// Execute Driver Options
//
DriverOption = EfiBootManagerGetLoadOptions (&DriverOptionCount, LoadOptionTypeDriver);
LoadDrivers (DriverOption, DriverOptionCount);
EfiBootManagerFreeLoadOptions (DriverOption, DriverOptionCount);
LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypeDriver);
ProcessLoadOptions (LoadOptions, LoadOptionCount);
EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
//
// Connect consoles
@ -1059,23 +1019,28 @@ BdsEntry (
PERF_END (NULL, "PlatformBootManagerAfterConsole", "BDS", 0);
DEBUG_CODE (
EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
UINTN BootOptionCount;
UINTN Index;
BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
DEBUG ((EFI_D_INFO, "[Bds]=============Dumping Boot Options=============\n"));
for (Index = 0; Index < BootOptionCount; Index++) {
UINTN Index;
EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType;
DEBUG ((EFI_D_INFO, "[Bds]=============Begin Load Options Dumping ...=============\n"));
for (LoadOptionType = 0; LoadOptionType < LoadOptionTypeMax; LoadOptionType++) {
DEBUG ((
EFI_D_INFO, "[Bds]Boot%04x: %s \t\t 0x%04x\n",
BootOptions[Index].OptionNumber,
BootOptions[Index].Description,
BootOptions[Index].Attributes
EFI_D_INFO, " %s Options:\n",
mBdsLoadOptionName[LoadOptionType]
));
LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionType);
for (Index = 0; Index < LoadOptionCount; Index++) {
DEBUG ((
EFI_D_INFO, " %s%04x: %s \t\t 0x%04x\n",
mBdsLoadOptionName[LoadOptionType],
LoadOptions[Index].OptionNumber,
LoadOptions[Index].Description,
LoadOptions[Index].Attributes
));
}
EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
}
DEBUG ((EFI_D_INFO, "[Bds]=============Dumping Boot Options Finished====\n"));
EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
);
DEBUG ((EFI_D_INFO, "[Bds]=============End Load Options Dumping=============\n"));
);
//
// Boot to Boot Manager Menu when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot
@ -1088,10 +1053,15 @@ BdsEntry (
&DataSize,
&OsIndication
);
if (!EFI_ERROR(Status) && ((OsIndication & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0)) {
//
// Clear EFI_OS_INDICATIONS_BOOT_TO_FW_UI to acknowledge OS
//
if (EFI_ERROR (Status)) {
OsIndication = 0;
}
BootFwUi = (BOOLEAN) ((OsIndication & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0);
//
// Clear EFI_OS_INDICATIONS_BOOT_TO_FW_UI to acknowledge OS
//
if (BootFwUi) {
OsIndication &= ~((UINT64) EFI_OS_INDICATIONS_BOOT_TO_FW_UI);
Status = gRT->SetVariable (
L"OsIndications",
@ -1104,7 +1074,12 @@ BdsEntry (
// Changing the content without increasing its size with current variable implementation shouldn't fail.
//
ASSERT_EFI_ERROR (Status);
}
//
// Launch Boot Manager Menu directly when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot
//
if (BootFwUi) {
//
// Follow generic rule, Call BdsDxeOnConnectConInCallBack to connect ConIn before enter UI
//
@ -1113,24 +1088,35 @@ BdsEntry (
}
//
// Directly boot to Boot Manager Menu.
// Directly enter the setup page.
// BootManagerMenu always contains the correct information even call fails.
//
EfiBootManagerGetBootManagerMenu (&BootOption);
EfiBootManagerBoot (&BootOption);
EfiBootManagerFreeLoadOption (&BootOption);
} else {
PERF_START (NULL, "BdsWait", "BDS", 0);
BdsWait (HotkeyTriggered);
PERF_END (NULL, "BdsWait", "BDS", 0);
//
// BdsReadKeys() be removed after all keyboard drivers invoke callback in timer callback.
//
BdsReadKeys ();
EfiBootManagerHotkeyBoot ();
EfiBootManagerGetBootManagerMenu (&BootManagerMenu);
EfiBootManagerBoot (&BootManagerMenu);
EfiBootManagerFreeLoadOption (&BootManagerMenu);
}
//
// Execute SysPrep####
//
LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypeSysPrep);
ProcessLoadOptions (LoadOptions, LoadOptionCount);
EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
//
// Execute Key####
//
PERF_START (NULL, "BdsWait", "BDS", 0);
BdsWait (HotkeyTriggered);
PERF_END (NULL, "BdsWait", "BDS", 0);
//
// BdsReadKeys() be removed after all keyboard drivers invoke callback in timer callback.
//
BdsReadKeys ();
EfiBootManagerHotkeyBoot ();
//
// Boot to "BootNext"
//