/** @file

Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>

This program and the accompanying materials
are licensed and made available under the terms and conditions
of the BSD License which accompanies this distribution.  The
full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#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 ((EFI_D_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 <= Suborninate 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 ((EFI_D_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 ((EFI_D_ERROR, "PIRQ table length insufficient - %x\n", PirqTableSize));
    } else {
      DEBUG ((EFI_D_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 ((EFI_D_INFO, "PciBus             - %02x\n", (UINTN)PciHandle->PciBus));
  DEBUG ((EFI_D_INFO, "PciDeviceFun       - %02x\n", (UINTN)PciHandle->PciDeviceFun));
  DEBUG ((EFI_D_INFO, "PciSegment         - %02x\n", (UINTN)PciHandle->PciSegment));
  DEBUG ((EFI_D_INFO, "PciClass           - %02x\n", (UINTN)PciHandle->PciClass));
  DEBUG ((EFI_D_INFO, "PciSubclass        - %02x\n", (UINTN)PciHandle->PciSubclass));
  DEBUG ((EFI_D_INFO, "PciInterface       - %02x\n", (UINTN)PciHandle->PciInterface));

  DEBUG ((EFI_D_INFO, "PrimaryIrq         - %02x\n", (UINTN)PciHandle->PrimaryIrq));
  DEBUG ((EFI_D_INFO, "PrimaryReserved    - %02x\n", (UINTN)PciHandle->PrimaryReserved));
  DEBUG ((EFI_D_INFO, "PrimaryControl     - %04x\n", (UINTN)PciHandle->PrimaryControl));
  DEBUG ((EFI_D_INFO, "PrimaryBase        - %04x\n", (UINTN)PciHandle->PrimaryBase));
  DEBUG ((EFI_D_INFO, "PrimaryBusMaster   - %04x\n", (UINTN)PciHandle->PrimaryBusMaster));

  DEBUG ((EFI_D_INFO, "SecondaryIrq       - %02x\n", (UINTN)PciHandle->SecondaryIrq));
  DEBUG ((EFI_D_INFO, "SecondaryReserved  - %02x\n", (UINTN)PciHandle->SecondaryReserved));
  DEBUG ((EFI_D_INFO, "SecondaryControl   - %04x\n", (UINTN)PciHandle->SecondaryControl));
  DEBUG ((EFI_D_INFO, "SecondaryBase      - %04x\n", (UINTN)PciHandle->SecondaryBase));
  DEBUG ((EFI_D_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 occuring.
  //
  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 it's 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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_ERROR, "return LegacyBiosInstallRom(%d): EFI_OUT_OF_RESOURCES (no more space for OpROM)\n", __LINE__));
      //
      // 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 ((EFI_D_ERROR, "return LegacyBiosInstallRom(%d): EFI_OUT_OF_RESOURCES (no more space for OpROM)\n", __LINE__));
      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 ((EFI_D_ERROR, "return LegacyBiosInstallRom(%d): EFI_OUT_OF_RESOURCES (no more space for OpROM)\n", __LINE__));
      //
      // 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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 it's 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 ((EFI_D_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;
}

