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