18#include <Library/VariablePolicyHelperLib.h>
20#define SET_BOOT_OPTION_SUPPORT_KEY_COUNT(a, c) { \
21 (a) = ((a) & ~EFI_BOOT_OPTION_SUPPORT_COUNT) | (((c) << LowBitSet32 (EFI_BOOT_OPTION_SUPPORT_COUNT)) & EFI_BOOT_OPTION_SUPPORT_COUNT); \
47CHAR16 *mBdsLoadOptionName[] = {
76 if (EFI_ERROR (Status)) {
81 DEBUG ((DEBUG_WARN,
"[Bds] Connect ConIn failed - %r!!!\n", Status));
110 CHAR16 *DevicePathStr;
117 Status =
gBS->LocateHandleBuffer (
119 &gEfiDeferredImageLoadProtocolGuid,
124 if (EFI_ERROR (Status)) {
128 for (Index = 0; Index < HandleCount; Index++) {
129 Status =
gBS->HandleProtocol (Handles[Index], &gEfiDeferredImageLoadProtocolGuid, (VOID **)&DeferredImage);
130 if (EFI_ERROR (Status)) {
134 for (ImageIndex = 0; ; ImageIndex++) {
138 Status = DeferredImage->GetImageInfo (
146 if (EFI_ERROR (Status)) {
151 DEBUG ((DEBUG_LOAD,
"[Bds] Image was deferred but not loaded: %s.\n", DevicePathStr));
152 if (DevicePathStr !=
NULL) {
158 if (Handles !=
NULL) {
189 Status =
gBS->InstallMultipleProtocolInterfaces (
191 &gEfiBdsArchProtocolGuid,
202 Status =
gBS->CreateEventEx (
207 &gEfiEventReadyToBootGuid,
228 IN UINT64 Timeout OPTIONAL
240 Status =
gBS->CreateEvent (EVT_TIMER, 0,
NULL,
NULL, &TimerEvent);
241 if (!EFI_ERROR (Status)) {
255 WaitList[1] = TimerEvent;
256 Status =
gBS->WaitForEvent (2, WaitList, &Index);
258 gBS->CloseEvent (TimerEvent);
264 Status = EFI_TIMEOUT;
271 Status =
gBS->WaitForEvent (1, &Event, &Index);
272 ASSERT (!EFI_ERROR (Status));
298 if (EFI_ERROR (Status)) {
320 UINT16 TimeoutRemain;
322 DEBUG ((DEBUG_INFO,
"[Bds]BdsWait ...Zzzzzzzzzzzz...\n"));
324 TimeoutRemain =
PcdGet16 (PcdPlatformBootTimeOut);
325 while (TimeoutRemain != 0) {
326 DEBUG ((DEBUG_INFO,
"[Bds]BdsWait(%d)..Zzzz...\n", (
UINTN)TimeoutRemain));
332 if (HotkeyTriggered !=
NULL) {
334 if (!EFI_ERROR (Status)) {
338 gBS->Stall (1000000);
345 if (TimeoutRemain != 0xffff) {
357 if ((
PcdGet16 (PcdPlatformBootTimeOut) != 0) && (TimeoutRemain == 0)) {
361 DEBUG ((DEBUG_INFO,
"[Bds]Exit the waiting!\n"));
391 for (Index = 0; Index < BootOptionCount; Index++) {
397 if ((BootOptions[Index].Attributes & LOAD_OPTION_ACTIVE) == 0) {
406 if ((BootOptions[Index].Attributes & LOAD_OPTION_CATEGORY) != LOAD_OPTION_CATEGORY_BOOT) {
422 if ((BootManagerMenu !=
NULL) && (BootOptions[Index].Status ==
EFI_SUCCESS)) {
428 return (BOOLEAN)(Index < BootOptionCount);
445 BOOLEAN ReconnectAll;
446 EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType;
448 ReconnectAll =
FALSE;
449 LoadOptionType = LoadOptionTypeMax;
454 for (Index = 0; Index < LoadOptionCount; Index++) {
459 LoadOptionType = LoadOptions[Index].OptionType;
462 ASSERT (LoadOptionType == LoadOptions[Index].OptionType);
463 ASSERT (LoadOptionType != LoadOptionTypeBoot);
471 if (!EFI_ERROR (Status)) {
476 (LoadOptionType == LoadOptionTypePlatformRecovery))
484 if (!EFI_ERROR (LoadOptions[Index].Status) &&
485 ((LoadOptions[Index].Attributes & LOAD_OPTION_FORCE_RECONNECT) != 0))
497 if (ReconnectAll && (LoadOptionType == LoadOptionTypeDriver)) {
514 IN CHAR16 *VariableName
523 Status =
gRT->SetVariable (
525 &gEfiGlobalVariableGuid,
536 if (DevicePath !=
NULL) {
558 UINT64 OsIndicationSupport;
568 if (Status != EFI_NOT_FOUND) {
569 OsIndicationSupport = EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
572 OsIndicationSupport = 0;
575 if (
PcdGetBool (PcdPlatformRecoverySupport)) {
576 OsIndicationSupport |= EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY;
580 OsIndicationSupport |= EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
583 Status =
gRT->SetVariable (
585 &gEfiGlobalVariableGuid,
586 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
604 DataSize =
sizeof (UINT64);
605 Status =
gRT->GetVariable (
607 &gEfiGlobalVariableGuid,
612 if (Status == EFI_NOT_FOUND) {
616 if ((DataSize !=
sizeof (OsIndication)) ||
617 ((OsIndication & ~OsIndicationSupport) != 0) ||
621 DEBUG ((DEBUG_ERROR,
"[Bds] Unformalized OsIndications variable exists. Delete it\n"));
622 Status =
gRT->SetVariable (
624 &gEfiGlobalVariableGuid,
674 UINTN LoadOptionCount;
675 CHAR16 *FirmwareVendor;
680 UINT32 BootOptionSupport;
686 CHAR16 BootNextVariableName[
sizeof (
"Boot####")];
689 BOOLEAN PlatformRecovery;
694 BOOLEAN PlatformDefaultBootOptionValid;
696 HotkeyTriggered =
NULL;
705 DEBUG ((DEBUG_INFO,
"[Bds] Entry...\n"));
710 FirmwareVendor = (CHAR16 *)
PcdGetPtr (PcdFirmwareVendor);
729 Status =
gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid,
NULL, (VOID **)&VariablePolicy);
730 DEBUG ((DEBUG_INFO,
"[BdsDxe] Locate Variable Policy protocol - %r\n", Status));
731 if (!EFI_ERROR (Status)) {
733 Status = RegisterBasicVariablePolicy (
735 &gEfiGlobalVariableGuid,
737 VARIABLE_POLICY_NO_MIN_SIZE,
738 VARIABLE_POLICY_NO_MAX_SIZE,
739 VARIABLE_POLICY_NO_MUST_ATTR,
740 VARIABLE_POLICY_NO_CANT_ATTR,
741 VARIABLE_POLICY_TYPE_LOCK_NOW
752 BootTimeOut =
PcdGet16 (PcdPlatformBootTimeOut);
753 if (BootTimeOut != 0xFFFF) {
760 &gEfiGlobalVariableGuid,
771 BootOptionSupport = EFI_BOOT_OPTION_SUPPORT_APP | EFI_BOOT_OPTION_SUPPORT_SYSPREP;
773 BootOptionSupport |= EFI_BOOT_OPTION_SUPPORT_KEY;
774 SET_BOOT_OPTION_SUPPORT_KEY_COUNT (BootOptionSupport, 3);
777 Status =
gRT->SetVariable (
779 &gEfiGlobalVariableGuid,
780 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
781 sizeof (BootOptionSupport),
794 if (DataSize !=
sizeof (UINT16)) {
795 if (BootNext !=
NULL) {
808 if (FilePath ==
NULL) {
809 DEBUG ((DEBUG_ERROR,
"Fail to allocate memory for default boot file path. Unable to boot.\n"));
814 &PlatformDefaultBootOption,
815 LoadOptionNumberUnassigned,
816 LoadOptionTypePlatformRecovery,
818 L
"Default PlatformRecovery",
823 ASSERT (PlatformDefaultBootOptionValid ==
TRUE);
830 if (PlatformDefaultBootOptionValid &&
PcdGetBool (PcdPlatformRecoverySupport)) {
833 for (Index = 0; Index < LoadOptionCount; Index++) {
838 if (LoadOptions[Index].OptionNumber != Index) {
843 PlatformDefaultBootOption.OptionNumber = Index;
865 Status =
gBS->CreateEventEx (
870 &gConnectConInEventGuid,
873 if (EFI_ERROR (Status)) {
874 gConnectConInEvent =
NULL;
939 DEBUG ((DEBUG_ERROR,
"**********************************\n"));
940 DEBUG ((DEBUG_ERROR,
"** WARNING: Test Key is used. **\n"));
941 DEBUG ((DEBUG_ERROR,
"**********************************\n"));
942 Print (L
"** WARNING: Test Key is used. **\n");
948 DataSize =
sizeof (UINT64);
949 Status =
gRT->GetVariable (
951 &gEfiGlobalVariableGuid,
956 if (EFI_ERROR (Status)) {
961 EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType;
963 DEBUG ((DEBUG_INFO,
"[Bds]OsIndication: %016x\n", OsIndication));
964 DEBUG ((DEBUG_INFO,
"[Bds]=============Begin Load Options Dumping ...=============\n"));
965 for (LoadOptionType = 0; LoadOptionType < LoadOptionTypeMax; LoadOptionType++) {
969 mBdsLoadOptionName[LoadOptionType]
972 for (Index = 0; Index < LoadOptionCount; Index++) {
975 " %s%04x: %s \t\t 0x%04x\n",
976 mBdsLoadOptionName[LoadOptionType],
977 LoadOptions[Index].OptionNumber,
978 LoadOptions[Index].Description,
979 LoadOptions[Index].Attributes
986 DEBUG ((DEBUG_INFO,
"[Bds]=============End Load Options Dumping=============\n"));
994 BootFwUi = (BOOLEAN)((OsIndication & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0);
995 PlatformRecovery = (BOOLEAN)((OsIndication & EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY) != 0);
999 if (BootFwUi || PlatformRecovery) {
1000 OsIndication &= ~((UINT64)(EFI_OS_INDICATIONS_BOOT_TO_FW_UI | EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY));
1001 Status =
gRT->SetVariable (
1003 &gEfiGlobalVariableGuid,
1017 if (BootFwUi && (BootManagerMenuStatus != EFI_NOT_FOUND)) {
1031 if (!PlatformRecovery) {
1052 if (BootNext !=
NULL) {
1056 Status =
gRT->SetVariable (
1058 &gEfiGlobalVariableGuid,
1066 ASSERT (Status ==
EFI_SUCCESS || Status == EFI_NOT_FOUND);
1071 UnicodeSPrint (BootNextVariableName,
sizeof (BootNextVariableName), L
"Boot%04x", *BootNext);
1073 if (!EFI_ERROR (Status)) {
1077 (BootManagerMenuStatus != EFI_NOT_FOUND) &&
1078 (LoadOption.OptionNumber != BootManagerMenu.OptionNumber))
1094 BootSuccess =
BootBootOptions (LoadOptions, LoadOptionCount, (BootManagerMenuStatus != EFI_NOT_FOUND) ? &BootManagerMenu :
NULL);
1096 }
while (BootSuccess);
1099 if (BootManagerMenuStatus != EFI_NOT_FOUND) {
1104 if (
PcdGetBool (PcdPlatformRecoverySupport)) {
1108 }
else if (PlatformDefaultBootOptionValid) {
1116 if (PlatformDefaultBootOptionValid) {
1120 DEBUG ((DEBUG_ERROR,
"[Bds] Unable to boot!\n"));
1160 IN CHAR16 *VariableName,
1162 IN UINT32 Attributes,
1171 Status =
gRT->SetVariable (
1178 if (EFI_ERROR (Status)) {
1179 NameSize =
StrSize (VariableName);
1181 if (SetVariableStatus !=
NULL) {
1182 CopyGuid (&SetVariableStatus->Guid, VendorGuid);
1183 SetVariableStatus->NameSize = NameSize;
1184 SetVariableStatus->DataSize = DataSize;
1185 SetVariableStatus->SetStatus = Status;
1186 SetVariableStatus->Attributes = Attributes;
1187 CopyMem (SetVariableStatus + 1, VariableName, NameSize);
1188 CopyMem (((UINT8 *)(SetVariableStatus + 1)) + NameSize, Data, DataSize);
1192 PcdGet32 (PcdErrorCodeSetVariable),
1195 &gEdkiiStatusCodeDataTypeVariableGuid,
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
VOID EFIAPI CpuDeadLoop(VOID)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
VOID BdsFormalizeOSIndicationVariable(VOID)
CHAR16 * mReadOnlyVariables[]
VOID BdsWait(IN EFI_EVENT HotkeyTriggered)
VOID EFIAPI CheckDeferredLoadImageOnReadyToBoot(IN EFI_EVENT Event, IN VOID *Context)
BOOLEAN BootBootOptions(IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions, IN UINTN BootOptionCount, IN EFI_BOOT_MANAGER_LOAD_OPTION *BootManagerMenu OPTIONAL)
VOID EFIAPI BdsEntry(IN EFI_BDS_ARCH_PROTOCOL *This)
VOID EFIAPI BdsDxeOnConnectConInCallBack(IN EFI_EVENT Event, IN VOID *Context)
VOID BdsFormalizeEfiGlobalVariable(VOID)
EFI_BDS_ARCH_PROTOCOL gBds
VOID ProcessLoadOptions(IN EFI_BOOT_MANAGER_LOAD_OPTION *LoadOptions, IN UINTN LoadOptionCount)
EFI_STATUS BdsDxeSetVariableAndReportStatusCodeOnError(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data)
EFI_STATUS BdsWaitForSingleEvent(IN EFI_EVENT Event, IN UINT64 Timeout OPTIONAL)
EFI_STATUS EFIAPI BdsInitialize(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
VOID BdsFormalizeConsoleVariable(IN CHAR16 *VariableName)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI FileDevicePath(IN EFI_HANDLE Device OPTIONAL, IN CONST CHAR16 *FileName)
BOOLEAN EFIAPI IsDevicePathValid(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN UINTN MaxSize)
CHAR16 *EFIAPI ConvertDevicePathToText(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN BOOLEAN DisplayOnly, IN BOOLEAN AllowShortcuts)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateRuntimeCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#define EFI_OS_INDICATIONS_VARIABLE_NAME
#define EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME
#define EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME
#define EFI_PLATFORM_LANG_CODES_VARIABLE_NAME
#define EFI_CON_IN_VARIABLE_NAME
#define EFI_LANG_CODES_VARIABLE_NAME
#define EFI_BOOT_NEXT_VARIABLE_NAME
#define EFI_TIME_OUT_VARIABLE_NAME
#define EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME
VOID InitializeHwErrRecSupport(VOID)
VOID InitializeLanguage(BOOLEAN LangCodesSettingRequired)
VOID EFIAPI PlatformBootManagerBeforeConsole(VOID)
VOID EFIAPI PlatformBootManagerWaitCallback(UINT16 TimeoutRemain)
VOID EFIAPI PlatformBootManagerUnableToBoot(VOID)
VOID EFIAPI PlatformBootManagerAfterConsole(VOID)
UINTN EFIAPI UnicodeSPrint(OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString,...)
EFI_RUNTIME_SERVICES * gRT
#define ARRAY_SIZE(Array)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG_CODE_BEGIN()
#define DEBUG(Expression)
#define DEBUG_CODE(Expression)
#define REPORT_STATUS_CODE_EX(Type, Value, Instance, CallerId, ExtendedDataGuid, ExtendedData, ExtendedDataSize)
#define REPORT_STATUS_CODE(Type, Value)
#define PcdGet16(TokenName)
#define PcdGet32(TokenName)
#define PcdGetBool(TokenName)
#define PcdGetPtr(TokenName)
#define EFI_PROGRESS_CODE
#define EFI_SW_DXE_BS_PC_BEGIN_CONNECTING_DRIVERS
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STATUS EFIAPI EfiBootManagerConnectConsoleVariable(IN CONSOLE_TYPE ConsoleType)
EFI_STATUS EFIAPI EfiBootManagerLoadOptionToVariable(IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *LoadOption)
VOID EFIAPI EfiBootManagerBoot(IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOption)
EFI_STATUS EFIAPI EfiBootManagerStartHotkeyService(IN EFI_EVENT *HotkeyTriggered)
EFI_STATUS EFIAPI EfiBootManagerFreeLoadOption(IN EFI_BOOT_MANAGER_LOAD_OPTION *LoadOption)
VOID EFIAPI EfiBootManagerHotkeyBoot(VOID)
EFI_STATUS EFIAPI EfiBootManagerConnectAllDefaultConsoles(VOID)
EFI_BOOT_MANAGER_LOAD_OPTION *EFIAPI EfiBootManagerGetLoadOptions(OUT UINTN *LoadOptionCount, IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType)
EFI_STATUS EFIAPI EfiBootManagerFreeLoadOptions(IN EFI_BOOT_MANAGER_LOAD_OPTION *LoadOptions, IN UINTN LoadOptionCount)
EFI_STATUS EFIAPI EfiBootManagerVariableToLoadOption(IN CHAR16 *VariableName, IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *LoadOption)
INTN EFIAPI EfiBootManagerFindLoadOption(IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key, IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array, IN UINTN Count)
VOID EFIAPI EfiBootManagerConnectAll(VOID)
EFI_STATUS EFIAPI EfiBootManagerGetBootManagerMenu(EFI_BOOT_MANAGER_LOAD_OPTION *BootOption)
EFI_STATUS EFIAPI EfiBootManagerInitializeLoadOption(IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *Option, IN UINTN OptionNumber, IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType, IN UINT32 Attributes, IN CHAR16 *Description, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN UINT8 *OptionalData, IN UINT32 OptionalDataSize)
VOID EFIAPI EfiBootManagerDisconnectAll(VOID)
EFI_STATUS EFIAPI EfiBootManagerProcessLoadOption(EFI_BOOT_MANAGER_LOAD_OPTION *LoadOption)
#define EFI_TIMER_PERIOD_SECONDS(Seconds)
EFI_STATUS EFIAPI GetEfiGlobalVariable2(IN CONST CHAR16 *Name, OUT VOID **Value, OUT UINTN *Size OPTIONAL)
UINTN EFIAPI Print(IN CONST CHAR16 *Format,...)
#define EFI_VARIABLE_NON_VOLATILE
EFI_SIMPLE_TEXT_INPUT_PROTOCOL * ConIn