X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FBdsDxe%2FBdsEntry.c;h=7968a58f3454dd6a19c9dac049ea4cbc7e7a08e8;hb=2de1f611be06ded3a59726a4052a9039be7d459b;hp=3191a986304b2aa2752ecff696b8736c8943fd3b;hpb=9f0d7651b3a786b4177a3a07a731592746136dd2;p=mirror_edk2.git
diff --git a/MdeModulePkg/Universal/BdsDxe/BdsEntry.c b/MdeModulePkg/Universal/BdsDxe/BdsEntry.c
index 3191a98630..7968a58f34 100644
--- a/MdeModulePkg/Universal/BdsDxe/BdsEntry.c
+++ b/MdeModulePkg/Universal/BdsDxe/BdsEntry.c
@@ -5,16 +5,10 @@
After DxeCore finish DXE phase, gEfiBdsArchProtocolGuid->BdsEntry will be invoked
to enter BDS phase.
-Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
(C) Copyright 2015 Hewlett-Packard Development Company, L.P.
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -293,9 +287,9 @@ BdsReadKeys (
}
while (gST->ConIn != NULL) {
-
+
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
-
+
if (EFI_ERROR (Status)) {
//
// No more keys.
@@ -347,6 +341,7 @@ BdsWait (
TimeoutRemain--;
}
}
+ PlatformBootManagerWaitCallback (0);
DEBUG ((EFI_D_INFO, "[Bds]Exit the waiting!\n"));
}
@@ -488,10 +483,10 @@ ProcessLoadOptions (
/**
- Validate input console variable data.
+ Validate input console variable data.
If found the device path is not a valid device path, remove the variable.
-
+
@param VariableName Input console variable name.
**/
@@ -505,7 +500,7 @@ BdsFormalizeConsoleVariable (
EFI_STATUS Status;
GetEfiGlobalVariable2 (VariableName, (VOID **) &DevicePath, &VariableSize);
- if ((DevicePath != NULL) && !IsDevicePathValid (DevicePath, VariableSize)) {
+ if ((DevicePath != NULL) && !IsDevicePathValid (DevicePath, VariableSize)) {
Status = gRT->SetVariable (
VariableName,
&gEfiGlobalVariableGuid,
@@ -525,17 +520,17 @@ BdsFormalizeConsoleVariable (
}
/**
- Formalize OsIndication related variables.
-
- For OsIndicationsSupported, Create a BS/RT/UINT64 variable to report caps
+ Formalize OsIndication related variables.
+
+ For OsIndicationsSupported, Create a BS/RT/UINT64 variable to report caps
Delete OsIndications variable if it is not NV/BS/RT UINT64.
-
+
Item 3 is used to solve case when OS corrupts OsIndications. Here simply delete this NV variable.
Create a boot option for BootManagerMenu if it hasn't been created yet
**/
-VOID
+VOID
BdsFormalizeOSIndicationVariable (
VOID
)
@@ -552,10 +547,18 @@ BdsFormalizeOSIndicationVariable (
//
Status = EfiBootManagerGetBootManagerMenu (&BootManagerMenu);
if (Status != EFI_NOT_FOUND) {
- OsIndicationSupport = EFI_OS_INDICATIONS_BOOT_TO_FW_UI | EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY;
+ OsIndicationSupport = EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
EfiBootManagerFreeLoadOption (&BootManagerMenu);
} else {
- OsIndicationSupport = EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY;
+ OsIndicationSupport = 0;
+ }
+
+ if (PcdGetBool (PcdPlatformRecoverySupport)) {
+ OsIndicationSupport |= EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY;
+ }
+
+ if (PcdGetBool(PcdCapsuleOnDiskSupport)) {
+ OsIndicationSupport |= EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
}
Status = gRT->SetVariable (
@@ -613,10 +616,10 @@ BdsFormalizeOSIndicationVariable (
/**
- Validate variables.
+ Validate variables.
**/
-VOID
+VOID
BdsFormalizeEfiGlobalVariable (
VOID
)
@@ -634,55 +637,6 @@ BdsFormalizeEfiGlobalVariable (
BdsFormalizeOSIndicationVariable ();
}
-/**
- Enter an infinite loop of calling the Boot Manager Menu.
-
- This is a last resort alternative to BdsEntry() giving up for good. This
- function never returns.
-
- @param[in] BootManagerMenu The EFI_BOOT_MANAGER_LOAD_OPTION located and/or
- created by the EfiBootManagerGetBootManagerMenu()
- call in BdsEntry().
-**/
-VOID
-BdsBootManagerMenuLoop (
- IN EFI_BOOT_MANAGER_LOAD_OPTION *BootManagerMenu
- )
-{
- EFI_INPUT_KEY Key;
-
- //
- // Normally BdsDxe does not print anything to the system console, but this is
- // a last resort -- the end-user will likely not see any DEBUG messages
- // logged in this situation.
- //
- // AsciiPrint() will NULL-check gST->ConOut internally. We check gST->ConIn
- // here to see if it makes sense to request and wait for a keypress.
- //
- if (gST->ConIn != NULL) {
- AsciiPrint (
- "%a: No bootable option or device was found.\n"
- "%a: Press any key to enter the Boot Manager Menu.\n",
- gEfiCallerBaseName,
- gEfiCallerBaseName
- );
- BdsWaitForSingleEvent (gST->ConIn->WaitForKey, 0);
-
- //
- // Drain any queued keys.
- //
- while (!EFI_ERROR (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key))) {
- //
- // just throw away Key
- //
- }
- }
-
- for (;;) {
- EfiBootManagerBoot (BootManagerMenu);
- }
-}
-
/**
Service routine for BdsInstance->Entry(). Devices are connected, the
@@ -717,6 +671,7 @@ BdsEntry (
BOOLEAN BootSuccess;
EFI_DEVICE_PATH_PROTOCOL *FilePath;
EFI_STATUS BootManagerMenuStatus;
+ EFI_BOOT_MANAGER_LOAD_OPTION PlatformDefaultBootOption;
HotkeyTriggered = NULL;
Status = EFI_SUCCESS;
@@ -725,8 +680,8 @@ BdsEntry (
//
// Insert the performance probe
//
- PERF_END (NULL, "DXE", NULL, 0);
- PERF_START (NULL, "BDS", NULL, 0);
+ PERF_CROSSMODULE_END("DXE");
+ PERF_CROSSMODULE_BEGIN("BDS");
DEBUG ((EFI_D_INFO, "[Bds] Entry...\n"));
//
@@ -818,14 +773,13 @@ BdsEntry (
//
InitializeLanguage (TRUE);
- //
- // System firmware must include a PlatformRecovery#### variable specifying
- // a short-form File Path Media Device Path containing the platform default
- // file path for removable media
- //
FilePath = FileDevicePath (NULL, EFI_REMOVABLE_MEDIA_FILE_NAME);
+ if (FilePath == NULL) {
+ DEBUG ((DEBUG_ERROR, "Fail to allocate memory for defualt boot file path. Unable to boot.\n"));
+ CpuDeadLoop ();
+ }
Status = EfiBootManagerInitializeLoadOption (
- &LoadOption,
+ &PlatformDefaultBootOption,
LoadOptionNumberUnassigned,
LoadOptionTypePlatformRecovery,
LOAD_OPTION_ACTIVE,
@@ -835,24 +789,31 @@ BdsEntry (
0
);
ASSERT_EFI_ERROR (Status);
- LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypePlatformRecovery);
- if (EfiBootManagerFindLoadOption (&LoadOption, LoadOptions, LoadOptionCount) == -1) {
- for (Index = 0; Index < LoadOptionCount; Index++) {
- //
- // The PlatformRecovery#### options are sorted by OptionNumber.
- // Find the the smallest unused number as the new OptionNumber.
- //
- if (LoadOptions[Index].OptionNumber != Index) {
- break;
+
+ //
+ // System firmware must include a PlatformRecovery#### variable specifying
+ // a short-form File Path Media Device Path containing the platform default
+ // file path for removable media if the platform supports Platform Recovery.
+ //
+ if (PcdGetBool (PcdPlatformRecoverySupport)) {
+ LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypePlatformRecovery);
+ if (EfiBootManagerFindLoadOption (&PlatformDefaultBootOption, LoadOptions, LoadOptionCount) == -1) {
+ for (Index = 0; Index < LoadOptionCount; Index++) {
+ //
+ // The PlatformRecovery#### options are sorted by OptionNumber.
+ // Find the the smallest unused number as the new OptionNumber.
+ //
+ if (LoadOptions[Index].OptionNumber != Index) {
+ break;
+ }
}
+ PlatformDefaultBootOption.OptionNumber = Index;
+ Status = EfiBootManagerLoadOptionToVariable (&PlatformDefaultBootOption);
+ ASSERT_EFI_ERROR (Status);
}
- LoadOption.OptionNumber = Index;
- Status = EfiBootManagerLoadOptionToVariable (&LoadOption);
- ASSERT_EFI_ERROR (Status);
+ EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
}
- EfiBootManagerFreeLoadOption (&LoadOption);
FreePool (FilePath);
- EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
//
// Report Status Code to indicate connecting drivers will happen
@@ -884,13 +845,13 @@ BdsEntry (
// Possible things that can be done in PlatformBootManagerBeforeConsole:
// > Update console variable: 1. include hot-plug devices; 2. Clear ConIn and add SOL for AMT
// > Register new Driver#### or Boot####
- // > Register new Key####: e.g.: F12
+ // > Register new Key####: e.g.: F12
// > Signal ReadyToLock event
// > Authentication action: 1. connect Auth devices; 2. Identify auto logon user.
//
- PERF_START (NULL, "PlatformBootManagerBeforeConsole", "BDS", 0);
+ PERF_INMODULE_BEGIN("PlatformBootManagerBeforeConsole");
PlatformBootManagerBeforeConsole ();
- PERF_END (NULL, "PlatformBootManagerBeforeConsole", "BDS", 0);
+ PERF_INMODULE_END("PlatformBootManagerBeforeConsole");
//
// Initialize hotkey service
@@ -907,7 +868,7 @@ BdsEntry (
//
// Connect consoles
//
- PERF_START (NULL, "EfiBootManagerConnectAllDefaultConsoles", "BDS", 0);
+ PERF_INMODULE_BEGIN("EfiBootManagerConnectAllDefaultConsoles");
if (PcdGetBool (PcdConInConnectOnDemand)) {
EfiBootManagerConnectConsoleVariable (ConOut);
EfiBootManagerConnectConsoleVariable (ErrOut);
@@ -917,7 +878,7 @@ BdsEntry (
} else {
EfiBootManagerConnectAllDefaultConsoles ();
}
- PERF_END (NULL, "EfiBootManagerConnectAllDefaultConsoles", "BDS", 0);
+ PERF_INMODULE_END("EfiBootManagerConnectAllDefaultConsoles");
//
// Do the platform specific action after the console is ready
@@ -929,10 +890,22 @@ BdsEntry (
// > Connect certain devices
// > Dispatch aditional option roms
// > Special boot: e.g.: USB boot, enter UI
- //
- PERF_START (NULL, "PlatformBootManagerAfterConsole", "BDS", 0);
+ //
+ PERF_INMODULE_BEGIN("PlatformBootManagerAfterConsole");
PlatformBootManagerAfterConsole ();
- PERF_END (NULL, "PlatformBootManagerAfterConsole", "BDS", 0);
+ PERF_INMODULE_END("PlatformBootManagerAfterConsole");
+
+ //
+ // If any component set PcdTestKeyUsed to TRUE because use of a test key
+ // was detected, then display a warning message on the debug log and the console
+ //
+ if (PcdGetBool (PcdTestKeyUsed)) {
+ DEBUG ((DEBUG_ERROR, "**********************************\n"));
+ DEBUG ((DEBUG_ERROR, "** WARNING: Test Key is used. **\n"));
+ DEBUG ((DEBUG_ERROR, "**********************************\n"));
+ Print (L"** WARNING: Test Key is used. **\n");
+ }
+
//
// Boot to Boot Manager Menu when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot
//
@@ -981,7 +954,7 @@ BdsEntry (
PlatformRecovery = (BOOLEAN) ((OsIndication & EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY) != 0);
//
// Clear EFI_OS_INDICATIONS_BOOT_TO_FW_UI to acknowledge OS
- //
+ //
if (BootFwUi || PlatformRecovery) {
OsIndication &= ~((UINT64) (EFI_OS_INDICATIONS_BOOT_TO_FW_UI | EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY));
Status = gRT->SetVariable (
@@ -1025,10 +998,9 @@ BdsEntry (
//
// Execute Key####
//
- PERF_START (NULL, "BdsWait", "BDS", 0);
+ PERF_INMODULE_BEGIN ("BdsWait");
BdsWait (HotkeyTriggered);
- PERF_END (NULL, "BdsWait", "BDS", 0);
-
+ PERF_INMODULE_END ("BdsWait");
//
// BdsReadKeys() can be removed after all keyboard drivers invoke callback in timer callback.
//
@@ -1060,7 +1032,7 @@ BdsEntry (
if (!EFI_ERROR (Status)) {
EfiBootManagerBoot (&LoadOption);
EfiBootManagerFreeLoadOption (&LoadOption);
- if ((LoadOption.Status == EFI_SUCCESS) &&
+ if ((LoadOption.Status == EFI_SUCCESS) &&
(BootManagerMenuStatus != EFI_NOT_FOUND) &&
(LoadOption.OptionNumber != BootManagerMenu.OptionNumber)) {
//
@@ -1082,20 +1054,26 @@ BdsEntry (
} while (BootSuccess);
}
- if (!BootSuccess) {
- LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypePlatformRecovery);
- ProcessLoadOptions (LoadOptions, LoadOptionCount);
- EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
+ if (BootManagerMenuStatus != EFI_NOT_FOUND) {
+ EfiBootManagerFreeLoadOption (&BootManagerMenu);
}
- //
- // If BootManagerMenu is available, fall back to it indefinitely.
- //
- if (BootManagerMenuStatus != EFI_NOT_FOUND) {
- BdsBootManagerMenuLoop (&BootManagerMenu);
+ if (!BootSuccess) {
+ if (PlatformRecovery) {
+ LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypePlatformRecovery);
+ ProcessLoadOptions (LoadOptions, LoadOptionCount);
+ EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
+ } else {
+ //
+ // When platform recovery is not enabled, still boot to platform default file path.
+ //
+ EfiBootManagerProcessLoadOption (&PlatformDefaultBootOption);
+ }
}
+ EfiBootManagerFreeLoadOption (&PlatformDefaultBootOption);
DEBUG ((EFI_D_ERROR, "[Bds] Unable to boot!\n"));
+ PlatformBootManagerUnableToBoot ();
CpuDeadLoop ();
}
@@ -1108,14 +1086,14 @@ BdsEntry (
then EFI_INVALID_PARAMETER is returned.
@param VendorGuid A unique identifier for the vendor.
@param Attributes Attributes bitmask to set for the variable.
- @param DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE,
+ @param DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE,
or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero
- causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is
- set, then a SetVariable() call with a DataSize of zero will not cause any change to
- the variable value (the timestamp associated with the variable may be updated however
- even if no new data value is provided,see the description of the
- EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not
- be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated).
+ causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is
+ set, then a SetVariable() call with a DataSize of zero will not cause any change to
+ the variable value (the timestamp associated with the variable may be updated however
+ even if no new data value is provided,see the description of the
+ EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not
+ be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated).
@param Data The contents for the variable.
@retval EFI_SUCCESS The firmware has successfully stored the variable and its data as