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

Reply via email to