mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-29 16:44:10 +02:00
MdeModulePkg: Enable PlatformRecovery in BdsDxe driver
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Reviewed-by: Sunny Wang <sunnywang@hpe.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18863 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
d175f4e612
commit
68456d8ac1
@ -24,9 +24,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include <Protocol/Bds.h>
|
#include <Protocol/Bds.h>
|
||||||
#include <Protocol/LoadedImage.h>
|
#include <Protocol/LoadedImage.h>
|
||||||
#include <Protocol/VariableLock.h>
|
#include <Protocol/VariableLock.h>
|
||||||
#include <Protocol/BlockIo.h>
|
|
||||||
#include <Protocol/LoadFile.h>
|
|
||||||
#include <Protocol/SimpleFileSystem.h>
|
|
||||||
|
|
||||||
#include <Library/UefiDriverEntryPoint.h>
|
#include <Library/UefiDriverEntryPoint.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
|
@ -51,10 +51,10 @@ CHAR16 *mReadOnlyVariables[] = {
|
|||||||
CHAR16 *mBdsLoadOptionName[] = {
|
CHAR16 *mBdsLoadOptionName[] = {
|
||||||
L"Driver",
|
L"Driver",
|
||||||
L"SysPrep",
|
L"SysPrep",
|
||||||
L"Boot"
|
L"Boot",
|
||||||
|
L"PlatformRecovery"
|
||||||
};
|
};
|
||||||
|
|
||||||
CHAR16 mRecoveryBoot[] = L"Recovery Boot";
|
|
||||||
/**
|
/**
|
||||||
Event to Connect ConIn.
|
Event to Connect ConIn.
|
||||||
|
|
||||||
@ -121,187 +121,6 @@ BdsInitialize (
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Emuerate all possible bootable medias in the following order:
|
|
||||||
1. Removable BlockIo - The boot option only points to the removable media
|
|
||||||
device, like USB key, DVD, Floppy etc.
|
|
||||||
2. Fixed BlockIo - The boot option only points to a Fixed blockIo device,
|
|
||||||
like HardDisk.
|
|
||||||
3. Non-BlockIo SimpleFileSystem - The boot option points to a device supporting
|
|
||||||
SimpleFileSystem Protocol, but not supporting BlockIo
|
|
||||||
protocol.
|
|
||||||
4. LoadFile - The boot option points to the media supporting
|
|
||||||
LoadFile protocol.
|
|
||||||
Reference: UEFI Spec chapter 3.3 Boot Option Variables Default Boot Behavior
|
|
||||||
|
|
||||||
@param BootOptionCount Return the boot option count which has been found.
|
|
||||||
|
|
||||||
@retval Pointer to the boot option array.
|
|
||||||
**/
|
|
||||||
EFI_BOOT_MANAGER_LOAD_OPTION *
|
|
||||||
BdsEnumerateBootOptions (
|
|
||||||
UINTN *BootOptionCount
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
|
|
||||||
UINTN HandleCount;
|
|
||||||
EFI_HANDLE *Handles;
|
|
||||||
EFI_BLOCK_IO_PROTOCOL *BlkIo;
|
|
||||||
UINTN Removable;
|
|
||||||
UINTN Index;
|
|
||||||
|
|
||||||
ASSERT (BootOptionCount != NULL);
|
|
||||||
|
|
||||||
*BootOptionCount = 0;
|
|
||||||
BootOptions = NULL;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Parse removable block io followed by fixed block io
|
|
||||||
//
|
|
||||||
gBS->LocateHandleBuffer (
|
|
||||||
ByProtocol,
|
|
||||||
&gEfiBlockIoProtocolGuid,
|
|
||||||
NULL,
|
|
||||||
&HandleCount,
|
|
||||||
&Handles
|
|
||||||
);
|
|
||||||
|
|
||||||
for (Removable = 0; Removable < 2; Removable++) {
|
|
||||||
for (Index = 0; Index < HandleCount; Index++) {
|
|
||||||
Status = gBS->HandleProtocol (
|
|
||||||
Handles[Index],
|
|
||||||
&gEfiBlockIoProtocolGuid,
|
|
||||||
(VOID **) &BlkIo
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Skip the logical partitions
|
|
||||||
//
|
|
||||||
if (BlkIo->Media->LogicalPartition) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Skip the fixed block io then the removable block io
|
|
||||||
//
|
|
||||||
if (BlkIo->Media->RemovableMedia == ((Removable == 0) ? FALSE : TRUE)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
BootOptions = ReallocatePool (
|
|
||||||
sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),
|
|
||||||
sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),
|
|
||||||
BootOptions
|
|
||||||
);
|
|
||||||
ASSERT (BootOptions != NULL);
|
|
||||||
|
|
||||||
Status = EfiBootManagerInitializeLoadOption (
|
|
||||||
&BootOptions[(*BootOptionCount)++],
|
|
||||||
LoadOptionNumberUnassigned,
|
|
||||||
LoadOptionTypeBoot,
|
|
||||||
LOAD_OPTION_ACTIVE,
|
|
||||||
mRecoveryBoot,
|
|
||||||
DevicePathFromHandle (Handles[Index]),
|
|
||||||
NULL,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HandleCount != 0) {
|
|
||||||
FreePool (Handles);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Parse simple file system not based on block io
|
|
||||||
//
|
|
||||||
gBS->LocateHandleBuffer (
|
|
||||||
ByProtocol,
|
|
||||||
&gEfiSimpleFileSystemProtocolGuid,
|
|
||||||
NULL,
|
|
||||||
&HandleCount,
|
|
||||||
&Handles
|
|
||||||
);
|
|
||||||
for (Index = 0; Index < HandleCount; Index++) {
|
|
||||||
Status = gBS->HandleProtocol (
|
|
||||||
Handles[Index],
|
|
||||||
&gEfiBlockIoProtocolGuid,
|
|
||||||
(VOID **) &BlkIo
|
|
||||||
);
|
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
//
|
|
||||||
// Skip if the file system handle supports a BlkIo protocol, which we've handled in above
|
|
||||||
//
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
BootOptions = ReallocatePool (
|
|
||||||
sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),
|
|
||||||
sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),
|
|
||||||
BootOptions
|
|
||||||
);
|
|
||||||
ASSERT (BootOptions != NULL);
|
|
||||||
|
|
||||||
Status = EfiBootManagerInitializeLoadOption (
|
|
||||||
&BootOptions[(*BootOptionCount)++],
|
|
||||||
LoadOptionNumberUnassigned,
|
|
||||||
LoadOptionTypeBoot,
|
|
||||||
LOAD_OPTION_ACTIVE,
|
|
||||||
mRecoveryBoot,
|
|
||||||
DevicePathFromHandle (Handles[Index]),
|
|
||||||
NULL,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HandleCount != 0) {
|
|
||||||
FreePool (Handles);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Parse load file, assuming UEFI Network boot option
|
|
||||||
//
|
|
||||||
gBS->LocateHandleBuffer (
|
|
||||||
ByProtocol,
|
|
||||||
&gEfiLoadFileProtocolGuid,
|
|
||||||
NULL,
|
|
||||||
&HandleCount,
|
|
||||||
&Handles
|
|
||||||
);
|
|
||||||
for (Index = 0; Index < HandleCount; Index++) {
|
|
||||||
|
|
||||||
BootOptions = ReallocatePool (
|
|
||||||
sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),
|
|
||||||
sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),
|
|
||||||
BootOptions
|
|
||||||
);
|
|
||||||
ASSERT (BootOptions != NULL);
|
|
||||||
|
|
||||||
Status = EfiBootManagerInitializeLoadOption (
|
|
||||||
&BootOptions[(*BootOptionCount)++],
|
|
||||||
LoadOptionNumberUnassigned,
|
|
||||||
LoadOptionTypeBoot,
|
|
||||||
LOAD_OPTION_ACTIVE,
|
|
||||||
mRecoveryBoot,
|
|
||||||
DevicePathFromHandle (Handles[Index]),
|
|
||||||
NULL,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HandleCount != 0) {
|
|
||||||
FreePool (Handles);
|
|
||||||
}
|
|
||||||
|
|
||||||
return BootOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Function waits for a given event to fire, or for an optional timeout to expire.
|
Function waits for a given event to fire, or for an optional timeout to expire.
|
||||||
|
|
||||||
@ -445,14 +264,16 @@ BdsWait (
|
|||||||
|
|
||||||
@param BootOptions Input boot option array.
|
@param BootOptions Input boot option array.
|
||||||
@param BootOptionCount Input boot option count.
|
@param BootOptionCount Input boot option count.
|
||||||
|
@param BootManagerMenu Input boot manager menu.
|
||||||
|
|
||||||
@retval TRUE Successfully boot one of the boot options.
|
@retval TRUE Successfully boot one of the boot options.
|
||||||
@retval FALSE Failed boot any of the boot options.
|
@retval FALSE Failed boot any of the boot options.
|
||||||
**/
|
**/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
BootAllBootOptions (
|
BootBootOptions (
|
||||||
IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions,
|
IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions,
|
||||||
IN UINTN BootOptionCount
|
IN UINTN BootOptionCount,
|
||||||
|
IN EFI_BOOT_MANAGER_LOAD_OPTION *BootManagerMenu
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
@ -486,9 +307,10 @@ BootAllBootOptions (
|
|||||||
EfiBootManagerBoot (&BootOptions[Index]);
|
EfiBootManagerBoot (&BootOptions[Index]);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Successful boot breaks the loop, otherwise tries next boot option
|
// If the boot via Boot#### returns with a status of EFI_SUCCESS, platform firmware
// supports boot manager menu, and if firmware is configured to boot in an
// interactive mode, the boot manager will stop processing the BootOrder variable and
// present a boot manager menu to the user.
|
||||||
//
|
//
|
||||||
if (BootOptions[Index].Status == EFI_SUCCESS) {
|
if (BootOptions[Index].Status == EFI_SUCCESS) {
|
||||||
|
EfiBootManagerBoot (BootManagerMenu);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -497,72 +319,10 @@ BootAllBootOptions (
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function attempts to boot per the boot order specified by platform policy.
|
The function will load and start every Driver####, SysPrep#### or PlatformRecovery####.
|
||||||
|
|
||||||
If the boot via Boot#### returns with a status of EFI_SUCCESS the boot manager will stop
|
|
||||||
processing the BootOrder variable and present a boot manager menu to the user. If a boot via
|
|
||||||
Boot#### returns a status other than EFI_SUCCESS, the boot has failed and the next Boot####
|
|
||||||
in the BootOrder variable will be tried until all possibilities are exhausted.
|
|
||||||
-- Chapter 3.1.1 Boot Manager Programming, the 4th paragraph
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
DefaultBootBehavior (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINTN BootOptionCount;
|
|
||||||
EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
|
|
||||||
EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu;
|
|
||||||
|
|
||||||
EfiBootManagerGetBootManagerMenu (&BootManagerMenu);
|
|
||||||
//
|
|
||||||
// BootManagerMenu always contains the correct information even the above function returns failure.
|
|
||||||
//
|
|
||||||
|
|
||||||
BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
|
|
||||||
|
|
||||||
if (BootAllBootOptions (BootOptions, BootOptionCount)) {
|
|
||||||
//
|
|
||||||
// Follow generic rule, Call BdsDxeOnConnectConInCallBack to connect ConIn before enter UI
|
|
||||||
//
|
|
||||||
if (PcdGetBool (PcdConInConnectOnDemand)) {
|
|
||||||
BdsDxeOnConnectConInCallBack (NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Show the Boot Manager Menu after successful boot
|
|
||||||
//
|
|
||||||
EfiBootManagerBoot (&BootManagerMenu);
|
|
||||||
} else {
|
|
||||||
EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
|
|
||||||
//
|
|
||||||
// Re-scan all EFI boot options in case all the boot#### are deleted or failed to boot
|
|
||||||
//
|
|
||||||
// If no valid boot options exist, the boot manager will enumerate all removable media
|
|
||||||
// devices followed by all fixed media devices. The order within each group is undefined.
|
|
||||||
// These new default boot options are not saved to non volatile storage.The boot manger
|
|
||||||
// will then attempt toboot from each boot option.
|
|
||||||
// -- Chapter 3.3 Boot Manager Programming, the 2nd paragraph
|
|
||||||
//
|
|
||||||
EfiBootManagerConnectAll ();
|
|
||||||
BootOptions = BdsEnumerateBootOptions (&BootOptionCount);
|
|
||||||
|
|
||||||
if (!BootAllBootOptions (BootOptions, BootOptionCount)) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "[Bds]No bootable device!\n"));
|
|
||||||
EfiBootManagerBoot (&BootManagerMenu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EfiBootManagerFreeLoadOption (&BootManagerMenu);
|
|
||||||
EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
The function will load and start every Driver####/SysPrep####.
|
|
||||||
|
|
||||||
@param LoadOptions Load option array.
|
@param LoadOptions Load option array.
|
||||||
@param LoadOptionCount Load option count.
|
@param LoadOptionCount Load option count.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
ProcessLoadOptions (
|
ProcessLoadOptions (
|
||||||
@ -575,7 +335,7 @@ ProcessLoadOptions (
|
|||||||
BOOLEAN ReconnectAll;
|
BOOLEAN ReconnectAll;
|
||||||
EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType;
|
EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType;
|
||||||
|
|
||||||
ReconnectAll = FALSE;
|
ReconnectAll = FALSE;
|
||||||
LoadOptionType = LoadOptionTypeMax;
|
LoadOptionType = LoadOptionTypeMax;
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -585,16 +345,23 @@ ProcessLoadOptions (
|
|||||||
//
|
//
|
||||||
// All the load options in the array should be of the same type.
|
// All the load options in the array should be of the same type.
|
||||||
//
|
//
|
||||||
if (LoadOptionType == LoadOptionTypeMax) {
|
if (Index == 0) {
|
||||||
LoadOptionType = LoadOptions[Index].OptionType;
|
LoadOptionType = LoadOptions[Index].OptionType;
|
||||||
}
|
}
|
||||||
ASSERT (LoadOptionType == LoadOptions[Index].OptionType);
|
ASSERT (LoadOptionType == LoadOptions[Index].OptionType);
|
||||||
ASSERT (LoadOptionType == LoadOptionTypeDriver || LoadOptionType == LoadOptionTypeSysPrep);
|
|
||||||
|
|
||||||
Status = EfiBootManagerProcessLoadOption (&LoadOptions[Index]);
|
Status = EfiBootManagerProcessLoadOption (&LoadOptions[Index]);
|
||||||
|
|
||||||
if (!EFI_ERROR (Status) && ((LoadOptions[Index].Attributes & LOAD_OPTION_FORCE_RECONNECT) != 0)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
ReconnectAll = TRUE;
|
if (LoadOptionType == LoadOptionTypePlatformRecovery) {
|
||||||
|
//
|
||||||
|
// Stop processing if any entry is successful
|
||||||
|
//
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((LoadOptions[Index].Attributes & LOAD_OPTION_FORCE_RECONNECT) != 0) {
|
||||||
|
ReconnectAll = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,7 +437,7 @@ BdsFormalizeOSIndicationVariable (
|
|||||||
//
|
//
|
||||||
// OS indicater support variable
|
// OS indicater support variable
|
||||||
//
|
//
|
||||||
OsIndicationSupport = EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
|
OsIndicationSupport = EFI_OS_INDICATIONS_BOOT_TO_FW_UI | EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY;
|
||||||
Status = gRT->SetVariable (
|
Status = gRT->SetVariable (
|
||||||
EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME,
|
EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME,
|
||||||
&gEfiGlobalVariableGuid,
|
&gEfiGlobalVariableGuid,
|
||||||
@ -828,10 +595,13 @@ BdsEntry (
|
|||||||
CHAR16 BootNextVariableName[sizeof ("Boot####")];
|
CHAR16 BootNextVariableName[sizeof ("Boot####")];
|
||||||
EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu;
|
EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu;
|
||||||
BOOLEAN BootFwUi;
|
BOOLEAN BootFwUi;
|
||||||
|
BOOLEAN PlatformRecovery;
|
||||||
|
BOOLEAN BootSuccess;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *FilePath;
|
EFI_DEVICE_PATH_PROTOCOL *FilePath;
|
||||||
|
|
||||||
HotkeyTriggered = NULL;
|
HotkeyTriggered = NULL;
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
|
BootSuccess = FALSE;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Insert the performance probe
|
// Insert the performance probe
|
||||||
@ -1038,9 +808,24 @@ BdsEntry (
|
|||||||
PERF_START (NULL, "PlatformBootManagerAfterConsole", "BDS", 0);
|
PERF_START (NULL, "PlatformBootManagerAfterConsole", "BDS", 0);
|
||||||
PlatformBootManagerAfterConsole ();
|
PlatformBootManagerAfterConsole ();
|
||||||
PERF_END (NULL, "PlatformBootManagerAfterConsole", "BDS", 0);
|
PERF_END (NULL, "PlatformBootManagerAfterConsole", "BDS", 0);
|
||||||
|
//
|
||||||
|
// Boot to Boot Manager Menu when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot
|
||||||
|
//
|
||||||
|
DataSize = sizeof (UINT64);
|
||||||
|
Status = gRT->GetVariable (
|
||||||
|
EFI_OS_INDICATIONS_VARIABLE_NAME,
|
||||||
|
&gEfiGlobalVariableGuid,
|
||||||
|
NULL,
|
||||||
|
&DataSize,
|
||||||
|
&OsIndication
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
OsIndication = 0;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_CODE (
|
DEBUG_CODE (
|
||||||
EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType;
|
EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType;
|
||||||
|
DEBUG ((EFI_D_INFO, "[Bds]OsIndication: %016x\n", OsIndication));
|
||||||
DEBUG ((EFI_D_INFO, "[Bds]=============Begin Load Options Dumping ...=============\n"));
|
DEBUG ((EFI_D_INFO, "[Bds]=============Begin Load Options Dumping ...=============\n"));
|
||||||
for (LoadOptionType = 0; LoadOptionType < LoadOptionTypeMax; LoadOptionType++) {
|
for (LoadOptionType = 0; LoadOptionType < LoadOptionTypeMax; LoadOptionType++) {
|
||||||
DEBUG ((
|
DEBUG ((
|
||||||
@ -1063,26 +848,17 @@ BdsEntry (
|
|||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Boot to Boot Manager Menu when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot
|
// BootManagerMenu always contains the correct information even call fails.
|
||||||
//
|
//
|
||||||
DataSize = sizeof (UINT64);
|
EfiBootManagerGetBootManagerMenu (&BootManagerMenu);
|
||||||
Status = gRT->GetVariable (
|
|
||||||
EFI_OS_INDICATIONS_VARIABLE_NAME,
|
|
||||||
&gEfiGlobalVariableGuid,
|
|
||||||
NULL,
|
|
||||||
&DataSize,
|
|
||||||
&OsIndication
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
OsIndication = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
BootFwUi = (BOOLEAN) ((OsIndication & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0);
|
BootFwUi = (BOOLEAN) ((OsIndication & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0);
|
||||||
|
PlatformRecovery = (BOOLEAN) ((OsIndication & EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY) != 0);
|
||||||
//
|
//
|
||||||
// Clear EFI_OS_INDICATIONS_BOOT_TO_FW_UI to acknowledge OS
|
// Clear EFI_OS_INDICATIONS_BOOT_TO_FW_UI to acknowledge OS
|
||||||
//
|
//
|
||||||
if (BootFwUi) {
|
if (BootFwUi || PlatformRecovery) {
|
||||||
OsIndication &= ~((UINT64) EFI_OS_INDICATIONS_BOOT_TO_FW_UI);
|
OsIndication &= ~((UINT64) (EFI_OS_INDICATIONS_BOOT_TO_FW_UI | EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY));
|
||||||
Status = gRT->SetVariable (
|
Status = gRT->SetVariable (
|
||||||
EFI_OS_INDICATIONS_VARIABLE_NAME,
|
EFI_OS_INDICATIONS_VARIABLE_NAME,
|
||||||
&gEfiGlobalVariableGuid,
|
&gEfiGlobalVariableGuid,
|
||||||
@ -1109,62 +885,70 @@ BdsEntry (
|
|||||||
|
|
||||||
//
|
//
|
||||||
// Directly enter the setup page.
|
// Directly enter the setup page.
|
||||||
// BootManagerMenu always contains the correct information even call fails.
|
|
||||||
//
|
//
|
||||||
EfiBootManagerGetBootManagerMenu (&BootManagerMenu);
|
|
||||||
EfiBootManagerBoot (&BootManagerMenu);
|
EfiBootManagerBoot (&BootManagerMenu);
|
||||||
EfiBootManagerFreeLoadOption (&BootManagerMenu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
if (!PlatformRecovery) {
|
||||||
// Execute SysPrep####
|
//
|
||||||
//
|
// Execute SysPrep####
|
||||||
LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypeSysPrep);
|
//
|
||||||
ProcessLoadOptions (LoadOptions, LoadOptionCount);
|
LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypeSysPrep);
|
||||||
EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
|
ProcessLoadOptions (LoadOptions, LoadOptionCount);
|
||||||
|
EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Execute Key####
|
// Execute Key####
|
||||||
//
|
//
|
||||||
PERF_START (NULL, "BdsWait", "BDS", 0);
|
PERF_START (NULL, "BdsWait", "BDS", 0);
|
||||||
BdsWait (HotkeyTriggered);
|
BdsWait (HotkeyTriggered);
|
||||||
PERF_END (NULL, "BdsWait", "BDS", 0);
|
PERF_END (NULL, "BdsWait", "BDS", 0);
|
||||||
|
|
||||||
//
|
//
|
||||||
// BdsReadKeys() be removed after all keyboard drivers invoke callback in timer callback.
|
// BdsReadKeys() can be removed after all keyboard drivers invoke callback in timer callback.
|
||||||
//
|
//
|
||||||
BdsReadKeys ();
|
BdsReadKeys ();
|
||||||
|
|
||||||
EfiBootManagerHotkeyBoot ();
|
EfiBootManagerHotkeyBoot ();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Boot to "BootNext"
|
// Boot to "BootNext"
|
||||||
//
|
//
|
||||||
if (BootNext != NULL) {
|
if (BootNext != NULL) {
|
||||||
UnicodeSPrint (BootNextVariableName, sizeof (BootNextVariableName), L"Boot%04x", *BootNext);
|
UnicodeSPrint (BootNextVariableName, sizeof (BootNextVariableName), L"Boot%04x", *BootNext);
|
||||||
Status = EfiBootManagerVariableToLoadOption (BootNextVariableName, &LoadOption);
|
Status = EfiBootManagerVariableToLoadOption (BootNextVariableName, &LoadOption);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
EfiBootManagerBoot (&LoadOption);
|
|
||||||
EfiBootManagerFreeLoadOption (&LoadOption);
|
|
||||||
if (LoadOption.Status == EFI_SUCCESS) {
|
|
||||||
//
|
|
||||||
// Boot to Boot Manager Menu upon EFI_SUCCESS
|
|
||||||
//
|
|
||||||
EfiBootManagerGetBootManagerMenu (&LoadOption);
|
|
||||||
EfiBootManagerBoot (&LoadOption);
|
EfiBootManagerBoot (&LoadOption);
|
||||||
EfiBootManagerFreeLoadOption (&LoadOption);
|
EfiBootManagerFreeLoadOption (&LoadOption);
|
||||||
|
if (LoadOption.Status == EFI_SUCCESS) {
|
||||||
|
//
|
||||||
|
// Boot to Boot Manager Menu upon EFI_SUCCESS
|
||||||
|
//
|
||||||
|
EfiBootManagerBoot (&BootManagerMenu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
//
|
||||||
|
// Retry to boot if any of the boot succeeds
|
||||||
|
//
|
||||||
|
LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypeBoot);
|
||||||
|
BootSuccess = BootBootOptions (LoadOptions, LoadOptionCount, &BootManagerMenu);
|
||||||
|
EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
|
||||||
|
} while (BootSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (TRUE) {
|
EfiBootManagerFreeLoadOption (&BootManagerMenu);
|
||||||
//
|
|
||||||
// BDS select the boot device to load OS
|
if (!BootSuccess) {
|
||||||
// Try next upon boot failure
|
LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypePlatformRecovery);
|
||||||
// Show Boot Manager Menu upon boot success
|
ProcessLoadOptions (LoadOptions, LoadOptionCount);
|
||||||
//
|
EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
|
||||||
DefaultBootBehavior ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG ((EFI_D_ERROR, "[Bds] Unable to boot!\n"));
|
||||||
|
CpuDeadLoop ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user