]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: remove QemuBootOrderLib instance
authorLaszlo Ersek <lersek@redhat.com>
Tue, 17 May 2016 16:52:49 +0000 (18:52 +0200)
committerLaszlo Ersek <lersek@redhat.com>
Wed, 25 May 2016 10:24:50 +0000 (12:24 +0200)
This library instance is no longer referenced.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Gary Ching-Pang Lin <glin@suse.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
OvmfPkg/Library/QemuBootOrderLib/ExtraRootBusMap.c [deleted file]
OvmfPkg/Library/QemuBootOrderLib/ExtraRootBusMap.h [deleted file]
OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c [deleted file]
OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf [deleted file]

diff --git a/OvmfPkg/Library/QemuBootOrderLib/ExtraRootBusMap.c b/OvmfPkg/Library/QemuBootOrderLib/ExtraRootBusMap.c
deleted file mode 100644 (file)
index ec42214..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-/** @file\r
-  Map positions of extra PCI root buses to bus numbers.\r
-\r
-  Copyright (C) 2015, Red Hat, Inc.\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
-  distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
-  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-**/\r
-\r
-#include <Library/DebugLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/OrderedCollectionLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Protocol/DevicePath.h>\r
-#include <Protocol/PciRootBridgeIo.h>\r
-\r
-#include "ExtraRootBusMap.h"\r
-\r
-//\r
-// The BusNumbers field is an array with Count elements. The elements increase\r
-// strictry monotonically. Zero is not an element (because the zero bus number\r
-// belongs to the "main" root bus, never to an extra root bus). Offset N in the\r
-// array maps the extra root bus with position (N+1) to its bus number (because\r
-// the root bus with position 0 is always the main root bus, therefore we don't\r
-// store it).\r
-//\r
-// If there are no extra root buses in the system, then Count is 0, and\r
-// BusNumbers is NULL.\r
-//\r
-struct EXTRA_ROOT_BUS_MAP_STRUCT {\r
-  UINT32 *BusNumbers;\r
-  UINTN  Count;\r
-};\r
-\r
-\r
-/**\r
-  An ORDERED_COLLECTION_USER_COMPARE function that compares root bridge\r
-  protocol device paths based on UID.\r
-\r
-  @param[in] UserStruct1  Pointer to the first ACPI_HID_DEVICE_PATH.\r
-\r
-  @param[in] UserStruct2  Pointer to the second ACPI_HID_DEVICE_PATH.\r
-\r
-  @retval <0  If UserStruct1 compares less than UserStruct2.\r
-\r
-  @retval  0  If UserStruct1 compares equal to UserStruct2.\r
-\r
-  @retval >0  If UserStruct1 compares greater than UserStruct2.\r
-**/\r
-STATIC\r
-INTN\r
-EFIAPI\r
-RootBridgePathCompare (\r
-  IN CONST VOID *UserStruct1,\r
-  IN CONST VOID *UserStruct2\r
-  )\r
-{\r
-  CONST ACPI_HID_DEVICE_PATH *Acpi1;\r
-  CONST ACPI_HID_DEVICE_PATH *Acpi2;\r
-\r
-  Acpi1 = UserStruct1;\r
-  Acpi2 = UserStruct2;\r
-\r
-  return Acpi1->UID < Acpi2->UID ? -1 :\r
-         Acpi1->UID > Acpi2->UID ?  1 :\r
-         0;\r
-}\r
-\r
-\r
-/**\r
-  An ORDERED_COLLECTION_KEY_COMPARE function that compares a root bridge\r
-  protocol device path against a UID.\r
-\r
-  @param[in] StandaloneKey  Pointer to the bare UINT32 UID.\r
-\r
-  @param[in] UserStruct     Pointer to the ACPI_HID_DEVICE_PATH with the\r
-                            embedded UINT32 UID.\r
-\r
-  @retval <0  If StandaloneKey compares less than UserStruct's key.\r
-\r
-  @retval  0  If StandaloneKey compares equal to UserStruct's key.\r
-\r
-  @retval >0  If StandaloneKey compares greater than UserStruct's key.\r
-**/\r
-STATIC\r
-INTN\r
-EFIAPI\r
-RootBridgePathKeyCompare (\r
-  IN CONST VOID *StandaloneKey,\r
-  IN CONST VOID *UserStruct\r
-  )\r
-{\r
-  CONST UINT32               *Uid;\r
-  CONST ACPI_HID_DEVICE_PATH *Acpi;\r
-\r
-  Uid  = StandaloneKey;\r
-  Acpi = UserStruct;\r
-\r
-  return *Uid < Acpi->UID ? -1 :\r
-         *Uid > Acpi->UID ?  1 :\r
-         0;\r
-}\r
-\r
-\r
-/**\r
-  Create a structure that maps the relative positions of PCI root buses to bus\r
-  numbers.\r
-\r
-  In the "bootorder" fw_cfg file, QEMU refers to extra PCI root buses by their\r
-  positions, in relative root bus number order, not by their actual PCI bus\r
-  numbers. The ACPI HID device path nodes however that are associated with\r
-  PciRootBridgeIo protocol instances in the system have their UID fields set to\r
-  the bus numbers. Create a map that gives, for each extra PCI root bus's\r
-  position (ie. "serial number") its actual PCI bus number.\r
-\r
-  @param[out] ExtraRootBusMap  The data structure implementing the map.\r
-\r
-  @retval EFI_SUCCESS           ExtraRootBusMap has been populated.\r
-\r
-  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.\r
-\r
-  @retval EFI_ALREADY_STARTED   A duplicate root bus number has been found in\r
-                                the system. (This should never happen.)\r
-\r
-  @return                       Error codes returned by\r
-                                gBS->LocateHandleBuffer() and\r
-                                gBS->HandleProtocol().\r
-\r
-**/\r
-EFI_STATUS\r
-CreateExtraRootBusMap (\r
-  OUT EXTRA_ROOT_BUS_MAP **ExtraRootBusMap\r
-  )\r
-{\r
-  EFI_STATUS               Status;\r
-  UINTN                    NumHandles;\r
-  EFI_HANDLE               *Handles;\r
-  ORDERED_COLLECTION       *Collection;\r
-  EXTRA_ROOT_BUS_MAP       *Map;\r
-  UINTN                    Idx;\r
-  ORDERED_COLLECTION_ENTRY *Entry, *Entry2;\r
-\r
-  //\r
-  // Handles and Collection are temporary / helper variables, while in Map we\r
-  // build the return value.\r
-  //\r
-\r
-  Status = gBS->LocateHandleBuffer (ByProtocol,\r
-                  &gEfiPciRootBridgeIoProtocolGuid, NULL /* SearchKey */,\r
-                  &NumHandles, &Handles);\r
-  if (EFI_ERROR (Status))  {\r
-    return Status;\r
-  }\r
-\r
-  Collection = OrderedCollectionInit (RootBridgePathCompare,\r
-                 RootBridgePathKeyCompare);\r
-  if (Collection == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto FreeHandles;\r
-  }\r
-\r
-  Map = AllocateZeroPool (sizeof *Map);\r
-  if (Map == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto FreeCollection;\r
-  }\r
-\r
-  //\r
-  // Collect the ACPI device path protocols of the root bridges.\r
-  //\r
-  for (Idx = 0; Idx < NumHandles; ++Idx) {\r
-    EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
-\r
-    Status = gBS->HandleProtocol (Handles[Idx], &gEfiDevicePathProtocolGuid,\r
-                    (VOID**)&DevicePath);\r
-    if (EFI_ERROR (Status)) {\r
-      goto FreeMap;\r
-    }\r
-\r
-    //\r
-    // Examine if the device path is an ACPI HID one, and if so, if UID is\r
-    // nonzero (ie. the root bridge that the bus number belongs to is "extra",\r
-    // not the main one). In that case, link the device path into Collection.\r
-    //\r
-    if (DevicePathType (DevicePath) == ACPI_DEVICE_PATH &&\r
-        DevicePathSubType (DevicePath) == ACPI_DP &&\r
-        ((ACPI_HID_DEVICE_PATH *)DevicePath)->HID == EISA_PNP_ID(0x0A03) &&\r
-        ((ACPI_HID_DEVICE_PATH *)DevicePath)->UID > 0) {\r
-      Status = OrderedCollectionInsert (Collection, NULL, DevicePath);\r
-      if (EFI_ERROR (Status)) {\r
-        goto FreeMap;\r
-      }\r
-      ++Map->Count;\r
-    }\r
-  }\r
-\r
-  if (Map->Count > 0) {\r
-    //\r
-    // At least one extra PCI root bus exists.\r
-    //\r
-    Map->BusNumbers = AllocatePool (Map->Count * sizeof *Map->BusNumbers);\r
-    if (Map->BusNumbers == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-      goto FreeMap;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Now collect the bus numbers of the extra PCI root buses into Map.\r
-  //\r
-  Idx = 0;\r
-  Entry = OrderedCollectionMin (Collection);\r
-  while (Idx < Map->Count) {\r
-    ACPI_HID_DEVICE_PATH *Acpi;\r
-\r
-    ASSERT (Entry != NULL);\r
-    Acpi = OrderedCollectionUserStruct (Entry);\r
-    Map->BusNumbers[Idx] = Acpi->UID;\r
-    DEBUG ((EFI_D_VERBOSE,\r
-      "%a: extra bus position 0x%Lx maps to bus number (UID) 0x%x\n",\r
-      __FUNCTION__, (UINT64)(Idx + 1), Acpi->UID));\r
-    ++Idx;\r
-    Entry = OrderedCollectionNext (Entry);\r
-  }\r
-  ASSERT (Entry == NULL);\r
-\r
-  *ExtraRootBusMap = Map;\r
-  Status = EFI_SUCCESS;\r
-\r
-  //\r
-  // Fall through in order to release temporaries.\r
-  //\r
-\r
-FreeMap:\r
-  if (EFI_ERROR (Status)) {\r
-    if (Map->BusNumbers != NULL) {\r
-      FreePool (Map->BusNumbers);\r
-    }\r
-    FreePool (Map);\r
-  }\r
-\r
-FreeCollection:\r
-  for (Entry = OrderedCollectionMin (Collection); Entry != NULL;\r
-       Entry = Entry2) {\r
-    Entry2 = OrderedCollectionNext (Entry);\r
-    OrderedCollectionDelete (Collection, Entry, NULL);\r
-  }\r
-  OrderedCollectionUninit (Collection);\r
-\r
-FreeHandles:\r
-  FreePool (Handles);\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Release a map created with CreateExtraRootBusMap().\r
-\r
-  @param[in] ExtraRootBusMap  The map to release.\r
-*/\r
-VOID\r
-DestroyExtraRootBusMap (\r
-  IN EXTRA_ROOT_BUS_MAP *ExtraRootBusMap\r
-  )\r
-{\r
-  if (ExtraRootBusMap->BusNumbers != NULL) {\r
-    FreePool (ExtraRootBusMap->BusNumbers);\r
-  }\r
-  FreePool (ExtraRootBusMap);\r
-}\r
-\r
-/**\r
-  Map the position (serial number) of an extra PCI root bus to its bus number.\r
-\r
-  @param[in]  ExtraRootBusMap  The map created with CreateExtraRootBusMap();\r
-\r
-  @param[in]  RootBusPos       The extra PCI root bus position to map.\r
-\r
-  @param[out] RootBusNr        The bus number belonging to the extra PCI root\r
-                               bus identified by RootBusPos.\r
-\r
-  @retval EFI_INVALID_PARAMETER  RootBusPos is zero. The zero position\r
-                                 identifies the main root bus, whose bus number\r
-                                 is always zero, and is therefore never\r
-                                 maintained in ExtraRootBusMap.\r
-\r
-  @retval EFI_NOT_FOUND          RootBusPos is not found in ExtraRootBusMap.\r
-\r
-  @retval EFI_SUCCESS            Mapping successful.\r
-**/\r
-EFI_STATUS\r
-MapRootBusPosToBusNr (\r
-  IN  CONST EXTRA_ROOT_BUS_MAP *ExtraRootBusMap,\r
-  IN  UINT64                   RootBusPos,\r
-  OUT UINT32                   *RootBusNr\r
-  )\r
-{\r
-  if (RootBusPos == 0) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  if (RootBusPos > ExtraRootBusMap->Count) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-  *RootBusNr = ExtraRootBusMap->BusNumbers[RootBusPos - 1];\r
-  return EFI_SUCCESS;\r
-}\r
diff --git a/OvmfPkg/Library/QemuBootOrderLib/ExtraRootBusMap.h b/OvmfPkg/Library/QemuBootOrderLib/ExtraRootBusMap.h
deleted file mode 100644 (file)
index e2dbc38..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/** @file\r
-  Map positions of extra PCI root buses to bus numbers.\r
-\r
-  Copyright (C) 2015, Red Hat, Inc.\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
-  distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
-  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-**/\r
-\r
-#ifndef __EXTRA_ROOT_BUS_MAP_H__\r
-#define __EXTRA_ROOT_BUS_MAP_H__\r
-\r
-/**\r
-  Incomplete ("opaque") data type implementing the map.\r
-**/\r
-typedef struct EXTRA_ROOT_BUS_MAP_STRUCT EXTRA_ROOT_BUS_MAP;\r
-\r
-EFI_STATUS\r
-CreateExtraRootBusMap (\r
-  OUT EXTRA_ROOT_BUS_MAP **ExtraRootBusMap\r
-  );\r
-\r
-VOID\r
-DestroyExtraRootBusMap (\r
-  IN EXTRA_ROOT_BUS_MAP *ExtraRootBusMap\r
-  );\r
-\r
-EFI_STATUS\r
-MapRootBusPosToBusNr (\r
-  IN  CONST EXTRA_ROOT_BUS_MAP *ExtraRootBusMap,\r
-  IN  UINT64                   RootBusPos,\r
-  OUT UINT32                   *RootBusNr\r
-  );\r
-\r
-#endif\r
diff --git a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
deleted file mode 100644 (file)
index 582b0bc..0000000
+++ /dev/null
@@ -1,1891 +0,0 @@
-/** @file\r
-  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
-\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
-  distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
-  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-**/\r
-\r
-#include <Library/QemuFwCfgLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/GenericBdsLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/PrintLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/QemuBootOrderLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Guid/GlobalVariable.h>\r
-#include <Guid/VirtioMmioTransport.h>\r
-\r
-#include "ExtraRootBusMap.h"\r
-\r
-/**\r
-  OpenFirmware to UEFI device path translation output buffer size in CHAR16's.\r
-**/\r
-#define TRANSLATION_OUTPUT_SIZE 0x100\r
-\r
-/**\r
-  Output buffer size for OpenFirmware to UEFI device path fragment translation,\r
-  in CHAR16's, for a sequence of PCI bridges.\r
-**/\r
-#define BRIDGE_TRANSLATION_OUTPUT_SIZE 0x40\r
-\r
-/**\r
-  Numbers of nodes in OpenFirmware device paths that are required and examined.\r
-**/\r
-#define REQUIRED_PCI_OFW_NODES  2\r
-#define REQUIRED_MMIO_OFW_NODES 1\r
-#define EXAMINED_OFW_NODES      6\r
-\r
-\r
-/**\r
-  Simple character classification routines, corresponding to POSIX class names\r
-  and ASCII encoding.\r
-**/\r
-STATIC\r
-BOOLEAN\r
-IsAlnum (\r
-  IN  CHAR8 Chr\r
-  )\r
-{\r
-  return (('0' <= Chr && Chr <= '9') ||\r
-          ('A' <= Chr && Chr <= 'Z') ||\r
-          ('a' <= Chr && Chr <= 'z')\r
-          );\r
-}\r
-\r
-\r
-STATIC\r
-BOOLEAN\r
-IsDriverNamePunct (\r
-  IN  CHAR8 Chr\r
-  )\r
-{\r
-  return (Chr == ',' ||  Chr == '.' || Chr == '_' ||\r
-          Chr == '+' || Chr == '-'\r
-          );\r
-}\r
-\r
-\r
-STATIC\r
-BOOLEAN\r
-IsPrintNotDelim (\r
-  IN  CHAR8 Chr\r
-  )\r
-{\r
-  return (32 <= Chr && Chr <= 126 &&\r
-          Chr != '/' && Chr != '@' && Chr != ':');\r
-}\r
-\r
-\r
-/**\r
-  Utility types and functions.\r
-**/\r
-typedef struct {\r
-  CONST CHAR8 *Ptr; // not necessarily NUL-terminated\r
-  UINTN       Len;  // number of non-NUL characters\r
-} SUBSTRING;\r
-\r
-\r
-/**\r
-\r
-  Check if Substring and String have identical contents.\r
-\r
-  The function relies on the restriction that a SUBSTRING cannot have embedded\r
-  NULs either.\r
-\r
-  @param[in] Substring  The SUBSTRING input to the comparison.\r
-\r
-  @param[in] String     The ASCII string input to the comparison.\r
-\r
-\r
-  @return  Whether the inputs have identical contents.\r
-\r
-**/\r
-STATIC\r
-BOOLEAN\r
-SubstringEq (\r
-  IN  SUBSTRING   Substring,\r
-  IN  CONST CHAR8 *String\r
-  )\r
-{\r
-  UINTN       Pos;\r
-  CONST CHAR8 *Chr;\r
-\r
-  Pos = 0;\r
-  Chr = String;\r
-\r
-  while (Pos < Substring.Len && Substring.Ptr[Pos] == *Chr) {\r
-    ++Pos;\r
-    ++Chr;\r
-  }\r
-\r
-  return (BOOLEAN)(Pos == Substring.Len && *Chr == '\0');\r
-}\r
-\r
-\r
-/**\r
-\r
-  Parse a comma-separated list of hexadecimal integers into the elements of an\r
-  UINT64 array.\r
-\r
-  Whitespace, "0x" prefixes, leading or trailing commas, sequences of commas,\r
-  or an empty string are not allowed; they are rejected.\r
-\r
-  The function relies on ASCII encoding.\r
-\r
-  @param[in]     UnitAddress  The substring to parse.\r
-\r
-  @param[out]    Result       The array, allocated by the caller, to receive\r
-                              the parsed values. This parameter may be NULL if\r
-                              NumResults is zero on input.\r
-\r
-  @param[in out] NumResults   On input, the number of elements allocated for\r
-                              Result. On output, the number of elements it has\r
-                              taken (or would have taken) to parse the string\r
-                              fully.\r
-\r
-\r
-  @retval RETURN_SUCCESS            UnitAddress has been fully parsed.\r
-                                    NumResults is set to the number of parsed\r
-                                    values; the corresponding elements have\r
-                                    been set in Result. The rest of Result's\r
-                                    elements are unchanged.\r
-\r
-  @retval RETURN_BUFFER_TOO_SMALL   UnitAddress has been fully parsed.\r
-                                    NumResults is set to the number of parsed\r
-                                    values, but elements have been stored only\r
-                                    up to the input value of NumResults, which\r
-                                    is less than what has been parsed.\r
-\r
-  @retval RETURN_INVALID_PARAMETER  Parse error. The contents of Results is\r
-                                    indeterminate. NumResults has not been\r
-                                    changed.\r
-\r
-**/\r
-STATIC\r
-RETURN_STATUS\r
-ParseUnitAddressHexList (\r
-  IN      SUBSTRING  UnitAddress,\r
-  OUT     UINT64     *Result,\r
-  IN OUT  UINTN      *NumResults\r
-  )\r
-{\r
-  UINTN         Entry;    // number of entry currently being parsed\r
-  UINT64        EntryVal; // value being constructed for current entry\r
-  CHAR8         PrevChr;  // UnitAddress character previously checked\r
-  UINTN         Pos;      // current position within UnitAddress\r
-  RETURN_STATUS Status;\r
-\r
-  Entry    = 0;\r
-  EntryVal = 0;\r
-  PrevChr  = ',';\r
-\r
-  for (Pos = 0; Pos < UnitAddress.Len; ++Pos) {\r
-    CHAR8 Chr;\r
-    INT8  Val;\r
-\r
-    Chr = UnitAddress.Ptr[Pos];\r
-    Val = ('a' <= Chr && Chr <= 'f') ? (Chr - 'a' + 10) :\r
-          ('A' <= Chr && Chr <= 'F') ? (Chr - 'A' + 10) :\r
-          ('0' <= Chr && Chr <= '9') ? (Chr - '0'     ) :\r
-          -1;\r
-\r
-    if (Val >= 0) {\r
-      if (EntryVal > 0xFFFFFFFFFFFFFFFull) {\r
-        return RETURN_INVALID_PARAMETER;\r
-      }\r
-      EntryVal = LShiftU64 (EntryVal, 4) | Val;\r
-    } else if (Chr == ',') {\r
-      if (PrevChr == ',') {\r
-        return RETURN_INVALID_PARAMETER;\r
-      }\r
-      if (Entry < *NumResults) {\r
-        Result[Entry] = EntryVal;\r
-      }\r
-      ++Entry;\r
-      EntryVal = 0;\r
-    } else {\r
-      return RETURN_INVALID_PARAMETER;\r
-    }\r
-\r
-    PrevChr = Chr;\r
-  }\r
-\r
-  if (PrevChr == ',') {\r
-    return RETURN_INVALID_PARAMETER;\r
-  }\r
-  if (Entry < *NumResults) {\r
-    Result[Entry] = EntryVal;\r
-    Status = RETURN_SUCCESS;\r
-  } else {\r
-    Status = RETURN_BUFFER_TOO_SMALL;\r
-  }\r
-  ++Entry;\r
-\r
-  *NumResults = Entry;\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  A simple array of Boot Option ID's.\r
-**/\r
-typedef struct {\r
-  UINT16 *Data;\r
-  UINTN  Allocated;\r
-  UINTN  Produced;\r
-} BOOT_ORDER;\r
-\r
-\r
-/**\r
-  Array element tracking an enumerated boot option that has the\r
-  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
-} ACTIVE_OPTION;\r
-\r
-\r
-/**\r
-\r
-  Append an active boot option to BootOrder, reallocating the latter if needed.\r
-\r
-  @param[in out] BootOrder     The structure pointing to the array and holding\r
-                               allocation and usage counters.\r
-\r
-  @param[in]     ActiveOption  The active boot option whose ID should be\r
-                               appended to the array.\r
-\r
-\r
-  @retval RETURN_SUCCESS           ID of ActiveOption appended.\r
-\r
-  @retval RETURN_OUT_OF_RESOURCES  Memory reallocation failed.\r
-\r
-**/\r
-STATIC\r
-RETURN_STATUS\r
-BootOrderAppend (\r
-  IN OUT  BOOT_ORDER    *BootOrder,\r
-  IN OUT  ACTIVE_OPTION *ActiveOption\r
-  )\r
-{\r
-  if (BootOrder->Produced == BootOrder->Allocated) {\r
-    UINTN  AllocatedNew;\r
-    UINT16 *DataNew;\r
-\r
-    ASSERT (BootOrder->Allocated > 0);\r
-    AllocatedNew = BootOrder->Allocated * 2;\r
-    DataNew = ReallocatePool (\r
-                BootOrder->Allocated * sizeof (*BootOrder->Data),\r
-                AllocatedNew         * sizeof (*DataNew),\r
-                BootOrder->Data\r
-                );\r
-    if (DataNew == NULL) {\r
-      return RETURN_OUT_OF_RESOURCES;\r
-    }\r
-    BootOrder->Allocated = AllocatedNew;\r
-    BootOrder->Data      = DataNew;\r
-  }\r
-\r
-  BootOrder->Data[BootOrder->Produced++] =\r
-                                         ActiveOption->BootOption->BootCurrent;\r
-  ActiveOption->Appended = TRUE;\r
-  return RETURN_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-\r
-  Create an array of ACTIVE_OPTION elements for a boot option list.\r
-\r
-  @param[in]  BootOptionList  A boot option list, created with\r
-                              BdsLibEnumerateAllBootOption().\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
-\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
-\r
-  @retval RETURN_OUT_OF_RESOURCES  Memory allocation failed.\r
-\r
-**/\r
-STATIC\r
-RETURN_STATUS\r
-CollectActiveOptions (\r
-  IN   CONST LIST_ENTRY *BootOptionList,\r
-  OUT  ACTIVE_OPTION    **ActiveOption,\r
-  OUT  UINTN            *Count\r
-  )\r
-{\r
-  UINTN ScanMode;\r
-\r
-  *ActiveOption = NULL;\r
-\r
-  //\r
-  // Scan the list twice:\r
-  // - count active entries,\r
-  // - 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
-        if (ScanMode == 1) {\r
-          (*ActiveOption)[*Count].BootOption = Current;\r
-          (*ActiveOption)[*Count].Appended   = FALSE;\r
-        }\r
-        ++*Count;\r
-      }\r
-      Link = Link->ForwardLink;\r
-    }\r
-\r
-    if (ScanMode == 0) {\r
-      if (*Count == 0) {\r
-        return RETURN_NOT_FOUND;\r
-      }\r
-      *ActiveOption = AllocatePool (*Count * sizeof **ActiveOption);\r
-      if (*ActiveOption == NULL) {\r
-        return RETURN_OUT_OF_RESOURCES;\r
-      }\r
-    }\r
-  }\r
-  return RETURN_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  OpenFirmware device path node\r
-**/\r
-typedef struct {\r
-  SUBSTRING DriverName;\r
-  SUBSTRING UnitAddress;\r
-  SUBSTRING DeviceArguments;\r
-} OFW_NODE;\r
-\r
-\r
-/**\r
-\r
-  Parse an OpenFirmware device path node into the caller-allocated OFW_NODE\r
-  structure, and advance in the input string.\r
-\r
-  The node format is mostly parsed after IEEE 1275-1994, 3.2.1.1 "Node names"\r
-  (a leading slash is expected and not returned):\r
-\r
-    /driver-name@unit-address[:device-arguments][<LF>]\r
-\r
-  A single trailing <LF> character is consumed but not returned. A trailing\r
-  <LF> or NUL character terminates the device path.\r
-\r
-  The function relies on ASCII encoding.\r
-\r
-  @param[in out] Ptr      Address of the pointer pointing to the start of the\r
-                          node string. After successful parsing *Ptr is set to\r
-                          the byte immediately following the consumed\r
-                          characters. On error it points to the byte that\r
-                          caused the error. The input string is never modified.\r
-\r
-  @param[out]    OfwNode  The members of this structure point into the input\r
-                          string, designating components of the node.\r
-                          Separators are never included. If "device-arguments"\r
-                          is missing, then DeviceArguments.Ptr is set to NULL.\r
-                          All components that are present have nonzero length.\r
-\r
-                          If the call doesn't succeed, the contents of this\r
-                          structure is indeterminate.\r
-\r
-  @param[out]    IsFinal  In case of successul parsing, this parameter signals\r
-                          whether the node just parsed is the final node in the\r
-                          device path. The call after a final node will attempt\r
-                          to start parsing the next path. If the call doesn't\r
-                          succeed, then this parameter is not changed.\r
-\r
-\r
-  @retval RETURN_SUCCESS            Parsing successful.\r
-\r
-  @retval RETURN_NOT_FOUND          Parsing terminated. *Ptr was (and is)\r
-                                    pointing to an empty string.\r
-\r
-  @retval RETURN_INVALID_PARAMETER  Parse error.\r
-\r
-**/\r
-STATIC\r
-RETURN_STATUS\r
-ParseOfwNode (\r
-  IN OUT  CONST CHAR8 **Ptr,\r
-  OUT     OFW_NODE    *OfwNode,\r
-  OUT     BOOLEAN     *IsFinal\r
-  )\r
-{\r
-  //\r
-  // A leading slash is expected. End of string is tolerated.\r
-  //\r
-  switch (**Ptr) {\r
-  case '\0':\r
-    return RETURN_NOT_FOUND;\r
-\r
-  case '/':\r
-    ++*Ptr;\r
-    break;\r
-\r
-  default:\r
-    return RETURN_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // driver-name\r
-  //\r
-  OfwNode->DriverName.Ptr = *Ptr;\r
-  OfwNode->DriverName.Len = 0;\r
-  while (OfwNode->DriverName.Len < 32 &&\r
-         (IsAlnum (**Ptr) || IsDriverNamePunct (**Ptr))\r
-         ) {\r
-    ++*Ptr;\r
-    ++OfwNode->DriverName.Len;\r
-  }\r
-\r
-  if (OfwNode->DriverName.Len == 0 || OfwNode->DriverName.Len == 32) {\r
-    return RETURN_INVALID_PARAMETER;\r
-  }\r
-\r
-\r
-  //\r
-  // unit-address\r
-  //\r
-  if (**Ptr != '@') {\r
-    return RETURN_INVALID_PARAMETER;\r
-  }\r
-  ++*Ptr;\r
-\r
-  OfwNode->UnitAddress.Ptr = *Ptr;\r
-  OfwNode->UnitAddress.Len = 0;\r
-  while (IsPrintNotDelim (**Ptr)) {\r
-    ++*Ptr;\r
-    ++OfwNode->UnitAddress.Len;\r
-  }\r
-\r
-  if (OfwNode->UnitAddress.Len == 0) {\r
-    return RETURN_INVALID_PARAMETER;\r
-  }\r
-\r
-\r
-  //\r
-  // device-arguments, may be omitted\r
-  //\r
-  OfwNode->DeviceArguments.Len = 0;\r
-  if (**Ptr == ':') {\r
-    ++*Ptr;\r
-    OfwNode->DeviceArguments.Ptr = *Ptr;\r
-\r
-    while (IsPrintNotDelim (**Ptr)) {\r
-      ++*Ptr;\r
-      ++OfwNode->DeviceArguments.Len;\r
-    }\r
-\r
-    if (OfwNode->DeviceArguments.Len == 0) {\r
-      return RETURN_INVALID_PARAMETER;\r
-    }\r
-  }\r
-  else {\r
-    OfwNode->DeviceArguments.Ptr = NULL;\r
-  }\r
-\r
-  switch (**Ptr) {\r
-  case '\n':\r
-    ++*Ptr;\r
-    //\r
-    // fall through\r
-    //\r
-\r
-  case '\0':\r
-    *IsFinal = TRUE;\r
-    break;\r
-\r
-  case '/':\r
-    *IsFinal = FALSE;\r
-    break;\r
-\r
-  default:\r
-    return RETURN_INVALID_PARAMETER;\r
-  }\r
-\r
-  DEBUG ((\r
-    DEBUG_VERBOSE,\r
-    "%a: DriverName=\"%.*a\" UnitAddress=\"%.*a\" DeviceArguments=\"%.*a\"\n",\r
-    __FUNCTION__,\r
-    OfwNode->DriverName.Len, OfwNode->DriverName.Ptr,\r
-    OfwNode->UnitAddress.Len, OfwNode->UnitAddress.Ptr,\r
-    OfwNode->DeviceArguments.Len,\r
-    OfwNode->DeviceArguments.Ptr == NULL ? "" : OfwNode->DeviceArguments.Ptr\r
-    ));\r
-  return RETURN_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-\r
-  Translate a PCI-like array of OpenFirmware device nodes to a UEFI device path\r
-  fragment.\r
-\r
-  @param[in]     OfwNode         Array of OpenFirmware device nodes to\r
-                                 translate, constituting the beginning of an\r
-                                 OpenFirmware device path.\r
-\r
-  @param[in]     NumNodes        Number of elements in OfwNode.\r
-\r
-  @param[in]     ExtraPciRoots   An EXTRA_ROOT_BUS_MAP object created with\r
-                                 CreateExtraRootBusMap(), to be used for\r
-                                 translating positions of extra root buses to\r
-                                 bus numbers.\r
-\r
-  @param[out]    Translated      Destination array receiving the UEFI path\r
-                                 fragment, allocated by the caller. If the\r
-                                 return value differs from RETURN_SUCCESS, its\r
-                                 contents is indeterminate.\r
-\r
-  @param[in out] TranslatedSize  On input, the number of CHAR16's in\r
-                                 Translated. On RETURN_SUCCESS this parameter\r
-                                 is assigned the number of non-NUL CHAR16's\r
-                                 written to Translated. In case of other return\r
-                                 values, TranslatedSize is indeterminate.\r
-\r
-\r
-  @retval RETURN_SUCCESS           Translation successful.\r
-\r
-  @retval RETURN_BUFFER_TOO_SMALL  The translation does not fit into the number\r
-                                   of bytes provided.\r
-\r
-  @retval RETURN_UNSUPPORTED       The array of OpenFirmware device nodes can't\r
-                                   be translated in the current implementation.\r
-\r
-  @retval RETURN_PROTOCOL_ERROR    The initial OpenFirmware node refers to an\r
-                                   extra PCI root bus (by serial number) that\r
-                                   is invalid according to ExtraPciRoots.\r
-\r
-**/\r
-STATIC\r
-RETURN_STATUS\r
-TranslatePciOfwNodes (\r
-  IN      CONST OFW_NODE           *OfwNode,\r
-  IN      UINTN                    NumNodes,\r
-  IN      CONST EXTRA_ROOT_BUS_MAP *ExtraPciRoots,\r
-  OUT     CHAR16                   *Translated,\r
-  IN OUT  UINTN                    *TranslatedSize\r
-  )\r
-{\r
-  UINT32 PciRoot;\r
-  CHAR8  *Comma;\r
-  UINTN  FirstNonBridge;\r
-  CHAR16 Bridges[BRIDGE_TRANSLATION_OUTPUT_SIZE];\r
-  UINTN  BridgesLen;\r
-  UINT64 PciDevFun[2];\r
-  UINTN  NumEntries;\r
-  UINTN  Written;\r
-\r
-  //\r
-  // Resolve the PCI root bus number.\r
-  //\r
-  // The initial OFW node for the main root bus (ie. bus number 0) is:\r
-  //\r
-  //   /pci@i0cf8\r
-  //\r
-  // For extra root buses, the initial OFW node is\r
-  //\r
-  //   /pci@i0cf8,4\r
-  //              ^\r
-  //              root bus serial number (not PCI bus number)\r
-  //\r
-  if (NumNodes < REQUIRED_PCI_OFW_NODES ||\r
-      !SubstringEq (OfwNode[0].DriverName, "pci")\r
-      ) {\r
-    return RETURN_UNSUPPORTED;\r
-  }\r
-\r
-  PciRoot = 0;\r
-  Comma = ScanMem8 (OfwNode[0].UnitAddress.Ptr, OfwNode[0].UnitAddress.Len,\r
-            ',');\r
-  if (Comma != NULL) {\r
-    SUBSTRING PciRootSerialSubString;\r
-    UINT64    PciRootSerial;\r
-\r
-    //\r
-    // Parse the root bus serial number from the unit address after the comma.\r
-    //\r
-    PciRootSerialSubString.Ptr = Comma + 1;\r
-    PciRootSerialSubString.Len = OfwNode[0].UnitAddress.Len -\r
-                                 (PciRootSerialSubString.Ptr -\r
-                                  OfwNode[0].UnitAddress.Ptr);\r
-    NumEntries = 1;\r
-    if (RETURN_ERROR (ParseUnitAddressHexList (PciRootSerialSubString,\r
-                      &PciRootSerial, &NumEntries))) {\r
-      return RETURN_UNSUPPORTED;\r
-    }\r
-\r
-    //\r
-    // Map the extra root bus's serial number to its actual bus number.\r
-    //\r
-    if (EFI_ERROR (MapRootBusPosToBusNr (ExtraPciRoots, PciRootSerial,\r
-                     &PciRoot))) {\r
-      return RETURN_PROTOCOL_ERROR;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Translate a sequence of PCI bridges. For each bridge, the OFW node is:\r
-  //\r
-  //   pci-bridge@1e[,0]\r
-  //              ^   ^\r
-  //              PCI slot & function on the parent, holding the bridge\r
-  //\r
-  // and the UEFI device path node is:\r
-  //\r
-  //   Pci(0x1E,0x0)\r
-  //\r
-  FirstNonBridge = 1;\r
-  Bridges[0] = L'\0';\r
-  BridgesLen = 0;\r
-  do {\r
-    UINT64 BridgeDevFun[2];\r
-    UINTN  BridgesFreeBytes;\r
-\r
-    if (!SubstringEq (OfwNode[FirstNonBridge].DriverName, "pci-bridge")) {\r
-      break;\r
-    }\r
-\r
-    BridgeDevFun[1] = 0;\r
-    NumEntries = sizeof BridgeDevFun / sizeof BridgeDevFun[0];\r
-    if (ParseUnitAddressHexList (OfwNode[FirstNonBridge].UnitAddress,\r
-          BridgeDevFun, &NumEntries) != RETURN_SUCCESS) {\r
-      return RETURN_UNSUPPORTED;\r
-    }\r
-\r
-    BridgesFreeBytes = sizeof Bridges - BridgesLen * sizeof Bridges[0];\r
-    Written = UnicodeSPrintAsciiFormat (Bridges + BridgesLen, BridgesFreeBytes,\r
-                "/Pci(0x%Lx,0x%Lx)", BridgeDevFun[0], BridgeDevFun[1]);\r
-    BridgesLen += Written;\r
-\r
-    //\r
-    // There's no way to differentiate between "completely used up without\r
-    // truncation" and "truncated", so treat the former as the latter.\r
-    //\r
-    if (BridgesLen + 1 == BRIDGE_TRANSLATION_OUTPUT_SIZE) {\r
-      return RETURN_UNSUPPORTED;\r
-    }\r
-\r
-    ++FirstNonBridge;\r
-  } while (FirstNonBridge < NumNodes);\r
-\r
-  if (FirstNonBridge == NumNodes) {\r
-    return RETURN_UNSUPPORTED;\r
-  }\r
-\r
-  //\r
-  // Parse the OFW nodes starting with the first non-bridge node.\r
-  //\r
-  PciDevFun[1] = 0;\r
-  NumEntries = sizeof (PciDevFun) / sizeof (PciDevFun[0]);\r
-  if (ParseUnitAddressHexList (\r
-        OfwNode[FirstNonBridge].UnitAddress,\r
-        PciDevFun,\r
-        &NumEntries\r
-        ) != RETURN_SUCCESS\r
-      ) {\r
-    return RETURN_UNSUPPORTED;\r
-  }\r
-\r
-  if (NumNodes >= FirstNonBridge + 3 &&\r
-      SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "ide") &&\r
-      SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "drive") &&\r
-      SubstringEq (OfwNode[FirstNonBridge + 2].DriverName, "disk")\r
-      ) {\r
-    //\r
-    // OpenFirmware device path (IDE disk, IDE CD-ROM):\r
-    //\r
-    //   /pci@i0cf8/ide@1,1/drive@0/disk@0\r
-    //        ^         ^ ^       ^      ^\r
-    //        |         | |       |      master or slave\r
-    //        |         | |       primary or secondary\r
-    //        |         PCI slot & function holding IDE controller\r
-    //        PCI root at system bus port, PIO\r
-    //\r
-    // UEFI device path:\r
-    //\r
-    //   PciRoot(0x0)/Pci(0x1,0x1)/Ata(Primary,Master,0x0)\r
-    //                                                ^\r
-    //                                                fixed LUN\r
-    //\r
-    UINT64 Secondary;\r
-    UINT64 Slave;\r
-\r
-    NumEntries = 1;\r
-    if (ParseUnitAddressHexList (\r
-          OfwNode[FirstNonBridge + 1].UnitAddress,\r
-          &Secondary,\r
-          &NumEntries\r
-          ) != RETURN_SUCCESS ||\r
-        Secondary > 1 ||\r
-        ParseUnitAddressHexList (\r
-          OfwNode[FirstNonBridge + 2].UnitAddress,\r
-          &Slave,\r
-          &NumEntries // reuse after previous single-element call\r
-          ) != RETURN_SUCCESS ||\r
-        Slave > 1\r
-        ) {\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)/Ata(%a,%a,0x0)",\r
-      PciRoot,\r
-      Bridges,\r
-      PciDevFun[0],\r
-      PciDevFun[1],\r
-      Secondary ? "Secondary" : "Primary",\r
-      Slave ? "Slave" : "Master"\r
-      );\r
-  } else if (NumNodes >= FirstNonBridge + 3 &&\r
-      SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "pci8086,2922") &&\r
-      SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "drive") &&\r
-      SubstringEq (OfwNode[FirstNonBridge + 2].DriverName, "disk")\r
-      ) {\r
-    //\r
-    // OpenFirmware device path (Q35 SATA disk and CD-ROM):\r
-    //\r
-    //   /pci@i0cf8/pci8086,2922@1f,2/drive@1/disk@0\r
-    //        ^                  ^  ^       ^      ^\r
-    //        |                  |  |       |      device number (fixed 0)\r
-    //        |                  |  |       channel (port) number\r
-    //        |                  PCI slot & function holding SATA HBA\r
-    //        PCI root at system bus port, PIO\r
-    //\r
-    // UEFI device path:\r
-    //\r
-    //   PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0xFFFF,0x0)\r
-    //                                   ^   ^      ^\r
-    //                                   |   |      LUN (always 0 on Q35)\r
-    //                                   |   port multiplier port number,\r
-    //                                   |   always 0xFFFF on Q35\r
-    //                                   channel (port) number\r
-    //\r
-    UINT64 Channel;\r
-\r
-    NumEntries = 1;\r
-    if (RETURN_ERROR (ParseUnitAddressHexList (\r
-                        OfwNode[FirstNonBridge + 1].UnitAddress, &Channel,\r
-                        &NumEntries))) {\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)/Sata(0x%Lx,0xFFFF,0x0)",\r
-      PciRoot,\r
-      Bridges,\r
-      PciDevFun[0],\r
-      PciDevFun[1],\r
-      Channel\r
-      );\r
-  } else if (NumNodes >= FirstNonBridge + 3 &&\r
-             SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "isa") &&\r
-             SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "fdc") &&\r
-             SubstringEq (OfwNode[FirstNonBridge + 2].DriverName, "floppy")\r
-             ) {\r
-    //\r
-    // OpenFirmware device path (floppy disk):\r
-    //\r
-    //   /pci@i0cf8/isa@1/fdc@03f0/floppy@0\r
-    //        ^         ^     ^           ^\r
-    //        |         |     |           A: or B:\r
-    //        |         |     ISA controller io-port (hex)\r
-    //        |         PCI slot holding ISA controller\r
-    //        PCI root at system bus port, PIO\r
-    //\r
-    // UEFI device path:\r
-    //\r
-    //   PciRoot(0x0)/Pci(0x1,0x0)/Floppy(0x0)\r
-    //                                    ^\r
-    //                                    ACPI UID\r
-    //\r
-    UINT64 AcpiUid;\r
-\r
-    NumEntries = 1;\r
-    if (ParseUnitAddressHexList (\r
-          OfwNode[FirstNonBridge + 2].UnitAddress,\r
-          &AcpiUid,\r
-          &NumEntries\r
-          ) != RETURN_SUCCESS ||\r
-        AcpiUid > 1\r
-        ) {\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)/Floppy(0x%Lx)",\r
-      PciRoot,\r
-      Bridges,\r
-      PciDevFun[0],\r
-      PciDevFun[1],\r
-      AcpiUid\r
-      );\r
-  } else if (NumNodes >= FirstNonBridge + 2 &&\r
-             SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "scsi") &&\r
-             SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "disk")\r
-             ) {\r
-    //\r
-    // OpenFirmware device path (virtio-blk disk):\r
-    //\r
-    //   /pci@i0cf8/scsi@6[,3]/disk@0,0\r
-    //        ^          ^  ^       ^ ^\r
-    //        |          |  |       fixed\r
-    //        |          |  PCI function corresponding to disk (optional)\r
-    //        |          PCI slot holding disk\r
-    //        PCI root at system bus port, PIO\r
-    //\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
-    //\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,\r
-      Bridges,\r
-      PciDevFun[0],\r
-      PciDevFun[1]\r
-      );\r
-  } else if (NumNodes >= FirstNonBridge + 3 &&\r
-             SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "scsi") &&\r
-             SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "channel") &&\r
-             SubstringEq (OfwNode[FirstNonBridge + 2].DriverName, "disk")\r
-             ) {\r
-    //\r
-    // OpenFirmware device path (virtio-scsi disk):\r
-    //\r
-    //   /pci@i0cf8/scsi@7[,3]/channel@0/disk@2,3\r
-    //        ^          ^             ^      ^ ^\r
-    //        |          |             |      | LUN\r
-    //        |          |             |      target\r
-    //        |          |             channel (unused, fixed 0)\r
-    //        |          PCI slot[, function] holding SCSI controller\r
-    //        PCI root at system bus port, PIO\r
-    //\r
-    // UEFI device path prefix:\r
-    //\r
-    //   PciRoot(0x0)/Pci(0x7,0x0)/Scsi(0x2,0x3)\r
-    //                                        -- if PCI function is 0 or absent\r
-    //   PciRoot(0x0)/Pci(0x7,0x3)/Scsi(0x2,0x3)\r
-    //                                -- if PCI function is present and nonzero\r
-    //\r
-    UINT64 TargetLun[2];\r
-\r
-    TargetLun[1] = 0;\r
-    NumEntries = sizeof (TargetLun) / sizeof (TargetLun[0]);\r
-    if (ParseUnitAddressHexList (\r
-          OfwNode[FirstNonBridge + 2].UnitAddress,\r
-          TargetLun,\r
-          &NumEntries\r
-          ) != RETURN_SUCCESS\r
-        ) {\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)/Scsi(0x%Lx,0x%Lx)",\r
-      PciRoot,\r
-      Bridges,\r
-      PciDevFun[0],\r
-      PciDevFun[1],\r
-      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 = sizeof (Namespace) / sizeof (Namespace[0]);\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 {\r
-    //\r
-    // Generic OpenFirmware device path for PCI devices:\r
-    //\r
-    //   /pci@i0cf8/ethernet@3[,2]\r
-    //        ^              ^\r
-    //        |              PCI slot[, function] holding Ethernet card\r
-    //        PCI root at system bus port, PIO\r
-    //\r
-    // UEFI device path prefix (dependent on presence of nonzero PCI function):\r
-    //\r
-    //   PciRoot(0x0)/Pci(0x3,0x0)\r
-    //   PciRoot(0x0)/Pci(0x3,0x2)\r
-    //\r
-    Written = UnicodeSPrintAsciiFormat (\r
-      Translated,\r
-      *TranslatedSize * sizeof (*Translated), // BufferSize in bytes\r
-      "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)",\r
-      PciRoot,\r
-      Bridges,\r
-      PciDevFun[0],\r
-      PciDevFun[1]\r
-      );\r
-  }\r
-\r
-  //\r
-  // There's no way to differentiate between "completely used up without\r
-  // truncation" and "truncated", so treat the former as the latter, and return\r
-  // success only for "some room left unused".\r
-  //\r
-  if (Written + 1 < *TranslatedSize) {\r
-    *TranslatedSize = Written;\r
-    return RETURN_SUCCESS;\r
-  }\r
-\r
-  return RETURN_BUFFER_TOO_SMALL;\r
-}\r
-\r
-\r
-//\r
-// A type providing easy raw access to the base address of a virtio-mmio\r
-// transport.\r
-//\r
-typedef union {\r
-  UINT64 Uint64;\r
-  UINT8  Raw[8];\r
-} VIRTIO_MMIO_BASE_ADDRESS;\r
-\r
-\r
-/**\r
-\r
-  Translate an MMIO-like array of OpenFirmware device nodes to a UEFI device\r
-  path fragment.\r
-\r
-  @param[in]     OfwNode         Array of OpenFirmware device nodes to\r
-                                 translate, constituting the beginning of an\r
-                                 OpenFirmware device path.\r
-\r
-  @param[in]     NumNodes        Number of elements in OfwNode.\r
-\r
-  @param[out]    Translated      Destination array receiving the UEFI path\r
-                                 fragment, allocated by the caller. If the\r
-                                 return value differs from RETURN_SUCCESS, its\r
-                                 contents is indeterminate.\r
-\r
-  @param[in out] TranslatedSize  On input, the number of CHAR16's in\r
-                                 Translated. On RETURN_SUCCESS this parameter\r
-                                 is assigned the number of non-NUL CHAR16's\r
-                                 written to Translated. In case of other return\r
-                                 values, TranslatedSize is indeterminate.\r
-\r
-\r
-  @retval RETURN_SUCCESS           Translation successful.\r
-\r
-  @retval RETURN_BUFFER_TOO_SMALL  The translation does not fit into the number\r
-                                   of bytes provided.\r
-\r
-  @retval RETURN_UNSUPPORTED       The array of OpenFirmware device nodes can't\r
-                                   be translated in the current implementation.\r
-\r
-**/\r
-STATIC\r
-RETURN_STATUS\r
-TranslateMmioOfwNodes (\r
-  IN      CONST OFW_NODE *OfwNode,\r
-  IN      UINTN          NumNodes,\r
-  OUT     CHAR16         *Translated,\r
-  IN OUT  UINTN          *TranslatedSize\r
-  )\r
-{\r
-  VIRTIO_MMIO_BASE_ADDRESS VirtioMmioBase;\r
-  CHAR16                   VenHwString[60 + 1];\r
-  UINTN                    NumEntries;\r
-  UINTN                    Written;\r
-\r
-  //\r
-  // Get the base address of the virtio-mmio transport.\r
-  //\r
-  if (NumNodes < REQUIRED_MMIO_OFW_NODES ||\r
-      !SubstringEq (OfwNode[0].DriverName, "virtio-mmio")\r
-      ) {\r
-    return RETURN_UNSUPPORTED;\r
-  }\r
-  NumEntries = 1;\r
-  if (ParseUnitAddressHexList (\r
-        OfwNode[0].UnitAddress,\r
-        &VirtioMmioBase.Uint64,\r
-        &NumEntries\r
-        ) != RETURN_SUCCESS\r
-      ) {\r
-    return RETURN_UNSUPPORTED;\r
-  }\r
-\r
-  UnicodeSPrintAsciiFormat (VenHwString, sizeof VenHwString,\r
-    "VenHw(%g,%02X%02X%02X%02X%02X%02X%02X%02X)", &gVirtioMmioTransportGuid,\r
-    VirtioMmioBase.Raw[0], VirtioMmioBase.Raw[1], VirtioMmioBase.Raw[2],\r
-    VirtioMmioBase.Raw[3], VirtioMmioBase.Raw[4], VirtioMmioBase.Raw[5],\r
-    VirtioMmioBase.Raw[6], VirtioMmioBase.Raw[7]);\r
-\r
-  if (NumNodes >= 2 &&\r
-      SubstringEq (OfwNode[1].DriverName, "disk")) {\r
-    //\r
-    // OpenFirmware device path (virtio-blk disk):\r
-    //\r
-    //   /virtio-mmio@000000000a003c00/disk@0,0\r
-    //                ^                     ^ ^\r
-    //                |                     fixed\r
-    //                base address of virtio-mmio register block\r
-    //\r
-    // UEFI device path prefix:\r
-    //\r
-    //   <VenHwString>/HD(\r
-    //\r
-    Written = UnicodeSPrintAsciiFormat (\r
-                Translated,\r
-                *TranslatedSize * sizeof (*Translated), // BufferSize in bytes\r
-                "%s/HD(",\r
-                VenHwString\r
-                );\r
-  } else if (NumNodes >= 3 &&\r
-             SubstringEq (OfwNode[1].DriverName, "channel") &&\r
-             SubstringEq (OfwNode[2].DriverName, "disk")) {\r
-    //\r
-    // OpenFirmware device path (virtio-scsi disk):\r
-    //\r
-    //   /virtio-mmio@000000000a003a00/channel@0/disk@2,3\r
-    //                ^                        ^      ^ ^\r
-    //                |                        |      | LUN\r
-    //                |                        |      target\r
-    //                |                        channel (unused, fixed 0)\r
-    //                base address of virtio-mmio register block\r
-    //\r
-    // UEFI device path prefix:\r
-    //\r
-    //   <VenHwString>/Scsi(0x2,0x3)\r
-    //\r
-    UINT64 TargetLun[2];\r
-\r
-    TargetLun[1] = 0;\r
-    NumEntries = sizeof (TargetLun) / sizeof (TargetLun[0]);\r
-    if (ParseUnitAddressHexList (\r
-          OfwNode[2].UnitAddress,\r
-          TargetLun,\r
-          &NumEntries\r
-          ) != RETURN_SUCCESS\r
-        ) {\r
-      return RETURN_UNSUPPORTED;\r
-    }\r
-\r
-    Written = UnicodeSPrintAsciiFormat (\r
-                Translated,\r
-                *TranslatedSize * sizeof (*Translated), // BufferSize in bytes\r
-                "%s/Scsi(0x%Lx,0x%Lx)",\r
-                VenHwString,\r
-                TargetLun[0],\r
-                TargetLun[1]\r
-                );\r
-  } else if (NumNodes >= 2 &&\r
-             SubstringEq (OfwNode[1].DriverName, "ethernet-phy")) {\r
-    //\r
-    // OpenFirmware device path (virtio-net NIC):\r
-    //\r
-    //   /virtio-mmio@000000000a003e00/ethernet-phy@0\r
-    //                ^                             ^\r
-    //                |                             fixed\r
-    //                base address of virtio-mmio register block\r
-    //\r
-    // UEFI device path prefix (dependent on presence of nonzero PCI function):\r
-    //\r
-    //   <VenHwString>/MAC(\r
-    //\r
-    Written = UnicodeSPrintAsciiFormat (\r
-                Translated,\r
-                *TranslatedSize * sizeof (*Translated), // BufferSize in bytes\r
-                "%s/MAC(",\r
-                VenHwString\r
-                );\r
-  } else {\r
-    return RETURN_UNSUPPORTED;\r
-  }\r
-\r
-  //\r
-  // There's no way to differentiate between "completely used up without\r
-  // truncation" and "truncated", so treat the former as the latter, and return\r
-  // success only for "some room left unused".\r
-  //\r
-  if (Written + 1 < *TranslatedSize) {\r
-    *TranslatedSize = Written;\r
-    return RETURN_SUCCESS;\r
-  }\r
-\r
-  return RETURN_BUFFER_TOO_SMALL;\r
-}\r
-\r
-\r
-/**\r
-\r
-  Translate an array of OpenFirmware device nodes to a UEFI device path\r
-  fragment.\r
-\r
-  @param[in]     OfwNode         Array of OpenFirmware device nodes to\r
-                                 translate, constituting the beginning of an\r
-                                 OpenFirmware device path.\r
-\r
-  @param[in]     NumNodes        Number of elements in OfwNode.\r
-\r
-  @param[in]     ExtraPciRoots   An EXTRA_ROOT_BUS_MAP object created with\r
-                                 CreateExtraRootBusMap(), to be used for\r
-                                 translating positions of extra root buses to\r
-                                 bus numbers.\r
-\r
-  @param[out]    Translated      Destination array receiving the UEFI path\r
-                                 fragment, allocated by the caller. If the\r
-                                 return value differs from RETURN_SUCCESS, its\r
-                                 contents is indeterminate.\r
-\r
-  @param[in out] TranslatedSize  On input, the number of CHAR16's in\r
-                                 Translated. On RETURN_SUCCESS this parameter\r
-                                 is assigned the number of non-NUL CHAR16's\r
-                                 written to Translated. In case of other return\r
-                                 values, TranslatedSize is indeterminate.\r
-\r
-\r
-  @retval RETURN_SUCCESS           Translation successful.\r
-\r
-  @retval RETURN_BUFFER_TOO_SMALL  The translation does not fit into the number\r
-                                   of bytes provided.\r
-\r
-  @retval RETURN_UNSUPPORTED       The array of OpenFirmware device nodes can't\r
-                                   be translated in the current implementation.\r
-\r
-  @retval RETURN_PROTOCOL_ERROR    The array of OpenFirmware device nodes has\r
-                                   been (partially) recognized, but it contains\r
-                                   a logic error / doesn't match system state.\r
-\r
-**/\r
-STATIC\r
-RETURN_STATUS\r
-TranslateOfwNodes (\r
-  IN      CONST OFW_NODE           *OfwNode,\r
-  IN      UINTN                    NumNodes,\r
-  IN      CONST EXTRA_ROOT_BUS_MAP *ExtraPciRoots,\r
-  OUT     CHAR16                   *Translated,\r
-  IN OUT  UINTN                    *TranslatedSize\r
-  )\r
-{\r
-  RETURN_STATUS Status;\r
-\r
-  Status = RETURN_UNSUPPORTED;\r
-\r
-  if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) {\r
-    Status = TranslatePciOfwNodes (OfwNode, NumNodes, ExtraPciRoots,\r
-               Translated, TranslatedSize);\r
-  }\r
-  if (Status == RETURN_UNSUPPORTED &&\r
-      FeaturePcdGet (PcdQemuBootOrderMmioTranslation)) {\r
-    Status = TranslateMmioOfwNodes (OfwNode, NumNodes, Translated,\r
-               TranslatedSize);\r
-  }\r
-  return Status;\r
-}\r
-\r
-/**\r
-\r
-  Translate an OpenFirmware device path fragment to a UEFI device path\r
-  fragment, and advance in the input string.\r
-\r
-  @param[in out] Ptr             Address of the pointer pointing to the start\r
-                                 of the path string. After successful\r
-                                 translation (RETURN_SUCCESS) or at least\r
-                                 successful parsing (RETURN_UNSUPPORTED,\r
-                                 RETURN_BUFFER_TOO_SMALL), *Ptr is set to the\r
-                                 byte immediately following the consumed\r
-                                 characters. In other error cases, it points to\r
-                                 the byte that caused the error.\r
-\r
-  @param[in]     ExtraPciRoots   An EXTRA_ROOT_BUS_MAP object created with\r
-                                 CreateExtraRootBusMap(), to be used for\r
-                                 translating positions of extra root buses to\r
-                                 bus numbers.\r
-\r
-  @param[out]    Translated      Destination array receiving the UEFI path\r
-                                 fragment, allocated by the caller. If the\r
-                                 return value differs from RETURN_SUCCESS, its\r
-                                 contents is indeterminate.\r
-\r
-  @param[in out] TranslatedSize  On input, the number of CHAR16's in\r
-                                 Translated. On RETURN_SUCCESS this parameter\r
-                                 is assigned the number of non-NUL CHAR16's\r
-                                 written to Translated. In case of other return\r
-                                 values, TranslatedSize is indeterminate.\r
-\r
-\r
-  @retval RETURN_SUCCESS            Translation successful.\r
-\r
-  @retval RETURN_BUFFER_TOO_SMALL   The OpenFirmware device path was parsed\r
-                                    successfully, but its translation did not\r
-                                    fit into the number of bytes provided.\r
-                                    Further calls to this function are\r
-                                    possible.\r
-\r
-  @retval RETURN_UNSUPPORTED        The OpenFirmware device path was parsed\r
-                                    successfully, but it can't be translated in\r
-                                    the current implementation. Further calls\r
-                                    to this function are possible.\r
-\r
-  @retval RETURN_PROTOCOL_ERROR     The OpenFirmware device path has been\r
-                                    (partially) recognized, but it contains a\r
-                                    logic error / doesn't match system state.\r
-                                    Further calls to this function are\r
-                                    possible.\r
-\r
-  @retval RETURN_NOT_FOUND          Translation terminated. On input, *Ptr was\r
-                                    pointing to the empty string or "HALT". On\r
-                                    output, *Ptr points to the empty string\r
-                                    (ie. "HALT" is consumed transparently when\r
-                                    present).\r
-\r
-  @retval RETURN_INVALID_PARAMETER  Parse error. This is a permanent error.\r
-\r
-**/\r
-STATIC\r
-RETURN_STATUS\r
-TranslateOfwPath (\r
-  IN OUT  CONST CHAR8              **Ptr,\r
-  IN      CONST EXTRA_ROOT_BUS_MAP *ExtraPciRoots,\r
-  OUT     CHAR16                   *Translated,\r
-  IN OUT  UINTN                    *TranslatedSize\r
-  )\r
-{\r
-  UINTN         NumNodes;\r
-  RETURN_STATUS Status;\r
-  OFW_NODE      Node[EXAMINED_OFW_NODES];\r
-  BOOLEAN       IsFinal;\r
-  OFW_NODE      Skip;\r
-\r
-  IsFinal = FALSE;\r
-  NumNodes = 0;\r
-  if (AsciiStrCmp (*Ptr, "HALT") == 0) {\r
-    *Ptr += 4;\r
-    Status = RETURN_NOT_FOUND;\r
-  } else {\r
-    Status = ParseOfwNode (Ptr, &Node[NumNodes], &IsFinal);\r
-  }\r
-\r
-  if (Status == RETURN_NOT_FOUND) {\r
-    DEBUG ((DEBUG_VERBOSE, "%a: no more nodes\n", __FUNCTION__));\r
-    return RETURN_NOT_FOUND;\r
-  }\r
-\r
-  while (Status == RETURN_SUCCESS && !IsFinal) {\r
-    ++NumNodes;\r
-    Status = ParseOfwNode (\r
-               Ptr,\r
-               (NumNodes < EXAMINED_OFW_NODES) ? &Node[NumNodes] : &Skip,\r
-               &IsFinal\r
-               );\r
-  }\r
-\r
-  switch (Status) {\r
-  case RETURN_SUCCESS:\r
-    ++NumNodes;\r
-    break;\r
-\r
-  case RETURN_INVALID_PARAMETER:\r
-    DEBUG ((DEBUG_VERBOSE, "%a: parse error\n", __FUNCTION__));\r
-    return RETURN_INVALID_PARAMETER;\r
-\r
-  default:\r
-    ASSERT (0);\r
-  }\r
-\r
-  Status = TranslateOfwNodes (\r
-             Node,\r
-             NumNodes < EXAMINED_OFW_NODES ? NumNodes : EXAMINED_OFW_NODES,\r
-             ExtraPciRoots,\r
-             Translated,\r
-             TranslatedSize);\r
-  switch (Status) {\r
-  case RETURN_SUCCESS:\r
-    DEBUG ((DEBUG_VERBOSE, "%a: success: \"%s\"\n", __FUNCTION__, Translated));\r
-    break;\r
-\r
-  case RETURN_BUFFER_TOO_SMALL:\r
-    DEBUG ((DEBUG_VERBOSE, "%a: buffer too small\n", __FUNCTION__));\r
-    break;\r
-\r
-  case RETURN_UNSUPPORTED:\r
-    DEBUG ((DEBUG_VERBOSE, "%a: unsupported\n", __FUNCTION__));\r
-    break;\r
-\r
-  case RETURN_PROTOCOL_ERROR:\r
-    DEBUG ((DEBUG_VERBOSE, "%a: logic error / system state mismatch\n",\r
-      __FUNCTION__));\r
-    break;\r
-\r
-  default:\r
-    ASSERT (0);\r
-  }\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-\r
-  Convert the UEFI DevicePath to full text representation with DevPathToText,\r
-  then match the UEFI device path fragment in Translated against it.\r
-\r
-  @param[in] Translated        UEFI device path fragment, translated from\r
-                               OpenFirmware format, to search for.\r
-\r
-  @param[in] TranslatedLength  The length of Translated in CHAR16's.\r
-\r
-  @param[in] DevicePath        Boot option device path whose textual rendering\r
-                               to search in.\r
-\r
-  @param[in] DevPathToText  Binary-to-text conversion protocol for DevicePath.\r
-\r
-\r
-  @retval TRUE   If Translated was found at the beginning of DevicePath after\r
-                 converting the latter to text.\r
-\r
-  @retval FALSE  If DevicePath was NULL, or it could not be converted, or there\r
-                 was no match.\r
-\r
-**/\r
-STATIC\r
-BOOLEAN\r
-Match (\r
-  IN  CONST CHAR16                           *Translated,\r
-  IN  UINTN                                  TranslatedLength,\r
-  IN  CONST EFI_DEVICE_PATH_PROTOCOL         *DevicePath\r
-  )\r
-{\r
-  CHAR16  *Converted;\r
-  BOOLEAN Result;\r
-\r
-  Converted = ConvertDevicePathToText (\r
-                DevicePath,\r
-                FALSE, // DisplayOnly\r
-                FALSE  // AllowShortcuts\r
-                );\r
-  if (Converted == NULL) {\r
-    return FALSE;\r
-  }\r
-\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
-  //\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
-      goto Exit;\r
-    }\r
-    AbsConverted = ConvertDevicePathToText (AbsDevicePath, FALSE, FALSE);\r
-    if (AbsConverted == NULL) {\r
-      goto Exit;\r
-    }\r
-    DEBUG ((DEBUG_VERBOSE,\r
-      "%a: expanded relative device path \"%s\" for prefix matching\n",\r
-      __FUNCTION__, Converted));\r
-    FreePool (Converted);\r
-    Converted = AbsConverted;\r
-  }\r
-\r
-  //\r
-  // Is Translated a prefix of Converted?\r
-  //\r
-  Result = (BOOLEAN)(StrnCmp (Converted, Translated, TranslatedLength) == 0);\r
-  DEBUG ((\r
-    DEBUG_VERBOSE,\r
-    "%a: against \"%s\": %a\n",\r
-    __FUNCTION__,\r
-    Converted,\r
-    Result ? "match" : "no match"\r
-    ));\r
-Exit:\r
-  FreePool (Converted);\r
-  return Result;\r
-}\r
-\r
-\r
-/**\r
-  Append some of the unselected active boot options to the boot order.\r
-\r
-  This function should accommodate any further policy changes in "boot option\r
-  survival". Currently we're adding back everything that starts with neither\r
-  PciRoot() nor HD() nor a virtio-mmio VenHw() node.\r
-\r
-  @param[in,out] BootOrder     The structure holding the boot order to\r
-                               complete. The caller is responsible for\r
-                               initializing (and potentially populating) it\r
-                               before calling this function.\r
-\r
-  @param[in,out] ActiveOption  The array of active boot options to scan.\r
-                               Entries marked as Appended will be skipped.\r
-                               Those of the rest that satisfy the survival\r
-                               policy will be added to BootOrder with\r
-                               BootOrderAppend().\r
-\r
-  @param[in]     ActiveCount   Number of elements in ActiveOption.\r
-\r
-\r
-  @retval RETURN_SUCCESS  BootOrder has been extended with any eligible boot\r
-                          options.\r
-\r
-  @return                 Error codes returned by BootOrderAppend().\r
-**/\r
-STATIC\r
-RETURN_STATUS\r
-BootOrderComplete (\r
-  IN OUT  BOOT_ORDER    *BootOrder,\r
-  IN OUT  ACTIVE_OPTION *ActiveOption,\r
-  IN      UINTN         ActiveCount\r
-  )\r
-{\r
-  RETURN_STATUS Status;\r
-  UINTN         Idx;\r
-\r
-  Status = RETURN_SUCCESS;\r
-  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
-\r
-      Current = ActiveOption[Idx].BootOption;\r
-      FirstNode = Current->DevicePath;\r
-      if (FirstNode != NULL) {\r
-        CHAR16        *Converted;\r
-        STATIC CHAR16 ConvFallBack[] = L"<unable to convert>";\r
-        BOOLEAN       Keep;\r
-\r
-        Converted = ConvertDevicePathToText (FirstNode, FALSE, FALSE);\r
-        if (Converted == NULL) {\r
-          Converted = ConvFallBack;\r
-        }\r
-\r
-        Keep = TRUE;\r
-        if (DevicePathType(FirstNode) == MEDIA_DEVICE_PATH &&\r
-            DevicePathSubType(FirstNode) == MEDIA_HARDDRIVE_DP) {\r
-          //\r
-          // drop HD()\r
-          //\r
-          Keep = FALSE;\r
-        } else if (DevicePathType(FirstNode) == ACPI_DEVICE_PATH &&\r
-                   DevicePathSubType(FirstNode) == ACPI_DP) {\r
-          ACPI_HID_DEVICE_PATH *Acpi;\r
-\r
-          Acpi = (ACPI_HID_DEVICE_PATH *) FirstNode;\r
-          if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST &&\r
-              EISA_ID_TO_NUM (Acpi->HID) == 0x0a03) {\r
-            //\r
-            // drop PciRoot() if we enabled the user to select PCI-like boot\r
-            // options, by providing translation for such OFW device path\r
-            // fragments\r
-            //\r
-            Keep = !FeaturePcdGet (PcdQemuBootOrderPciTranslation);\r
-          }\r
-        } else if (DevicePathType(FirstNode) == HARDWARE_DEVICE_PATH &&\r
-                   DevicePathSubType(FirstNode) == HW_VENDOR_DP) {\r
-          VENDOR_DEVICE_PATH *VenHw;\r
-\r
-          VenHw = (VENDOR_DEVICE_PATH *)FirstNode;\r
-          if (CompareGuid (&VenHw->Guid, &gVirtioMmioTransportGuid)) {\r
-            //\r
-            // drop virtio-mmio if we enabled the user to select boot options\r
-            // referencing such device paths\r
-            //\r
-            Keep = !FeaturePcdGet (PcdQemuBootOrderMmioTranslation);\r
-          }\r
-        }\r
-\r
-        if (Keep) {\r
-          Status = BootOrderAppend (BootOrder, &ActiveOption[Idx]);\r
-          if (!RETURN_ERROR (Status)) {\r
-            DEBUG ((DEBUG_VERBOSE, "%a: keeping \"%s\"\n", __FUNCTION__,\r
-              Converted));\r
-          }\r
-        } else {\r
-          DEBUG ((DEBUG_VERBOSE, "%a: dropping \"%s\"\n", __FUNCTION__,\r
-            Converted));\r
-        }\r
-\r
-        if (Converted != ConvFallBack) {\r
-          FreePool (Converted);\r
-        }\r
-      }\r
-    }\r
-    ++Idx;\r
-  }\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Delete Boot#### variables that stand for such active boot options that have\r
-  been dropped (ie. have not been selected by either matching or "survival\r
-  policy").\r
-\r
-  @param[in]  ActiveOption  The array of active boot options to scan. Each\r
-                            entry not marked as appended will trigger the\r
-                            deletion of the matching Boot#### variable.\r
-\r
-  @param[in]  ActiveCount   Number of elements in ActiveOption.\r
-**/\r
-STATIC\r
-VOID\r
-PruneBootVariables (\r
-  IN  CONST ACTIVE_OPTION *ActiveOption,\r
-  IN  UINTN               ActiveCount\r
-  )\r
-{\r
-  UINTN Idx;\r
-\r
-  for (Idx = 0; Idx < ActiveCount; ++Idx) {\r
-    if (!ActiveOption[Idx].Appended) {\r
-      CHAR16 VariableName[9];\r
-\r
-      UnicodeSPrintAsciiFormat (VariableName, sizeof VariableName, "Boot%04x",\r
-        ActiveOption[Idx].BootOption->BootCurrent);\r
-\r
-      //\r
-      // "The space consumed by the deleted variable may not be available until\r
-      // the next power cycle", but that's good enough.\r
-      //\r
-      gRT->SetVariable (VariableName, &gEfiGlobalVariableGuid,\r
-             0,   // Attributes, 0 means deletion\r
-             0,   // DataSize, 0 means deletion\r
-             NULL // Data\r
-             );\r
-    }\r
-  }\r
-}\r
-\r
-\r
-/**\r
-\r
-  Set the boot order based on configuration retrieved from QEMU.\r
-\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
-\r
-\r
-  @retval RETURN_SUCCESS            BootOrder NvVar rewritten.\r
-\r
-  @retval RETURN_UNSUPPORTED        QEMU's fw_cfg is not supported.\r
-\r
-  @retval RETURN_NOT_FOUND          Empty or nonexistent "bootorder" fw_cfg\r
-                                    file, or no match found between the\r
-                                    "bootorder" fw_cfg file and BootOptionList.\r
-\r
-  @retval RETURN_INVALID_PARAMETER  Parse error in the "bootorder" fw_cfg file.\r
-\r
-  @retval RETURN_OUT_OF_RESOURCES   Memory allocation failed.\r
-\r
-  @return                           Values returned by gBS->LocateProtocol ()\r
-                                    or gRT->SetVariable ().\r
-\r
-**/\r
-RETURN_STATUS\r
-SetBootOrderFromQemu (\r
-  IN  CONST LIST_ENTRY *BootOptionList\r
-  )\r
-{\r
-  RETURN_STATUS                    Status;\r
-  FIRMWARE_CONFIG_ITEM             FwCfgItem;\r
-  UINTN                            FwCfgSize;\r
-  CHAR8                            *FwCfg;\r
-  CONST CHAR8                      *FwCfgPtr;\r
-\r
-  BOOT_ORDER                       BootOrder;\r
-  ACTIVE_OPTION                    *ActiveOption;\r
-  UINTN                            ActiveCount;\r
-\r
-  EXTRA_ROOT_BUS_MAP               *ExtraPciRoots;\r
-\r
-  UINTN                            TranslatedSize;\r
-  CHAR16                           Translated[TRANSLATION_OUTPUT_SIZE];\r
-\r
-  Status = QemuFwCfgFindFile ("bootorder", &FwCfgItem, &FwCfgSize);\r
-  if (Status != RETURN_SUCCESS) {\r
-    return Status;\r
-  }\r
-\r
-  if (FwCfgSize == 0) {\r
-    return RETURN_NOT_FOUND;\r
-  }\r
-\r
-  FwCfg = AllocatePool (FwCfgSize);\r
-  if (FwCfg == NULL) {\r
-    return RETURN_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  QemuFwCfgSelectItem (FwCfgItem);\r
-  QemuFwCfgReadBytes (FwCfgSize, FwCfg);\r
-  if (FwCfg[FwCfgSize - 1] != '\0') {\r
-    Status = RETURN_INVALID_PARAMETER;\r
-    goto ErrorFreeFwCfg;\r
-  }\r
-\r
-  DEBUG ((DEBUG_VERBOSE, "%a: FwCfg:\n", __FUNCTION__));\r
-  DEBUG ((DEBUG_VERBOSE, "%a\n", FwCfg));\r
-  DEBUG ((DEBUG_VERBOSE, "%a: FwCfg: <end>\n", __FUNCTION__));\r
-  FwCfgPtr = FwCfg;\r
-\r
-  BootOrder.Produced  = 0;\r
-  BootOrder.Allocated = 1;\r
-  BootOrder.Data = AllocatePool (\r
-                     BootOrder.Allocated * sizeof (*BootOrder.Data)\r
-                     );\r
-  if (BootOrder.Data == NULL) {\r
-    Status = RETURN_OUT_OF_RESOURCES;\r
-    goto ErrorFreeFwCfg;\r
-  }\r
-\r
-  Status = CollectActiveOptions (BootOptionList, &ActiveOption, &ActiveCount);\r
-  if (RETURN_ERROR (Status)) {\r
-    goto ErrorFreeBootOrder;\r
-  }\r
-\r
-  if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) {\r
-    Status = CreateExtraRootBusMap (&ExtraPciRoots);\r
-    if (EFI_ERROR (Status)) {\r
-      goto ErrorFreeActiveOption;\r
-    }\r
-  } else {\r
-    ExtraPciRoots = NULL;\r
-  }\r
-\r
-  //\r
-  // translate each OpenFirmware path\r
-  //\r
-  TranslatedSize = sizeof (Translated) / sizeof (Translated[0]);\r
-  Status = TranslateOfwPath (&FwCfgPtr, ExtraPciRoots, Translated,\r
-             &TranslatedSize);\r
-  while (Status == RETURN_SUCCESS ||\r
-         Status == RETURN_UNSUPPORTED ||\r
-         Status == RETURN_PROTOCOL_ERROR ||\r
-         Status == RETURN_BUFFER_TOO_SMALL) {\r
-    if (Status == RETURN_SUCCESS) {\r
-      UINTN Idx;\r
-\r
-      //\r
-      // match translated OpenFirmware path against all active boot options\r
-      //\r
-      for (Idx = 0; Idx < ActiveCount; ++Idx) {\r
-        if (Match (\r
-              Translated,\r
-              TranslatedSize, // contains length, not size, in CHAR16's here\r
-              ActiveOption[Idx].BootOption->DevicePath\r
-              )\r
-            ) {\r
-          //\r
-          // match found, store ID and continue with next OpenFirmware path\r
-          //\r
-          Status = BootOrderAppend (&BootOrder, &ActiveOption[Idx]);\r
-          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
-    Status = TranslateOfwPath (&FwCfgPtr, ExtraPciRoots, Translated,\r
-               &TranslatedSize);\r
-  } // scanning of OpenFirmware paths done\r
-\r
-  if (Status == RETURN_NOT_FOUND && BootOrder.Produced > 0) {\r
-    //\r
-    // No more OpenFirmware paths, some matches found: rewrite BootOrder NvVar.\r
-    // Some of the active boot options that have not been selected over fw_cfg\r
-    // should be preserved at the end of the boot order.\r
-    //\r
-    Status = BootOrderComplete (&BootOrder, ActiveOption, ActiveCount);\r
-    if (RETURN_ERROR (Status)) {\r
-      goto ErrorFreeExtraPciRoots;\r
-    }\r
-\r
-    //\r
-    // See Table 10 in the UEFI Spec 2.3.1 with Errata C for the required\r
-    // attributes.\r
-    //\r
-    Status = gRT->SetVariable (\r
-                    L"BootOrder",\r
-                    &gEfiGlobalVariableGuid,\r
-                    EFI_VARIABLE_NON_VOLATILE |\r
-                      EFI_VARIABLE_BOOTSERVICE_ACCESS |\r
-                      EFI_VARIABLE_RUNTIME_ACCESS,\r
-                    BootOrder.Produced * sizeof (*BootOrder.Data),\r
-                    BootOrder.Data\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((DEBUG_ERROR, "%a: setting BootOrder: %r\n", __FUNCTION__, Status));\r
-      goto ErrorFreeExtraPciRoots;\r
-    }\r
-\r
-    DEBUG ((DEBUG_INFO, "%a: setting BootOrder: success\n", __FUNCTION__));\r
-    PruneBootVariables (ActiveOption, ActiveCount);\r
-  }\r
-\r
-ErrorFreeExtraPciRoots:\r
-  if (ExtraPciRoots != NULL) {\r
-    DestroyExtraRootBusMap (ExtraPciRoots);\r
-  }\r
-\r
-ErrorFreeActiveOption:\r
-  FreePool (ActiveOption);\r
-\r
-ErrorFreeBootOrder:\r
-  FreePool (BootOrder.Data);\r
-\r
-ErrorFreeFwCfg:\r
-  FreePool (FwCfg);\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Calculate the number of seconds we should be showing the FrontPage progress\r
-  bar for.\r
-\r
-  @return  The TimeoutDefault argument for PlatformBdsEnterFrontPage().\r
-**/\r
-UINT16\r
-GetFrontPageTimeoutFromQemu (\r
-  VOID\r
-  )\r
-{\r
-  FIRMWARE_CONFIG_ITEM BootMenuWaitItem;\r
-  UINTN                BootMenuWaitSize;\r
-\r
-  QemuFwCfgSelectItem (QemuFwCfgItemBootMenu);\r
-  if (QemuFwCfgRead16 () == 0) {\r
-    //\r
-    // The user specified "-boot menu=off", or didn't specify "-boot\r
-    // menu=(on|off)" at all. Return the platform default.\r
-    //\r
-    return PcdGet16 (PcdPlatformBootTimeOut);\r
-  }\r
-\r
-  if (RETURN_ERROR (QemuFwCfgFindFile ("etc/boot-menu-wait", &BootMenuWaitItem,\r
-                      &BootMenuWaitSize)) ||\r
-      BootMenuWaitSize != sizeof (UINT16)) {\r
-    //\r
-    // "-boot menu=on" was specified without "splash-time=N". In this case,\r
-    // return three seconds if the platform default would cause us to skip the\r
-    // front page, and return the platform default otherwise.\r
-    //\r
-    UINT16 Timeout;\r
-\r
-    Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
-    if (Timeout == 0) {\r
-      Timeout = 3;\r
-    }\r
-    return Timeout;\r
-  }\r
-\r
-  //\r
-  // "-boot menu=on,splash-time=N" was specified, where N is in units of\r
-  // milliseconds. The Intel BDS Front Page progress bar only supports whole\r
-  // seconds, round N up.\r
-  //\r
-  QemuFwCfgSelectItem (BootMenuWaitItem);\r
-  return (UINT16)((QemuFwCfgRead16 () + 999) / 1000);\r
-}\r
diff --git a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
deleted file mode 100644 (file)
index 1024328..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-## @file\r
-#  Rewrite the BootOrder NvVar based on QEMU's "bootorder" fw_cfg file.\r
-#\r
-#  Copyright (C) 2012 - 2014, Red Hat, Inc.\r
-#  Copyright (c) 2007 - 2015, 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
-#  distribution.  The full text of the license may be found at\r
-#  http://opensource.org/licenses/bsd-license.php\r
-#\r
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR\r
-#  IMPLIED.\r
-#\r
-##\r
-\r
-[Defines]\r
-  INF_VERSION                    = 0x00010005\r
-  BASE_NAME                      = QemuBootOrderLib\r
-  FILE_GUID                      = 4FFFA9E1-103D-4CF2-9C06-563BDD03050E\r
-  MODULE_TYPE                    = DXE_DRIVER\r
-  VERSION_STRING                 = 1.0\r
-  LIBRARY_CLASS                  = QemuBootOrderLib|DXE_DRIVER\r
-\r
-#\r
-# The following information is for reference only and not required by the build\r
-# tools.\r
-#\r
-#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC ARM AARCH64\r
-#\r
-\r
-[Sources]\r
-  QemuBootOrderLib.c\r
-  ExtraRootBusMap.c\r
-\r
-[Packages]\r
-  MdePkg/MdePkg.dec\r
-  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec\r
-  OvmfPkg/OvmfPkg.dec\r
-\r
-[LibraryClasses]\r
-  QemuFwCfgLib\r
-  DebugLib\r
-  MemoryAllocationLib\r
-  GenericBdsLib\r
-  UefiBootServicesTableLib\r
-  UefiRuntimeServicesTableLib\r
-  BaseLib\r
-  PrintLib\r
-  DevicePathLib\r
-  BaseMemoryLib\r
-  OrderedCollectionLib\r
-\r
-[Guids]\r
-  gEfiGlobalVariableGuid\r
-  gVirtioMmioTransportGuid\r
-\r
-[FeaturePcd]\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation\r
-\r
-[Pcd]\r
-  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut\r
-\r
-[Protocols]\r
-  gEfiDevicePathProtocolGuid                            ## CONSUMES\r
-  gEfiPciRootBridgeIoProtocolGuid                       ## CONSUMES\r