/** @file

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "LegacyBiosInterface.h"
#include <IndustryStandard/Pci30.h>

#define PCI_START_ADDRESS(x)  (((x) + 0x7ff) & ~0x7ff)

#define MAX_BRIDGE_INDEX  0x20
typedef struct {
  UINTN    PciSegment;
  UINTN    PciBus;
  UINTN    PciDevice;
  UINTN    PciFunction;
  UINT8    PrimaryBus;
  UINT8    SecondaryBus;
  UINT8    SubordinateBus;
} BRIDGE_TABLE;

#define ROM_MAX_ENTRIES  24
BRIDGE_TABLE                 Bridges[MAX_BRIDGE_INDEX];
UINTN                        SortedBridgeIndex[MAX_BRIDGE_INDEX];
UINTN                        NumberOfBridges;
LEGACY_PNP_EXPANSION_HEADER  *mBasePnpPtr;
UINT16                       mBbsRomSegment;
UINTN                        mHandleCount;
EFI_HANDLE                   mVgaHandle;
BOOLEAN                      mIgnoreBbsUpdateFlag;
BOOLEAN                      mVgaInstallationInProgress = FALSE;
UINT32                       mRomCount                  = 0x00;
ROM_INSTANCE_ENTRY           mRomEntry[ROM_MAX_ENTRIES];
EDKII_IOMMU_PROTOCOL         *mIoMmu;

/**
  Query shadowed legacy ROM parameters registered by RomShadow() previously.

  @param  PciHandle        PCI device whos ROM has been shadowed
  @param  DiskStart        DiskStart value from EFI_LEGACY_BIOS_PROTOCOL.InstallPciRom
  @param  DiskEnd          DiskEnd value from EFI_LEGACY_BIOS_PROTOCOL.InstallPciRom
  @param  RomShadowAddress Address where ROM was shadowed
  @param  ShadowedSize     Runtime size of ROM

  @retval EFI_SUCCESS      Query Logging successful.
  @retval EFI_NOT_FOUND    No logged data found about PciHandle.

**/
EFI_STATUS
GetShadowedRomParameters (
  IN EFI_HANDLE  PciHandle,
  OUT UINT8      *DiskStart          OPTIONAL,
  OUT UINT8      *DiskEnd            OPTIONAL,
  OUT VOID       **RomShadowAddress  OPTIONAL,
  OUT UINTN      *ShadowedSize       OPTIONAL
  )
{
  EFI_STATUS           Status;
  EFI_PCI_IO_PROTOCOL  *PciIo;
  UINTN                Index;
  UINTN                PciSegment;
  UINTN                PciBus;
  UINTN                PciDevice;
  UINTN                PciFunction;

  //
  // Get the PCI I/O Protocol on PciHandle
  //
  Status = gBS->HandleProtocol (
                  PciHandle,
                  &gEfiPciIoProtocolGuid,
                  (VOID **)&PciIo
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get the location of the PCI device
  //
  PciIo->GetLocation (
           PciIo,
           &PciSegment,
           &PciBus,
           &PciDevice,
           &PciFunction
           );

  for (Index = 0; Index < mRomCount; Index++) {
    if ((mRomEntry[Index].PciSegment == PciSegment) &&
        (mRomEntry[Index].PciBus == PciBus)         &&
        (mRomEntry[Index].PciDevice == PciDevice)   &&
        (mRomEntry[Index].PciFunction == PciFunction))
    {
      break;
    }
  }

  if (Index == mRomCount) {
    return EFI_NOT_FOUND;
  }

  if (DiskStart != NULL) {
    *DiskStart = mRomEntry[Index].DiskStart;
  }

  if (DiskEnd != NULL) {
    *DiskEnd = mRomEntry[Index].DiskEnd;
  }

  if (RomShadowAddress != NULL) {
    *RomShadowAddress = (VOID *)(UINTN)mRomEntry[Index].ShadowAddress;
  }

  if (ShadowedSize != NULL) {
    *ShadowedSize = mRomEntry[Index].ShadowedSize;
  }

  return EFI_SUCCESS;
}

/**
  Every legacy ROM that is shadowed by the Legacy BIOS driver will be
  registered into this API so that the policy code can know what has
  happend

  @param  PciHandle              PCI device whos ROM is being shadowed
  @param  ShadowAddress          Address that ROM was shadowed
  @param  ShadowedSize           Runtime size of ROM
  @param  DiskStart              DiskStart value from
                                 EFI_LEGACY_BIOS_PROTOCOL.InstallPciRom
  @param  DiskEnd                DiskEnd value from
                                 EFI_LEGACY_BIOS_PROTOCOL.InstallPciRom

  @retval EFI_SUCCESS            Logging successful.
  @retval EFI_OUT_OF_RESOURCES   No remaining room for registering another option
                                 ROM.

**/
EFI_STATUS
RomShadow (
  IN  EFI_HANDLE  PciHandle,
  IN  UINT32      ShadowAddress,
  IN  UINT32      ShadowedSize,
  IN  UINT8       DiskStart,
  IN  UINT8       DiskEnd
  )
{
  EFI_STATUS           Status;
  EFI_PCI_IO_PROTOCOL  *PciIo;

  //
  // See if there is room to register another option ROM
  //
  if (mRomCount >= ROM_MAX_ENTRIES) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Get the PCI I/O Protocol on PciHandle
  //
  Status = gBS->HandleProtocol (
                  PciHandle,
                  &gEfiPciIoProtocolGuid,
                  (VOID **)&PciIo
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get the location of the PCI device
  //
  PciIo->GetLocation (
           PciIo,
           &mRomEntry[mRomCount].PciSegment,
           &mRomEntry[mRomCount].PciBus,
           &mRomEntry[mRomCount].PciDevice,
           &mRomEntry[mRomCount].PciFunction
           );
  mRomEntry[mRomCount].ShadowAddress = ShadowAddress;
  mRomEntry[mRomCount].ShadowedSize  = ShadowedSize;
  mRomEntry[mRomCount].DiskStart     = DiskStart;
  mRomEntry[mRomCount].DiskEnd       = DiskEnd;

  mRomCount++;

  return EFI_SUCCESS;
}

/**
  Return EFI_SUCCESS if PciHandle has had a legacy BIOS ROM shadowed. This
  information represents every call to RomShadow ()

  @param  PciHandle              PCI device to get status for

  @retval EFI_SUCCESS            Legacy ROM loaded for this device
  @retval EFI_NOT_FOUND          No Legacy ROM loaded for this device

**/
EFI_STATUS
IsLegacyRom (
  IN  EFI_HANDLE  PciHandle
  )
{
  EFI_STATUS           Status;
  EFI_PCI_IO_PROTOCOL  *PciIo;
  UINTN                Index;
  UINTN                Segment;
  UINTN                Bus;
  UINTN                Device;
  UINTN                Function;

  //
  // Get the PCI I/O Protocol on PciHandle
  //
  Status = gBS->HandleProtocol (
                  PciHandle,
                  &gEfiPciIoProtocolGuid,
                  (VOID **)&PciIo
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get the location of the PCI device
  //
  PciIo->GetLocation (
           PciIo,
           &Segment,
           &Bus,
           &Device,
           &Function
           );

  //
  // See if the option ROM from PciHandle has been previously posted
  //
  for (Index = 0; Index < mRomCount; Index++) {
    if ((mRomEntry[Index].PciSegment == Segment) &&
        (mRomEntry[Index].PciBus == Bus) &&
        (mRomEntry[Index].PciDevice == Device) &&
        (mRomEntry[Index].PciFunction == Function)
        )
    {
      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

/**
  Find the PC-AT ROM Image in the raw PCI Option ROM. Also return the
  related information from the header.

  @param  Csm16Revision           The PCI interface version of underlying CSM16
  @param  VendorId                Vendor ID of the PCI device
  @param  DeviceId                Device ID of the PCI device
  @param  Rom                     On input pointing to beginning of the raw PCI OpROM
                                  On output pointing to the first legacy PCI OpROM
  @param  ImageSize               On input is the size of Raw PCI Rom
                                  On output is the size of the first legacy PCI ROM
  @param  MaxRuntimeImageLength   The max runtime image length only valid if OpRomRevision >= 3
  @param  OpRomRevision           Revision of the PCI Rom
  @param  ConfigUtilityCodeHeader Pointer to Configuration Utility Code Header

  @retval EFI_SUCCESS             Successfully find the legacy PCI ROM
  @retval EFI_NOT_FOUND           Failed to find the legacy PCI ROM

**/
EFI_STATUS
GetPciLegacyRom (
  IN     UINT16  Csm16Revision,
  IN     UINT16  VendorId,
  IN     UINT16  DeviceId,
  IN OUT VOID    **Rom,
  IN OUT UINTN   *ImageSize,
  OUT    UINTN   *MaxRuntimeImageLength    OPTIONAL,
  OUT    UINT8   *OpRomRevision            OPTIONAL,
  OUT    VOID    **ConfigUtilityCodeHeader OPTIONAL
  )
{
  BOOLEAN                 Match;
  UINT16                  *DeviceIdList;
  EFI_PCI_ROM_HEADER      RomHeader;
  PCI_3_0_DATA_STRUCTURE  *Pcir;
  VOID                    *BackupImage;
  VOID                    *BestImage;

  if (*ImageSize < sizeof (EFI_PCI_ROM_HEADER)) {
    return EFI_NOT_FOUND;
  }

  BestImage     = NULL;
  BackupImage   = NULL;
  RomHeader.Raw = *Rom;
  while (RomHeader.Generic->Signature == PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
    if ((RomHeader.Generic->PcirOffset == 0) ||
        ((RomHeader.Generic->PcirOffset & 3) != 0) ||
        (*ImageSize < RomHeader.Raw - (UINT8 *)*Rom + RomHeader.Generic->PcirOffset + sizeof (PCI_DATA_STRUCTURE)))
    {
      break;
    }

    Pcir = (PCI_3_0_DATA_STRUCTURE *)(RomHeader.Raw + RomHeader.Generic->PcirOffset);
    //
    // Check signature in the PCI Data Structure.
    //
    if (Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {
      break;
    }

    if (((UINTN)RomHeader.Raw - (UINTN)*Rom) + Pcir->ImageLength * 512 > *ImageSize) {
      break;
    }

    if (Pcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {
      Match = FALSE;
      if (Pcir->VendorId == VendorId) {
        if (Pcir->DeviceId == DeviceId) {
          Match = TRUE;
        } else if ((Pcir->Revision >= 3) && (Pcir->DeviceListOffset != 0)) {
          DeviceIdList = (UINT16 *)(((UINT8 *)Pcir) + Pcir->DeviceListOffset);
          //
          // Checking the device list
          //
          while (*DeviceIdList != 0) {
            if (*DeviceIdList == DeviceId) {
              Match = TRUE;
              break;
            }

            DeviceIdList++;
          }
        }
      }

      if (Match) {
        if (Csm16Revision >= 0x0300) {
          //
          // Case 1: CSM16 3.0
          //
          if (Pcir->Revision >= 3) {
            //
            // case 1.1: meets OpRom 3.0
            //           Perfect!!!
            //
            BestImage = RomHeader.Raw;
            break;
          } else {
            //
            // case 1.2: meets OpRom 2.x
            //           Store it and try to find the OpRom 3.0
            //
            BackupImage = RomHeader.Raw;
          }
        } else {
          //
          // Case 2: CSM16 2.x
          //
          if (Pcir->Revision >= 3) {
            //
            // case 2.1: meets OpRom 3.0
            //           Store it and try to find the OpRom 2.x
            //
            BackupImage = RomHeader.Raw;
          } else {
            //
            // case 2.2: meets OpRom 2.x
            //           Perfect!!!
            //
            BestImage = RomHeader.Raw;
            break;
          }
        }
      } else {
        DEBUG ((DEBUG_ERROR, "GetPciLegacyRom - OpRom not match (%04x-%04x)\n", (UINTN)VendorId, (UINTN)DeviceId));
      }
    }

    if ((Pcir->Indicator & 0x80) == 0x80) {
      break;
    } else {
      RomHeader.Raw += 512 * Pcir->ImageLength;
    }
  }

  if (BestImage == NULL) {
    if (BackupImage == NULL) {
      return EFI_NOT_FOUND;
    }

    //
    // The versions of CSM16 and OpRom don't match exactly
    //
    BestImage = BackupImage;
  }

  RomHeader.Raw = BestImage;
  Pcir          = (PCI_3_0_DATA_STRUCTURE *)(RomHeader.Raw + RomHeader.Generic->PcirOffset);
  *Rom          = BestImage;
  *ImageSize    = Pcir->ImageLength * 512;

  if (MaxRuntimeImageLength != NULL) {
    if (Pcir->Revision < 3) {
      *MaxRuntimeImageLength = 0;
    } else {
      *MaxRuntimeImageLength = Pcir->MaxRuntimeImageLength * 512;
    }
  }

  if (OpRomRevision != NULL) {
    //
    // Optional return PCI Data Structure revision
    //
    if (Pcir->Length >= 0x1C) {
      *OpRomRevision = Pcir->Revision;
    } else {
      *OpRomRevision = 0;
    }
  }

  if (ConfigUtilityCodeHeader != NULL) {
    //
    // Optional return ConfigUtilityCodeHeaderOffset supported by the PC-AT ROM
    //
    if ((Pcir->Revision < 3) || (Pcir->ConfigUtilityCodeHeaderOffset == 0)) {
      *ConfigUtilityCodeHeader = NULL;
    } else {
      *ConfigUtilityCodeHeader = RomHeader.Raw + Pcir->ConfigUtilityCodeHeaderOffset;
    }
  }

  return EFI_SUCCESS;
}

/**
  Build a table of bridge info for PIRQ translation.

  @param  RoutingTable         RoutingTable obtained from Platform.
  @param  RoutingTableEntries  Number of RoutingTable entries.

  @retval EFI_SUCCESS          New Subordinate bus.
  @retval EFI_NOT_FOUND        No more Subordinate busses.

**/
EFI_STATUS
CreateBridgeTable (
  IN EFI_LEGACY_IRQ_ROUTING_ENTRY  *RoutingTable,
  IN UINTN                         RoutingTableEntries
  )
{
  EFI_STATUS           Status;
  UINTN                HandleCount;
  EFI_HANDLE           *HandleBuffer;
  UINTN                BridgeIndex;
  UINTN                Index;
  UINTN                Index1;
  EFI_PCI_IO_PROTOCOL  *PciIo;
  PCI_TYPE01           PciConfigHeader;
  BRIDGE_TABLE         SlotBridges[MAX_BRIDGE_INDEX];
  UINTN                SlotBridgeIndex;

  BridgeIndex     = 0x00;
  SlotBridgeIndex = 0x00;

  //
  // Assumption is table is built from low bus to high bus numbers.
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiPciIoProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  for (Index = 0; Index < HandleCount; Index++) {
    Status = gBS->HandleProtocol (
                    HandleBuffer[Index],
                    &gEfiPciIoProtocolGuid,
                    (VOID **)&PciIo
                    );
    if (EFI_ERROR (Status)) {
      continue;
    }

    PciIo->Pci.Read (
                 PciIo,
                 EfiPciIoWidthUint32,
                 0,
                 sizeof (PciConfigHeader) / sizeof (UINT32),
                 &PciConfigHeader
                 );

    if (IS_PCI_P2P (&PciConfigHeader) && (BridgeIndex < MAX_BRIDGE_INDEX)) {
      PciIo->GetLocation (
               PciIo,
               &Bridges[BridgeIndex].PciSegment,
               &Bridges[BridgeIndex].PciBus,
               &Bridges[BridgeIndex].PciDevice,
               &Bridges[BridgeIndex].PciFunction
               );

      Bridges[BridgeIndex].PrimaryBus = PciConfigHeader.Bridge.PrimaryBus;

      Bridges[BridgeIndex].SecondaryBus = PciConfigHeader.Bridge.SecondaryBus;

      Bridges[BridgeIndex].SubordinateBus = PciConfigHeader.Bridge.SubordinateBus;

      for (Index1 = 0; Index1 < RoutingTableEntries; Index1++) {
        //
        // Test whether we have found the Bridge in the slot, must be the one that directly interfaced to the board
        // Once we find one, store it in the SlotBridges[]
        //
        if (  (RoutingTable[Index1].Slot != 0) && (Bridges[BridgeIndex].PrimaryBus == RoutingTable[Index1].Bus)
           && ((Bridges[BridgeIndex].PciDevice << 3) == RoutingTable[Index1].Device))
        {
          CopyMem (&SlotBridges[SlotBridgeIndex], &Bridges[BridgeIndex], sizeof (BRIDGE_TABLE));
          SlotBridgeIndex++;

          break;
        }
      }

      ++BridgeIndex;
    }
  }

  //
  // Pack up Bridges by removing those useless ones
  //
  for (Index = 0; Index < BridgeIndex;) {
    for (Index1 = 0; Index1 < SlotBridgeIndex; Index1++) {
      if (((Bridges[Index].PciBus == SlotBridges[Index1].PrimaryBus) && (Bridges[Index].PciDevice == SlotBridges[Index1].PciDevice)) ||
          ((Bridges[Index].PciBus >= SlotBridges[Index1].SecondaryBus) && (Bridges[Index].PciBus <= SlotBridges[Index1].SubordinateBus)))
      {
        //
        // We have found one that meets our criteria
        //
        Index++;
        break;
      }
    }

    //
    // This one doesn't meet criteria, pack it
    //
    if (Index1 >= SlotBridgeIndex) {
      for (Index1 = Index; BridgeIndex > 1 && Index1 < BridgeIndex - 1; Index1++) {
        CopyMem (&Bridges[Index1], &Bridges[Index1 + 1], sizeof (BRIDGE_TABLE));
      }

      BridgeIndex--;
    }
  }

  NumberOfBridges = BridgeIndex;

  //
  // Sort bridges low to high by Secondary bus followed by subordinate bus
  //
  if (NumberOfBridges > 1) {
    Index = 0;
    do {
      SortedBridgeIndex[Index] = Index;
      ++Index;
    } while (Index < NumberOfBridges);

    for (Index = 0; Index < NumberOfBridges - 1; Index++) {
      for (Index1 = Index + 1; Index1 < NumberOfBridges; Index1++) {
        if (Bridges[Index].SecondaryBus > Bridges[Index1].SecondaryBus) {
          SortedBridgeIndex[Index]  = Index1;
          SortedBridgeIndex[Index1] = Index;
        }

        if ((Bridges[Index].SecondaryBus == Bridges[Index1].SecondaryBus) &&
            (Bridges[Index].SubordinateBus > Bridges[Index1].SubordinateBus)
            )
        {
          SortedBridgeIndex[Index]  = Index1;
          SortedBridgeIndex[Index1] = Index;
        }
      }
    }
  }

  FreePool (HandleBuffer);
  return EFI_SUCCESS;
}

/**
  Find base Bridge for device.

  @param  Private                Legacy  BIOS Instance data
  @param  PciBus                 Input = Bus of device.
  @param  PciDevice              Input = Device.
  @param  RoutingTable           The platform specific routing table
  @param  RoutingTableEntries    Number of entries in table

  @retval EFI_SUCCESS            At base bus.
  @retval EFI_NOT_FOUND          Behind a bridge.

**/
EFI_STATUS
GetBaseBus (
  IN  LEGACY_BIOS_INSTANCE         *Private,
  IN UINTN                         PciBus,
  IN UINTN                         PciDevice,
  IN EFI_LEGACY_IRQ_ROUTING_ENTRY  *RoutingTable,
  IN UINTN                         RoutingTableEntries
  )
{
  UINTN  Index;

  for (Index = 0; Index < RoutingTableEntries; Index++) {
    if ((RoutingTable[Index].Bus == PciBus) && (RoutingTable[Index].Device == (PciDevice << 3))) {
      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

/**
  Translate PIRQ through busses

  @param  Private              Legacy  BIOS Instance data
  @param  PciBus               Input = Bus of device. Output = Translated Bus
  @param  PciDevice            Input = Device. Output = Translated Device
  @param  PciFunction          Input = Function. Output = Translated Function
  @param  PirqIndex            Input = Original PIRQ index. If single function
                                  device then 0, otherwise 0-3.
                               Output = Translated Index

  @retval EFI_SUCCESS          Pirq successfully translated.
  @retval EFI_NOT_FOUND        The device is not behind any known bridge.

**/
EFI_STATUS
TranslateBusPirq (
  IN  LEGACY_BIOS_INSTANCE  *Private,
  IN OUT UINTN              *PciBus,
  IN OUT UINTN              *PciDevice,
  IN OUT UINTN              *PciFunction,
  IN OUT UINT8              *PirqIndex
  )
{
  /*
  This routine traverses the PCI busses from base slot
  and translates the PIRQ register to the appropriate one.

  Example:

  Bus 0, Device 1 is PCI-PCI bridge that all PCI slots reside on.
    Primary bus# = 0
    Secondary bus # = 1
    Subordinate bus # is highest bus # behind this bus
       Bus 1, Device 0 is Slot 0 and is not a bridge.
       Bus 1, Device 1 is Slot 1 and is a bridge.
         Slot PIRQ routing is A,B,C,D.
         Primary bus # = 1
         Secondary bus # = 2
         Subordinate bus # = 5
            Bus 2, Device 6 is a bridge. It has no bridges behind it.
              Primary bus # = 2
              Secondary bus # = 3
              Subordinate bus # = 3
              Bridge PIRQ routing is C,D,A,B
            Bus 2, Device 7 is a bridge. It has 1 bridge behind it.
              Primary bus # = 2
              Secondary bus = 4   Device 6 takes bus 2.
              Subordinate bus = 5.
              Bridge PIRQ routing is D,A,B,C
                 Bus 4, Device 2 is a bridge. It has no bridges behind it.
                   Primary bus # = 4
                   Secondary bus # = 5
                   Subordinate bus = 5
                   Bridge PIRQ routing is B,C,D,A
                      Bus 5, Device 1 is to be programmed.
                         Device PIRQ routing is C,D,A,B


Search busses starting from slot bus for final bus >= Secondary bus and
final bus <= Subordinate bus. Assumption is bus entries increase in bus
number.
Starting PIRQ is A,B,C,D.
Bus 2, Device 7 satisfies search criteria. Rotate (A,B,C,D) left by device
  7 modulo 4 giving (D,A,B,C).
Bus 4, Device 2 satisfies search criteria. Rotate (D,A,B,C) left by 2 giving
  (B,C,D,A).
No other busses match criteria. Device to be programmed is Bus 5, Device 1.
Rotate (B,C,D,A) by 1 giving C,D,A,B. Translated PIRQ is C.

*/
  UINTN    LocalBus;
  UINTN    LocalDevice;
  UINTN    BaseBus;
  UINTN    BaseDevice;
  UINTN    BaseFunction;
  UINT8    LocalPirqIndex;
  BOOLEAN  BaseIndexFlag;
  UINTN    BridgeIndex;
  UINTN    SBridgeIndex;

  BaseIndexFlag = FALSE;
  BridgeIndex   = 0x00;

  LocalPirqIndex = *PirqIndex;
  LocalBus       = *PciBus;
  LocalDevice    = *PciDevice;
  BaseBus        = *PciBus;
  BaseDevice     = *PciDevice;
  BaseFunction   = *PciFunction;

  //
  // LocalPirqIndex list PIRQs in rotated fashion
  // = 0  A,B,C,D
  // = 1  B,C,D,A
  // = 2  C,D,A,B
  // = 3  D,A,B,C
  //

  for (BridgeIndex = 0; BridgeIndex < NumberOfBridges; BridgeIndex++) {
    SBridgeIndex = SortedBridgeIndex[BridgeIndex];
    //
    // Check if device behind this bridge
    //
    if ((LocalBus >= Bridges[SBridgeIndex].SecondaryBus) && (LocalBus <= Bridges[SBridgeIndex].SubordinateBus)) {
      //
      // If BaseIndexFlag = FALSE then have found base bridge, i.e
      // bridge in slot. Save info for use by IRQ routing table.
      //
      if (!BaseIndexFlag) {
        BaseBus       = Bridges[SBridgeIndex].PciBus;
        BaseDevice    = Bridges[SBridgeIndex].PciDevice;
        BaseFunction  = Bridges[SBridgeIndex].PciFunction;
        BaseIndexFlag = TRUE;
      } else {
        LocalPirqIndex = (UINT8)((LocalPirqIndex + (UINT8)Bridges[SBridgeIndex].PciDevice)%4);
      }

      //
      // Check if at device. If not get new PCI location & PIRQ
      //
      if (Bridges[SBridgeIndex].SecondaryBus == (UINT8)LocalBus) {
        //
        // Translate PIRQ
        //
        LocalPirqIndex = (UINT8)((LocalPirqIndex + (UINT8)(LocalDevice)) % 4);
        break;
      }
    }
  }

  //
  // In case we fail to find the Bridge just above us, this is some potential error and we want to warn the user
  //
  if (BridgeIndex >= NumberOfBridges) {
    DEBUG ((DEBUG_ERROR, "Cannot Find IRQ Routing for Bus %d, Device %d, Function %d\n", *PciBus, *PciDevice, *PciFunction));
  }

  *PirqIndex   = LocalPirqIndex;
  *PciBus      = BaseBus;
  *PciDevice   = BaseDevice;
  *PciFunction = BaseFunction;

  return EFI_SUCCESS;
}

/**
  Copy the $PIR table as required.

  @param  Private                Legacy  BIOS Instance data
  @param  RoutingTable           Pointer to IRQ routing table
  @param  RoutingTableEntries    IRQ routing table entries
  @param  PirqTable              Pointer to $PIR table
  @param  PirqTableSize          Length of table

**/
VOID
CopyPirqTable (
  IN  LEGACY_BIOS_INSTANCE         *Private,
  IN EFI_LEGACY_IRQ_ROUTING_ENTRY  *RoutingTable,
  IN UINTN                         RoutingTableEntries,
  IN EFI_LEGACY_PIRQ_TABLE_HEADER  *PirqTable,
  IN UINTN                         PirqTableSize
  )
{
  EFI_IA32_REGISTER_SET  Regs;
  UINT32                 Granularity;

  //
  // Copy $PIR table, if it exists.
  //
  if (PirqTable != NULL) {
    Private->LegacyRegion->UnLock (
                             Private->LegacyRegion,
                             0xE0000,
                             0x20000,
                             &Granularity
                             );

    Private->InternalIrqRoutingTable = RoutingTable;
    Private->NumberIrqRoutingEntries = (UINT16)(RoutingTableEntries);
    ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));

    Regs.X.AX = Legacy16GetTableAddress;
    Regs.X.CX = (UINT16)PirqTableSize;
    //
    // Allocate at F segment according to PCI IRQ Routing Table Specification
    //
    Regs.X.BX = (UINT16)0x1;
    //
    // 16-byte boundary alignment requirement according to
    // PCI IRQ Routing Table Specification
    //
    Regs.X.DX = 0x10;
    Private->LegacyBios.FarCall86 (
                          &Private->LegacyBios,
                          Private->Legacy16CallSegment,
                          Private->Legacy16CallOffset,
                          &Regs,
                          NULL,
                          0
                          );

    Private->Legacy16Table->IrqRoutingTablePointer = (UINT32)(Regs.X.DS * 16 + Regs.X.BX);
    if (Regs.X.AX != 0) {
      DEBUG ((DEBUG_ERROR, "PIRQ table length insufficient - %x\n", PirqTableSize));
    } else {
      DEBUG ((DEBUG_INFO, "PIRQ table in legacy region - %x\n", Private->Legacy16Table->IrqRoutingTablePointer));
      Private->Legacy16Table->IrqRoutingTableLength = (UINT32)PirqTableSize;
      CopyMem (
        (VOID *)(UINTN)Private->Legacy16Table->IrqRoutingTablePointer,
        PirqTable,
        PirqTableSize
        );
    }

    Private->Cpu->FlushDataCache (Private->Cpu, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate);
    Private->LegacyRegion->Lock (
                             Private->LegacyRegion,
                             0xE0000,
                             0x20000,
                             &Granularity
                             );
  }

  Private->PciInterruptLine = TRUE;
  mHandleCount              = 0;
}

/**
  Dump EFI_LEGACY_INSTALL_PCI_HANDLER structure information.

  @param  PciHandle               The pointer to EFI_LEGACY_INSTALL_PCI_HANDLER structure

**/
VOID
DumpPciHandle (
  IN EFI_LEGACY_INSTALL_PCI_HANDLER  *PciHandle
  )
{
  DEBUG ((DEBUG_INFO, "PciBus             - %02x\n", (UINTN)PciHandle->PciBus));
  DEBUG ((DEBUG_INFO, "PciDeviceFun       - %02x\n", (UINTN)PciHandle->PciDeviceFun));
  DEBUG ((DEBUG_INFO, "PciSegment         - %02x\n", (UINTN)PciHandle->PciSegment));
  DEBUG ((DEBUG_INFO, "PciClass           - %02x\n", (UINTN)PciHandle->PciClass));
  DEBUG ((DEBUG_INFO, "PciSubclass        - %02x\n", (UINTN)PciHandle->PciSubclass));
  DEBUG ((DEBUG_INFO, "PciInterface       - %02x\n", (UINTN)PciHandle->PciInterface));

  DEBUG ((DEBUG_INFO, "PrimaryIrq         - %02x\n", (UINTN)PciHandle->PrimaryIrq));
  DEBUG ((DEBUG_INFO, "PrimaryReserved    - %02x\n", (UINTN)PciHandle->PrimaryReserved));
  DEBUG ((DEBUG_INFO, "PrimaryControl     - %04x\n", (UINTN)PciHandle->PrimaryControl));
  DEBUG ((DEBUG_INFO, "PrimaryBase        - %04x\n", (UINTN)PciHandle->PrimaryBase));
  DEBUG ((DEBUG_INFO, "PrimaryBusMaster   - %04x\n", (UINTN)PciHandle->PrimaryBusMaster));

  DEBUG ((DEBUG_INFO, "SecondaryIrq       - %02x\n", (UINTN)PciHandle->SecondaryIrq));
  DEBUG ((DEBUG_INFO, "SecondaryReserved  - %02x\n", (UINTN)PciHandle->SecondaryReserved));
  DEBUG ((DEBUG_INFO, "SecondaryControl   - %04x\n", (UINTN)PciHandle->SecondaryControl));
  DEBUG ((DEBUG_INFO, "SecondaryBase      - %04x\n", (UINTN)PciHandle->SecondaryBase));
  DEBUG ((DEBUG_INFO, "SecondaryBusMaster - %04x\n", (UINTN)PciHandle->SecondaryBusMaster));
  return;
}

/**
  Copy the $PIR table as required.

  @param  Private                Legacy  BIOS Instance data
  @param  PciIo                  Pointer to PCI_IO protocol
  @param  PciIrq                 Pci IRQ number
  @param  PciConfigHeader        Type00 Pci configuration header

**/
VOID
InstallLegacyIrqHandler (
  IN LEGACY_BIOS_INSTANCE  *Private,
  IN EFI_PCI_IO_PROTOCOL   *PciIo,
  IN UINT8                 PciIrq,
  IN PCI_TYPE00            *PciConfigHeader
  )
{
  EFI_IA32_REGISTER_SET     Regs;
  UINT16                    LegMask;
  UINTN                     PciSegment;
  UINTN                     PciBus;
  UINTN                     PciDevice;
  UINTN                     PciFunction;
  EFI_LEGACY_8259_PROTOCOL  *Legacy8259;
  UINT16                    PrimaryMaster;
  UINT16                    SecondaryMaster;
  UINTN                     TempData;
  UINTN                     RegisterAddress;
  UINT32                    Granularity;

  PrimaryMaster   = 0;
  SecondaryMaster = 0;
  Legacy8259      = Private->Legacy8259;
  //
  // Disable interrupt in PIC, in case shared, to prevent an
  // interrupt from occurring.
  //
  Legacy8259->GetMask (
                Legacy8259,
                &LegMask,
                NULL,
                NULL,
                NULL
                );

  LegMask = (UINT16)(LegMask | (UINT16)(1 << PciIrq));

  Legacy8259->SetMask (
                Legacy8259,
                &LegMask,
                NULL,
                NULL,
                NULL
                );

  PciIo->GetLocation (
           PciIo,
           &PciSegment,
           &PciBus,
           &PciDevice,
           &PciFunction
           );
  Private->IntThunk->PciHandler.PciBus       = (UINT8)PciBus;
  Private->IntThunk->PciHandler.PciDeviceFun = (UINT8)((PciDevice << 3) + PciFunction);
  Private->IntThunk->PciHandler.PciSegment   = (UINT8)PciSegment;
  Private->IntThunk->PciHandler.PciClass     = PciConfigHeader->Hdr.ClassCode[2];
  Private->IntThunk->PciHandler.PciSubclass  = PciConfigHeader->Hdr.ClassCode[1];
  Private->IntThunk->PciHandler.PciInterface = PciConfigHeader->Hdr.ClassCode[0];

  //
  // Use native mode base address registers in two cases:
  // 1. Programming Interface (PI) register indicates Primary Controller is
  // in native mode OR
  // 2. PCI device Sub Class Code is not IDE
  //
  Private->IntThunk->PciHandler.PrimaryBusMaster = (UINT16)(PciConfigHeader->Device.Bar[4] & 0xfffc);
  if (((PciConfigHeader->Hdr.ClassCode[0] & 0x01) != 0) || (PciConfigHeader->Hdr.ClassCode[1] != PCI_CLASS_MASS_STORAGE_IDE)) {
    Private->IntThunk->PciHandler.PrimaryIrq     = PciIrq;
    Private->IntThunk->PciHandler.PrimaryBase    = (UINT16)(PciConfigHeader->Device.Bar[0] & 0xfffc);
    Private->IntThunk->PciHandler.PrimaryControl = (UINT16)((PciConfigHeader->Device.Bar[1] & 0xfffc) + 2);
  } else {
    Private->IntThunk->PciHandler.PrimaryIrq     = 14;
    Private->IntThunk->PciHandler.PrimaryBase    = 0x1f0;
    Private->IntThunk->PciHandler.PrimaryControl = 0x3f6;
  }

  //
  // Secondary controller data
  //
  if (Private->IntThunk->PciHandler.PrimaryBusMaster != 0) {
    Private->IntThunk->PciHandler.SecondaryBusMaster = (UINT16)((PciConfigHeader->Device.Bar[4] & 0xfffc) + 8);
    PrimaryMaster                                    = (UINT16)(Private->IntThunk->PciHandler.PrimaryBusMaster + 2);
    SecondaryMaster                                  = (UINT16)(Private->IntThunk->PciHandler.SecondaryBusMaster + 2);

    //
    // Clear pending interrupts in Bus Master registers
    //
    IoWrite16 (PrimaryMaster, 0x04);
    IoWrite16 (SecondaryMaster, 0x04);
  }

  //
  // Use native mode base address registers in two cases:
  // 1. Programming Interface (PI) register indicates Secondary Controller is
  // in native mode OR
  // 2. PCI device Sub Class Code is not IDE
  //
  if (((PciConfigHeader->Hdr.ClassCode[0] & 0x04) != 0) || (PciConfigHeader->Hdr.ClassCode[1] != PCI_CLASS_MASS_STORAGE_IDE)) {
    Private->IntThunk->PciHandler.SecondaryIrq     = PciIrq;
    Private->IntThunk->PciHandler.SecondaryBase    = (UINT16)(PciConfigHeader->Device.Bar[2] & 0xfffc);
    Private->IntThunk->PciHandler.SecondaryControl = (UINT16)((PciConfigHeader->Device.Bar[3] & 0xfffc) + 2);
  } else {
    Private->IntThunk->PciHandler.SecondaryIrq     = 15;
    Private->IntThunk->PciHandler.SecondaryBase    = 0x170;
    Private->IntThunk->PciHandler.SecondaryControl = 0x376;
  }

  //
  // Clear pending interrupts in IDE Command Block Status reg before we
  // Thunk to CSM16 below.  Don't want a pending Interrupt before we
  // install the handlers as wierd corruption would occur and hang system.
  //
  //
  // Read IDE CMD blk status reg to clear out any pending interrupts.
  // Do here for Primary and Secondary IDE channels
  //
  RegisterAddress = (UINT16)Private->IntThunk->PciHandler.PrimaryBase + 0x07;
  IoRead8 (RegisterAddress);
  RegisterAddress = (UINT16)Private->IntThunk->PciHandler.SecondaryBase + 0x07;
  IoRead8 (RegisterAddress);

  Private->IntThunk->PciHandler.PrimaryReserved   = 0;
  Private->IntThunk->PciHandler.SecondaryReserved = 0;
  Private->LegacyRegion->UnLock (
                           Private->LegacyRegion,
                           0xE0000,
                           0x20000,
                           &Granularity
                           );

  Regs.X.AX = Legacy16InstallPciHandler;
  TempData  = (UINTN)&Private->IntThunk->PciHandler;
  Regs.X.ES = EFI_SEGMENT ((UINT32)TempData);
  Regs.X.BX = EFI_OFFSET ((UINT32)TempData);

  DumpPciHandle (&Private->IntThunk->PciHandler);

  Private->LegacyBios.FarCall86 (
                        &Private->LegacyBios,
                        Private->Legacy16CallSegment,
                        Private->Legacy16CallOffset,
                        &Regs,
                        NULL,
                        0
                        );

  Private->Cpu->FlushDataCache (Private->Cpu, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate);
  Private->LegacyRegion->Lock (
                           Private->LegacyRegion,
                           0xE0000,
                           0x20000,
                           &Granularity
                           );
}

/**
  Program the interrupt routing register in all the PCI devices. On a PC AT system
  this register contains the 8259 IRQ vector that matches its PCI interrupt.

  @param  Private                Legacy  BIOS Instance data

  @retval EFI_SUCCESS            Succeed.
  @retval EFI_ALREADY_STARTED    All PCI devices have been processed.

**/
EFI_STATUS
PciProgramAllInterruptLineRegisters (
  IN  LEGACY_BIOS_INSTANCE  *Private
  )
{
  EFI_STATUS                         Status;
  EFI_PCI_IO_PROTOCOL                *PciIo;
  EFI_LEGACY_8259_PROTOCOL           *Legacy8259;
  EFI_LEGACY_INTERRUPT_PROTOCOL      *LegacyInterrupt;
  EFI_LEGACY_BIOS_PLATFORM_PROTOCOL  *LegacyBiosPlatform;
  UINT8                              InterruptPin;
  UINTN                              Index;
  UINTN                              HandleCount;
  EFI_HANDLE                         *HandleBuffer;
  UINTN                              MassStorageHandleCount;
  EFI_HANDLE                         *MassStorageHandleBuffer;
  UINTN                              MassStorageHandleIndex;
  UINT8                              PciIrq;
  UINT16                             Command;
  UINTN                              PciSegment;
  UINTN                              PciBus;
  UINTN                              PciDevice;
  UINTN                              PciFunction;
  EFI_LEGACY_IRQ_ROUTING_ENTRY       *RoutingTable;
  UINTN                              RoutingTableEntries;
  UINT16                             LegMask;
  UINT16                             LegEdgeLevel;
  PCI_TYPE00                         PciConfigHeader;
  EFI_LEGACY_PIRQ_TABLE_HEADER       *PirqTable;
  UINTN                              PirqTableSize;
  UINTN                              Flags;
  HDD_INFO                           *HddInfo;
  UINT64                             Supports;

  //
  // Note - This routine use to return immediately if Private->PciInterruptLine
  //        was true. Routine changed since resets etc can cause not all
  //        PciIo protocols to be registered the first time through.
  // New algorithm is to do the copy $PIR table on first pass and save
  // HandleCount on first pass. If subsequent passes LocateHandleBuffer gives
  // a larger handle count then proceed with body of function else return
  // EFI_ALREADY_STARTED. In addition check if PCI device InterruptLine != 0.
  // If zero then function unprogrammed else skip function.
  //
  Legacy8259         = Private->Legacy8259;
  LegacyInterrupt    = Private->LegacyInterrupt;
  LegacyBiosPlatform = Private->LegacyBiosPlatform;

  LegacyBiosPlatform->GetRoutingTable (
                        Private->LegacyBiosPlatform,
                        (VOID *)&RoutingTable,
                        &RoutingTableEntries,
                        (VOID *)&PirqTable,
                        &PirqTableSize,
                        NULL,
                        NULL
                        );
  CreateBridgeTable (RoutingTable, RoutingTableEntries);

  if (!Private->PciInterruptLine) {
    CopyPirqTable (
      Private,
      RoutingTable,
      RoutingTableEntries,
      PirqTable,
      PirqTableSize
      );
  }

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiPciIoProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  if (HandleCount == mHandleCount) {
    FreePool (HandleBuffer);
    return EFI_ALREADY_STARTED;
  }

  if (mHandleCount == 0x00) {
    mHandleCount = HandleCount;
  }

  for (Index = 0; Index < HandleCount; Index++) {
    //
    // If VGA then only do VGA to allow drives fore time to spin up
    // otherwise assign PCI IRQs to all potential devices.
    //
    if ((mVgaInstallationInProgress) && (HandleBuffer[Index] != mVgaHandle)) {
      continue;
    } else {
      //
      // Force code to go through all handles next time called if video.
      // This will catch case where HandleCount doesn't change but want
      //  to get drive info etc.
      //
      mHandleCount = 0x00;
    }

    Status = gBS->HandleProtocol (
                    HandleBuffer[Index],
                    &gEfiPciIoProtocolGuid,
                    (VOID **)&PciIo
                    );
    ASSERT_EFI_ERROR (Status);

    //
    // Test whether the device can be enabled or not.
    // If it can't be enabled, then just skip it to avoid further operation.
    //
    PciIo->Pci.Read (
                 PciIo,
                 EfiPciIoWidthUint32,
                 0,
                 sizeof (PciConfigHeader) / sizeof (UINT32),
                 &PciConfigHeader
                 );
    Command = PciConfigHeader.Hdr.Command;

    //
    // Note PciIo->Attributes does not program the PCI command register
    //
    Status = PciIo->Attributes (
                      PciIo,
                      EfiPciIoAttributeOperationSupported,
                      0,
                      &Supports
                      );
    if (!EFI_ERROR (Status)) {
      Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
      Status    = PciIo->Attributes (
                           PciIo,
                           EfiPciIoAttributeOperationEnable,
                           Supports,
                           NULL
                           );
    }

    PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x04, 1, &Command);

    if (EFI_ERROR (Status)) {
      continue;
    }

    InterruptPin = PciConfigHeader.Device.InterruptPin;

    if ((InterruptPin != 0) && (PciConfigHeader.Device.InterruptLine == PCI_INT_LINE_UNKNOWN)) {
      PciIo->GetLocation (
               PciIo,
               &PciSegment,
               &PciBus,
               &PciDevice,
               &PciFunction
               );
      //
      // Translate PIRQ index back thru busses to slot bus with InterruptPin
      // zero based
      //
      InterruptPin -= 1;

      Status = GetBaseBus (
                 Private,
                 PciBus,
                 PciDevice,
                 RoutingTable,
                 RoutingTableEntries
                 );

      if (Status == EFI_NOT_FOUND) {
        TranslateBusPirq (
          Private,
          &PciBus,
          &PciDevice,
          &PciFunction,
          &InterruptPin
          );
      }

      //
      // Translate InterruptPin(0-3) into PIRQ
      //
      Status = LegacyBiosPlatform->TranslatePirq (
                                     LegacyBiosPlatform,
                                     PciBus,
                                     (PciDevice << 3),
                                     PciFunction,
                                     &InterruptPin,
                                     &PciIrq
                                     );
      //
      // TranslatePirq() should never fail or we are in trouble
      // If it does return failure status, check your PIRQ routing table to see if some item is missing or incorrect
      //
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "Translate Pirq Failed - Status = %r\n ", Status));
        continue;
      }

      LegacyInterrupt->WritePirq (
                         LegacyInterrupt,
                         InterruptPin,
                         PciIrq
                         );

      //
      // Check if device has an OPROM associated with it.
      // If not invoke special 16-bit function, to allow 16-bit
      // code to install an interrupt handler.
      //
      Status = LegacyBiosCheckPciRom (
                 &Private->LegacyBios,
                 HandleBuffer[Index],
                 NULL,
                 NULL,
                 &Flags
                 );
      if ((EFI_ERROR (Status)) && (PciConfigHeader.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE)) {
        //
        // Device has no OPROM associated with it and is a mass storage
        // device. It needs to have an PCI IRQ handler installed. To
        // correctly install the handler we need to insure device is
        // connected. The device may just have register itself but not
        // been connected. Re-read PCI config space after as it can
        // change
        //
        //
        // Get IDE Handle. If matches handle then skip ConnectController
        // since ConnectController may force native mode and we don't
        // want that for primary IDE controller
        //
        MassStorageHandleCount  = 0;
        MassStorageHandleBuffer = NULL;
        LegacyBiosPlatform->GetPlatformHandle (
                              Private->LegacyBiosPlatform,
                              EfiGetPlatformIdeHandle,
                              0,
                              &MassStorageHandleBuffer,
                              &MassStorageHandleCount,
                              NULL
                              );

        HddInfo = &Private->IntThunk->EfiToLegacy16BootTable.HddInfo[0];

        LegacyBiosBuildIdeData (Private, &HddInfo, 0);
        PciIo->Pci.Read (
                     PciIo,
                     EfiPciIoWidthUint32,
                     0,
                     sizeof (PciConfigHeader) / sizeof (UINT32),
                     &PciConfigHeader
                     );

        for (MassStorageHandleIndex = 0; MassStorageHandleIndex < MassStorageHandleCount; MassStorageHandleIndex++) {
          if (MassStorageHandleBuffer[MassStorageHandleIndex] == HandleBuffer[Index]) {
            //
            // InstallLegacyIrqHandler according to Platform requirement
            //
            InstallLegacyIrqHandler (
              Private,
              PciIo,
              PciIrq,
              &PciConfigHeader
              );
            break;
          }
        }
      }

      //
      // Write InterruptPin and enable 8259.
      //
      PciIo->Pci.Write (
                   PciIo,
                   EfiPciIoWidthUint8,
                   0x3c,
                   1,
                   &PciIrq
                   );
      Private->IntThunk->EfiToLegacy16BootTable.PciIrqMask = (UINT16)(Private->IntThunk->EfiToLegacy16BootTable.PciIrqMask | (UINT16)(1 << PciIrq));

      Legacy8259->GetMask (
                    Legacy8259,
                    &LegMask,
                    &LegEdgeLevel,
                    NULL,
                    NULL
                    );

      LegMask      = (UINT16)(LegMask & (UINT16) ~(1 << PciIrq));
      LegEdgeLevel = (UINT16)(LegEdgeLevel | (UINT16)(1 << PciIrq));
      Legacy8259->SetMask (
                    Legacy8259,
                    &LegMask,
                    &LegEdgeLevel,
                    NULL,
                    NULL
                    );
    }
  }

  FreePool (HandleBuffer);
  return EFI_SUCCESS;
}

/**
  Find & verify PnP Expansion header in ROM image

  @param  Private                Protocol instance pointer.
  @param  FirstHeader            1 = Find first header, 0 = Find successive headers
  @param  PnpPtr                 Input Rom start if FirstHeader =1, Current Header
                                 otherwise Output Next header, if it exists

  @retval EFI_SUCCESS            Next Header found at BasePnpPtr
  @retval EFI_NOT_FOUND          No more headers

**/
EFI_STATUS
FindNextPnpExpansionHeader (
  IN  LEGACY_BIOS_INSTANCE            *Private,
  IN BOOLEAN                          FirstHeader,
  IN OUT LEGACY_PNP_EXPANSION_HEADER  **PnpPtr

  )
{
  UINTN                        TempData;
  LEGACY_PNP_EXPANSION_HEADER  *LocalPnpPtr;

  LocalPnpPtr = *PnpPtr;
  if (FirstHeader == FIRST_INSTANCE) {
    mBasePnpPtr    = LocalPnpPtr;
    mBbsRomSegment = (UINT16)((UINTN)mBasePnpPtr >> 4);
    //
    // Offset 0x1a gives offset to PnP expansion header for the first
    // instance, there after the structure gives the offset to the next
    // structure
    //
    LocalPnpPtr = (LEGACY_PNP_EXPANSION_HEADER *)((UINT8 *)LocalPnpPtr + 0x1a);
    TempData    = (*((UINT16 *)LocalPnpPtr));
  } else {
    TempData = (UINT16)LocalPnpPtr->NextHeader;
  }

  LocalPnpPtr = (LEGACY_PNP_EXPANSION_HEADER *)(((UINT8 *)mBasePnpPtr + TempData));

  //
  // Search for PnP table in Shadowed ROM
  //
  *PnpPtr = LocalPnpPtr;
  if (*(UINT32 *)LocalPnpPtr == SIGNATURE_32 ('$', 'P', 'n', 'P')) {
    return EFI_SUCCESS;
  } else {
    return EFI_NOT_FOUND;
  }
}

/**
  Update list of Bev or BCV table entries.

  @param  Private                Protocol instance pointer.
  @param  RomStart               Table of ROM start address in RAM/ROM. PciIo  _
                                 Handle to PCI IO for this device
  @param  PciIo                  Instance of PCI I/O Protocol

  @retval EFI_SUCCESS            Always should succeed.

**/
EFI_STATUS
UpdateBevBcvTable (
  IN  LEGACY_BIOS_INSTANCE             *Private,
  IN  EFI_LEGACY_EXPANSION_ROM_HEADER  *RomStart,
  IN  EFI_PCI_IO_PROTOCOL              *PciIo
  )
{
  VOID                             *RomEnd;
  BBS_TABLE                        *BbsTable;
  UINTN                            BbsIndex;
  EFI_LEGACY_EXPANSION_ROM_HEADER  *PciPtr;
  LEGACY_PNP_EXPANSION_HEADER      *PnpPtr;
  BOOLEAN                          Instance;
  EFI_STATUS                       Status;
  UINTN                            Segment;
  UINTN                            Bus;
  UINTN                            Device;
  UINTN                            Function;
  UINT8                            Class;
  UINT16                           DeviceType;

  Segment    = 0;
  Bus        = 0;
  Device     = 0;
  Function   = 0;
  Class      = 0;
  DeviceType = BBS_UNKNOWN;

  //
  // Skip floppy and 2*onboard IDE controller entries(Master/Slave per
  // controller).
  //
  BbsIndex = Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries;

  BbsTable = (BBS_TABLE *)(UINTN)Private->IntThunk->EfiToLegacy16BootTable.BbsTable;
  PnpPtr   = (LEGACY_PNP_EXPANSION_HEADER *)RomStart;
  PciPtr   = (EFI_LEGACY_EXPANSION_ROM_HEADER *)RomStart;

  RomEnd   = (VOID *)(PciPtr->Size512 * 512 + (UINTN)PciPtr);
  Instance = FIRST_INSTANCE;
  //
  // OPROMs like PXE may not be tied to a piece of hardware and thus
  // don't have a PciIo associated with them
  //
  if (PciIo != NULL) {
    PciIo->GetLocation (
             PciIo,
             &Segment,
             &Bus,
             &Device,
             &Function
             );
    PciIo->Pci.Read (
                 PciIo,
                 EfiPciIoWidthUint8,
                 0x0b,
                 1,
                 &Class
                 );

    if (Class == PCI_CLASS_MASS_STORAGE) {
      DeviceType = BBS_HARDDISK;
    } else {
      if (Class == PCI_CLASS_NETWORK) {
        DeviceType = BBS_EMBED_NETWORK;
      }
    }
  }

  while (TRUE) {
    Status   = FindNextPnpExpansionHeader (Private, Instance, &PnpPtr);
    Instance = NOT_FIRST_INSTANCE;
    if (EFI_ERROR (Status)) {
      break;
    }

    //
    // There can be additional $PnP headers within the OPROM.
    // Example: SCSI can have one per drive.
    //
    BbsTable[BbsIndex].BootPriority             = BBS_UNPRIORITIZED_ENTRY;
    BbsTable[BbsIndex].DeviceType               = DeviceType;
    BbsTable[BbsIndex].Bus                      = (UINT32)Bus;
    BbsTable[BbsIndex].Device                   = (UINT32)Device;
    BbsTable[BbsIndex].Function                 = (UINT32)Function;
    BbsTable[BbsIndex].StatusFlags.OldPosition  = 0;
    BbsTable[BbsIndex].StatusFlags.Reserved1    = 0;
    BbsTable[BbsIndex].StatusFlags.Enabled      = 0;
    BbsTable[BbsIndex].StatusFlags.Failed       = 0;
    BbsTable[BbsIndex].StatusFlags.MediaPresent = 0;
    BbsTable[BbsIndex].StatusFlags.Reserved2    = 0;
    BbsTable[BbsIndex].Class                    = PnpPtr->Class;
    BbsTable[BbsIndex].SubClass                 = PnpPtr->SubClass;
    BbsTable[BbsIndex].DescStringOffset         = PnpPtr->ProductNamePointer;
    BbsTable[BbsIndex].DescStringSegment        = mBbsRomSegment;
    BbsTable[BbsIndex].MfgStringOffset          = PnpPtr->MfgPointer;
    BbsTable[BbsIndex].MfgStringSegment         = mBbsRomSegment;
    BbsTable[BbsIndex].BootHandlerSegment       = mBbsRomSegment;

    //
    // Have seen case where PXE base code have PnP expansion ROM
    // header but no Bcv or Bev vectors.
    //
    if (PnpPtr->Bcv != 0) {
      BbsTable[BbsIndex].BootHandlerOffset = PnpPtr->Bcv;
      ++BbsIndex;
    }

    if (PnpPtr->Bev != 0) {
      BbsTable[BbsIndex].BootHandlerOffset = PnpPtr->Bev;
      BbsTable[BbsIndex].DeviceType        = BBS_BEV_DEVICE;
      ++BbsIndex;
    }

    if ((PnpPtr == (LEGACY_PNP_EXPANSION_HEADER *)PciPtr) || (PnpPtr > (LEGACY_PNP_EXPANSION_HEADER *)RomEnd)) {
      break;
    }
  }

  BbsTable[BbsIndex].BootPriority                            = BBS_IGNORE_ENTRY;
  Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries = (UINT32)BbsIndex;
  return EFI_SUCCESS;
}

/**
  Shadow all the PCI legacy ROMs. Use data from the Legacy BIOS Protocol
  to chose the order. Skip any devices that have already have legacy
  BIOS run.

  @param  Private                Protocol instance pointer.

  @retval EFI_SUCCESS            Succeed.
  @retval EFI_UNSUPPORTED        Cannot get VGA device handle.

**/
EFI_STATUS
PciShadowRoms (
  IN  LEGACY_BIOS_INSTANCE  *Private
  )
{
  EFI_STATUS           Status;
  EFI_PCI_IO_PROTOCOL  *PciIo;
  PCI_TYPE00           Pci;
  UINTN                Index;
  UINTN                HandleCount;
  EFI_HANDLE           *HandleBuffer;
  EFI_HANDLE           VgaHandle;
  EFI_HANDLE           FirstHandle;
  VOID                 **RomStart;
  UINTN                Flags;
  PCI_TYPE00           PciConfigHeader;
  UINT16               *Command;
  UINT64               Supports;

  //
  // Make the VGA device first
  //
  Status = Private->LegacyBiosPlatform->GetPlatformHandle (
                                          Private->LegacyBiosPlatform,
                                          EfiGetPlatformVgaHandle,
                                          0,
                                          &HandleBuffer,
                                          &HandleCount,
                                          NULL
                                          );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  VgaHandle = HandleBuffer[0];

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiPciIoProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Place the VGA handle as first.
  //
  for (Index = 0; Index < HandleCount; Index++) {
    if (HandleBuffer[Index] == VgaHandle) {
      FirstHandle         = HandleBuffer[0];
      HandleBuffer[0]     = HandleBuffer[Index];
      HandleBuffer[Index] = FirstHandle;
      break;
    }
  }

  //
  // Allocate memory to save Command WORD from each device. We do this
  // to restore devices to same state as EFI after switching to legacy.
  //
  Command = (UINT16 *)AllocatePool (
                        sizeof (UINT16) * (HandleCount + 1)
                        );
  if (NULL == Command) {
    FreePool (HandleBuffer);
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Disconnect all EFI devices first. This covers cases where alegacy BIOS
  // may control multiple PCI devices.
  //
  for (Index = 0; Index < HandleCount; Index++) {
    Status = gBS->HandleProtocol (
                    HandleBuffer[Index],
                    &gEfiPciIoProtocolGuid,
                    (VOID **)&PciIo
                    );
    ASSERT_EFI_ERROR (Status);

    //
    // Save command register for "connect" loop
    //
    PciIo->Pci.Read (
                 PciIo,
                 EfiPciIoWidthUint32,
                 0,
                 sizeof (PciConfigHeader) / sizeof (UINT32),
                 &PciConfigHeader
                 );
    Command[Index] = PciConfigHeader.Hdr.Command;
    //
    // Skip any device that already has a legacy ROM run
    //
    Status = IsLegacyRom (HandleBuffer[Index]);
    if (!EFI_ERROR (Status)) {
      continue;
    }

    //
    // Stop EFI Drivers with oprom.
    //
    gBS->DisconnectController (
           HandleBuffer[Index],
           NULL,
           NULL
           );
  }

  //
  // For every device that has not had a legacy ROM started. Start a legacy ROM.
  //
  for (Index = 0; Index < HandleCount; Index++) {
    Status = gBS->HandleProtocol (
                    HandleBuffer[Index],
                    &gEfiPciIoProtocolGuid,
                    (VOID **)&PciIo
                    );

    ASSERT_EFI_ERROR (Status);

    //
    // Here make sure if one VGA have been shadowed,
    // then wil not shadowed another one.
    //
    PciIo->Pci.Read (
                 PciIo,
                 EfiPciIoWidthUint32,
                 0,
                 sizeof (Pci) / sizeof (UINT32),
                 &Pci
                 );

    //
    // Only one Video OPROM can be given control in BIOS phase. If there are multiple Video devices,
    // one will work in legacy mode (OPROM will be given control) and
    // other Video devices will work in native mode (OS driver will handle these devices).
    //
    if (IS_PCI_DISPLAY (&Pci) && (Index != 0)) {
      continue;
    }

    //
    // Skip any device that already has a legacy ROM run
    //
    Status = IsLegacyRom (HandleBuffer[Index]);
    if (!EFI_ERROR (Status)) {
      continue;
    }

    //
    // If legacy VBIOS Oprom has not been dispatched before, install legacy VBIOS here.
    //
    if (IS_PCI_DISPLAY (&Pci) && (Index == 0)) {
      Status = LegacyBiosInstallVgaRom (Private);
      //
      // A return status of EFI_NOT_FOUND is considered valid (No EFI
      // driver is controlling video).
      //
      ASSERT ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND));
      continue;
    }

    //
    // Install legacy ROM
    //
    Status = LegacyBiosInstallPciRom (
               &Private->LegacyBios,
               HandleBuffer[Index],
               NULL,
               &Flags,
               NULL,
               NULL,
               (VOID **)&RomStart,
               NULL
               );
    if (EFI_ERROR (Status)) {
      if (!((Status == EFI_UNSUPPORTED) && (Flags == NO_ROM))) {
        continue;
      }
    }

    //
    // Restore Command register so legacy has same devices enabled or disabled
    // as EFI.
    // If Flags = NO_ROM use command register as is. This covers the
    //            following cases:
    //              Device has no ROMs associated with it.
    //              Device has ROM associated with it but was already
    //              installed.
    //          = ROM_FOUND but not VALID_LEGACY_ROM, disable it.
    //          = ROM_FOUND and VALID_LEGACY_ROM, enable it.
    //
    if ((Flags & ROM_FOUND) == ROM_FOUND) {
      if ((Flags & VALID_LEGACY_ROM) == 0) {
        Command[Index] = 0;
      } else {
        //
        // For several VGAs, only one of them can be enabled.
        //
        Status = PciIo->Attributes (
                          PciIo,
                          EfiPciIoAttributeOperationSupported,
                          0,
                          &Supports
                          );
        if (!EFI_ERROR (Status)) {
          Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
          Status    = PciIo->Attributes (
                               PciIo,
                               EfiPciIoAttributeOperationEnable,
                               Supports,
                               NULL
                               );
        }

        if (!EFI_ERROR (Status)) {
          Command[Index] = 0x1f;
        }
      }
    }

    PciIo->Pci.Write (
                 PciIo,
                 EfiPciIoWidthUint16,
                 0x04,
                 1,
                 &Command[Index]
                 );
  }

  FreePool (Command);
  FreePool (HandleBuffer);
  return EFI_SUCCESS;
}

/**
  Test to see if a legacy PCI ROM exists for this device. Optionally return
  the Legacy ROM instance for this PCI device.

  @param  This                   Protocol instance pointer.
  @param  PciHandle              The PCI PC-AT OPROM from this devices ROM BAR will
                                 be loaded
  @param  RomImage               Return the legacy PCI ROM for this device
  @param  RomSize                Size of ROM Image
  @param  Flags                  Indicates if ROM found and if PC-AT.

  @retval EFI_SUCCESS            Legacy Option ROM available for this device
  @retval EFI_UNSUPPORTED        Legacy Option ROM not supported.

**/
EFI_STATUS
EFIAPI
LegacyBiosCheckPciRom (
  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
  IN  EFI_HANDLE               PciHandle,
  OUT VOID                     **RomImage  OPTIONAL,
  OUT UINTN                    *RomSize  OPTIONAL,
  OUT UINTN                    *Flags
  )
{
  return LegacyBiosCheckPciRomEx (
           This,
           PciHandle,
           RomImage,
           RomSize,
           NULL,
           Flags,
           NULL,
           NULL
           );
}

/**

  Routine Description:
    Test to see if a legacy PCI ROM exists for this device. Optionally return
    the Legacy ROM instance for this PCI device.

    @param[in] This          Protocol instance pointer.
    @param[in] PciHandle               The PCI PC-AT OPROM from this devices ROM BAR will be loaded
    @param[out] RomImage               Return the legacy PCI ROM for this device
    @param[out] RomSize                Size of ROM Image
    @param[out] RuntimeImageLength     Runtime size of ROM Image
    @param[out] Flags                  Indicates if ROM found and if PC-AT.
    @param[out] OpromRevision          Revision of the PCI Rom
    @param[out] ConfigUtilityCodeHeaderPointer of Configuration Utility Code Header

    @return EFI_SUCCESS            Legacy Option ROM available for this device
    @return EFI_ALREADY_STARTED    This device is already managed by its Oprom
    @return EFI_UNSUPPORTED        Legacy Option ROM not supported.

**/
EFI_STATUS
LegacyBiosCheckPciRomEx (
  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
  IN  EFI_HANDLE               PciHandle,
  OUT VOID                     **RomImage  OPTIONAL,
  OUT UINTN                    *RomSize  OPTIONAL,
  OUT UINTN                    *RuntimeImageLength  OPTIONAL,
  OUT UINTN                    *Flags  OPTIONAL,
  OUT UINT8                    *OpromRevision  OPTIONAL,
  OUT VOID                     **ConfigUtilityCodeHeader OPTIONAL
  )
{
  EFI_STATUS            Status;
  LEGACY_BIOS_INSTANCE  *Private;
  EFI_PCI_IO_PROTOCOL   *PciIo;
  UINTN                 LocalRomSize;
  VOID                  *LocalRomImage;
  PCI_TYPE00            PciConfigHeader;
  VOID                  *LocalConfigUtilityCodeHeader;

  LocalConfigUtilityCodeHeader = NULL;
  *Flags                       = NO_ROM;
  Status                       = gBS->HandleProtocol (
                                        PciHandle,
                                        &gEfiPciIoProtocolGuid,
                                        (VOID **)&PciIo
                                        );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  //
  // See if the option ROM for PciHandle has already been executed
  //
  Status = IsLegacyRom (PciHandle);
  if (!EFI_ERROR (Status)) {
    *Flags |= (UINTN)(ROM_FOUND | VALID_LEGACY_ROM);
    return EFI_SUCCESS;
  }

  //
  // Check for PCI ROM Bar
  //
  LocalRomSize  = (UINTN)PciIo->RomSize;
  LocalRomImage = PciIo->RomImage;
  if (LocalRomSize != 0) {
    *Flags |= ROM_FOUND;
  }

  //
  // PCI specification states you should check VendorId and Device Id.
  //
  PciIo->Pci.Read (
               PciIo,
               EfiPciIoWidthUint32,
               0,
               sizeof (PciConfigHeader) / sizeof (UINT32),
               &PciConfigHeader
               );

  Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This);
  Status  = GetPciLegacyRom (
              Private->Csm16PciInterfaceVersion,
              PciConfigHeader.Hdr.VendorId,
              PciConfigHeader.Hdr.DeviceId,
              &LocalRomImage,
              &LocalRomSize,
              RuntimeImageLength,
              OpromRevision,
              &LocalConfigUtilityCodeHeader
              );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  *Flags |= VALID_LEGACY_ROM;

  //
  // See if Configuration Utility Code Header valid
  //
  if (LocalConfigUtilityCodeHeader != NULL) {
    *Flags |= ROM_WITH_CONFIG;
  }

  if (ConfigUtilityCodeHeader != NULL) {
    *ConfigUtilityCodeHeader = LocalConfigUtilityCodeHeader;
  }

  if (RomImage != NULL) {
    *RomImage = LocalRomImage;
  }

  if (RomSize != NULL) {
    *RomSize = LocalRomSize;
  }

  return EFI_SUCCESS;
}

/**
  Load a legacy PC-AT OPROM on the PciHandle device. Return information
  about how many disks were added by the OPROM and the shadow address and
  size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C:

  @retval EFI_SUCCESS   Legacy ROM loaded for this device
  @retval EFI_NOT_FOUND No PS2 Keyboard found

**/
EFI_STATUS
EnablePs2Keyboard (
  VOID
  )
{
  EFI_STATUS           Status;
  EFI_HANDLE           *HandleBuffer;
  UINTN                HandleCount;
  EFI_ISA_IO_PROTOCOL  *IsaIo;
  UINTN                Index;

  //
  // Get SimpleTextIn and find PS2 controller
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiSimpleTextInProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  for (Index = 0; Index < HandleCount; Index++) {
    //
    // Open the IO Abstraction(s) needed to perform the supported test
    //
    Status = gBS->OpenProtocol (
                    HandleBuffer[Index],
                    &gEfiIsaIoProtocolGuid,
                    (VOID **)&IsaIo,
                    NULL,
                    HandleBuffer[Index],
                    EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
                    );

    if (!EFI_ERROR (Status)) {
      //
      // Use the ISA I/O Protocol to see if Controller is the Keyboard
      // controller
      //
      if ((IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x303)) || (IsaIo->ResourceList->Device.UID != 0)) {
        Status = EFI_UNSUPPORTED;
      }

      gBS->CloseProtocol (
             HandleBuffer[Index],
             &gEfiIsaIoProtocolGuid,
             NULL,
             HandleBuffer[Index]
             );
    }

    if (!EFI_ERROR (Status)) {
      gBS->ConnectController (HandleBuffer[Index], NULL, NULL, FALSE);
    }
  }

  FreePool (HandleBuffer);
  return EFI_SUCCESS;
}

/**
  Load a legacy PC-AT OpROM for VGA controller.

  @param  Private                Driver private data.

  @retval EFI_SUCCESS            Legacy ROM successfully installed for this device.
  @retval EFI_DEVICE_ERROR       No VGA device handle found, or native EFI video
                                 driver cannot be successfully disconnected, or VGA
                                 thunk driver cannot be successfully connected.

**/
EFI_STATUS
LegacyBiosInstallVgaRom (
  IN  LEGACY_BIOS_INSTANCE  *Private
  )
{
  EFI_STATUS                           Status;
  EFI_HANDLE                           VgaHandle;
  UINTN                                HandleCount;
  EFI_HANDLE                           *HandleBuffer;
  EFI_HANDLE                           *ConnectHandleBuffer;
  EFI_PCI_IO_PROTOCOL                  *PciIo;
  PCI_TYPE00                           PciConfigHeader;
  UINT64                               Supports;
  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfoBuffer;
  UINTN                                EntryCount;
  UINTN                                Index;
  VOID                                 *Interface;

  //
  // EfiLegacyBiosGuild attached to a device implies that there is a legacy
  // BIOS associated with that device.
  //
  // There are 3 cases to consider.
  //   Case 1: No EFI driver is controlling the video.
  //     Action: Return EFI_SUCCESS from DisconnectController, search
  //             video thunk driver, and connect it.
  //   Case 2: EFI driver is controlling the video and EfiLegacyBiosGuid is
  //           not on the image handle.
  //     Action: Disconnect EFI driver.
  //             ConnectController for video thunk
  //   Case 3: EFI driver is controlling the video and EfiLegacyBiosGuid is
  //           on the image handle.
  //     Action: Do nothing and set Private->VgaInstalled = TRUE.
  //             Then this routine is not called any more.
  //
  //
  // Get the VGA device.
  //
  Status = Private->LegacyBiosPlatform->GetPlatformHandle (
                                          Private->LegacyBiosPlatform,
                                          EfiGetPlatformVgaHandle,
                                          0,
                                          &HandleBuffer,
                                          &HandleCount,
                                          NULL
                                          );
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  VgaHandle = HandleBuffer[0];

  //
  // Check whether video thunk driver already starts.
  //
  Status = gBS->OpenProtocolInformation (
                  VgaHandle,
                  &gEfiPciIoProtocolGuid,
                  &OpenInfoBuffer,
                  &EntryCount
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  for (Index = 0; Index < EntryCount; Index++) {
    if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
      Status = gBS->HandleProtocol (
                      OpenInfoBuffer[Index].AgentHandle,
                      &gEfiLegacyBiosGuid,
                      (VOID **)&Interface
                      );
      if (!EFI_ERROR (Status)) {
        //
        // This should be video thunk driver which is managing video device
        // So it need not start again
        //
        DEBUG ((DEBUG_INFO, "Video thunk driver already start! Return!\n"));
        Private->VgaInstalled = TRUE;
        return EFI_SUCCESS;
      }
    }
  }

  //
  // Kick off the native EFI driver
  //
  Status = gBS->DisconnectController (
                  VgaHandle,
                  NULL,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    if (Status != EFI_NOT_FOUND) {
      return EFI_DEVICE_ERROR;
    } else {
      return Status;
    }
  }

  //
  // Find all the Thunk Driver
  //
  HandleBuffer = NULL;
  Status       = gBS->LocateHandleBuffer (
                        ByProtocol,
                        &gEfiLegacyBiosGuid,
                        NULL,
                        &HandleCount,
                        &HandleBuffer
                        );
  ASSERT_EFI_ERROR (Status);
  ConnectHandleBuffer = (EFI_HANDLE *)AllocatePool (sizeof (EFI_HANDLE) * (HandleCount + 1));
  ASSERT (ConnectHandleBuffer != NULL);

  CopyMem (
    ConnectHandleBuffer,
    HandleBuffer,
    sizeof (EFI_HANDLE) * HandleCount
    );
  ConnectHandleBuffer[HandleCount] = NULL;

  FreePool (HandleBuffer);

  //
  // Enable the device and make sure VGA cycles are being forwarded to this VGA device
  //
  Status = gBS->HandleProtocol (
                  VgaHandle,
                  &gEfiPciIoProtocolGuid,
                  (VOID **)&PciIo
                  );
  ASSERT_EFI_ERROR (Status);
  PciIo->Pci.Read (
               PciIo,
               EfiPciIoWidthUint32,
               0,
               sizeof (PciConfigHeader) / sizeof (UINT32),
               &PciConfigHeader
               );

  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationSupported,
                    0,
                    &Supports
                    );
  if (!EFI_ERROR (Status)) {
    Supports &= (UINT64)(EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | \
                         EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16);
    Status = PciIo->Attributes (
                      PciIo,
                      EfiPciIoAttributeOperationEnable,
                      Supports,
                      NULL
                      );
  }

  if (Status == EFI_SUCCESS) {
    Private->VgaInstalled = TRUE;

    //
    // Attach the VGA thunk driver.
    // Assume the video is installed. This prevents potential of infinite recursion.
    //
    Status = gBS->ConnectController (
                    VgaHandle,
                    ConnectHandleBuffer,
                    NULL,
                    TRUE
                    );
  }

  FreePool (ConnectHandleBuffer);

  if (EFI_ERROR (Status)) {
    Private->VgaInstalled = FALSE;

    //
    // Reconnect the EFI VGA driver.
    //
    gBS->ConnectController (VgaHandle, NULL, NULL, TRUE);
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

/**
  Load a legacy PC-AT OpROM.

  @param  This                              Protocol instance pointer.
  @param  Private                          Driver's private data.
  @param  PciHandle                      The EFI handle for the PCI device. It could be
                                                    NULL if the  OpROM image is not associated with
                                                    any device.
  @param  OpromRevision              The revision of PCI PC-AT ROM image.
  @param  RomImage                    Pointer to PCI PC-AT ROM image header. It must not
                                                    be NULL.
  @param  ImageSize                     Size of the PCI PC-AT ROM image.
  @param  RuntimeImageLength      On input is the max runtime image length indicated by the PCIR structure
                                                    On output is the actual runtime image length
  @param  DiskStart                       Disk number of first device hooked by the ROM. If
                                                    DiskStart is the same as DiskEnd no disked were
                                                    hooked.
  @param  DiskEnd                         Disk number of the last device hooked by the ROM.
  @param  RomShadowAddress       Shadow address of PC-AT ROM

  @retval EFI_SUCCESS            Legacy ROM loaded for this device
  @retval EFI_OUT_OF_RESOURCES   No more space for this ROM

**/
EFI_STATUS
EFIAPI
LegacyBiosInstallRom (
  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
  IN LEGACY_BIOS_INSTANCE      *Private,
  IN EFI_HANDLE                PciHandle,
  IN UINT8                     OpromRevision,
  IN VOID                      *RomImage,
  IN UINTN                     ImageSize,
  IN OUT UINTN                 *RuntimeImageLength,
  OUT UINT8                    *DiskStart  OPTIONAL,
  OUT UINT8                    *DiskEnd  OPTIONAL,
  OUT VOID                     **RomShadowAddress OPTIONAL
  )
{
  EFI_STATUS             Status;
  EFI_STATUS             PciEnableStatus;
  EFI_PCI_IO_PROTOCOL    *PciIo;
  UINT8                  LocalDiskStart;
  UINT8                  LocalDiskEnd;
  UINTN                  Segment;
  UINTN                  Bus;
  UINTN                  Device;
  UINTN                  Function;
  EFI_IA32_REGISTER_SET  Regs;
  UINT8                  VideoMode;
  UINT8                  OldVideoMode;
  EFI_TIME               BootTime;
  UINT32                 *BdaPtr;
  UINT32                 LocalTime;
  UINT32                 StartBbsIndex;
  UINT32                 EndBbsIndex;
  UINT32                 MaxRomAddr;
  UINTN                  TempData;
  UINTN                  InitAddress;
  UINTN                  RuntimeAddress;
  EFI_PHYSICAL_ADDRESS   PhysicalAddress;
  UINT32                 Granularity;

  PciIo           = NULL;
  LocalDiskStart  = 0;
  LocalDiskEnd    = 0;
  Segment         = 0;
  Bus             = 0;
  Device          = 0;
  Function        = 0;
  VideoMode       = 0;
  OldVideoMode    = 0;
  PhysicalAddress = 0;
  MaxRomAddr      = PcdGet32 (PcdEndOpromShadowAddress);

  if ((Private->Legacy16Table->TableLength >= OFFSET_OF (EFI_COMPATIBILITY16_TABLE, HiPermanentMemoryAddress)) &&
      (Private->Legacy16Table->UmaAddress != 0) &&
      (Private->Legacy16Table->UmaSize != 0) &&
      (MaxRomAddr > (Private->Legacy16Table->UmaAddress)))
  {
    MaxRomAddr = Private->Legacy16Table->UmaAddress;
  }

  PciProgramAllInterruptLineRegisters (Private);

  if ((OpromRevision >= 3) && (Private->Csm16PciInterfaceVersion >= 0x0300)) {
    //
    // CSM16 3.0 meets PCI 3.0 OpROM
    //   first test if there is enough space for its INIT code
    //
    PhysicalAddress = CONVENTIONAL_MEMORY_TOP;
    Status          = gBS->AllocatePages (
                             AllocateMaxAddress,
                             EfiBootServicesCode,
                             EFI_SIZE_TO_PAGES (ImageSize),
                             &PhysicalAddress
                             );

    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "return LegacyBiosInstallRom(%d): EFI_OUT_OF_RESOURCES (no more space for OpROM)\n", DEBUG_LINE_NUMBER));
      //
      // Report Status Code to indicate that there is no enough space for OpROM
      //
      REPORT_STATUS_CODE (
        EFI_ERROR_CODE | EFI_ERROR_MINOR,
        (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE)
        );
      return EFI_OUT_OF_RESOURCES;
    }

    InitAddress = (UINTN)PhysicalAddress;
    //
    //   then test if there is enough space for its RT code
    //
    RuntimeAddress = Private->OptionRom;
    if (RuntimeAddress + *RuntimeImageLength > MaxRomAddr) {
      DEBUG ((DEBUG_ERROR, "return LegacyBiosInstallRom(%d): EFI_OUT_OF_RESOURCES (no more space for OpROM)\n", DEBUG_LINE_NUMBER));
      gBS->FreePages (PhysicalAddress, EFI_SIZE_TO_PAGES (ImageSize));
      //
      // Report Status Code to indicate that there is no enough space for OpROM
      //
      REPORT_STATUS_CODE (
        EFI_ERROR_CODE | EFI_ERROR_MINOR,
        (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE)
        );
      return EFI_OUT_OF_RESOURCES;
    }
  } else {
    // CSM16 3.0 meets PCI 2.x OpROM
    // CSM16 2.x meets PCI 2.x/3.0 OpROM
    //   test if there is enough space for its INIT code
    //
    InitAddress = PCI_START_ADDRESS (Private->OptionRom);
    if (InitAddress + ImageSize > MaxRomAddr) {
      DEBUG ((DEBUG_ERROR, "return LegacyBiosInstallRom(%d): EFI_OUT_OF_RESOURCES (no more space for OpROM)\n", DEBUG_LINE_NUMBER));
      //
      // Report Status Code to indicate that there is no enough space for OpROM
      //
      REPORT_STATUS_CODE (
        EFI_ERROR_CODE | EFI_ERROR_MINOR,
        (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE)
        );
      return EFI_OUT_OF_RESOURCES;
    }

    RuntimeAddress = InitAddress;
  }

  Private->LegacyRegion->UnLock (
                           Private->LegacyRegion,
                           0xE0000,
                           0x20000,
                           &Granularity
                           );

  Private->LegacyRegion->UnLock (
                           Private->LegacyRegion,
                           (UINT32)RuntimeAddress,
                           (UINT32)ImageSize,
                           &Granularity
                           );

  DEBUG ((DEBUG_INFO, " Shadowing OpROM init/runtime/isize = %x/%x/%x\n", InitAddress, RuntimeAddress, ImageSize));

  CopyMem ((VOID *)InitAddress, RomImage, ImageSize);

  //
  // Read the highest disk number "installed: and assume a new disk will
  // show up on the first drive past the current value.
  // There are several considerations here:
  // 1. Non-BBS compliant drives will change 40:75 but 16-bit CSM will undo
  //    the change until boot selection time frame.
  // 2. BBS compliants drives will not change 40:75 until boot time.
  // 3. Onboard IDE controllers will change 40:75
  //
  ACCESS_PAGE0_CODE (
    LocalDiskStart = (UINT8)((*(UINT8 *)((UINTN)0x475)) + 0x80);
    if ((Private->Disk4075 + 0x80) < LocalDiskStart) {
    //
    // Update table since onboard IDE drives found
    //
    Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciSegment       = 0xff;
    Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciBus           = 0xff;
    Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciDevice        = 0xff;
    Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciFunction      = 0xff;
    Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].StartDriveNumber = (UINT8)(Private->Disk4075 + 0x80);
    Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].EndDriveNumber   = LocalDiskStart;
    Private->LegacyEfiHddTableIndex++;
    Private->Disk4075 = (UINT8)(LocalDiskStart & 0x7f);
    Private->DiskEnd  = LocalDiskStart;
  }

    if (PciHandle != mVgaHandle) {
    EnablePs2Keyboard ();

    //
    // Store current mode settings since PrepareToScanRom may change mode.
    //
    VideoMode = *(UINT8 *)((UINTN)(0x400 + BDA_VIDEO_MODE));
  }

    );

  //
  // Notify the platform that we are about to scan the ROM
  //
  Status = Private->LegacyBiosPlatform->PlatformHooks (
                                          Private->LegacyBiosPlatform,
                                          EfiPlatformHookPrepareToScanRom,
                                          0,
                                          PciHandle,
                                          &InitAddress,
                                          NULL,
                                          NULL
                                          );

  //
  // If Status returned is EFI_UNSUPPORTED then abort due to platform
  // policy.
  //
  if (Status == EFI_UNSUPPORTED) {
    goto Done;
  }

  //
  // Report corresponding status code
  //
  REPORT_STATUS_CODE (
    EFI_PROGRESS_CODE,
    (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_CSM_LEGACY_ROM_INIT)
    );

  //
  // Generate number of ticks since midnight for BDA. Some OPROMs require
  // this. Place result in 40:6C-6F
  //
  gRT->GetTime (&BootTime, NULL);
  LocalTime = BootTime.Hour * 3600 + BootTime.Minute * 60 + BootTime.Second;

  //
  // Multiply result by 18.2 for number of ticks since midnight.
  // Use 182/10 to avoid floating point math.
  //
  ACCESS_PAGE0_CODE (
    LocalTime = (LocalTime * 182) / 10;
    BdaPtr    = (UINT32 *)((UINTN)0x46C);
    *BdaPtr   = LocalTime;
    );

  //
  // Pass in handoff data
  //
  PciEnableStatus = EFI_UNSUPPORTED;
  ZeroMem (&Regs, sizeof (Regs));
  if (PciHandle != NULL) {
    Status = gBS->HandleProtocol (
                    PciHandle,
                    &gEfiPciIoProtocolGuid,
                    (VOID **)&PciIo
                    );
    ASSERT_EFI_ERROR (Status);

    //
    // Enable command register.
    //
    PciEnableStatus = PciIo->Attributes (
                               PciIo,
                               EfiPciIoAttributeOperationEnable,
                               EFI_PCI_DEVICE_ENABLE,
                               NULL
                               );

    PciIo->GetLocation (
             PciIo,
             &Segment,
             &Bus,
             &Device,
             &Function
             );
    DEBUG ((DEBUG_INFO, "Shadowing OpROM on the PCI device %x/%x/%x\n", Bus, Device, Function));
  }

  mIgnoreBbsUpdateFlag = FALSE;
  Regs.X.AX            = Legacy16DispatchOprom;

  //
  // Generate DispatchOpRomTable data
  //
  Private->IntThunk->DispatchOpromTable.PnPInstallationCheckSegment = Private->Legacy16Table->PnPInstallationCheckSegment;
  Private->IntThunk->DispatchOpromTable.PnPInstallationCheckOffset  = Private->Legacy16Table->PnPInstallationCheckOffset;
  Private->IntThunk->DispatchOpromTable.OpromSegment                = (UINT16)(InitAddress >> 4);
  Private->IntThunk->DispatchOpromTable.PciBus                      = (UINT8)Bus;
  Private->IntThunk->DispatchOpromTable.PciDeviceFunction           = (UINT8)((Device << 3) | Function);
  Private->IntThunk->DispatchOpromTable.NumberBbsEntries            = (UINT8)Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries;
  Private->IntThunk->DispatchOpromTable.BbsTablePointer             = (UINT32)(UINTN)Private->BbsTablePtr;
  Private->IntThunk->DispatchOpromTable.RuntimeSegment              = (UINT16)((OpromRevision < 3) ? 0xffff : (RuntimeAddress >> 4));
  TempData                                                          = (UINTN)&Private->IntThunk->DispatchOpromTable;
  Regs.X.ES                                                         = EFI_SEGMENT ((UINT32)TempData);
  Regs.X.BX                                                         = EFI_OFFSET ((UINT32)TempData);
  //
  // Skip dispatching ROM for those PCI devices that can not be enabled by PciIo->Attributes
  // Otherwise, it may cause the system to hang in some cases
  //
  if (!EFI_ERROR (PciEnableStatus)) {
    DEBUG ((DEBUG_INFO, " Legacy16DispatchOprom - %02x/%02x/%02x\n", Bus, Device, Function));
    Private->LegacyBios.FarCall86 (
                          &Private->LegacyBios,
                          Private->Legacy16CallSegment,
                          Private->Legacy16CallOffset,
                          &Regs,
                          NULL,
                          0
                          );
  } else {
    Regs.X.BX = 0;
  }

  if (Private->IntThunk->DispatchOpromTable.NumberBbsEntries != (UINT8)Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries) {
    Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries = (UINT8)Private->IntThunk->DispatchOpromTable.NumberBbsEntries;
    mIgnoreBbsUpdateFlag                                       = TRUE;
  }

  //
  // Check if non-BBS compliant drives found
  //
  if (Regs.X.BX != 0) {
    LocalDiskEnd                                                                 = (UINT8)(LocalDiskStart + Regs.H.BL);
    Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciSegment       = (UINT8)Segment;
    Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciBus           = (UINT8)Bus;
    Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciDevice        = (UINT8)Device;
    Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciFunction      = (UINT8)Function;
    Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].StartDriveNumber = Private->DiskEnd;
    Private->DiskEnd                                                             = LocalDiskEnd;
    Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].EndDriveNumber   = Private->DiskEnd;
    Private->LegacyEfiHddTableIndex                                             += 1;
  }

  //
  // Skip video mode set, if installing VGA
  //
  if (PciHandle != mVgaHandle) {
    //
    // Set mode settings since PrepareToScanRom may change mode
    //
    ACCESS_PAGE0_CODE (
    {
      OldVideoMode = *(UINT8 *)((UINTN)(0x400 + BDA_VIDEO_MODE));
    }
      );

    if (VideoMode != OldVideoMode) {
      //
      // The active video mode is changed, restore it to original mode.
      //
      Regs.H.AH = 0x00;
      Regs.H.AL = VideoMode;
      Private->LegacyBios.Int86 (&Private->LegacyBios, 0x10, &Regs);
    }
  }

  //
  // Regs.X.AX from the adapter initializion is ignored since some adapters
  // do not follow the standard of setting AX = 0 on success.
  //
  //
  // The ROM could have updated its size so we need to read again.
  //
  if (((EFI_LEGACY_EXPANSION_ROM_HEADER *)RuntimeAddress)->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
    //
    // Now we check the signature (0xaa55) to judge whether the run-time code is truly generated by INIT function.
    // If signature is not valid, that means the INIT function didn't copy the run-time code to RuntimeAddress.
    //
    *RuntimeImageLength = 0;
  } else {
    *RuntimeImageLength = ((EFI_LEGACY_EXPANSION_ROM_HEADER *)RuntimeAddress)->Size512 * 512;
  }

  DEBUG ((DEBUG_INFO, " fsize = %x\n", *RuntimeImageLength));

  //
  // If OpROM runs in 2.0 mode
  //
  if (PhysicalAddress == 0) {
    if (*RuntimeImageLength < ImageSize) {
      //
      // Make area from end of shadowed rom to end of original rom all ffs
      //
      gBS->SetMem ((VOID *)(InitAddress + *RuntimeImageLength), ImageSize - *RuntimeImageLength, 0xff);
    }
  }

  ACCESS_PAGE0_CODE (
    LocalDiskEnd = (UINT8)((*(UINT8 *)((UINTN)0x475)) + 0x80);
    );

  //
  // Allow platform to perform any required actions after the
  // OPROM has been initialized.
  //
  Status = Private->LegacyBiosPlatform->PlatformHooks (
                                          Private->LegacyBiosPlatform,
                                          EfiPlatformHookAfterRomInit,
                                          0,
                                          PciHandle,
                                          &RuntimeAddress,
                                          NULL,
                                          NULL
                                          );
  if (PciHandle != NULL) {
    //
    // If no PCI Handle then no header or Bevs.
    //
    if ((*RuntimeImageLength != 0) && (!mIgnoreBbsUpdateFlag)) {
      StartBbsIndex = Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries;
      TempData      = RuntimeAddress;
      UpdateBevBcvTable (
        Private,
        (EFI_LEGACY_EXPANSION_ROM_HEADER *)TempData,
        PciIo
        );
      EndBbsIndex  = Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries;
      LocalDiskEnd = (UINT8)(LocalDiskStart + (UINT8)(EndBbsIndex - StartBbsIndex));
      if (LocalDiskEnd != LocalDiskStart) {
        Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciSegment       = (UINT8)Segment;
        Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciBus           = (UINT8)Bus;
        Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciDevice        = (UINT8)Device;
        Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciFunction      = (UINT8)Function;
        Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].StartDriveNumber = Private->DiskEnd;
        Private->DiskEnd                                                             = LocalDiskEnd;
        Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].EndDriveNumber   = Private->DiskEnd;
        Private->LegacyEfiHddTableIndex                                             += 1;
      }
    }

    //
    // Mark PCI device as having a legacy BIOS ROM loaded.
    //
    RomShadow (
      PciHandle,
      (UINT32)RuntimeAddress,
      (UINT32)*RuntimeImageLength,
      LocalDiskStart,
      LocalDiskEnd
      );
  }

  //
  // Stuff caller's OPTIONAL return parameters.
  //
  if (RomShadowAddress != NULL) {
    *RomShadowAddress = (VOID *)RuntimeAddress;
  }

  if (DiskStart != NULL) {
    *DiskStart = LocalDiskStart;
  }

  if (DiskEnd != NULL) {
    *DiskEnd = LocalDiskEnd;
  }

  Private->OptionRom = (UINT32)(RuntimeAddress + *RuntimeImageLength);

  Status = EFI_SUCCESS;

Done:
  if (PhysicalAddress != 0) {
    //
    // Free pages when OpROM is 3.0
    //
    gBS->FreePages (PhysicalAddress, EFI_SIZE_TO_PAGES (ImageSize));
  }

  //
  // Insure all shadowed  areas are locked
  //
  Private->LegacyRegion->Lock (
                           Private->LegacyRegion,
                           0xC0000,
                           0x40000,
                           &Granularity
                           );

  return Status;
}

/**
  Let IOMMU grant DMA access for the PCI device.

  @param  PciHandle             The EFI handle for the PCI device.
  @param  HostAddress           The system memory address to map to the PCI controller.
  @param  NumberOfBytes         The number of bytes to map.

  @retval EFI_SUCCESS  The DMA access is granted.
**/
EFI_STATUS
IoMmuGrantAccess (
  IN  EFI_HANDLE            PciHandle,
  IN  EFI_PHYSICAL_ADDRESS  HostAddress,
  IN  UINTN                 NumberOfBytes
  )
{
  EFI_PHYSICAL_ADDRESS  DeviceAddress;
  VOID                  *Mapping;
  EFI_STATUS            Status;

  if (PciHandle == NULL) {
    return EFI_UNSUPPORTED;
  }

  Status = EFI_SUCCESS;
  if (mIoMmu == NULL) {
    gBS->LocateProtocol (&gEdkiiIoMmuProtocolGuid, NULL, (VOID **)&mIoMmu);
  }

  if (mIoMmu != NULL) {
    Status = mIoMmu->Map (
                       mIoMmu,
                       EdkiiIoMmuOperationBusMasterCommonBuffer,
                       (VOID *)(UINTN)HostAddress,
                       &NumberOfBytes,
                       &DeviceAddress,
                       &Mapping
                       );
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "LegacyPci - IoMmuMap - %r\n", Status));
    } else {
      ASSERT (DeviceAddress == HostAddress);
      Status = mIoMmu->SetAttribute (
                         mIoMmu,
                         PciHandle,
                         Mapping,
                         EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE
                         );
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "LegacyPci - IoMmuSetAttribute - %r\n", Status));
      }
    }
  }

  return Status;
}

/**
  Load a legacy PC-AT OPROM on the PciHandle device. Return information
  about how many disks were added by the OPROM and the shadow address and
  size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C:

  @param  This                   Protocol instance pointer.
  @param  PciHandle              The PCI PC-AT OPROM from this devices ROM BAR will
                                 be loaded. This value is NULL if RomImage is
                                 non-NULL. This is the normal case.
  @param  RomImage               A PCI PC-AT ROM image. This argument is non-NULL
                                 if there is no hardware associated with the ROM
                                 and thus no PciHandle, otherwise is must be NULL.
                                 Example is PXE base code.
  @param  Flags                  Indicates if ROM found and if PC-AT.
  @param  DiskStart              Disk number of first device hooked by the ROM. If
                                 DiskStart is the same as DiskEnd no disked were
                                 hooked.
  @param  DiskEnd                Disk number of the last device hooked by the ROM.
  @param  RomShadowAddress       Shadow address of PC-AT ROM
  @param  RomShadowedSize        Size of RomShadowAddress in bytes

  @retval EFI_SUCCESS            Legacy ROM loaded for this device
  @retval EFI_INVALID_PARAMETER  PciHandle not found
  @retval EFI_UNSUPPORTED        There is no PCI ROM in the ROM BAR or no onboard
                                 ROM

**/
EFI_STATUS
EFIAPI
LegacyBiosInstallPciRom (
  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
  IN  EFI_HANDLE               PciHandle,
  IN  VOID                     **RomImage,
  OUT UINTN                    *Flags,
  OUT UINT8                    *DiskStart  OPTIONAL,
  OUT UINT8                    *DiskEnd  OPTIONAL,
  OUT VOID                     **RomShadowAddress  OPTIONAL,
  OUT UINT32                   *RomShadowedSize OPTIONAL
  )
{
  EFI_STATUS              Status;
  LEGACY_BIOS_INSTANCE    *Private;
  VOID                    *LocalRomImage;
  UINTN                   ImageSize;
  UINTN                   RuntimeImageLength;
  EFI_PCI_IO_PROTOCOL     *PciIo;
  PCI_TYPE01              PciConfigHeader;
  UINTN                   HandleCount;
  EFI_HANDLE              *HandleBuffer;
  UINTN                   PciSegment;
  UINTN                   PciBus;
  UINTN                   PciDevice;
  UINTN                   PciFunction;
  UINTN                   LastBus;
  UINTN                   Index;
  UINT8                   OpromRevision;
  UINT32                  Granularity;
  PCI_3_0_DATA_STRUCTURE  *Pcir;

  OpromRevision = 0;

  Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This);
  if (Private->Legacy16Table->LastPciBus == 0) {
    //
    // Get last bus number if not already found
    //
    Status = gBS->LocateHandleBuffer (
                    ByProtocol,
                    &gEfiPciIoProtocolGuid,
                    NULL,
                    &HandleCount,
                    &HandleBuffer
                    );

    LastBus = 0;
    for (Index = 0; Index < HandleCount; Index++) {
      Status = gBS->HandleProtocol (
                      HandleBuffer[Index],
                      &gEfiPciIoProtocolGuid,
                      (VOID **)&PciIo
                      );
      if (EFI_ERROR (Status)) {
        continue;
      }

      Status = PciIo->GetLocation (
                        PciIo,
                        &PciSegment,
                        &PciBus,
                        &PciDevice,
                        &PciFunction
                        );
      if (PciBus > LastBus) {
        LastBus = PciBus;
      }
    }

    Private->LegacyRegion->UnLock (
                             Private->LegacyRegion,
                             0xE0000,
                             0x20000,
                             &Granularity
                             );
    Private->Legacy16Table->LastPciBus = (UINT8)LastBus;
    Private->LegacyRegion->Lock (
                             Private->LegacyRegion,
                             0xE0000,
                             0x20000,
                             &Granularity
                             );
  }

  *Flags = 0;
  if ((PciHandle != NULL) && (RomImage == NULL)) {
    //
    // If PciHandle has OpRom to Execute
    // and OpRom are all associated with Hardware
    //
    Status = gBS->HandleProtocol (
                    PciHandle,
                    &gEfiPciIoProtocolGuid,
                    (VOID **)&PciIo
                    );

    if (!EFI_ERROR (Status)) {
      PciIo->Pci.Read (
                   PciIo,
                   EfiPciIoWidthUint32,
                   0,
                   sizeof (PciConfigHeader) / sizeof (UINT32),
                   &PciConfigHeader
                   );

      //
      // if video installed & OPROM is video return
      //
      if (
            (
               ((PciConfigHeader.Hdr.ClassCode[2] == PCI_CLASS_OLD) &&
              (PciConfigHeader.Hdr.ClassCode[1] == PCI_CLASS_OLD_VGA))
            ||
             ((PciConfigHeader.Hdr.ClassCode[2] == PCI_CLASS_DISPLAY) &&
              (PciConfigHeader.Hdr.ClassCode[1] == PCI_CLASS_DISPLAY_VGA))
            )
         &&
            (!Private->VgaInstalled)
            )
      {
        mVgaInstallationInProgress = TRUE;

        //
        //      return EFI_UNSUPPORTED;
        //
      }
    }

    //
    // To run any legacy image, the VGA needs to be installed first.
    // if installing the video, then don't need the thunk as already installed.
    //
    Status = Private->LegacyBiosPlatform->GetPlatformHandle (
                                            Private->LegacyBiosPlatform,
                                            EfiGetPlatformVgaHandle,
                                            0,
                                            &HandleBuffer,
                                            &HandleCount,
                                            NULL
                                            );

    if (!EFI_ERROR (Status)) {
      mVgaHandle = HandleBuffer[0];
      if ((!Private->VgaInstalled) && (PciHandle != mVgaHandle)) {
        //
        // A return status of EFI_NOT_FOUND is considered valid (No EFI
        // driver is controlling video.
        //
        mVgaInstallationInProgress = TRUE;
        Status                     = LegacyBiosInstallVgaRom (Private);
        if (EFI_ERROR (Status)) {
          if (Status != EFI_NOT_FOUND) {
            mVgaInstallationInProgress = FALSE;
            return Status;
          }
        } else {
          mVgaInstallationInProgress = FALSE;
        }
      }
    }

    //
    // See if the option ROM for PciHandle has already been executed
    //
    Status = IsLegacyRom (PciHandle);

    if (!EFI_ERROR (Status)) {
      mVgaInstallationInProgress = FALSE;
      GetShadowedRomParameters (
        PciHandle,
        DiskStart,
        DiskEnd,
        RomShadowAddress,
        (UINTN *)RomShadowedSize
        );
      return EFI_SUCCESS;
    }

    Status = LegacyBiosCheckPciRomEx (
               &Private->LegacyBios,
               PciHandle,
               &LocalRomImage,
               &ImageSize,
               &RuntimeImageLength,
               Flags,
               &OpromRevision,
               NULL
               );
    if (EFI_ERROR (Status)) {
      //
      // There is no PCI ROM in the ROM BAR or no onboard ROM
      //
      mVgaInstallationInProgress = FALSE;
      return EFI_UNSUPPORTED;
    }
  } else {
    if ((RomImage == NULL) || (*RomImage == NULL)) {
      //
      // If PciHandle is NULL, and no OpRom is to be associated
      //
      mVgaInstallationInProgress = FALSE;
      return EFI_UNSUPPORTED;
    }

    Status = Private->LegacyBiosPlatform->GetPlatformHandle (
                                            Private->LegacyBiosPlatform,
                                            EfiGetPlatformVgaHandle,
                                            0,
                                            &HandleBuffer,
                                            &HandleCount,
                                            NULL
                                            );
    if ((!EFI_ERROR (Status)) && (!Private->VgaInstalled)) {
      //
      // A return status of EFI_NOT_FOUND is considered valid (No EFI
      // driver is controlling video.
      //
      mVgaInstallationInProgress = TRUE;
      Status                     = LegacyBiosInstallVgaRom (Private);
      if (EFI_ERROR (Status)) {
        if (Status != EFI_NOT_FOUND) {
          mVgaInstallationInProgress = FALSE;
          return Status;
        }
      } else {
        mVgaInstallationInProgress = FALSE;
      }
    }

    LocalRomImage = *RomImage;
    if ((((PCI_EXPANSION_ROM_HEADER *)LocalRomImage)->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) ||
        (((PCI_EXPANSION_ROM_HEADER *)LocalRomImage)->PcirOffset == 0) ||
        ((((PCI_EXPANSION_ROM_HEADER *)LocalRomImage)->PcirOffset & 3) != 0))
    {
      mVgaInstallationInProgress = FALSE;
      return EFI_UNSUPPORTED;
    }

    Pcir = (PCI_3_0_DATA_STRUCTURE *)
           ((UINT8 *)LocalRomImage + ((PCI_EXPANSION_ROM_HEADER *)LocalRomImage)->PcirOffset);

    if ((Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) || (Pcir->CodeType != PCI_CODE_TYPE_PCAT_IMAGE)) {
      mVgaInstallationInProgress = FALSE;
      return EFI_UNSUPPORTED;
    }

    ImageSize = Pcir->ImageLength * 512;
    if (Pcir->Length >= 0x1C) {
      OpromRevision = Pcir->Revision;
    } else {
      OpromRevision = 0;
    }

    if (Pcir->Revision < 3) {
      RuntimeImageLength = 0;
    } else {
      RuntimeImageLength = Pcir->MaxRuntimeImageLength * 512;
    }
  }

  //
  // Grant access for below 1M
  // BDA/EBDA/LowPMM and scratch memory for OPROM.
  //
  IoMmuGrantAccess (PciHandle, 0, SIZE_1MB);
  //
  // Grant access for HiPmm
  //
  IoMmuGrantAccess (
    PciHandle,
    Private->IntThunk->EfiToLegacy16InitTable.HiPmmMemory,
    Private->IntThunk->EfiToLegacy16InitTable.HiPmmMemorySizeInBytes
    );

  //
  // Shadow and initialize the OpROM.
  //
  ASSERT (Private->TraceIndex < 0x200);
  Private->Trace[Private->TraceIndex] = LEGACY_PCI_TRACE_000;
  Private->TraceIndex++;
  Private->TraceIndex = (UINT16)(Private->TraceIndex % 0x200);
  Status              = LegacyBiosInstallRom (
                          This,
                          Private,
                          PciHandle,
                          OpromRevision,
                          LocalRomImage,
                          ImageSize,
                          &RuntimeImageLength,
                          DiskStart,
                          DiskEnd,
                          RomShadowAddress
                          );
  if (RomShadowedSize != NULL) {
    *RomShadowedSize = (UINT32)RuntimeImageLength;
  }

  mVgaInstallationInProgress = FALSE;
  return Status;
}
