From 323c24539e68b1961b1578a930a0b98719335d3f Mon Sep 17 00:00:00 2001 From: Aaron <105021049+apop5@users.noreply.github.com> Date: Mon, 17 Apr 2023 12:44:26 -0700 Subject: [PATCH] MdeModulePkg: BdsDxe: Introduce infinite boot retries This is a feature of infinite boot retries based on a newly created PCD. When true, the system will never stop retrying the boot options. PCD default is FALSE to match existing functionality. This change is tested on QEMU based virtual platforms and physical platforms. Co-authored-by: Kun Qin Co-authored-by: Aaron Pop Co-authored-by: Michael Kubacki --- MdeModulePkg/MdeModulePkg.dec | 9 ++++++ MdeModulePkg/Universal/BdsDxe/BdsDxe.inf | 1 + MdeModulePkg/Universal/BdsDxe/BdsEntry.c | 36 +++++++++++++++++------- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 7b74deb53d..34a6580dbf 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -1185,6 +1185,15 @@ # @Prompt Delay access XHCI register after it issues HCRST (us) gEfiMdeModulePkgTokenSpaceGuid.PcdDelayXhciHCReset|2000|UINT16|0x30001060 + # MU_CHANGE [BEGIN] - Support indefinite boot retries + # # Some platforms require that all EfiLoadOptions are retried until one of the options + # # succeeds. When True, this Pcd will force Bds to retry all the valid EfiLoadOptions + # # indefinitely until one of the options succeeds. + # # TRUE - Efi boot options will be retried indefinitely. + # # FALSE - Efi boot options will not be retried. + gEfiMdeModulePkgTokenSpaceGuid.PcdSupportInfiniteBootRetries|FALSE|BOOLEAN|0x40000152 + # MU_CHANGE [END] + [PcdsFixedAtBuild, PcdsPatchableInModule] ## Dynamic type PCD can be registered callback function for Pcd setting action. # PcdMaxPeiPcdCallBackNumberPerPcdEntry indicates the maximum number of callback function diff --git a/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf b/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf index 5bac635def..d8f9c29954 100644 --- a/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf +++ b/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf @@ -98,6 +98,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleOnDiskSupport ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdPlatformRecoverySupport ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSupportInfiniteBootRetries ## CONSUMES // MU_CHANGE [Depex] TRUE diff --git a/MdeModulePkg/Universal/BdsDxe/BdsEntry.c b/MdeModulePkg/Universal/BdsDxe/BdsEntry.c index 72de8d3211..c5e4eb63b3 100644 --- a/MdeModulePkg/Universal/BdsDxe/BdsEntry.c +++ b/MdeModulePkg/Universal/BdsDxe/BdsEntry.c @@ -388,6 +388,7 @@ BootBootOptions ( // // Attempt boot each boot option // + for (Index = 0; Index < BootOptionCount; Index++) { // // According to EFI Specification, if a load option is not marked @@ -413,16 +414,31 @@ BootBootOptions ( // EfiBootManagerBoot (&BootOptions[Index]); - // - // 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 ((BootManagerMenu != NULL) && (BootOptions[Index].Status == EFI_SUCCESS)) { - EfiBootManagerBoot (BootManagerMenu); - break; + // MU_CHANGE [BEGIN] - Support infinite boot retries + // Changes for PcdSupportInfiniteBootRetries are meant to minimize upkeep in mu repos. + // If/when upstreaming this change, refactoring calling loop in BdsEntry() would be + // better location. + if (!PcdGetBool (PcdSupportInfiniteBootRetries)) { + // MU_CHANGE [END] - Support infinite boot retries + + // + // 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 ((BootManagerMenu != NULL) && (BootOptions[Index].Status == EFI_SUCCESS)) { + EfiBootManagerBoot (BootManagerMenu); + break; + } + + // MU_CHANGE [BEGIN]- Support infinite boot retries + // Changes for PcdSupportInfiniteBootRetries are meant to minimize upkeep in mu repos. + // If/when upstreaming this change, refactoring calling loop in BdsEntry() would be + // better location. } + + // MU_CHANGE [END]- Support infinite boot retries } return (BOOLEAN)(Index < BootOptionCount); @@ -1093,7 +1109,7 @@ BdsEntry ( LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypeBoot); BootSuccess = BootBootOptions (LoadOptions, LoadOptionCount, (BootManagerMenuStatus != EFI_NOT_FOUND) ? &BootManagerMenu : NULL); EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount); - } while (BootSuccess); + } while (BootSuccess || PcdGetBool (PcdSupportInfiniteBootRetries)); // MU_CHANGE add PcdSupportInfiniteBootRetries support } if (BootManagerMenuStatus != EFI_NOT_FOUND) {