/** @file
  Rewrite the BootOrder NvVar based on QEMU's "bootorder" fw_cfg file.

  Copyright (C) 2012 - 2014, Red Hat, Inc.
  Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Library/QemuFwCfgLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootManagerLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/BaseLib.h>
#include <Library/PrintLib.h>
#include <Library/DevicePathLib.h>
#include <Library/QemuBootOrderLib.h>
#include <Library/BaseMemoryLib.h>
#include <Guid/GlobalVariable.h>
#include <Guid/VirtioMmioTransport.h>

#include "ExtraRootBusMap.h"

/**
  OpenFirmware to UEFI device path translation output buffer size in CHAR16's.
**/
#define TRANSLATION_OUTPUT_SIZE 0x100

/**
  Output buffer size for OpenFirmware to UEFI device path fragment translation,
  in CHAR16's, for a sequence of PCI bridges.
**/
#define BRIDGE_TRANSLATION_OUTPUT_SIZE 0x40

/**
  Numbers of nodes in OpenFirmware device paths that are required and examined.
**/
#define REQUIRED_PCI_OFW_NODES  2
#define REQUIRED_MMIO_OFW_NODES 1
#define EXAMINED_OFW_NODES      6


/**
  Simple character classification routines, corresponding to POSIX class names
  and ASCII encoding.
**/
STATIC
BOOLEAN
IsAlnum (
  IN  CHAR8 Chr
  )
{
  return (('0' <= Chr && Chr <= '9') ||
          ('A' <= Chr && Chr <= 'Z') ||
          ('a' <= Chr && Chr <= 'z')
          );
}


STATIC
BOOLEAN
IsDriverNamePunct (
  IN  CHAR8 Chr
  )
{
  return (Chr == ',' ||  Chr == '.' || Chr == '_' ||
          Chr == '+' || Chr == '-'
          );
}


STATIC
BOOLEAN
IsPrintNotDelim (
  IN  CHAR8 Chr
  )
{
  return (32 <= Chr && Chr <= 126 &&
          Chr != '/' && Chr != '@' && Chr != ':');
}


/**
  Utility types and functions.
**/
typedef struct {
  CONST CHAR8 *Ptr; // not necessarily NUL-terminated
  UINTN       Len;  // number of non-NUL characters
} SUBSTRING;


/**

  Check if Substring and String have identical contents.

  The function relies on the restriction that a SUBSTRING cannot have embedded
  NULs either.

  @param[in] Substring  The SUBSTRING input to the comparison.

  @param[in] String     The ASCII string input to the comparison.


  @return  Whether the inputs have identical contents.

**/
STATIC
BOOLEAN
SubstringEq (
  IN  SUBSTRING   Substring,
  IN  CONST CHAR8 *String
  )
{
  UINTN       Pos;
  CONST CHAR8 *Chr;

  Pos = 0;
  Chr = String;

  while (Pos < Substring.Len && Substring.Ptr[Pos] == *Chr) {
    ++Pos;
    ++Chr;
  }

  return (BOOLEAN)(Pos == Substring.Len && *Chr == '\0');
}


/**

  Parse a comma-separated list of hexadecimal integers into the elements of an
  UINT64 array.

  Whitespace, "0x" prefixes, leading or trailing commas, sequences of commas,
  or an empty string are not allowed; they are rejected.

  The function relies on ASCII encoding.

  @param[in]     UnitAddress  The substring to parse.

  @param[out]    Result       The array, allocated by the caller, to receive
                              the parsed values. This parameter may be NULL if
                              NumResults is zero on input.

  @param[in out] NumResults   On input, the number of elements allocated for
                              Result. On output, the number of elements it has
                              taken (or would have taken) to parse the string
                              fully.


  @retval RETURN_SUCCESS            UnitAddress has been fully parsed.
                                    NumResults is set to the number of parsed
                                    values; the corresponding elements have
                                    been set in Result. The rest of Result's
                                    elements are unchanged.

  @retval RETURN_BUFFER_TOO_SMALL   UnitAddress has been fully parsed.
                                    NumResults is set to the number of parsed
                                    values, but elements have been stored only
                                    up to the input value of NumResults, which
                                    is less than what has been parsed.

  @retval RETURN_INVALID_PARAMETER  Parse error. The contents of Results is
                                    indeterminate. NumResults has not been
                                    changed.

**/
STATIC
RETURN_STATUS
ParseUnitAddressHexList (
  IN      SUBSTRING  UnitAddress,
  OUT     UINT64     *Result,
  IN OUT  UINTN      *NumResults
  )
{
  UINTN         Entry;    // number of entry currently being parsed
  UINT64        EntryVal; // value being constructed for current entry
  CHAR8         PrevChr;  // UnitAddress character previously checked
  UINTN         Pos;      // current position within UnitAddress
  RETURN_STATUS Status;

  Entry    = 0;
  EntryVal = 0;
  PrevChr  = ',';

  for (Pos = 0; Pos < UnitAddress.Len; ++Pos) {
    CHAR8 Chr;
    INT8  Val;

    Chr = UnitAddress.Ptr[Pos];
    Val = ('a' <= Chr && Chr <= 'f') ? (Chr - 'a' + 10) :
          ('A' <= Chr && Chr <= 'F') ? (Chr - 'A' + 10) :
          ('0' <= Chr && Chr <= '9') ? (Chr - '0'     ) :
          -1;

    if (Val >= 0) {
      if (EntryVal > 0xFFFFFFFFFFFFFFFull) {
        return RETURN_INVALID_PARAMETER;
      }
      EntryVal = LShiftU64 (EntryVal, 4) | Val;
    } else if (Chr == ',') {
      if (PrevChr == ',') {
        return RETURN_INVALID_PARAMETER;
      }
      if (Entry < *NumResults) {
        Result[Entry] = EntryVal;
      }
      ++Entry;
      EntryVal = 0;
    } else {
      return RETURN_INVALID_PARAMETER;
    }

    PrevChr = Chr;
  }

  if (PrevChr == ',') {
    return RETURN_INVALID_PARAMETER;
  }
  if (Entry < *NumResults) {
    Result[Entry] = EntryVal;
    Status = RETURN_SUCCESS;
  } else {
    Status = RETURN_BUFFER_TOO_SMALL;
  }
  ++Entry;

  *NumResults = Entry;
  return Status;
}


/**
  A simple array of Boot Option ID's.
**/
typedef struct {
  UINT16 *Data;
  UINTN  Allocated;
  UINTN  Produced;
} BOOT_ORDER;


/**
  Array element tracking an enumerated boot option that has the
  LOAD_OPTION_ACTIVE attribute.
**/
typedef struct {
  CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOption; // reference only, no
                                                  //   ownership
  BOOLEAN                            Appended;    // has been added to a
                                                  //   BOOT_ORDER?
} ACTIVE_OPTION;


/**

  Append an active boot option to BootOrder, reallocating the latter if needed.

  @param[in out] BootOrder     The structure pointing to the array and holding
                               allocation and usage counters.

  @param[in]     ActiveOption  The active boot option whose ID should be
                               appended to the array.


  @retval RETURN_SUCCESS           ID of ActiveOption appended.

  @retval RETURN_OUT_OF_RESOURCES  Memory reallocation failed.

**/
STATIC
RETURN_STATUS
BootOrderAppend (
  IN OUT  BOOT_ORDER    *BootOrder,
  IN OUT  ACTIVE_OPTION *ActiveOption
  )
{
  if (BootOrder->Produced == BootOrder->Allocated) {
    UINTN  AllocatedNew;
    UINT16 *DataNew;

    ASSERT (BootOrder->Allocated > 0);
    AllocatedNew = BootOrder->Allocated * 2;
    DataNew = ReallocatePool (
                BootOrder->Allocated * sizeof (*BootOrder->Data),
                AllocatedNew         * sizeof (*DataNew),
                BootOrder->Data
                );
    if (DataNew == NULL) {
      return RETURN_OUT_OF_RESOURCES;
    }
    BootOrder->Allocated = AllocatedNew;
    BootOrder->Data      = DataNew;
  }

  BootOrder->Data[BootOrder->Produced++] =
                               (UINT16) ActiveOption->BootOption->OptionNumber;
  ActiveOption->Appended = TRUE;
  return RETURN_SUCCESS;
}


/**

  Create an array of ACTIVE_OPTION elements for a boot option array.

  @param[in]  BootOptions      A boot option array, created with
                               EfiBootManagerRefreshAllBootOption () and
                               EfiBootManagerGetLoadOptions ().

  @param[in]  BootOptionCount  The number of elements in BootOptions.

  @param[out] ActiveOption     Pointer to the first element in the new array.
                               The caller is responsible for freeing the array
                               with FreePool() after use.

  @param[out] Count            Number of elements in the new array.


  @retval RETURN_SUCCESS           The ActiveOption array has been created.

  @retval RETURN_NOT_FOUND         No active entry has been found in
                                   BootOptions.

  @retval RETURN_OUT_OF_RESOURCES  Memory allocation failed.

**/
STATIC
RETURN_STATUS
CollectActiveOptions (
  IN   CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions,
  IN   UINTN                              BootOptionCount,
  OUT  ACTIVE_OPTION                      **ActiveOption,
  OUT  UINTN                              *Count
  )
{
  UINTN Index;
  UINTN ScanMode;

  *ActiveOption = NULL;

  //
  // Scan the list twice:
  // - count active entries,
  // - store links to active entries.
  //
  for (ScanMode = 0; ScanMode < 2; ++ScanMode) {
    *Count = 0;
    for (Index = 0; Index < BootOptionCount; Index++) {
      if ((BootOptions[Index].Attributes & LOAD_OPTION_ACTIVE) != 0) {
        if (ScanMode == 1) {
          (*ActiveOption)[*Count].BootOption = &BootOptions[Index];
          (*ActiveOption)[*Count].Appended   = FALSE;
        }
        ++*Count;
      }
    }

    if (ScanMode == 0) {
      if (*Count == 0) {
        return RETURN_NOT_FOUND;
      }
      *ActiveOption = AllocatePool (*Count * sizeof **ActiveOption);
      if (*ActiveOption == NULL) {
        return RETURN_OUT_OF_RESOURCES;
      }
    }
  }
  return RETURN_SUCCESS;
}


/**
  OpenFirmware device path node
**/
typedef struct {
  SUBSTRING DriverName;
  SUBSTRING UnitAddress;
  SUBSTRING DeviceArguments;
} OFW_NODE;


/**

  Parse an OpenFirmware device path node into the caller-allocated OFW_NODE
  structure, and advance in the input string.

  The node format is mostly parsed after IEEE 1275-1994, 3.2.1.1 "Node names"
  (a leading slash is expected and not returned):

    /driver-name@unit-address[:device-arguments][<LF>]

  A single trailing <LF> character is consumed but not returned. A trailing
  <LF> or NUL character terminates the device path.

  The function relies on ASCII encoding.

  @param[in out] Ptr      Address of the pointer pointing to the start of the
                          node string. After successful parsing *Ptr is set to
                          the byte immediately following the consumed
                          characters. On error it points to the byte that
                          caused the error. The input string is never modified.

  @param[out]    OfwNode  The members of this structure point into the input
                          string, designating components of the node.
                          Separators are never included. If "device-arguments"
                          is missing, then DeviceArguments.Ptr is set to NULL.
                          All components that are present have nonzero length.

                          If the call doesn't succeed, the contents of this
                          structure is indeterminate.

  @param[out]    IsFinal  In case of successful parsing, this parameter signals
                          whether the node just parsed is the final node in the
                          device path. The call after a final node will attempt
                          to start parsing the next path. If the call doesn't
                          succeed, then this parameter is not changed.


  @retval RETURN_SUCCESS            Parsing successful.

  @retval RETURN_NOT_FOUND          Parsing terminated. *Ptr was (and is)
                                    pointing to an empty string.

  @retval RETURN_INVALID_PARAMETER  Parse error.

**/
STATIC
RETURN_STATUS
ParseOfwNode (
  IN OUT  CONST CHAR8 **Ptr,
  OUT     OFW_NODE    *OfwNode,
  OUT     BOOLEAN     *IsFinal
  )
{
  //
  // A leading slash is expected. End of string is tolerated.
  //
  switch (**Ptr) {
  case '\0':
    return RETURN_NOT_FOUND;

  case '/':
    ++*Ptr;
    break;

  default:
    return RETURN_INVALID_PARAMETER;
  }

  //
  // driver-name
  //
  OfwNode->DriverName.Ptr = *Ptr;
  OfwNode->DriverName.Len = 0;
  while (OfwNode->DriverName.Len < 32 &&
         (IsAlnum (**Ptr) || IsDriverNamePunct (**Ptr))
         ) {
    ++*Ptr;
    ++OfwNode->DriverName.Len;
  }

  if (OfwNode->DriverName.Len == 0 || OfwNode->DriverName.Len == 32) {
    return RETURN_INVALID_PARAMETER;
  }


  //
  // unit-address
  //
  if (**Ptr != '@') {
    return RETURN_INVALID_PARAMETER;
  }
  ++*Ptr;

  OfwNode->UnitAddress.Ptr = *Ptr;
  OfwNode->UnitAddress.Len = 0;
  while (IsPrintNotDelim (**Ptr)) {
    ++*Ptr;
    ++OfwNode->UnitAddress.Len;
  }

  if (OfwNode->UnitAddress.Len == 0) {
    return RETURN_INVALID_PARAMETER;
  }


  //
  // device-arguments, may be omitted
  //
  OfwNode->DeviceArguments.Len = 0;
  if (**Ptr == ':') {
    ++*Ptr;
    OfwNode->DeviceArguments.Ptr = *Ptr;

    while (IsPrintNotDelim (**Ptr)) {
      ++*Ptr;
      ++OfwNode->DeviceArguments.Len;
    }

    if (OfwNode->DeviceArguments.Len == 0) {
      return RETURN_INVALID_PARAMETER;
    }
  }
  else {
    OfwNode->DeviceArguments.Ptr = NULL;
  }

  switch (**Ptr) {
  case '\n':
    ++*Ptr;
    //
    // fall through
    //

  case '\0':
    *IsFinal = TRUE;
    break;

  case '/':
    *IsFinal = FALSE;
    break;

  default:
    return RETURN_INVALID_PARAMETER;
  }

  DEBUG ((
    DEBUG_VERBOSE,
    "%a: DriverName=\"%.*a\" UnitAddress=\"%.*a\" DeviceArguments=\"%.*a\"\n",
    __FUNCTION__,
    OfwNode->DriverName.Len, OfwNode->DriverName.Ptr,
    OfwNode->UnitAddress.Len, OfwNode->UnitAddress.Ptr,
    OfwNode->DeviceArguments.Len,
    OfwNode->DeviceArguments.Ptr == NULL ? "" : OfwNode->DeviceArguments.Ptr
    ));
  return RETURN_SUCCESS;
}


/**

  Translate a PCI-like array of OpenFirmware device nodes to a UEFI device path
  fragment.

  @param[in]     OfwNode         Array of OpenFirmware device nodes to
                                 translate, constituting the beginning of an
                                 OpenFirmware device path.

  @param[in]     NumNodes        Number of elements in OfwNode.

  @param[in]     ExtraPciRoots   An EXTRA_ROOT_BUS_MAP object created with
                                 CreateExtraRootBusMap(), to be used for
                                 translating positions of extra root buses to
                                 bus numbers.

  @param[out]    Translated      Destination array receiving the UEFI path
                                 fragment, allocated by the caller. If the
                                 return value differs from RETURN_SUCCESS, its
                                 contents is indeterminate.

  @param[in out] TranslatedSize  On input, the number of CHAR16's in
                                 Translated. On RETURN_SUCCESS this parameter
                                 is assigned the number of non-NUL CHAR16's
                                 written to Translated. In case of other return
                                 values, TranslatedSize is indeterminate.


  @retval RETURN_SUCCESS           Translation successful.

  @retval RETURN_BUFFER_TOO_SMALL  The translation does not fit into the number
                                   of bytes provided.

  @retval RETURN_UNSUPPORTED       The array of OpenFirmware device nodes can't
                                   be translated in the current implementation.

  @retval RETURN_PROTOCOL_ERROR    The initial OpenFirmware node refers to an
                                   extra PCI root bus (by serial number) that
                                   is invalid according to ExtraPciRoots.

**/
STATIC
RETURN_STATUS
TranslatePciOfwNodes (
  IN      CONST OFW_NODE           *OfwNode,
  IN      UINTN                    NumNodes,
  IN      CONST EXTRA_ROOT_BUS_MAP *ExtraPciRoots,
  OUT     CHAR16                   *Translated,
  IN OUT  UINTN                    *TranslatedSize
  )
{
  UINT32 PciRoot;
  CHAR8  *Comma;
  UINTN  FirstNonBridge;
  CHAR16 Bridges[BRIDGE_TRANSLATION_OUTPUT_SIZE];
  UINTN  BridgesLen;
  UINT64 PciDevFun[2];
  UINTN  NumEntries;
  UINTN  Written;

  //
  // Resolve the PCI root bus number.
  //
  // The initial OFW node for the main root bus (ie. bus number 0) is:
  //
  //   /pci@i0cf8
  //
  // For extra root buses, the initial OFW node is
  //
  //   /pci@i0cf8,4
  //              ^
  //              root bus serial number (not PCI bus number)
  //
  if (NumNodes < REQUIRED_PCI_OFW_NODES ||
      !SubstringEq (OfwNode[0].DriverName, "pci")
      ) {
    return RETURN_UNSUPPORTED;
  }

  PciRoot = 0;
  Comma = ScanMem8 (OfwNode[0].UnitAddress.Ptr, OfwNode[0].UnitAddress.Len,
            ',');
  if (Comma != NULL) {
    SUBSTRING PciRootSerialSubString;
    UINT64    PciRootSerial;

    //
    // Parse the root bus serial number from the unit address after the comma.
    //
    PciRootSerialSubString.Ptr = Comma + 1;
    PciRootSerialSubString.Len = OfwNode[0].UnitAddress.Len -
                                 (PciRootSerialSubString.Ptr -
                                  OfwNode[0].UnitAddress.Ptr);
    NumEntries = 1;
    if (RETURN_ERROR (ParseUnitAddressHexList (PciRootSerialSubString,
                      &PciRootSerial, &NumEntries))) {
      return RETURN_UNSUPPORTED;
    }

    //
    // Map the extra root bus's serial number to its actual bus number.
    //
    if (EFI_ERROR (MapRootBusPosToBusNr (ExtraPciRoots, PciRootSerial,
                     &PciRoot))) {
      return RETURN_PROTOCOL_ERROR;
    }
  }

  //
  // Translate a sequence of PCI bridges. For each bridge, the OFW node is:
  //
  //   pci-bridge@1e[,0]
  //              ^   ^
  //              PCI slot & function on the parent, holding the bridge
  //
  // and the UEFI device path node is:
  //
  //   Pci(0x1E,0x0)
  //
  FirstNonBridge = 1;
  Bridges[0] = L'\0';
  BridgesLen = 0;
  do {
    UINT64 BridgeDevFun[2];
    UINTN  BridgesFreeBytes;

    if (!SubstringEq (OfwNode[FirstNonBridge].DriverName, "pci-bridge")) {
      break;
    }

    BridgeDevFun[1] = 0;
    NumEntries = sizeof BridgeDevFun / sizeof BridgeDevFun[0];
    if (ParseUnitAddressHexList (OfwNode[FirstNonBridge].UnitAddress,
          BridgeDevFun, &NumEntries) != RETURN_SUCCESS) {
      return RETURN_UNSUPPORTED;
    }

    BridgesFreeBytes = sizeof Bridges - BridgesLen * sizeof Bridges[0];
    Written = UnicodeSPrintAsciiFormat (Bridges + BridgesLen, BridgesFreeBytes,
                "/Pci(0x%Lx,0x%Lx)", BridgeDevFun[0], BridgeDevFun[1]);
    BridgesLen += Written;

    //
    // There's no way to differentiate between "completely used up without
    // truncation" and "truncated", so treat the former as the latter.
    //
    if (BridgesLen + 1 == BRIDGE_TRANSLATION_OUTPUT_SIZE) {
      return RETURN_UNSUPPORTED;
    }

    ++FirstNonBridge;
  } while (FirstNonBridge < NumNodes);

  if (FirstNonBridge == NumNodes) {
    return RETURN_UNSUPPORTED;
  }

  //
  // Parse the OFW nodes starting with the first non-bridge node.
  //
  PciDevFun[1] = 0;
  NumEntries = ARRAY_SIZE (PciDevFun);
  if (ParseUnitAddressHexList (
        OfwNode[FirstNonBridge].UnitAddress,
        PciDevFun,
        &NumEntries
        ) != RETURN_SUCCESS
      ) {
    return RETURN_UNSUPPORTED;
  }

  if (NumNodes >= FirstNonBridge + 3 &&
      SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "ide") &&
      SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "drive") &&
      SubstringEq (OfwNode[FirstNonBridge + 2].DriverName, "disk")
      ) {
    //
    // OpenFirmware device path (IDE disk, IDE CD-ROM):
    //
    //   /pci@i0cf8/ide@1,1/drive@0/disk@0
    //        ^         ^ ^       ^      ^
    //        |         | |       |      master or slave
    //        |         | |       primary or secondary
    //        |         PCI slot & function holding IDE controller
    //        PCI root at system bus port, PIO
    //
    // UEFI device path:
    //
    //   PciRoot(0x0)/Pci(0x1,0x1)/Ata(Primary,Master,0x0)
    //                                                ^
    //                                                fixed LUN
    //
    UINT64 Secondary;
    UINT64 Slave;

    NumEntries = 1;
    if (ParseUnitAddressHexList (
          OfwNode[FirstNonBridge + 1].UnitAddress,
          &Secondary,
          &NumEntries
          ) != RETURN_SUCCESS ||
        Secondary > 1 ||
        ParseUnitAddressHexList (
          OfwNode[FirstNonBridge + 2].UnitAddress,
          &Slave,
          &NumEntries // reuse after previous single-element call
          ) != RETURN_SUCCESS ||
        Slave > 1
        ) {
      return RETURN_UNSUPPORTED;
    }

    Written = UnicodeSPrintAsciiFormat (
      Translated,
      *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
      "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/Ata(%a,%a,0x0)",
      PciRoot,
      Bridges,
      PciDevFun[0],
      PciDevFun[1],
      Secondary ? "Secondary" : "Primary",
      Slave ? "Slave" : "Master"
      );
  } else if (NumNodes >= FirstNonBridge + 3 &&
      SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "pci8086,2922") &&
      SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "drive") &&
      SubstringEq (OfwNode[FirstNonBridge + 2].DriverName, "disk")
      ) {
    //
    // OpenFirmware device path (Q35 SATA disk and CD-ROM):
    //
    //   /pci@i0cf8/pci8086,2922@1f,2/drive@1/disk@0
    //        ^                  ^  ^       ^      ^
    //        |                  |  |       |      device number (fixed 0)
    //        |                  |  |       channel (port) number
    //        |                  PCI slot & function holding SATA HBA
    //        PCI root at system bus port, PIO
    //
    // UEFI device path:
    //
    //   PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x1,0xFFFF,0x0)
    //                                   ^   ^      ^
    //                                   |   |      LUN (always 0 on Q35)
    //                                   |   port multiplier port number,
    //                                   |   always 0xFFFF on Q35
    //                                   channel (port) number
    //
    UINT64 Channel;

    NumEntries = 1;
    if (RETURN_ERROR (ParseUnitAddressHexList (
                        OfwNode[FirstNonBridge + 1].UnitAddress, &Channel,
                        &NumEntries))) {
      return RETURN_UNSUPPORTED;
    }

    Written = UnicodeSPrintAsciiFormat (
      Translated,
      *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
      "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/Sata(0x%Lx,0xFFFF,0x0)",
      PciRoot,
      Bridges,
      PciDevFun[0],
      PciDevFun[1],
      Channel
      );
  } else if (NumNodes >= FirstNonBridge + 3 &&
             SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "isa") &&
             SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "fdc") &&
             SubstringEq (OfwNode[FirstNonBridge + 2].DriverName, "floppy")
             ) {
    //
    // OpenFirmware device path (floppy disk):
    //
    //   /pci@i0cf8/isa@1/fdc@03f0/floppy@0
    //        ^         ^     ^           ^
    //        |         |     |           A: or B:
    //        |         |     ISA controller io-port (hex)
    //        |         PCI slot holding ISA controller
    //        PCI root at system bus port, PIO
    //
    // UEFI device path:
    //
    //   PciRoot(0x0)/Pci(0x1,0x0)/Floppy(0x0)
    //                                    ^
    //                                    ACPI UID
    //
    UINT64 AcpiUid;

    NumEntries = 1;
    if (ParseUnitAddressHexList (
          OfwNode[FirstNonBridge + 2].UnitAddress,
          &AcpiUid,
          &NumEntries
          ) != RETURN_SUCCESS ||
        AcpiUid > 1
        ) {
      return RETURN_UNSUPPORTED;
    }

    Written = UnicodeSPrintAsciiFormat (
      Translated,
      *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
      "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/Floppy(0x%Lx)",
      PciRoot,
      Bridges,
      PciDevFun[0],
      PciDevFun[1],
      AcpiUid
      );
  } else if (NumNodes >= FirstNonBridge + 2 &&
             SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "scsi") &&
             SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "disk")
             ) {
    //
    // OpenFirmware device path (virtio-blk disk):
    //
    //   /pci@i0cf8/scsi@6[,3]/disk@0,0
    //        ^          ^  ^       ^ ^
    //        |          |  |       fixed
    //        |          |  PCI function corresponding to disk (optional)
    //        |          PCI slot holding disk
    //        PCI root at system bus port, PIO
    //
    // UEFI device path prefix:
    //
    //   PciRoot(0x0)/Pci(0x6,0x0) -- if PCI function is 0 or absent
    //   PciRoot(0x0)/Pci(0x6,0x3) -- if PCI function is present and nonzero
    //
    Written = UnicodeSPrintAsciiFormat (
      Translated,
      *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
      "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)",
      PciRoot,
      Bridges,
      PciDevFun[0],
      PciDevFun[1]
      );
  } else if (NumNodes >= FirstNonBridge + 3 &&
             SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "scsi") &&
             SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "channel") &&
             SubstringEq (OfwNode[FirstNonBridge + 2].DriverName, "disk")
             ) {
    //
    // OpenFirmware device path (virtio-scsi disk):
    //
    //   /pci@i0cf8/scsi@7[,3]/channel@0/disk@2,3
    //        ^          ^             ^      ^ ^
    //        |          |             |      | LUN
    //        |          |             |      target
    //        |          |             channel (unused, fixed 0)
    //        |          PCI slot[, function] holding SCSI controller
    //        PCI root at system bus port, PIO
    //
    // UEFI device path prefix:
    //
    //   PciRoot(0x0)/Pci(0x7,0x0)/Scsi(0x2,0x3)
    //                                        -- if PCI function is 0 or absent
    //   PciRoot(0x0)/Pci(0x7,0x3)/Scsi(0x2,0x3)
    //                                -- if PCI function is present and nonzero
    //
    UINT64 TargetLun[2];

    TargetLun[1] = 0;
    NumEntries = ARRAY_SIZE (TargetLun);
    if (ParseUnitAddressHexList (
          OfwNode[FirstNonBridge + 2].UnitAddress,
          TargetLun,
          &NumEntries
          ) != RETURN_SUCCESS
        ) {
      return RETURN_UNSUPPORTED;
    }

    Written = UnicodeSPrintAsciiFormat (
      Translated,
      *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
      "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/Scsi(0x%Lx,0x%Lx)",
      PciRoot,
      Bridges,
      PciDevFun[0],
      PciDevFun[1],
      TargetLun[0],
      TargetLun[1]
      );
  } else if (NumNodes >= FirstNonBridge + 2 &&
      SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "pci8086,5845") &&
      SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "namespace")
      ) {
    //
    // OpenFirmware device path (NVMe device):
    //
    //   /pci@i0cf8/pci8086,5845@6[,1]/namespace@1,0
    //        ^                  ^  ^            ^ ^
    //        |                  |  |            | Extended Unique Identifier
    //        |                  |  |            | (EUI-64), big endian interp.
    //        |                  |  |            namespace ID
    //        |                  PCI slot & function holding NVMe controller
    //        PCI root at system bus port, PIO
    //
    // UEFI device path:
    //
    //   PciRoot(0x0)/Pci(0x6,0x1)/NVMe(0x1,00-00-00-00-00-00-00-00)
    //                                  ^   ^
    //                                  |   octets of the EUI-64
    //                                  |   in address order
    //                                  namespace ID
    //
    UINT64 Namespace[2];
    UINTN  RequiredEntries;
    UINT8  *Eui64;

    RequiredEntries = ARRAY_SIZE (Namespace);
    NumEntries = RequiredEntries;
    if (ParseUnitAddressHexList (
          OfwNode[FirstNonBridge + 1].UnitAddress,
          Namespace,
          &NumEntries
          ) != RETURN_SUCCESS ||
        NumEntries != RequiredEntries ||
        Namespace[0] == 0 ||
        Namespace[0] >= MAX_UINT32
        ) {
      return RETURN_UNSUPPORTED;
    }

    Eui64 = (UINT8 *)&Namespace[1];
    Written = UnicodeSPrintAsciiFormat (
      Translated,
      *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
      "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/"
      "NVMe(0x%Lx,%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)",
      PciRoot,
      Bridges,
      PciDevFun[0],
      PciDevFun[1],
      Namespace[0],
      Eui64[7], Eui64[6], Eui64[5], Eui64[4],
      Eui64[3], Eui64[2], Eui64[1], Eui64[0]
      );
  } else if (NumNodes >= FirstNonBridge + 2 &&
             SubstringEq (OfwNode[FirstNonBridge + 0].DriverName, "usb") &&
             SubstringEq (OfwNode[FirstNonBridge + 1].DriverName, "storage")) {
    //
    // OpenFirmware device path (usb-storage device in XHCI port):
    //
    //   /pci@i0cf8/usb@3[,1]/storage@2/channel@0/disk@0,0
    //        ^         ^  ^          ^         ^      ^ ^
    //        |         |  |          |         fixed  fixed
    //        |         |  |          XHCI port number, 1-based
    //        |         |  PCI function corresponding to XHCI (optional)
    //        |         PCI slot holding XHCI
    //        PCI root at system bus port, PIO
    //
    // UEFI device path prefix:
    //
    //   PciRoot(0x0)/Pci(0x3,0x1)/USB(0x1,0x0)
    //                        ^        ^
    //                        |        XHCI port number in 0-based notation
    //                        0x0 if PCI function is 0, or absent from OFW
    //
    RETURN_STATUS ParseStatus;
    UINT64        OneBasedXhciPort;

    NumEntries = 1;
    ParseStatus = ParseUnitAddressHexList (
                    OfwNode[FirstNonBridge + 1].UnitAddress,
                    &OneBasedXhciPort,
                    &NumEntries
                    );
    if (RETURN_ERROR (ParseStatus) || OneBasedXhciPort == 0) {
      return RETURN_UNSUPPORTED;
    }

    Written = UnicodeSPrintAsciiFormat (
                Translated,
                *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
                "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/USB(0x%Lx,0x0)",
                PciRoot,
                Bridges,
                PciDevFun[0],
                PciDevFun[1],
                OneBasedXhciPort - 1
                );
  } else {
    //
    // Generic OpenFirmware device path for PCI devices:
    //
    //   /pci@i0cf8/ethernet@3[,2]
    //        ^              ^
    //        |              PCI slot[, function] holding Ethernet card
    //        PCI root at system bus port, PIO
    //
    // UEFI device path prefix (dependent on presence of nonzero PCI function):
    //
    //   PciRoot(0x0)/Pci(0x3,0x0)
    //   PciRoot(0x0)/Pci(0x3,0x2)
    //
    Written = UnicodeSPrintAsciiFormat (
      Translated,
      *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
      "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)",
      PciRoot,
      Bridges,
      PciDevFun[0],
      PciDevFun[1]
      );
  }

  //
  // There's no way to differentiate between "completely used up without
  // truncation" and "truncated", so treat the former as the latter, and return
  // success only for "some room left unused".
  //
  if (Written + 1 < *TranslatedSize) {
    *TranslatedSize = Written;
    return RETURN_SUCCESS;
  }

  return RETURN_BUFFER_TOO_SMALL;
}


//
// A type providing easy raw access to the base address of a virtio-mmio
// transport.
//
typedef union {
  UINT64 Uint64;
  UINT8  Raw[8];
} VIRTIO_MMIO_BASE_ADDRESS;


/**

  Translate an MMIO-like array of OpenFirmware device nodes to a UEFI device
  path fragment.

  @param[in]     OfwNode         Array of OpenFirmware device nodes to
                                 translate, constituting the beginning of an
                                 OpenFirmware device path.

  @param[in]     NumNodes        Number of elements in OfwNode.

  @param[out]    Translated      Destination array receiving the UEFI path
                                 fragment, allocated by the caller. If the
                                 return value differs from RETURN_SUCCESS, its
                                 contents is indeterminate.

  @param[in out] TranslatedSize  On input, the number of CHAR16's in
                                 Translated. On RETURN_SUCCESS this parameter
                                 is assigned the number of non-NUL CHAR16's
                                 written to Translated. In case of other return
                                 values, TranslatedSize is indeterminate.


  @retval RETURN_SUCCESS           Translation successful.

  @retval RETURN_BUFFER_TOO_SMALL  The translation does not fit into the number
                                   of bytes provided.

  @retval RETURN_UNSUPPORTED       The array of OpenFirmware device nodes can't
                                   be translated in the current implementation.

**/
STATIC
RETURN_STATUS
TranslateMmioOfwNodes (
  IN      CONST OFW_NODE *OfwNode,
  IN      UINTN          NumNodes,
  OUT     CHAR16         *Translated,
  IN OUT  UINTN          *TranslatedSize
  )
{
  VIRTIO_MMIO_BASE_ADDRESS VirtioMmioBase;
  CHAR16                   VenHwString[60 + 1];
  UINTN                    NumEntries;
  UINTN                    Written;

  //
  // Get the base address of the virtio-mmio transport.
  //
  if (NumNodes < REQUIRED_MMIO_OFW_NODES ||
      !SubstringEq (OfwNode[0].DriverName, "virtio-mmio")
      ) {
    return RETURN_UNSUPPORTED;
  }
  NumEntries = 1;
  if (ParseUnitAddressHexList (
        OfwNode[0].UnitAddress,
        &VirtioMmioBase.Uint64,
        &NumEntries
        ) != RETURN_SUCCESS
      ) {
    return RETURN_UNSUPPORTED;
  }

  UnicodeSPrintAsciiFormat (VenHwString, sizeof VenHwString,
    "VenHw(%g,%02X%02X%02X%02X%02X%02X%02X%02X)", &gVirtioMmioTransportGuid,
    VirtioMmioBase.Raw[0], VirtioMmioBase.Raw[1], VirtioMmioBase.Raw[2],
    VirtioMmioBase.Raw[3], VirtioMmioBase.Raw[4], VirtioMmioBase.Raw[5],
    VirtioMmioBase.Raw[6], VirtioMmioBase.Raw[7]);

  if (NumNodes >= 2 &&
      SubstringEq (OfwNode[1].DriverName, "disk")) {
    //
    // OpenFirmware device path (virtio-blk disk):
    //
    //   /virtio-mmio@000000000a003c00/disk@0,0
    //                ^                     ^ ^
    //                |                     fixed
    //                base address of virtio-mmio register block
    //
    // UEFI device path prefix:
    //
    //   <VenHwString>
    //
    Written = UnicodeSPrintAsciiFormat (
                Translated,
                *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
                "%s",
                VenHwString
                );
  } else if (NumNodes >= 3 &&
             SubstringEq (OfwNode[1].DriverName, "channel") &&
             SubstringEq (OfwNode[2].DriverName, "disk")) {
    //
    // OpenFirmware device path (virtio-scsi disk):
    //
    //   /virtio-mmio@000000000a003a00/channel@0/disk@2,3
    //                ^                        ^      ^ ^
    //                |                        |      | LUN
    //                |                        |      target
    //                |                        channel (unused, fixed 0)
    //                base address of virtio-mmio register block
    //
    // UEFI device path prefix:
    //
    //   <VenHwString>/Scsi(0x2,0x3)
    //
    UINT64 TargetLun[2];

    TargetLun[1] = 0;
    NumEntries = ARRAY_SIZE (TargetLun);
    if (ParseUnitAddressHexList (
          OfwNode[2].UnitAddress,
          TargetLun,
          &NumEntries
          ) != RETURN_SUCCESS
        ) {
      return RETURN_UNSUPPORTED;
    }

    Written = UnicodeSPrintAsciiFormat (
                Translated,
                *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
                "%s/Scsi(0x%Lx,0x%Lx)",
                VenHwString,
                TargetLun[0],
                TargetLun[1]
                );
  } else if (NumNodes >= 2 &&
             SubstringEq (OfwNode[1].DriverName, "ethernet-phy")) {
    //
    // OpenFirmware device path (virtio-net NIC):
    //
    //   /virtio-mmio@000000000a003e00/ethernet-phy@0
    //                ^                             ^
    //                |                             fixed
    //                base address of virtio-mmio register block
    //
    // UEFI device path prefix:
    //
    //   <VenHwString>
    //
    Written = UnicodeSPrintAsciiFormat (
                Translated,
                *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
                "%s",
                VenHwString
                );
  } else {
    return RETURN_UNSUPPORTED;
  }

  //
  // There's no way to differentiate between "completely used up without
  // truncation" and "truncated", so treat the former as the latter, and return
  // success only for "some room left unused".
  //
  if (Written + 1 < *TranslatedSize) {
    *TranslatedSize = Written;
    return RETURN_SUCCESS;
  }

  return RETURN_BUFFER_TOO_SMALL;
}


/**

  Translate an array of OpenFirmware device nodes to a UEFI device path
  fragment.

  @param[in]     OfwNode         Array of OpenFirmware device nodes to
                                 translate, constituting the beginning of an
                                 OpenFirmware device path.

  @param[in]     NumNodes        Number of elements in OfwNode.

  @param[in]     ExtraPciRoots   An EXTRA_ROOT_BUS_MAP object created with
                                 CreateExtraRootBusMap(), to be used for
                                 translating positions of extra root buses to
                                 bus numbers.

  @param[out]    Translated      Destination array receiving the UEFI path
                                 fragment, allocated by the caller. If the
                                 return value differs from RETURN_SUCCESS, its
                                 contents is indeterminate.

  @param[in out] TranslatedSize  On input, the number of CHAR16's in
                                 Translated. On RETURN_SUCCESS this parameter
                                 is assigned the number of non-NUL CHAR16's
                                 written to Translated. In case of other return
                                 values, TranslatedSize is indeterminate.


  @retval RETURN_SUCCESS           Translation successful.

  @retval RETURN_BUFFER_TOO_SMALL  The translation does not fit into the number
                                   of bytes provided.

  @retval RETURN_UNSUPPORTED       The array of OpenFirmware device nodes can't
                                   be translated in the current implementation.

  @retval RETURN_PROTOCOL_ERROR    The array of OpenFirmware device nodes has
                                   been (partially) recognized, but it contains
                                   a logic error / doesn't match system state.

**/
STATIC
RETURN_STATUS
TranslateOfwNodes (
  IN      CONST OFW_NODE           *OfwNode,
  IN      UINTN                    NumNodes,
  IN      CONST EXTRA_ROOT_BUS_MAP *ExtraPciRoots,
  OUT     CHAR16                   *Translated,
  IN OUT  UINTN                    *TranslatedSize
  )
{
  RETURN_STATUS Status;

  Status = RETURN_UNSUPPORTED;

  if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) {
    Status = TranslatePciOfwNodes (OfwNode, NumNodes, ExtraPciRoots,
               Translated, TranslatedSize);
  }
  if (Status == RETURN_UNSUPPORTED &&
      FeaturePcdGet (PcdQemuBootOrderMmioTranslation)) {
    Status = TranslateMmioOfwNodes (OfwNode, NumNodes, Translated,
               TranslatedSize);
  }
  return Status;
}

/**

  Translate an OpenFirmware device path fragment to a UEFI device path
  fragment, and advance in the input string.

  @param[in out] Ptr             Address of the pointer pointing to the start
                                 of the path string. After successful
                                 translation (RETURN_SUCCESS) or at least
                                 successful parsing (RETURN_UNSUPPORTED,
                                 RETURN_BUFFER_TOO_SMALL), *Ptr is set to the
                                 byte immediately following the consumed
                                 characters. In other error cases, it points to
                                 the byte that caused the error.

  @param[in]     ExtraPciRoots   An EXTRA_ROOT_BUS_MAP object created with
                                 CreateExtraRootBusMap(), to be used for
                                 translating positions of extra root buses to
                                 bus numbers.

  @param[out]    Translated      Destination array receiving the UEFI path
                                 fragment, allocated by the caller. If the
                                 return value differs from RETURN_SUCCESS, its
                                 contents is indeterminate.

  @param[in out] TranslatedSize  On input, the number of CHAR16's in
                                 Translated. On RETURN_SUCCESS this parameter
                                 is assigned the number of non-NUL CHAR16's
                                 written to Translated. In case of other return
                                 values, TranslatedSize is indeterminate.


  @retval RETURN_SUCCESS            Translation successful.

  @retval RETURN_BUFFER_TOO_SMALL   The OpenFirmware device path was parsed
                                    successfully, but its translation did not
                                    fit into the number of bytes provided.
                                    Further calls to this function are
                                    possible.

  @retval RETURN_UNSUPPORTED        The OpenFirmware device path was parsed
                                    successfully, but it can't be translated in
                                    the current implementation. Further calls
                                    to this function are possible.

  @retval RETURN_PROTOCOL_ERROR     The OpenFirmware device path has been
                                    (partially) recognized, but it contains a
                                    logic error / doesn't match system state.
                                    Further calls to this function are
                                    possible.

  @retval RETURN_NOT_FOUND          Translation terminated. On input, *Ptr was
                                    pointing to the empty string or "HALT". On
                                    output, *Ptr points to the empty string
                                    (ie. "HALT" is consumed transparently when
                                    present).

  @retval RETURN_INVALID_PARAMETER  Parse error. This is a permanent error.

**/
STATIC
RETURN_STATUS
TranslateOfwPath (
  IN OUT  CONST CHAR8              **Ptr,
  IN      CONST EXTRA_ROOT_BUS_MAP *ExtraPciRoots,
  OUT     CHAR16                   *Translated,
  IN OUT  UINTN                    *TranslatedSize
  )
{
  UINTN         NumNodes;
  RETURN_STATUS Status;
  OFW_NODE      Node[EXAMINED_OFW_NODES];
  BOOLEAN       IsFinal;
  OFW_NODE      Skip;

  IsFinal = FALSE;
  NumNodes = 0;
  if (AsciiStrCmp (*Ptr, "HALT") == 0) {
    *Ptr += 4;
    Status = RETURN_NOT_FOUND;
  } else {
    Status = ParseOfwNode (Ptr, &Node[NumNodes], &IsFinal);
  }

  if (Status == RETURN_NOT_FOUND) {
    DEBUG ((DEBUG_VERBOSE, "%a: no more nodes\n", __FUNCTION__));
    return RETURN_NOT_FOUND;
  }

  while (Status == RETURN_SUCCESS && !IsFinal) {
    ++NumNodes;
    Status = ParseOfwNode (
               Ptr,
               (NumNodes < EXAMINED_OFW_NODES) ? &Node[NumNodes] : &Skip,
               &IsFinal
               );
  }

  switch (Status) {
  case RETURN_SUCCESS:
    ++NumNodes;
    break;

  case RETURN_INVALID_PARAMETER:
    DEBUG ((DEBUG_VERBOSE, "%a: parse error\n", __FUNCTION__));
    return RETURN_INVALID_PARAMETER;

  default:
    ASSERT (0);
  }

  Status = TranslateOfwNodes (
             Node,
             NumNodes < EXAMINED_OFW_NODES ? NumNodes : EXAMINED_OFW_NODES,
             ExtraPciRoots,
             Translated,
             TranslatedSize);
  switch (Status) {
  case RETURN_SUCCESS:
    DEBUG ((DEBUG_VERBOSE, "%a: success: \"%s\"\n", __FUNCTION__, Translated));
    break;

  case RETURN_BUFFER_TOO_SMALL:
    DEBUG ((DEBUG_VERBOSE, "%a: buffer too small\n", __FUNCTION__));
    break;

  case RETURN_UNSUPPORTED:
    DEBUG ((DEBUG_VERBOSE, "%a: unsupported\n", __FUNCTION__));
    break;

  case RETURN_PROTOCOL_ERROR:
    DEBUG ((DEBUG_VERBOSE, "%a: logic error / system state mismatch\n",
      __FUNCTION__));
    break;

  default:
    ASSERT (0);
  }
  return Status;
}


/**
  Connect devices based on the boot order retrieved from QEMU.

  Attempt to retrieve the "bootorder" fw_cfg file from QEMU. Translate the
  OpenFirmware device paths therein to UEFI device path fragments. Connect the
  devices identified by the UEFI devpath prefixes as narrowly as possible, then
  connect all their child devices, recursively.

  If this function fails, then platform BDS should fall back to
  EfiBootManagerConnectAll(), or some other method for connecting any expected
  boot devices.

  @retval RETURN_SUCCESS            The "bootorder" fw_cfg file has been
                                    parsed, and the referenced device-subtrees
                                    have been connected.

  @retval RETURN_UNSUPPORTED        QEMU's fw_cfg is not supported.

  @retval RETURN_NOT_FOUND          Empty or nonexistent "bootorder" fw_cfg
                                    file.

  @retval RETURN_INVALID_PARAMETER  Parse error in the "bootorder" fw_cfg file.

  @retval RETURN_OUT_OF_RESOURCES   Memory allocation failed.

  @return                           Error statuses propagated from underlying
                                    functions.
**/
RETURN_STATUS
EFIAPI
ConnectDevicesFromQemu (
  VOID
  )
{
  RETURN_STATUS        Status;
  FIRMWARE_CONFIG_ITEM FwCfgItem;
  UINTN                FwCfgSize;
  CHAR8                *FwCfg;
  EFI_STATUS           EfiStatus;
  EXTRA_ROOT_BUS_MAP   *ExtraPciRoots;
  CONST CHAR8          *FwCfgPtr;
  UINTN                NumConnected;
  UINTN                TranslatedSize;
  CHAR16               Translated[TRANSLATION_OUTPUT_SIZE];

  Status = QemuFwCfgFindFile ("bootorder", &FwCfgItem, &FwCfgSize);
  if (RETURN_ERROR (Status)) {
    return Status;
  }

  if (FwCfgSize == 0) {
    return RETURN_NOT_FOUND;
  }

  FwCfg = AllocatePool (FwCfgSize);
  if (FwCfg == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  QemuFwCfgSelectItem (FwCfgItem);
  QemuFwCfgReadBytes (FwCfgSize, FwCfg);
  if (FwCfg[FwCfgSize - 1] != '\0') {
    Status = RETURN_INVALID_PARAMETER;
    goto FreeFwCfg;
  }
  DEBUG ((DEBUG_VERBOSE, "%a: FwCfg:\n", __FUNCTION__));
  DEBUG ((DEBUG_VERBOSE, "%a\n", FwCfg));
  DEBUG ((DEBUG_VERBOSE, "%a: FwCfg: <end>\n", __FUNCTION__));

  if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) {
    EfiStatus = CreateExtraRootBusMap (&ExtraPciRoots);
    if (EFI_ERROR (EfiStatus)) {
      Status = (RETURN_STATUS)EfiStatus;
      goto FreeFwCfg;
    }
  } else {
    ExtraPciRoots = NULL;
  }

  //
  // Translate each OpenFirmware path to a UEFI devpath prefix.
  //
  FwCfgPtr = FwCfg;
  NumConnected = 0;
  TranslatedSize = ARRAY_SIZE (Translated);
  Status = TranslateOfwPath (&FwCfgPtr, ExtraPciRoots, Translated,
             &TranslatedSize);
  while (!RETURN_ERROR (Status)) {
    EFI_DEVICE_PATH_PROTOCOL *DevicePath;
    EFI_HANDLE               Controller;

    //
    // Convert the UEFI devpath prefix to binary representation.
    //
    ASSERT (Translated[TranslatedSize] == L'\0');
    DevicePath = ConvertTextToDevicePath (Translated);
    if (DevicePath == NULL) {
      Status = RETURN_OUT_OF_RESOURCES;
      goto FreeExtraPciRoots;
    }
    //
    // Advance along DevicePath, connecting the nodes individually, and asking
    // drivers not to produce sibling nodes. Retrieve the controller handle
    // associated with the full DevicePath -- this is the device that QEMU's
    // OFW devpath refers to.
    //
    EfiStatus = EfiBootManagerConnectDevicePath (DevicePath, &Controller);
    FreePool (DevicePath);
    if (EFI_ERROR (EfiStatus)) {
      Status = (RETURN_STATUS)EfiStatus;
      goto FreeExtraPciRoots;
    }
    //
    // Because QEMU's OFW devpaths have lesser expressive power than UEFI
    // devpaths (i.e., DevicePath is considered a prefix), connect the tree
    // rooted at Controller, recursively. If no children are produced
    // (EFI_NOT_FOUND), that's OK.
    //
    EfiStatus = gBS->ConnectController (Controller, NULL, NULL, TRUE);
    if (EFI_ERROR (EfiStatus) && EfiStatus != EFI_NOT_FOUND) {
      Status = (RETURN_STATUS)EfiStatus;
      goto FreeExtraPciRoots;
    }
    ++NumConnected;
    //
    // Move to the next OFW devpath.
    //
    TranslatedSize = ARRAY_SIZE (Translated);
    Status = TranslateOfwPath (&FwCfgPtr, ExtraPciRoots, Translated,
               &TranslatedSize);
  }

  if (Status == RETURN_NOT_FOUND && NumConnected > 0) {
    DEBUG ((DEBUG_INFO, "%a: %Lu OpenFirmware device path(s) connected\n",
      __FUNCTION__, (UINT64)NumConnected));
    Status = RETURN_SUCCESS;
  }

FreeExtraPciRoots:
  if (ExtraPciRoots != NULL) {
    DestroyExtraRootBusMap (ExtraPciRoots);
  }

FreeFwCfg:
  FreePool (FwCfg);

  return Status;
}


/**

  Convert the UEFI DevicePath to full text representation with DevPathToText,
  then match the UEFI device path fragment in Translated against it.

  @param[in] Translated        UEFI device path fragment, translated from
                               OpenFirmware format, to search for.

  @param[in] TranslatedLength  The length of Translated in CHAR16's.

  @param[in] DevicePath        Boot option device path whose textual rendering
                               to search in.

  @param[in] DevPathToText  Binary-to-text conversion protocol for DevicePath.


  @retval TRUE   If Translated was found at the beginning of DevicePath after
                 converting the latter to text.

  @retval FALSE  If DevicePath was NULL, or it could not be converted, or there
                 was no match.

**/
STATIC
BOOLEAN
Match (
  IN  CONST CHAR16                           *Translated,
  IN  UINTN                                  TranslatedLength,
  IN  EFI_DEVICE_PATH_PROTOCOL               *DevicePath
  )
{
  CHAR16                   *Converted;
  BOOLEAN                  Result;
  VOID                     *FileBuffer;
  UINTN                    FileSize;
  EFI_DEVICE_PATH_PROTOCOL *AbsDevicePath;
  CHAR16                   *AbsConverted;
  BOOLEAN                  Shortform;
  EFI_DEVICE_PATH_PROTOCOL *Node;

  Converted = ConvertDevicePathToText (
                DevicePath,
                FALSE, // DisplayOnly
                FALSE  // AllowShortcuts
                );
  if (Converted == NULL) {
    return FALSE;
  }

  Result = FALSE;
  Shortform = FALSE;
  //
  // Expand the short-form device path to full device path
  //
  if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
      (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)) {
    //
    // Harddrive shortform device path
    //
    Shortform = TRUE;
  } else if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
             (DevicePathSubType (DevicePath) == MEDIA_FILEPATH_DP)) {
    //
    // File-path shortform device path
    //
    Shortform = TRUE;
  } else if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
             (DevicePathSubType (DevicePath) == MSG_URI_DP)) {
    //
    // URI shortform device path
    //
    Shortform = TRUE;
  } else {
    for ( Node = DevicePath
        ; !IsDevicePathEnd (Node)
        ; Node = NextDevicePathNode (Node)
        ) {
      if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) &&
          ((DevicePathSubType (Node) == MSG_USB_CLASS_DP) ||
           (DevicePathSubType (Node) == MSG_USB_WWID_DP))) {
        Shortform = TRUE;
        break;
      }
    }
  }

  //
  // Attempt to expand any relative UEFI device path to
  // an absolute device path first.
  //
  if (Shortform) {
    FileBuffer = EfiBootManagerGetLoadOptionBuffer (
                   DevicePath, &AbsDevicePath, &FileSize
                   );
    if (FileBuffer == NULL) {
      goto Exit;
    }
    FreePool (FileBuffer);
    AbsConverted = ConvertDevicePathToText (AbsDevicePath, FALSE, FALSE);
    FreePool (AbsDevicePath);
    if (AbsConverted == NULL) {
      goto Exit;
    }
    DEBUG ((DEBUG_VERBOSE,
      "%a: expanded relative device path \"%s\" for prefix matching\n",
      __FUNCTION__, Converted));
    FreePool (Converted);
    Converted = AbsConverted;
  }

  //
  // Is Translated a prefix of Converted?
  //
  Result = (BOOLEAN)(StrnCmp (Converted, Translated, TranslatedLength) == 0);
  DEBUG ((
    DEBUG_VERBOSE,
    "%a: against \"%s\": %a\n",
    __FUNCTION__,
    Converted,
    Result ? "match" : "no match"
    ));
Exit:
  FreePool (Converted);
  return Result;
}


/**
  Append some of the unselected active boot options to the boot order.

  This function should accommodate any further policy changes in "boot option
  survival". Currently we're adding back everything that starts with neither
  PciRoot() nor HD() nor a virtio-mmio VenHw() node.

  @param[in,out] BootOrder     The structure holding the boot order to
                               complete. The caller is responsible for
                               initializing (and potentially populating) it
                               before calling this function.

  @param[in,out] ActiveOption  The array of active boot options to scan.
                               Entries marked as Appended will be skipped.
                               Those of the rest that satisfy the survival
                               policy will be added to BootOrder with
                               BootOrderAppend().

  @param[in]     ActiveCount   Number of elements in ActiveOption.


  @retval RETURN_SUCCESS  BootOrder has been extended with any eligible boot
                          options.

  @return                 Error codes returned by BootOrderAppend().
**/
STATIC
RETURN_STATUS
BootOrderComplete (
  IN OUT  BOOT_ORDER    *BootOrder,
  IN OUT  ACTIVE_OPTION *ActiveOption,
  IN      UINTN         ActiveCount
  )
{
  RETURN_STATUS Status;
  UINTN         Idx;

  Status = RETURN_SUCCESS;
  Idx = 0;
  while (!RETURN_ERROR (Status) && Idx < ActiveCount) {
    if (!ActiveOption[Idx].Appended) {
      CONST EFI_BOOT_MANAGER_LOAD_OPTION *Current;
      CONST EFI_DEVICE_PATH_PROTOCOL     *FirstNode;

      Current = ActiveOption[Idx].BootOption;
      FirstNode = Current->FilePath;
      if (FirstNode != NULL) {
        CHAR16        *Converted;
        STATIC CHAR16 ConvFallBack[] = L"<unable to convert>";
        BOOLEAN       Keep;

        Converted = ConvertDevicePathToText (FirstNode, FALSE, FALSE);
        if (Converted == NULL) {
          Converted = ConvFallBack;
        }

        Keep = TRUE;
        if (DevicePathType(FirstNode) == MEDIA_DEVICE_PATH &&
            DevicePathSubType(FirstNode) == MEDIA_HARDDRIVE_DP) {
          //
          // drop HD()
          //
          Keep = FALSE;
        } else if (DevicePathType(FirstNode) == ACPI_DEVICE_PATH &&
                   DevicePathSubType(FirstNode) == ACPI_DP) {
          ACPI_HID_DEVICE_PATH *Acpi;

          Acpi = (ACPI_HID_DEVICE_PATH *) FirstNode;
          if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST &&
              EISA_ID_TO_NUM (Acpi->HID) == 0x0a03) {
            //
            // drop PciRoot() if we enabled the user to select PCI-like boot
            // options, by providing translation for such OFW device path
            // fragments
            //
            Keep = !FeaturePcdGet (PcdQemuBootOrderPciTranslation);
          }
        } else if (DevicePathType(FirstNode) == HARDWARE_DEVICE_PATH &&
                   DevicePathSubType(FirstNode) == HW_VENDOR_DP) {
          VENDOR_DEVICE_PATH *VenHw;

          VenHw = (VENDOR_DEVICE_PATH *)FirstNode;
          if (CompareGuid (&VenHw->Guid, &gVirtioMmioTransportGuid)) {
            //
            // drop virtio-mmio if we enabled the user to select boot options
            // referencing such device paths
            //
            Keep = !FeaturePcdGet (PcdQemuBootOrderMmioTranslation);
          }
        }

        if (Keep) {
          Status = BootOrderAppend (BootOrder, &ActiveOption[Idx]);
          if (!RETURN_ERROR (Status)) {
            DEBUG ((DEBUG_VERBOSE, "%a: keeping \"%s\"\n", __FUNCTION__,
              Converted));
          }
        } else {
          DEBUG ((DEBUG_VERBOSE, "%a: dropping \"%s\"\n", __FUNCTION__,
            Converted));
        }

        if (Converted != ConvFallBack) {
          FreePool (Converted);
        }
      }
    }
    ++Idx;
  }
  return Status;
}


/**
  Delete Boot#### variables that stand for such active boot options that have
  been dropped (ie. have not been selected by either matching or "survival
  policy").

  @param[in]  ActiveOption  The array of active boot options to scan. Each
                            entry not marked as appended will trigger the
                            deletion of the matching Boot#### variable.

  @param[in]  ActiveCount   Number of elements in ActiveOption.
**/
STATIC
VOID
PruneBootVariables (
  IN  CONST ACTIVE_OPTION *ActiveOption,
  IN  UINTN               ActiveCount
  )
{
  UINTN Idx;

  for (Idx = 0; Idx < ActiveCount; ++Idx) {
    if (!ActiveOption[Idx].Appended) {
      CHAR16 VariableName[9];

      UnicodeSPrintAsciiFormat (VariableName, sizeof VariableName, "Boot%04x",
        ActiveOption[Idx].BootOption->OptionNumber);

      //
      // "The space consumed by the deleted variable may not be available until
      // the next power cycle", but that's good enough.
      //
      gRT->SetVariable (VariableName, &gEfiGlobalVariableGuid,
             0,   // Attributes, 0 means deletion
             0,   // DataSize, 0 means deletion
             NULL // Data
             );
    }
  }
}


/**

  Set the boot order based on configuration retrieved from QEMU.

  Attempt to retrieve the "bootorder" fw_cfg file from QEMU. Translate the
  OpenFirmware device paths therein to UEFI device path fragments. Match the
  translated fragments against the current list of boot options, and rewrite
  the BootOrder NvVar so that it corresponds to the order described in fw_cfg.

  Platform BDS should call this function after connecting any expected boot
  devices and calling EfiBootManagerRefreshAllBootOption ().

  @retval RETURN_SUCCESS            BootOrder NvVar rewritten.

  @retval RETURN_UNSUPPORTED        QEMU's fw_cfg is not supported.

  @retval RETURN_NOT_FOUND          Empty or nonexistent "bootorder" fw_cfg
                                    file, or no match found between the
                                    "bootorder" fw_cfg file and BootOptionList.

  @retval RETURN_INVALID_PARAMETER  Parse error in the "bootorder" fw_cfg file.

  @retval RETURN_OUT_OF_RESOURCES   Memory allocation failed.

  @return                           Values returned by gBS->LocateProtocol ()
                                    or gRT->SetVariable ().

**/
RETURN_STATUS
EFIAPI
SetBootOrderFromQemu (
  VOID
  )
{
  RETURN_STATUS                    Status;
  FIRMWARE_CONFIG_ITEM             FwCfgItem;
  UINTN                            FwCfgSize;
  CHAR8                            *FwCfg;
  CONST CHAR8                      *FwCfgPtr;

  BOOT_ORDER                       BootOrder;
  ACTIVE_OPTION                    *ActiveOption;
  UINTN                            ActiveCount;

  EXTRA_ROOT_BUS_MAP               *ExtraPciRoots;

  UINTN                            TranslatedSize;
  CHAR16                           Translated[TRANSLATION_OUTPUT_SIZE];
  EFI_BOOT_MANAGER_LOAD_OPTION     *BootOptions;
  UINTN                            BootOptionCount;

  Status = QemuFwCfgFindFile ("bootorder", &FwCfgItem, &FwCfgSize);
  if (Status != RETURN_SUCCESS) {
    return Status;
  }

  if (FwCfgSize == 0) {
    return RETURN_NOT_FOUND;
  }

  FwCfg = AllocatePool (FwCfgSize);
  if (FwCfg == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  QemuFwCfgSelectItem (FwCfgItem);
  QemuFwCfgReadBytes (FwCfgSize, FwCfg);
  if (FwCfg[FwCfgSize - 1] != '\0') {
    Status = RETURN_INVALID_PARAMETER;
    goto ErrorFreeFwCfg;
  }

  DEBUG ((DEBUG_VERBOSE, "%a: FwCfg:\n", __FUNCTION__));
  DEBUG ((DEBUG_VERBOSE, "%a\n", FwCfg));
  DEBUG ((DEBUG_VERBOSE, "%a: FwCfg: <end>\n", __FUNCTION__));
  FwCfgPtr = FwCfg;

  BootOrder.Produced  = 0;
  BootOrder.Allocated = 1;
  BootOrder.Data = AllocatePool (
                     BootOrder.Allocated * sizeof (*BootOrder.Data)
                     );
  if (BootOrder.Data == NULL) {
    Status = RETURN_OUT_OF_RESOURCES;
    goto ErrorFreeFwCfg;
  }

  BootOptions = EfiBootManagerGetLoadOptions (
                  &BootOptionCount, LoadOptionTypeBoot
                  );
  if (BootOptions == NULL) {
    Status = RETURN_NOT_FOUND;
    goto ErrorFreeBootOrder;
  }

  Status = CollectActiveOptions (
             BootOptions, BootOptionCount, &ActiveOption, &ActiveCount
             );
  if (RETURN_ERROR (Status)) {
    goto ErrorFreeBootOptions;
  }

  if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) {
    Status = CreateExtraRootBusMap (&ExtraPciRoots);
    if (EFI_ERROR (Status)) {
      goto ErrorFreeActiveOption;
    }
  } else {
    ExtraPciRoots = NULL;
  }

  //
  // translate each OpenFirmware path
  //
  TranslatedSize = ARRAY_SIZE (Translated);
  Status = TranslateOfwPath (&FwCfgPtr, ExtraPciRoots, Translated,
             &TranslatedSize);
  while (Status == RETURN_SUCCESS ||
         Status == RETURN_UNSUPPORTED ||
         Status == RETURN_PROTOCOL_ERROR ||
         Status == RETURN_BUFFER_TOO_SMALL) {
    if (Status == RETURN_SUCCESS) {
      UINTN Idx;

      //
      // match translated OpenFirmware path against all active boot options
      //
      for (Idx = 0; Idx < ActiveCount; ++Idx) {
        if (!ActiveOption[Idx].Appended &&
            Match (
              Translated,
              TranslatedSize, // contains length, not size, in CHAR16's here
              ActiveOption[Idx].BootOption->FilePath
              )
            ) {
          //
          // match found, store ID and continue with next OpenFirmware path
          //
          Status = BootOrderAppend (&BootOrder, &ActiveOption[Idx]);
          if (Status != RETURN_SUCCESS) {
            goto ErrorFreeExtraPciRoots;
          }
        }
      } // scanned all active boot options
    }   // translation successful

    TranslatedSize = ARRAY_SIZE (Translated);
    Status = TranslateOfwPath (&FwCfgPtr, ExtraPciRoots, Translated,
               &TranslatedSize);
  } // scanning of OpenFirmware paths done

  if (Status == RETURN_NOT_FOUND && BootOrder.Produced > 0) {
    //
    // No more OpenFirmware paths, some matches found: rewrite BootOrder NvVar.
    // Some of the active boot options that have not been selected over fw_cfg
    // should be preserved at the end of the boot order.
    //
    Status = BootOrderComplete (&BootOrder, ActiveOption, ActiveCount);
    if (RETURN_ERROR (Status)) {
      goto ErrorFreeExtraPciRoots;
    }

    //
    // See Table 10 in the UEFI Spec 2.3.1 with Errata C for the required
    // attributes.
    //
    Status = gRT->SetVariable (
                    L"BootOrder",
                    &gEfiGlobalVariableGuid,
                    EFI_VARIABLE_NON_VOLATILE |
                      EFI_VARIABLE_BOOTSERVICE_ACCESS |
                      EFI_VARIABLE_RUNTIME_ACCESS,
                    BootOrder.Produced * sizeof (*BootOrder.Data),
                    BootOrder.Data
                    );
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "%a: setting BootOrder: %r\n", __FUNCTION__,
        Status));
      goto ErrorFreeExtraPciRoots;
    }

    DEBUG ((DEBUG_INFO, "%a: setting BootOrder: success\n", __FUNCTION__));
    PruneBootVariables (ActiveOption, ActiveCount);
  }

ErrorFreeExtraPciRoots:
  if (ExtraPciRoots != NULL) {
    DestroyExtraRootBusMap (ExtraPciRoots);
  }

ErrorFreeActiveOption:
  FreePool (ActiveOption);

ErrorFreeBootOptions:
  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);

ErrorFreeBootOrder:
  FreePool (BootOrder.Data);

ErrorFreeFwCfg:
  FreePool (FwCfg);

  return Status;
}


/**
  Calculate the number of seconds we should be showing the FrontPage progress
  bar for.

  @return  The TimeoutDefault argument for PlatformBdsEnterFrontPage().
**/
UINT16
EFIAPI
GetFrontPageTimeoutFromQemu (
  VOID
  )
{
  FIRMWARE_CONFIG_ITEM BootMenuWaitItem;
  UINTN                BootMenuWaitSize;

  QemuFwCfgSelectItem (QemuFwCfgItemBootMenu);
  if (QemuFwCfgRead16 () == 0) {
    //
    // The user specified "-boot menu=off", or didn't specify "-boot
    // menu=(on|off)" at all. Return the platform default.
    //
    return PcdGet16 (PcdPlatformBootTimeOut);
  }

  if (RETURN_ERROR (QemuFwCfgFindFile ("etc/boot-menu-wait", &BootMenuWaitItem,
                      &BootMenuWaitSize)) ||
      BootMenuWaitSize != sizeof (UINT16)) {
    //
    // "-boot menu=on" was specified without "splash-time=N". In this case,
    // return three seconds if the platform default would cause us to skip the
    // front page, and return the platform default otherwise.
    //
    UINT16 Timeout;

    Timeout = PcdGet16 (PcdPlatformBootTimeOut);
    if (Timeout == 0) {
      Timeout = 3;
    }
    return Timeout;
  }

  //
  // "-boot menu=on,splash-time=N" was specified, where N is in units of
  // milliseconds. The Intel BDS Front Page progress bar only supports whole
  // seconds, round N up.
  //
  QemuFwCfgSelectItem (BootMenuWaitItem);
  return (UINT16)((QemuFwCfgRead16 () + 999) / 1000);
}
