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