MdeModulePkg: BdsDxe: Introduce infinite boot retries

This PR introduces a new feature to enable infinite boot retries based on a newly created PCD.
When true, the system will continuously loop over all boot options.

PCD default is FALSE to match existing functionality.

This change is tested on QEMU based virtual platforms and physical
platforms.

This change is useful for certain server cases. Infinite retries allows
a server to continuously attempt boot in case of network failure and
recovery, and for such attempts to be accurately recorded in the TCG
logs.

Co-authored-by: Kun Qin <kun.qin@microsoft.com>
Co-authored-by: Aaron Pop <aaron.pop@microsoft.com>
Co-authored-by: Michael Kubacki <michael.kubacki@microsoft.com>

Signed-off-by: Sherry Fan <sherryfan@microsoft.com>
This commit is contained in:
Sherry Fan 2026-01-21 16:41:39 -08:00 committed by mergify[bot]
parent ff69be3519
commit 64ad6f20d8
3 changed files with 25 additions and 9 deletions

View file

@ -1211,6 +1211,14 @@
# @Prompt FFA TX/RX Buffer Page Count
gEfiMdeModulePkgTokenSpaceGuid.PcdFfaTxRxPageCount|1|UINT64|0x30001062
## Some platforms require that all EfiLoadOptions are retried until one of the options
# boots. When True, this Pcd will force Bds to retry all the valid EfiLoadOptions
# indefinitely until one of the options boots.
# TRUE - Efi boot options will be retried indefinitely.
# FALSE - Efi boot options will not be retried.
# @Prompt Enable infinite retries during BDS.
gEfiMdeModulePkgTokenSpaceGuid.PcdSupportInfiniteBootRetries|FALSE|BOOLEAN|0x40000152
[PcdsFixedAtBuild, PcdsPatchableInModule]
## Dynamic type PCD can be registered callback function for Pcd setting action.
# PcdMaxPeiPcdCallBackNumberPerPcdEntry indicates the maximum number of callback function

View file

@ -99,6 +99,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleOnDiskSupport ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleFmpSupport ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdPlatformRecoverySupport ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdSupportInfiniteBootRetries ## CONSUMES
[Depex]
TRUE

View file

@ -414,14 +414,20 @@ 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 infinite retries is enabled, do not break out of the loop.
// This allows all boot options to be attempted on each iteration.
//
if ((BootManagerMenu != NULL) && (BootOptions[Index].Status == EFI_SUCCESS)) {
EfiBootManagerBoot (BootManagerMenu);
break;
if (!PcdGetBool (PcdSupportInfiniteBootRetries)) {
//
// 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;
}
}
}
@ -1103,7 +1109,8 @@ BdsEntry (
do {
//
// Retry to boot if any of the boot succeeds
// Retry to boot if any of the boot succeeds.
// If infinite retries is enabled, always retry. This allows a continuous loop over all boot options.
//
BootSuccess = FALSE;
LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypeBoot);
@ -1111,7 +1118,7 @@ BdsEntry (
BootSuccess = BootBootOptions (LoadOptions, LoadOptionCount, (BootManagerMenuStatus != EFI_NOT_FOUND) ? &BootManagerMenu : NULL);
EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
}
} while (BootSuccess);
} while (BootSuccess || PcdGetBool (PcdSupportInfiniteBootRetries));
}
if (BootManagerMenuStatus != EFI_NOT_FOUND) {