]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
OvmfPkg/QemuBootOrderLib: sort [Sources*] sections in the INF file
[mirror_edk2.git] / OvmfPkg / Library / QemuBootOrderLib / QemuBootOrderLib.c
index 43dbaffaa421747a931acb4e2c1e2b07cfeebe60..366104adf535294f8db65737e2f4aedeaea53315 100644 (file)
@@ -2,7 +2,7 @@
   Rewrite the BootOrder NvVar based on QEMU's "bootorder" fw_cfg file.\r
 \r
   Copyright (C) 2012 - 2014, Red Hat, Inc.\r
-  Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials are licensed and made available\r
   under the terms and conditions of the BSD License which accompanies this\r
@@ -16,7 +16,7 @@
 #include <Library/QemuFwCfgLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
-#include <Library/GenericBdsLib.h>\r
+#include <Library/UefiBootManagerLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/UefiRuntimeServicesTableLib.h>\r
 #include <Library/BaseLib.h>\r
@@ -253,8 +253,10 @@ typedef struct {
   LOAD_OPTION_ACTIVE attribute.\r
 **/\r
 typedef struct {\r
-  CONST BDS_COMMON_OPTION *BootOption; // reference only, no ownership\r
-  BOOLEAN                 Appended;    // has been added to a BOOT_ORDER?\r
+  CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOption; // reference only, no\r
+                                                  //   ownership\r
+  BOOLEAN                            Appended;    // has been added to a\r
+                                                  //   BOOT_ORDER?\r
 } ACTIVE_OPTION;\r
 \r
 \r
@@ -300,7 +302,7 @@ BootOrderAppend (
   }\r
 \r
   BootOrder->Data[BootOrder->Produced++] =\r
-                                         ActiveOption->BootOption->BootCurrent;\r
+                               (UINT16) ActiveOption->BootOption->OptionNumber;\r
   ActiveOption->Appended = TRUE;\r
   return RETURN_SUCCESS;\r
 }\r
@@ -308,22 +310,25 @@ BootOrderAppend (
 \r
 /**\r
 \r
-  Create an array of ACTIVE_OPTION elements for a boot option list.\r
+  Create an array of ACTIVE_OPTION elements for a boot option array.\r
 \r
-  @param[in]  BootOptionList  A boot option list, created with\r
-                              BdsLibEnumerateAllBootOption().\r
+  @param[in]  BootOptions      A boot option array, created with\r
+                               EfiBootManagerRefreshAllBootOption () and\r
+                               EfiBootManagerGetLoadOptions ().\r
 \r
-  @param[out] ActiveOption    Pointer to the first element in the new array.\r
-                              The caller is responsible for freeing the array\r
-                              with FreePool() after use.\r
+  @param[in]  BootOptionCount  The number of elements in BootOptions.\r
 \r
-  @param[out] Count           Number of elements in the new array.\r
+  @param[out] ActiveOption     Pointer to the first element in the new array.\r
+                               The caller is responsible for freeing the array\r
+                               with FreePool() after use.\r
+\r
+  @param[out] Count            Number of elements in the new array.\r
 \r
 \r
   @retval RETURN_SUCCESS           The ActiveOption array has been created.\r
 \r
   @retval RETURN_NOT_FOUND         No active entry has been found in\r
-                                   BootOptionList.\r
+                                   BootOptions.\r
 \r
   @retval RETURN_OUT_OF_RESOURCES  Memory allocation failed.\r
 \r
@@ -331,11 +336,13 @@ BootOrderAppend (
 STATIC\r
 RETURN_STATUS\r
 CollectActiveOptions (\r
-  IN   CONST LIST_ENTRY *BootOptionList,\r
-  OUT  ACTIVE_OPTION    **ActiveOption,\r
-  OUT  UINTN            *Count\r
+  IN   CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions,\r
+  IN   UINTN                              BootOptionCount,\r
+  OUT  ACTIVE_OPTION                      **ActiveOption,\r
+  OUT  UINTN                              *Count\r
   )\r
 {\r
+  UINTN Index;\r
   UINTN ScanMode;\r
 \r
   *ActiveOption = NULL;\r
@@ -346,22 +353,15 @@ CollectActiveOptions (
   // - store links to active entries.\r
   //\r
   for (ScanMode = 0; ScanMode < 2; ++ScanMode) {\r
-    CONST LIST_ENTRY *Link;\r
-\r
-    Link = BootOptionList->ForwardLink;\r
     *Count = 0;\r
-    while (Link != BootOptionList) {\r
-      CONST BDS_COMMON_OPTION *Current;\r
-\r
-      Current = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
-      if (IS_LOAD_OPTION_TYPE (Current->Attribute, LOAD_OPTION_ACTIVE)) {\r
+    for (Index = 0; Index < BootOptionCount; Index++) {\r
+      if ((BootOptions[Index].Attributes & LOAD_OPTION_ACTIVE) != 0) {\r
         if (ScanMode == 1) {\r
-          (*ActiveOption)[*Count].BootOption = Current;\r
+          (*ActiveOption)[*Count].BootOption = &BootOptions[Index];\r
           (*ActiveOption)[*Count].Appended   = FALSE;\r
         }\r
         ++*Count;\r
       }\r
-      Link = Link->ForwardLink;\r
     }\r
 \r
     if (ScanMode == 0) {\r
@@ -707,7 +707,7 @@ TranslatePciOfwNodes (
   // Parse the OFW nodes starting with the first non-bridge node.\r
   //\r
   PciDevFun[1] = 0;\r
-  NumEntries = sizeof (PciDevFun) / sizeof (PciDevFun[0]);\r
+  NumEntries = ARRAY_SIZE (PciDevFun);\r
   if (ParseUnitAddressHexList (\r
         OfwNode[FirstNonBridge].UnitAddress,\r
         PciDevFun,\r
@@ -786,11 +786,11 @@ TranslatePciOfwNodes (
     //\r
     // UEFI device path:\r
     //\r
-    //   PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0x0,0x0)\r
-    //                                   ^   ^   ^\r
-    //                                   |   |   LUN (always 0 on Q35)\r
+    //   PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0xFFFF,0x0)\r
+    //                                   ^   ^      ^\r
+    //                                   |   |      LUN (always 0 on Q35)\r
     //                                   |   port multiplier port number,\r
-    //                                   |   always 0 on Q35\r
+    //                                   |   always 0xFFFF on Q35\r
     //                                   channel (port) number\r
     //\r
     UINT64 Channel;\r
@@ -805,7 +805,7 @@ TranslatePciOfwNodes (
     Written = UnicodeSPrintAsciiFormat (\r
       Translated,\r
       *TranslatedSize * sizeof (*Translated), // BufferSize in bytes\r
-      "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/Sata(0x%Lx,0x0,0x0)",\r
+      "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/Sata(0x%Lx,0xFFFF,0x0)",\r
       PciRoot,\r
       Bridges,\r
       PciDevFun[0],\r
@@ -872,13 +872,13 @@ TranslatePciOfwNodes (
     //\r
     // UEFI device path prefix:\r
     //\r
-    //   PciRoot(0x0)/Pci(0x6,0x0)/HD( -- if PCI function is 0 or absent\r
-    //   PciRoot(0x0)/Pci(0x6,0x3)/HD( -- if PCI function is present and nonzero\r
+    //   PciRoot(0x0)/Pci(0x6,0x0) -- if PCI function is 0 or absent\r
+    //   PciRoot(0x0)/Pci(0x6,0x3) -- if PCI function is present and nonzero\r
     //\r
     Written = UnicodeSPrintAsciiFormat (\r
       Translated,\r
       *TranslatedSize * sizeof (*Translated), // BufferSize in bytes\r
-      "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/HD(",\r
+      "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)",\r
       PciRoot,\r
       Bridges,\r
       PciDevFun[0],\r
@@ -910,7 +910,7 @@ TranslatePciOfwNodes (
     UINT64 TargetLun[2];\r
 \r
     TargetLun[1] = 0;\r
-    NumEntries = sizeof (TargetLun) / sizeof (TargetLun[0]);\r
+    NumEntries = ARRAY_SIZE (TargetLun);\r
     if (ParseUnitAddressHexList (\r
           OfwNode[FirstNonBridge + 2].UnitAddress,\r
           TargetLun,\r
@@ -931,6 +931,105 @@ TranslatePciOfwNodes (
       TargetLun[0],\r
       TargetLun[1]\r
       );\r
+  } else if (NumNodes >= FirstNonBridge + 2 &&\r
+      SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "pci8086,5845") &&\r
+      SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "namespace")\r
+      ) {\r
+    //\r
+    // OpenFirmware device path (NVMe device):\r
+    //\r
+    //   /pci@i0cf8/pci8086,5845@6[,1]/namespace@1,0\r
+    //        ^                  ^  ^            ^ ^\r
+    //        |                  |  |            | Extended Unique Identifier\r
+    //        |                  |  |            | (EUI-64), big endian interp.\r
+    //        |                  |  |            namespace ID\r
+    //        |                  PCI slot & function holding NVMe controller\r
+    //        PCI root at system bus port, PIO\r
+    //\r
+    // UEFI device path:\r
+    //\r
+    //   PciRoot(0x0)/Pci(0x6,0x1)/NVMe(0x1,00-00-00-00-00-00-00-00)\r
+    //                                  ^   ^\r
+    //                                  |   octets of the EUI-64\r
+    //                                  |   in address order\r
+    //                                  namespace ID\r
+    //\r
+    UINT64 Namespace[2];\r
+    UINTN  RequiredEntries;\r
+    UINT8  *Eui64;\r
+\r
+    RequiredEntries = ARRAY_SIZE (Namespace);\r
+    NumEntries = RequiredEntries;\r
+    if (ParseUnitAddressHexList (\r
+          OfwNode[FirstNonBridge + 1].UnitAddress,\r
+          Namespace,\r
+          &NumEntries\r
+          ) != RETURN_SUCCESS ||\r
+        NumEntries != RequiredEntries ||\r
+        Namespace[0] == 0 ||\r
+        Namespace[0] >= MAX_UINT32\r
+        ) {\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
+\r
+    Eui64 = (UINT8 *)&Namespace[1];\r
+    Written = UnicodeSPrintAsciiFormat (\r
+      Translated,\r
+      *TranslatedSize * sizeof (*Translated), // BufferSize in bytes\r
+      "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/"\r
+      "NVMe(0x%Lx,%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)",\r
+      PciRoot,\r
+      Bridges,\r
+      PciDevFun[0],\r
+      PciDevFun[1],\r
+      Namespace[0],\r
+      Eui64[7], Eui64[6], Eui64[5], Eui64[4],\r
+      Eui64[3], Eui64[2], Eui64[1], Eui64[0]\r
+      );\r
+  } else if (NumNodes >= FirstNonBridge + 2 &&\r
+             SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "usb") &&\r
+             SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "storage")) {\r
+    //\r
+    // OpenFirmware device path (usb-storage device in XHCI port):\r
+    //\r
+    //   /pci@i0cf8/usb@3[,1]/storage@2/channel@0/disk@0,0\r
+    //        ^         ^  ^          ^         ^      ^ ^\r
+    //        |         |  |          |         fixed  fixed\r
+    //        |         |  |          XHCI port number, 1-based\r
+    //        |         |  PCI function corresponding to XHCI (optional)\r
+    //        |         PCI slot holding XHCI\r
+    //        PCI root at system bus port, PIO\r
+    //\r
+    // UEFI device path prefix:\r
+    //\r
+    //   PciRoot(0x0)/Pci(0x3,0x1)/USB(0x1,0x0)\r
+    //                        ^        ^\r
+    //                        |        XHCI port number in 0-based notation\r
+    //                        0x0 if PCI function is 0, or absent from OFW\r
+    //\r
+    RETURN_STATUS ParseStatus;\r
+    UINT64        OneBasedXhciPort;\r
+\r
+    NumEntries = 1;\r
+    ParseStatus = ParseUnitAddressHexList (\r
+                    OfwNode[FirstNonBridge + 1].UnitAddress,\r
+                    &OneBasedXhciPort,\r
+                    &NumEntries\r
+                    );\r
+    if (RETURN_ERROR (ParseStatus) || OneBasedXhciPort == 0) {\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
+\r
+    Written = UnicodeSPrintAsciiFormat (\r
+                Translated,\r
+                *TranslatedSize * sizeof (*Translated), // BufferSize in bytes\r
+                "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/USB(0x%Lx,0x0)",\r
+                PciRoot,\r
+                Bridges,\r
+                PciDevFun[0],\r
+                PciDevFun[1],\r
+                OneBasedXhciPort - 1\r
+                );\r
   } else {\r
     //\r
     // Generic OpenFirmware device path for PCI devices:\r
@@ -1062,12 +1161,12 @@ TranslateMmioOfwNodes (
     //\r
     // UEFI device path prefix:\r
     //\r
-    //   <VenHwString>/HD(\r
+    //   <VenHwString>\r
     //\r
     Written = UnicodeSPrintAsciiFormat (\r
                 Translated,\r
                 *TranslatedSize * sizeof (*Translated), // BufferSize in bytes\r
-                "%s/HD(",\r
+                "%s",\r
                 VenHwString\r
                 );\r
   } else if (NumNodes >= 3 &&\r
@@ -1090,7 +1189,7 @@ TranslateMmioOfwNodes (
     UINT64 TargetLun[2];\r
 \r
     TargetLun[1] = 0;\r
-    NumEntries = sizeof (TargetLun) / sizeof (TargetLun[0]);\r
+    NumEntries = ARRAY_SIZE (TargetLun);\r
     if (ParseUnitAddressHexList (\r
           OfwNode[2].UnitAddress,\r
           TargetLun,\r
@@ -1382,11 +1481,17 @@ BOOLEAN
 Match (\r
   IN  CONST CHAR16                           *Translated,\r
   IN  UINTN                                  TranslatedLength,\r
-  IN  CONST EFI_DEVICE_PATH_PROTOCOL         *DevicePath\r
+  IN  EFI_DEVICE_PATH_PROTOCOL               *DevicePath\r
   )\r
 {\r
-  CHAR16  *Converted;\r
-  BOOLEAN Result;\r
+  CHAR16                   *Converted;\r
+  BOOLEAN                  Result;\r
+  VOID                     *FileBuffer;\r
+  UINTN                    FileSize;\r
+  EFI_DEVICE_PATH_PROTOCOL *AbsDevicePath;\r
+  CHAR16                   *AbsConverted;\r
+  BOOLEAN                  Shortform;\r
+  EFI_DEVICE_PATH_PROTOCOL *Node;\r
 \r
   Converted = ConvertDevicePathToText (\r
                 DevicePath,\r
@@ -1397,24 +1502,57 @@ Match (
     return FALSE;\r
   }\r
 \r
+  Result = FALSE;\r
+  Shortform = FALSE;\r
   //\r
-  // Attempt to expand any relative UEFI device path starting with HD() to an\r
-  // absolute device path first. The logic imitates BdsLibBootViaBootOption().\r
-  // We don't have to free the absolute device path,\r
-  // BdsExpandPartitionPartialDevicePathToFull() has internal caching.\r
+  // Expand the short-form device path to full device path\r
   //\r
-  Result = FALSE;\r
-  if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH &&\r
-      DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP) {\r
-    EFI_DEVICE_PATH_PROTOCOL *AbsDevicePath;\r
-    CHAR16                   *AbsConverted;\r
-\r
-    AbsDevicePath = BdsExpandPartitionPartialDevicePathToFull (\r
-                      (HARDDRIVE_DEVICE_PATH *) DevicePath);\r
-    if (AbsDevicePath == NULL) {\r
+  if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&\r
+      (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)) {\r
+    //\r
+    // Harddrive shortform device path\r
+    //\r
+    Shortform = TRUE;\r
+  } else if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&\r
+             (DevicePathSubType (DevicePath) == MEDIA_FILEPATH_DP)) {\r
+    //\r
+    // File-path shortform device path\r
+    //\r
+    Shortform = TRUE;\r
+  } else if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&\r
+             (DevicePathSubType (DevicePath) == MSG_URI_DP)) {\r
+    //\r
+    // URI shortform device path\r
+    //\r
+    Shortform = TRUE;\r
+  } else {\r
+    for ( Node = DevicePath\r
+        ; !IsDevicePathEnd (Node)\r
+        ; Node = NextDevicePathNode (Node)\r
+        ) {\r
+      if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) &&\r
+          ((DevicePathSubType (Node) == MSG_USB_CLASS_DP) ||\r
+           (DevicePathSubType (Node) == MSG_USB_WWID_DP))) {\r
+        Shortform = TRUE;\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Attempt to expand any relative UEFI device path to\r
+  // an absolute device path first.\r
+  //\r
+  if (Shortform) {\r
+    FileBuffer = EfiBootManagerGetLoadOptionBuffer (\r
+                   DevicePath, &AbsDevicePath, &FileSize\r
+                   );\r
+    if (FileBuffer == NULL) {\r
       goto Exit;\r
     }\r
+    FreePool (FileBuffer);\r
     AbsConverted = ConvertDevicePathToText (AbsDevicePath, FALSE, FALSE);\r
+    FreePool (AbsDevicePath);\r
     if (AbsConverted == NULL) {\r
       goto Exit;\r
     }\r
@@ -1483,11 +1621,11 @@ BootOrderComplete (
   Idx = 0;\r
   while (!RETURN_ERROR (Status) && Idx < ActiveCount) {\r
     if (!ActiveOption[Idx].Appended) {\r
-      CONST BDS_COMMON_OPTION        *Current;\r
-      CONST EFI_DEVICE_PATH_PROTOCOL *FirstNode;\r
+      CONST EFI_BOOT_MANAGER_LOAD_OPTION *Current;\r
+      CONST EFI_DEVICE_PATH_PROTOCOL     *FirstNode;\r
 \r
       Current = ActiveOption[Idx].BootOption;\r
-      FirstNode = Current->DevicePath;\r
+      FirstNode = Current->FilePath;\r
       if (FirstNode != NULL) {\r
         CHAR16        *Converted;\r
         STATIC CHAR16 ConvFallBack[] = L"<unable to convert>";\r
@@ -1580,7 +1718,7 @@ PruneBootVariables (
       CHAR16 VariableName[9];\r
 \r
       UnicodeSPrintAsciiFormat (VariableName, sizeof VariableName, "Boot%04x",\r
-        ActiveOption[Idx].BootOption->BootCurrent);\r
+        ActiveOption[Idx].BootOption->OptionNumber);\r
 \r
       //\r
       // "The space consumed by the deleted variable may not be available until\r
@@ -1602,12 +1740,11 @@ PruneBootVariables (
 \r
   Attempt to retrieve the "bootorder" fw_cfg file from QEMU. Translate the\r
   OpenFirmware device paths therein to UEFI device path fragments. Match the\r
-  translated fragments against BootOptionList, and rewrite the BootOrder NvVar\r
-  so that it corresponds to the order described in fw_cfg.\r
-\r
-  @param[in] BootOptionList  A boot option list, created with\r
-                             BdsLibEnumerateAllBootOption ().\r
+  translated fragments against the current list of boot options, and rewrite\r
+  the BootOrder NvVar so that it corresponds to the order described in fw_cfg.\r
 \r
+  Platform BDS should call this function after EfiBootManagerConnectAll () and\r
+  EfiBootManagerRefreshAllBootOption () return.\r
 \r
   @retval RETURN_SUCCESS            BootOrder NvVar rewritten.\r
 \r
@@ -1627,7 +1764,7 @@ PruneBootVariables (
 **/\r
 RETURN_STATUS\r
 SetBootOrderFromQemu (\r
-  IN  CONST LIST_ENTRY *BootOptionList\r
+  VOID\r
   )\r
 {\r
   RETURN_STATUS                    Status;\r
@@ -1644,6 +1781,8 @@ SetBootOrderFromQemu (
 \r
   UINTN                            TranslatedSize;\r
   CHAR16                           Translated[TRANSLATION_OUTPUT_SIZE];\r
+  EFI_BOOT_MANAGER_LOAD_OPTION     *BootOptions;\r
+  UINTN                            BootOptionCount;\r
 \r
   Status = QemuFwCfgFindFile ("bootorder", &FwCfgItem, &FwCfgSize);\r
   if (Status != RETURN_SUCCESS) {\r
@@ -1681,11 +1820,21 @@ SetBootOrderFromQemu (
     goto ErrorFreeFwCfg;\r
   }\r
 \r
-  Status = CollectActiveOptions (BootOptionList, &ActiveOption, &ActiveCount);\r
-  if (RETURN_ERROR (Status)) {\r
+  BootOptions = EfiBootManagerGetLoadOptions (\r
+                  &BootOptionCount, LoadOptionTypeBoot\r
+                  );\r
+  if (BootOptions == NULL) {\r
+    Status = RETURN_NOT_FOUND;\r
     goto ErrorFreeBootOrder;\r
   }\r
 \r
+  Status = CollectActiveOptions (\r
+             BootOptions, BootOptionCount, &ActiveOption, &ActiveCount\r
+             );\r
+  if (RETURN_ERROR (Status)) {\r
+    goto ErrorFreeBootOptions;\r
+  }\r
+\r
   if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) {\r
     Status = CreateExtraRootBusMap (&ExtraPciRoots);\r
     if (EFI_ERROR (Status)) {\r
@@ -1698,7 +1847,7 @@ SetBootOrderFromQemu (
   //\r
   // translate each OpenFirmware path\r
   //\r
-  TranslatedSize = sizeof (Translated) / sizeof (Translated[0]);\r
+  TranslatedSize = ARRAY_SIZE (Translated);\r
   Status = TranslateOfwPath (&FwCfgPtr, ExtraPciRoots, Translated,\r
              &TranslatedSize);\r
   while (Status == RETURN_SUCCESS ||\r
@@ -1712,10 +1861,11 @@ SetBootOrderFromQemu (
       // match translated OpenFirmware path against all active boot options\r
       //\r
       for (Idx = 0; Idx < ActiveCount; ++Idx) {\r
-        if (Match (\r
+        if (!ActiveOption[Idx].Appended &&\r
+            Match (\r
               Translated,\r
               TranslatedSize, // contains length, not size, in CHAR16's here\r
-              ActiveOption[Idx].BootOption->DevicePath\r
+              ActiveOption[Idx].BootOption->FilePath\r
               )\r
             ) {\r
           //\r
@@ -1725,12 +1875,11 @@ SetBootOrderFromQemu (
           if (Status != RETURN_SUCCESS) {\r
             goto ErrorFreeExtraPciRoots;\r
           }\r
-          break;\r
         }\r
       } // scanned all active boot options\r
     }   // translation successful\r
 \r
-    TranslatedSize = sizeof (Translated) / sizeof (Translated[0]);\r
+    TranslatedSize = ARRAY_SIZE (Translated);\r
     Status = TranslateOfwPath (&FwCfgPtr, ExtraPciRoots, Translated,\r
                &TranslatedSize);\r
   } // scanning of OpenFirmware paths done\r
@@ -1776,6 +1925,9 @@ ErrorFreeExtraPciRoots:
 ErrorFreeActiveOption:\r
   FreePool (ActiveOption);\r
 \r
+ErrorFreeBootOptions:\r
+  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
+\r
 ErrorFreeBootOrder:\r
   FreePool (BootOrder.Data);\r
 \r