In preparation for the next patch, collect active UEFI boot options in advance into a new array. Rebase the current inner loop (the matching loop) to this array.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <[email protected]> --- OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c | 115 ++++++++++++++++++++---- 1 files changed, 97 insertions(+), 18 deletions(-) diff --git a/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c b/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c index e9580b9..7139cc2 100644 --- a/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c +++ b/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c @@ -238,6 +238,15 @@ typedef struct { /** + Array element tracking an enumerated boot option that has the + LOAD_OPTION_ACTIVE attribute. +**/ +typedef struct { + CONST BDS_COMMON_OPTION *BootOption; // reference only, no ownership +} ACTIVE_OPTION; + + +/** Append BootOptionId to BootOrder, reallocating the latter if needed. @@ -283,6 +292,75 @@ BootOrderAppend ( /** + + Create an array of ACTIVE_OPTION elements for a boot option list. + + @param[in] BootOptionList A boot option list, created with + BdsLibEnumerateAllBootOption(). + + @param[out] ActiveOption Pointer to the first element in the new array. + The caller is responsible for freeing the array + with FreePool() after use. + + @param[out] Count Number of elements in the new array. + + + @retval RETURN_SUCCESS The ActiveOption array has been created. + + @retval RETURN_NOT_FOUND No active entry has been found in + BootOptionList. + + @retval RETURN_OUT_OF_RESOURCES Memory allocation failed. + +**/ +STATIC +RETURN_STATUS +CollectActiveOptions ( + IN CONST LIST_ENTRY *BootOptionList, + OUT ACTIVE_OPTION **ActiveOption, + OUT UINTN *Count + ) +{ + UINTN ScanMode; + + // + // Scan the list twice: + // - count active entries, + // - store links to active entries. + // + for (ScanMode = 0; ScanMode < 2; ++ScanMode) { + CONST LIST_ENTRY *Link; + + Link = BootOptionList->ForwardLink; + *Count = 0; + while (Link != BootOptionList) { + CONST BDS_COMMON_OPTION *Current; + + Current = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE); + if (IS_LOAD_OPTION_TYPE (Current->Attribute, LOAD_OPTION_ACTIVE)) { + if (ScanMode == 1) { + (*ActiveOption)[*Count].BootOption = Current; + } + ++*Count; + } + Link = Link->ForwardLink; + } + + if (ScanMode == 0) { + if (*Count == 0) { + return RETURN_NOT_FOUND; + } + *ActiveOption = AllocatePool (*Count * sizeof **ActiveOption); + if (*ActiveOption == NULL) { + return RETURN_OUT_OF_RESOURCES; + } + } + } + return RETURN_SUCCESS; +} + + +/** OpenFirmware device path node **/ typedef struct { @@ -967,6 +1045,8 @@ SetBootOrderFromQemu ( CONST CHAR8 *FwCfgPtr; BOOT_ORDER BootOrder; + ACTIVE_OPTION *ActiveOption; + UINTN ActiveCount; UINTN TranslatedSize; CHAR16 Translated[TRANSLATION_OUTPUT_SIZE]; @@ -1007,6 +1087,11 @@ SetBootOrderFromQemu ( goto ErrorFreeFwCfg; } + Status = CollectActiveOptions (BootOptionList, &ActiveOption, &ActiveCount); + if (RETURN_ERROR (Status)) { + goto ErrorFreeBootOrder; + } + // // translate each OpenFirmware path // @@ -1016,38 +1101,29 @@ SetBootOrderFromQemu ( Status == RETURN_UNSUPPORTED || Status == RETURN_BUFFER_TOO_SMALL) { if (Status == RETURN_SUCCESS) { - CONST LIST_ENTRY *Link; + UINTN Idx; // - // match translated OpenFirmware path against all enumerated boot options + // match translated OpenFirmware path against all active boot options // - for (Link = BootOptionList->ForwardLink; Link != BootOptionList; - Link = Link->ForwardLink) { - CONST BDS_COMMON_OPTION *BootOption; - - BootOption = CR ( - Link, - BDS_COMMON_OPTION, - Link, - BDS_LOAD_OPTION_SIGNATURE - ); - if (IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE) && - Match ( + for (Idx = 0; Idx < ActiveCount; ++Idx) { + if (Match ( Translated, TranslatedSize, // contains length, not size, in CHAR16's here - BootOption->DevicePath + ActiveOption[Idx].BootOption->DevicePath ) ) { // // match found, store ID and continue with next OpenFirmware path // - Status = BootOrderAppend (&BootOrder, BootOption->BootCurrent); + Status = BootOrderAppend (&BootOrder, + ActiveOption[Idx].BootOption->BootCurrent); if (Status != RETURN_SUCCESS) { - goto ErrorFreeBootOrder; + goto ErrorFreeActiveOption; } break; } - } // scanned all enumerated boot options + } // scanned all active boot options } // translation successful TranslatedSize = sizeof (Translated) / sizeof (Translated[0]); @@ -1077,6 +1153,9 @@ SetBootOrderFromQemu ( )); } +ErrorFreeActiveOption: + FreePool (ActiveOption); + ErrorFreeBootOrder: FreePool (BootOrder.Data); -- 1.7.1 ------------------------------------------------------------------------------ Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more! Discover the easy way to master current and previous Microsoft technologies and advance your career. Get an incredible 1,500+ hours of step-by-step tutorial videos with LearnDevNow. Subscribe today and save! http://pubads.g.doubleclick.net/gampad/clk?id=58041391&iu=/4140/ostg.clktrk _______________________________________________ edk2-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/edk2-devel
