]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
MdeModulePkg: Update PciEnumeratorSupport to ignore OptionRom if needed
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciEnumeratorSupport.c
index f2108284d3aa7631b205b53bfef093033d8dd48b..509f828b621d07258cb864ab328327fc5d35285e 100644 (file)
@@ -1,19 +1,22 @@
 /** @file\r
   PCI emumeration support functions implementation for PCI Bus module.\r
 \r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "PciBus.h"\r
 \r
+extern CHAR16                          *mBarTypeStr[];\r
+extern EDKII_DEVICE_SECURITY_PROTOCOL  *mDeviceSecurityProtocol;\r
+\r
+#define OLD_ALIGN    0xFFFFFFFFFFFFFFFFULL\r
+#define EVEN_ALIGN   0xFFFFFFFFFFFFFFFEULL\r
+#define SQUAD_ALIGN  0xFFFFFFFFFFFFFFFDULL\r
+#define DQUAD_ALIGN  0xFFFFFFFFFFFFFFFCULL\r
+\r
 /**\r
   This routine is used to check whether the pci device is present.\r
 \r
@@ -29,11 +32,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/\r
 EFI_STATUS\r
 PciDevicePresent (\r
-  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL     *PciRootBridgeIo,\r
-  OUT PCI_TYPE00                          *Pci,\r
-  IN  UINT8                               Bus,\r
-  IN  UINT8                               Device,\r
-  IN  UINT8                               Func\r
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo,\r
+  OUT PCI_TYPE00                       *Pci,\r
+  IN  UINT8                            Bus,\r
+  IN  UINT8                            Device,\r
+  IN  UINT8                            Func\r
   )\r
 {\r
   UINT64      Address;\r
@@ -55,7 +58,7 @@ PciDevicePresent (
                                   Pci\r
                                   );\r
 \r
-  if (!EFI_ERROR (Status) && (Pci->Hdr).VendorId != 0xffff) {\r
+  if (!EFI_ERROR (Status) && ((Pci->Hdr).VendorId != 0xffff)) {\r
     //\r
     // Read the entire config header for the device\r
     //\r
@@ -80,7 +83,7 @@ PciDevicePresent (
   root bridge will then be created.\r
 \r
   @param Bridge         Parent bridge instance.\r
-  @param StartBusNumber Bus number of begining.\r
+  @param StartBusNumber Bus number of beginning.\r
 \r
   @retval EFI_SUCCESS   PCI device is found.\r
   @retval other         Some error occurred when reading PCI bridge information.\r
@@ -88,41 +91,46 @@ PciDevicePresent (
 **/\r
 EFI_STATUS\r
 PciPciDeviceInfoCollector (\r
-  IN PCI_IO_DEVICE                      *Bridge,\r
-  IN UINT8                              StartBusNumber\r
+  IN PCI_IO_DEVICE  *Bridge,\r
+  IN UINT8          StartBusNumber\r
   )\r
 {\r
-  EFI_STATUS          Status;\r
-  PCI_TYPE00          Pci;\r
-  UINT8               Device;\r
-  UINT8               Func;\r
-  UINT8               SecBus;\r
-  PCI_IO_DEVICE       *PciIoDevice;\r
-  EFI_PCI_IO_PROTOCOL *PciIo;\r
+  EFI_STATUS           Status;\r
+  PCI_TYPE00           Pci;\r
+  UINT8                Device;\r
+  UINT8                Func;\r
+  UINT8                SecBus;\r
+  PCI_IO_DEVICE        *PciIoDevice;\r
+  EFI_PCI_IO_PROTOCOL  *PciIo;\r
 \r
-  Status  = EFI_SUCCESS;\r
-  SecBus  = 0;\r
+  Status = EFI_SUCCESS;\r
+  SecBus = 0;\r
 \r
   for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
-\r
     for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
-\r
       //\r
       // Check to see whether PCI device is present\r
       //\r
       Status = PciDevicePresent (\r
                  Bridge->PciRootBridgeIo,\r
                  &Pci,\r
-                 (UINT8) StartBusNumber,\r
-                 (UINT8) Device,\r
-                 (UINT8) Func\r
+                 (UINT8)StartBusNumber,\r
+                 (UINT8)Device,\r
+                 (UINT8)Func\r
                  );\r
-      if (!EFI_ERROR (Status)) {\r
 \r
+      if (EFI_ERROR (Status) && (Func == 0)) {\r
+        //\r
+        // go to next device if there is no Function 0\r
+        //\r
+        break;\r
+      }\r
+\r
+      if (!EFI_ERROR (Status)) {\r
         //\r
         // Call back to host bridge function\r
         //\r
-        PreprocessController (Bridge, (UINT8) StartBusNumber, Device, Func, EfiPciBeforeResourceCollection);\r
+        PreprocessController (Bridge, (UINT8)StartBusNumber, Device, Func, EfiPciBeforeResourceCollection);\r
 \r
         //\r
         // Collect all the information about the PCI device discovered\r
@@ -130,7 +138,7 @@ PciPciDeviceInfoCollector (
         Status = PciSearchDevice (\r
                    Bridge,\r
                    &Pci,\r
-                   (UINT8) StartBusNumber,\r
+                   (UINT8)StartBusNumber,\r
                    Device,\r
                    Func,\r
                    &PciIoDevice\r
@@ -141,18 +149,25 @@ PciPciDeviceInfoCollector (
         //\r
         //\r
         if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {\r
-\r
           //\r
           // If it is PPB, we need to get the secondary bus to continue the enumeration\r
           //\r
-          PciIo   = &(PciIoDevice->PciIo);\r
+          PciIo = &(PciIoDevice->PciIo);\r
 \r
-          Status  = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 1, &SecBus);\r
+          Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 1, &SecBus);\r
 \r
           if (EFI_ERROR (Status)) {\r
             return Status;\r
           }\r
 \r
+          //\r
+          // Ensure secondary bus number is greater than the primary bus number to avoid\r
+          // any potential dead loop when PcdPciDisableBusEnumeration is set to TRUE\r
+          //\r
+          if (SecBus <= StartBusNumber) {\r
+            break;\r
+          }\r
+\r
           //\r
           // Get resource padding for PPB\r
           //\r
@@ -163,20 +178,17 @@ PciPciDeviceInfoCollector (
           //\r
           Status = PciPciDeviceInfoCollector (\r
                      PciIoDevice,\r
-                     (UINT8) (SecBus)\r
+                     (UINT8)(SecBus)\r
                      );\r
-\r
         }\r
 \r
-        if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
-\r
+        if ((Func == 0) && !IS_PCI_MULTI_FUNC (&Pci)) {\r
           //\r
           // Skip sub functions, this is not a multi function device\r
           //\r
           Func = PCI_MAX_FUNC;\r
         }\r
       }\r
-\r
     }\r
   }\r
 \r
@@ -184,7 +196,7 @@ PciPciDeviceInfoCollector (
 }\r
 \r
 /**\r
-  Seach required device and create PCI device instance.\r
+  Search required device and create PCI device instance.\r
 \r
   @param Bridge     Parent bridge instance.\r
   @param Pci        Input PCI device information block.\r
@@ -199,20 +211,32 @@ PciPciDeviceInfoCollector (
 **/\r
 EFI_STATUS\r
 PciSearchDevice (\r
-  IN  PCI_IO_DEVICE                         *Bridge,\r
-  IN  PCI_TYPE00                            *Pci,\r
-  IN  UINT8                                 Bus,\r
-  IN  UINT8                                 Device,\r
-  IN  UINT8                                 Func,\r
-  OUT PCI_IO_DEVICE                         **PciDevice\r
+  IN  PCI_IO_DEVICE  *Bridge,\r
+  IN  PCI_TYPE00     *Pci,\r
+  IN  UINT8          Bus,\r
+  IN  UINT8          Device,\r
+  IN  UINT8          Func,\r
+  OUT PCI_IO_DEVICE  **PciDevice\r
   )\r
 {\r
-  PCI_IO_DEVICE *PciIoDevice;\r
-\r
-  PciIoDevice = NULL;\r
+  PCI_IO_DEVICE  *PciIoDevice;\r
+  BOOLEAN        IgnoreOptionRom;\r
+\r
+  PciIoDevice     = NULL;\r
+  IgnoreOptionRom = FALSE;\r
+\r
+  DEBUG ((\r
+    DEBUG_INFO,\r
+    "PciBus: Discovered %s @ [%02x|%02x|%02x]\n",\r
+    IS_PCI_BRIDGE (Pci) ?     L"PPB" :\r
+    IS_CARDBUS_BRIDGE (Pci) ? L"P2C" :\r
+    L"PCI",\r
+    Bus,\r
+    Device,\r
+    Func\r
+    ));\r
 \r
   if (!IS_PCI_BRIDGE (Pci)) {\r
-\r
     if (IS_CARDBUS_BRIDGE (Pci)) {\r
       PciIoDevice = GatherP2CInfo (\r
                       Bridge,\r
@@ -225,7 +249,6 @@ PciSearchDevice (
         InitializeP2C (PciIoDevice);\r
       }\r
     } else {\r
-\r
       //\r
       // Create private data for Pci Device\r
       //\r
@@ -236,11 +259,8 @@ PciSearchDevice (
                       Device,\r
                       Func\r
                       );\r
-\r
     }\r
-\r
   } else {\r
-\r
     //\r
     // Create private data for PPB\r
     //\r
@@ -267,7 +287,7 @@ PciSearchDevice (
   //\r
   // Update the bar information for this PCI device so as to support some specific device\r
   //\r
-  UpdatePciInfo (PciIoDevice);\r
+  UpdatePciInfo (PciIoDevice, &IgnoreOptionRom);\r
 \r
   if (PciIoDevice->DevicePath == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
@@ -277,15 +297,11 @@ PciSearchDevice (
   // Detect this function has option rom\r
   //\r
   if (gFullEnumeration) {\r
-\r
-    if (!IS_CARDBUS_BRIDGE (Pci)) {\r
-\r
+    if (!IS_CARDBUS_BRIDGE (Pci) && !IgnoreOptionRom) {\r
       GetOpRomInfo (PciIoDevice);\r
-\r
     }\r
 \r
     ResetPowerManagementFeature (PciIoDevice);\r
-\r
   }\r
 \r
   //\r
@@ -304,6 +320,127 @@ PciSearchDevice (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Dump the PPB padding resource information.\r
+\r
+  @param PciIoDevice     PCI IO instance.\r
+  @param ResourceType    The desired resource type to dump.\r
+                         PciBarTypeUnknown means to dump all types of resources.\r
+**/\r
+VOID\r
+DumpPpbPaddingResource (\r
+  IN PCI_IO_DEVICE  *PciIoDevice,\r
+  IN PCI_BAR_TYPE   ResourceType\r
+  )\r
+{\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Descriptor;\r
+  PCI_BAR_TYPE                       Type;\r
+\r
+  if (PciIoDevice->ResourcePaddingDescriptors == NULL) {\r
+    return;\r
+  }\r
+\r
+  if ((ResourceType == PciBarTypeIo16) || (ResourceType == PciBarTypeIo32)) {\r
+    ResourceType = PciBarTypeIo;\r
+  }\r
+\r
+  for (Descriptor = PciIoDevice->ResourcePaddingDescriptors; Descriptor->Desc != ACPI_END_TAG_DESCRIPTOR; Descriptor++) {\r
+    Type = PciBarTypeUnknown;\r
+    if ((Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) && (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_IO)) {\r
+      Type = PciBarTypeIo;\r
+    } else if ((Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) && (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM)) {\r
+      if (Descriptor->AddrSpaceGranularity == 32) {\r
+        //\r
+        // prefetchable\r
+        //\r
+        if (Descriptor->SpecificFlag == EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) {\r
+          Type = PciBarTypePMem32;\r
+        }\r
+\r
+        //\r
+        // Non-prefetchable\r
+        //\r
+        if (Descriptor->SpecificFlag == 0) {\r
+          Type = PciBarTypeMem32;\r
+        }\r
+      }\r
+\r
+      if (Descriptor->AddrSpaceGranularity == 64) {\r
+        //\r
+        // prefetchable\r
+        //\r
+        if (Descriptor->SpecificFlag == EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) {\r
+          Type = PciBarTypePMem64;\r
+        }\r
+\r
+        //\r
+        // Non-prefetchable\r
+        //\r
+        if (Descriptor->SpecificFlag == 0) {\r
+          Type = PciBarTypeMem64;\r
+        }\r
+      }\r
+    }\r
+\r
+    if ((Type != PciBarTypeUnknown) && ((ResourceType == PciBarTypeUnknown) || (ResourceType == Type))) {\r
+      DEBUG ((\r
+        DEBUG_INFO,\r
+        "   Padding: Type = %s; Alignment = 0x%lx;\tLength = 0x%lx\n",\r
+        mBarTypeStr[Type],\r
+        Descriptor->AddrRangeMax,\r
+        Descriptor->AddrLen\r
+        ));\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Dump the PCI BAR information.\r
+\r
+  @param PciIoDevice     PCI IO instance.\r
+**/\r
+VOID\r
+DumpPciBars (\r
+  IN PCI_IO_DEVICE  *PciIoDevice\r
+  )\r
+{\r
+  UINTN  Index;\r
+\r
+  for (Index = 0; Index < PCI_MAX_BAR; Index++) {\r
+    if (PciIoDevice->PciBar[Index].BarType == PciBarTypeUnknown) {\r
+      continue;\r
+    }\r
+\r
+    DEBUG ((\r
+      DEBUG_INFO,\r
+      "   BAR[%d]: Type = %s; Alignment = 0x%lx;\tLength = 0x%lx;\tOffset = 0x%02x\n",\r
+      Index,\r
+      mBarTypeStr[MIN (PciIoDevice->PciBar[Index].BarType, PciBarTypeMaxType)],\r
+      PciIoDevice->PciBar[Index].Alignment,\r
+      PciIoDevice->PciBar[Index].Length,\r
+      PciIoDevice->PciBar[Index].Offset\r
+      ));\r
+  }\r
+\r
+  for (Index = 0; Index < PCI_MAX_BAR; Index++) {\r
+    if ((PciIoDevice->VfPciBar[Index].BarType == PciBarTypeUnknown) && (PciIoDevice->VfPciBar[Index].Length == 0)) {\r
+      continue;\r
+    }\r
+\r
+    DEBUG ((\r
+      DEBUG_INFO,\r
+      " VFBAR[%d]: Type = %s; Alignment = 0x%lx;\tLength = 0x%lx;\tOffset = 0x%02x\n",\r
+      Index,\r
+      mBarTypeStr[MIN (PciIoDevice->VfPciBar[Index].BarType, PciBarTypeMaxType)],\r
+      PciIoDevice->VfPciBar[Index].Alignment,\r
+      PciIoDevice->VfPciBar[Index].Length,\r
+      PciIoDevice->VfPciBar[Index].Offset\r
+      ));\r
+  }\r
+\r
+  DEBUG ((DEBUG_INFO, "\n"));\r
+}\r
+\r
 /**\r
   Create PCI device instance for PCI device.\r
 \r
@@ -318,16 +455,16 @@ PciSearchDevice (
 **/\r
 PCI_IO_DEVICE *\r
 GatherDeviceInfo (\r
-  IN PCI_IO_DEVICE                    *Bridge,\r
-  IN PCI_TYPE00                       *Pci,\r
-  IN UINT8                            Bus,\r
-  IN UINT8                            Device,\r
-  IN UINT8                            Func\r
+  IN PCI_IO_DEVICE  *Bridge,\r
+  IN PCI_TYPE00     *Pci,\r
+  IN UINT8          Bus,\r
+  IN UINT8          Device,\r
+  IN UINT8          Func\r
   )\r
 {\r
-  UINTN                           Offset;\r
-  UINTN                           BarIndex;\r
-  PCI_IO_DEVICE                   *PciIoDevice;\r
+  UINTN          Offset;\r
+  UINTN          BarIndex;\r
+  PCI_IO_DEVICE  *PciIoDevice;\r
 \r
   PciIoDevice = CreatePciIoDevice (\r
                   Bridge,\r
@@ -341,21 +478,11 @@ GatherDeviceInfo (
     return NULL;\r
   }\r
 \r
-  //\r
-  // Create a device path for this PCI device and store it into its private data\r
-  //\r
-  CreatePciDevicePath (\r
-    Bridge->DevicePath,\r
-    PciIoDevice\r
-    );\r
-\r
   //\r
   // If it is a full enumeration, disconnect the device in advance\r
   //\r
   if (gFullEnumeration) {\r
-\r
     PCI_DISABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
-\r
   }\r
 \r
   //\r
@@ -368,15 +495,19 @@ GatherDeviceInfo (
   //\r
   // Parse the SR-IOV VF bars\r
   //\r
-  if (PcdGetBool (PcdSrIovSupport) && PciIoDevice->SrIovCapabilityOffset != 0) {\r
+  if (PcdGetBool (PcdSrIovSupport) && (PciIoDevice->SrIovCapabilityOffset != 0)) {\r
     for (Offset = PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR0, BarIndex = 0;\r
          Offset <= PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR5;\r
-         BarIndex++) {\r
-\r
+         BarIndex++)\r
+    {\r
       ASSERT (BarIndex < PCI_MAX_BAR);\r
       Offset = PciIovParseVfBar (PciIoDevice, Offset, BarIndex);\r
     }\r
   }\r
+\r
+  DEBUG_CODE (\r
+    DumpPciBars (PciIoDevice);\r
+    );\r
   return PciIoDevice;\r
 }\r
 \r
@@ -394,18 +525,21 @@ GatherDeviceInfo (
 **/\r
 PCI_IO_DEVICE *\r
 GatherPpbInfo (\r
-  IN PCI_IO_DEVICE                    *Bridge,\r
-  IN PCI_TYPE00                       *Pci,\r
-  IN UINT8                            Bus,\r
-  IN UINT8                            Device,\r
-  IN UINT8                            Func\r
+  IN PCI_IO_DEVICE  *Bridge,\r
+  IN PCI_TYPE00     *Pci,\r
+  IN UINT8          Bus,\r
+  IN UINT8          Device,\r
+  IN UINT8          Func\r
   )\r
 {\r
-  PCI_IO_DEVICE                   *PciIoDevice;\r
-  EFI_STATUS                      Status;\r
-  UINT8                           Value;\r
-  EFI_PCI_IO_PROTOCOL             *PciIo;\r
-  UINT8                           Temp;\r
+  PCI_IO_DEVICE        *PciIoDevice;\r
+  EFI_STATUS           Status;\r
+  UINT8                Value;\r
+  EFI_PCI_IO_PROTOCOL  *PciIo;\r
+  UINT8                Temp;\r
+  UINT32               PMemBaseLimit;\r
+  UINT16               PrefetchableMemoryBase;\r
+  UINT16               PrefetchableMemoryLimit;\r
 \r
   PciIoDevice = CreatePciIoDevice (\r
                   Bridge,\r
@@ -419,22 +553,13 @@ GatherPpbInfo (
     return NULL;\r
   }\r
 \r
-  //\r
-  // Create a device path for this PCI device and store it into its private data\r
-  //\r
-  CreatePciDevicePath (\r
-    Bridge->DevicePath,\r
-    PciIoDevice\r
-    );\r
-\r
   if (gFullEnumeration) {\r
     PCI_DISABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
 \r
     //\r
-    // Initalize the bridge control register\r
+    // Initialize the bridge control register\r
     //\r
     PCI_DISABLE_BRIDGE_CONTROL_REGISTER (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED);\r
-\r
   }\r
 \r
   //\r
@@ -467,14 +592,14 @@ GatherPpbInfo (
 \r
   //\r
   // if PcdPciBridgeIoAlignmentProbe is TRUE, PCI bus driver probes\r
-  // PCI bridge supporting non-stardard I/O window alignment less than 4K.\r
+  // PCI bridge supporting non-standard I/O window alignment less than 4K.\r
   //\r
 \r
   PciIoDevice->BridgeIoAlignment = 0xFFF;\r
   if (FeaturePcdGet (PcdPciBridgeIoAlignmentProbe)) {\r
     //\r
     // Check any bits of bit 3-1 of I/O Base Register are writable.\r
-    // if so, it is assumed non-stardard I/O window alignment is supported by this bridge.\r
+    // if so, it is assumed non-standard I/O window alignment is supported by this bridge.\r
     // Per spec, bit 3-1 of I/O Base Register are reserved bits, so its content can't be assumed.\r
     //\r
     Value = (UINT8)(Temp ^ (BIT3 | BIT2 | BIT1));\r
@@ -496,23 +621,32 @@ GatherPpbInfo (
   }\r
 \r
   Status = BarExisted (\r
-            PciIoDevice,\r
-            0x24,\r
-            NULL,\r
-            NULL\r
-            );\r
+             PciIoDevice,\r
+             0x24,\r
+             NULL,\r
+             &PMemBaseLimit\r
+             );\r
 \r
   //\r
   // Test if it supports 64 memory or not\r
   //\r
-  if (!EFI_ERROR (Status)) {\r
-\r
+  // The bottom 4 bits of both the Prefetchable Memory Base and Prefetchable Memory Limit\r
+  // registers:\r
+  //   0 - the bridge supports only 32 bit addresses.\r
+  //   1 - the bridge supports 64-bit addresses.\r
+  //\r
+  PrefetchableMemoryBase  = (UINT16)(PMemBaseLimit & 0xffff);\r
+  PrefetchableMemoryLimit = (UINT16)(PMemBaseLimit >> 16);\r
+  if (!EFI_ERROR (Status) &&\r
+      ((PrefetchableMemoryBase & 0x000f) == 0x0001) &&\r
+      ((PrefetchableMemoryLimit & 0x000f) == 0x0001))\r
+  {\r
     Status = BarExisted (\r
-              PciIoDevice,\r
-              0x28,\r
-              NULL,\r
-              NULL\r
-              );\r
+               PciIoDevice,\r
+               0x28,\r
+               NULL,\r
+               NULL\r
+               );\r
 \r
     if (!EFI_ERROR (Status)) {\r
       PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
@@ -529,10 +663,14 @@ GatherPpbInfo (
 \r
   GetResourcePaddingPpb (PciIoDevice);\r
 \r
+  DEBUG_CODE (\r
+    DumpPpbPaddingResource (PciIoDevice, PciBarTypeUnknown);\r
+    DumpPciBars (PciIoDevice);\r
+    );\r
+\r
   return PciIoDevice;\r
 }\r
 \r
-\r
 /**\r
   Create PCI device instance for PCI Card bridge device.\r
 \r
@@ -547,14 +685,14 @@ GatherPpbInfo (
 **/\r
 PCI_IO_DEVICE *\r
 GatherP2CInfo (\r
-  IN PCI_IO_DEVICE                    *Bridge,\r
-  IN PCI_TYPE00                       *Pci,\r
-  IN UINT8                            Bus,\r
-  IN UINT8                            Device,\r
-  IN UINT8                            Func\r
+  IN PCI_IO_DEVICE  *Bridge,\r
+  IN PCI_TYPE00     *Pci,\r
+  IN UINT8          Bus,\r
+  IN UINT8          Device,\r
+  IN UINT8          Func\r
   )\r
 {\r
-  PCI_IO_DEVICE                   *PciIoDevice;\r
+  PCI_IO_DEVICE  *PciIoDevice;\r
 \r
   PciIoDevice = CreatePciIoDevice (\r
                   Bridge,\r
@@ -568,19 +706,11 @@ GatherP2CInfo (
     return NULL;\r
   }\r
 \r
-  //\r
-  // Create a device path for this PCI device and store it into its private data\r
-  //\r
-  CreatePciDevicePath (\r
-    Bridge->DevicePath,\r
-    PciIoDevice\r
-    );\r
-\r
   if (gFullEnumeration) {\r
     PCI_DISABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
 \r
     //\r
-    // Initalize the bridge control register\r
+    // Initialize the bridge control register\r
     //\r
     PCI_DISABLE_BRIDGE_CONTROL_REGISTER (PciIoDevice, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED);\r
   }\r
@@ -598,11 +728,15 @@ GatherP2CInfo (
                          EFI_BRIDGE_PMEM32_DECODE_SUPPORTED |\r
                          EFI_BRIDGE_IO32_DECODE_SUPPORTED;\r
 \r
+  DEBUG_CODE (\r
+    DumpPciBars (PciIoDevice);\r
+    );\r
+\r
   return PciIoDevice;\r
 }\r
 \r
 /**\r
-  Create device path for pci deivce.\r
+  Create device path for pci device.\r
 \r
   @param ParentDevicePath  Parent bridge's path.\r
   @param PciIoDevice       Pci device instance.\r
@@ -612,18 +746,17 @@ GatherP2CInfo (
 **/\r
 EFI_DEVICE_PATH_PROTOCOL *\r
 CreatePciDevicePath (\r
-  IN  EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
-  IN  PCI_IO_DEVICE            *PciIoDevice\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath,\r
+  IN  PCI_IO_DEVICE             *PciIoDevice\r
   )\r
 {\r
-\r
-  PCI_DEVICE_PATH PciNode;\r
+  PCI_DEVICE_PATH  PciNode;\r
 \r
   //\r
   // Create PCI device path\r
   //\r
-  PciNode.Header.Type     = HARDWARE_DEVICE_PATH;\r
-  PciNode.Header.SubType  = HW_PCI_DP;\r
+  PciNode.Header.Type    = HARDWARE_DEVICE_PATH;\r
+  PciNode.Header.SubType = HW_PCI_DP;\r
   SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));\r
 \r
   PciNode.Device          = PciIoDevice->DeviceNumber;\r
@@ -647,16 +780,16 @@ CreatePciDevicePath (
 **/\r
 EFI_STATUS\r
 VfBarExisted (\r
-  IN PCI_IO_DEVICE *PciIoDevice,\r
-  IN UINTN         Offset,\r
-  OUT UINT32       *BarLengthValue,\r
-  OUT UINT32       *OriginalBarValue\r
+  IN PCI_IO_DEVICE  *PciIoDevice,\r
+  IN UINTN          Offset,\r
+  OUT UINT32        *BarLengthValue,\r
+  OUT UINT32        *OriginalBarValue\r
   )\r
 {\r
-  EFI_PCI_IO_PROTOCOL *PciIo;\r
-  UINT32              OriginalValue;\r
-  UINT32              Value;\r
-  EFI_TPL             OldTpl;\r
+  EFI_PCI_IO_PROTOCOL  *PciIo;\r
+  UINT32               OriginalValue;\r
+  UINT32               Value;\r
+  EFI_TPL              OldTpl;\r
 \r
   //\r
   // Ensure it is called properly\r
@@ -721,36 +854,36 @@ VfBarExisted (
 **/\r
 EFI_STATUS\r
 BarExisted (\r
-  IN  PCI_IO_DEVICE *PciIoDevice,\r
-  IN  UINTN         Offset,\r
-  OUT UINT32        *BarLengthValue,\r
-  OUT UINT32        *OriginalBarValue\r
+  IN  PCI_IO_DEVICE  *PciIoDevice,\r
+  IN  UINTN          Offset,\r
+  OUT UINT32         *BarLengthValue,\r
+  OUT UINT32         *OriginalBarValue\r
   )\r
 {\r
-  EFI_PCI_IO_PROTOCOL *PciIo;\r
-  UINT32              OriginalValue;\r
-  UINT32              Value;\r
-  EFI_TPL             OldTpl;\r
+  EFI_PCI_IO_PROTOCOL  *PciIo;\r
+  UINT32               OriginalValue;\r
+  UINT32               Value;\r
+  EFI_TPL              OldTpl;\r
 \r
   PciIo = &PciIoDevice->PciIo;\r
 \r
   //\r
   // Preserve the original value\r
   //\r
-  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);\r
+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8)Offset, 1, &OriginalValue);\r
 \r
   //\r
   // Raise TPL to high level to disable timer interrupt while the BAR is probed\r
   //\r
   OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
 \r
-  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &gAllOne);\r
-  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &Value);\r
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8)Offset, 1, &gAllOne);\r
+  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8)Offset, 1, &Value);\r
 \r
   //\r
   // Write back the original value\r
   //\r
-  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);\r
+  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8)Offset, 1, &OriginalValue);\r
 \r
   //\r
   // Restore TPL to its original level\r
@@ -778,7 +911,7 @@ BarExisted (
   @param PciIoDevice      Pci device instance.\r
   @param Command          Input command register value, and\r
                           returned supported register value.\r
-  @param BridgeControl    Inout bridge control value for PPB or P2C, and\r
+  @param BridgeControl    Input bridge control value for PPB or P2C, and\r
                           returned supported bridge control value.\r
   @param OldCommand       Returned and stored old command register offset.\r
   @param OldBridgeControl Returned and stored old Bridge control value for PPB or P2C.\r
@@ -786,14 +919,15 @@ BarExisted (
 **/\r
 VOID\r
 PciTestSupportedAttribute (\r
-  IN     PCI_IO_DEVICE                      *PciIoDevice,\r
-  IN OUT UINT16                             *Command,\r
-  IN OUT UINT16                             *BridgeControl,\r
-     OUT UINT16                             *OldCommand,\r
-     OUT UINT16                             *OldBridgeControl\r
+  IN     PCI_IO_DEVICE  *PciIoDevice,\r
+  IN OUT UINT16         *Command,\r
+  IN OUT UINT16         *BridgeControl,\r
+  OUT UINT16            *OldCommand,\r
+  OUT UINT16            *OldBridgeControl\r
   )\r
 {\r
-  EFI_TPL OldTpl;\r
+  EFI_TPL  OldTpl;\r
+  UINT16   CommandValue;\r
 \r
   //\r
   // Preserve the original value\r
@@ -803,11 +937,13 @@ PciTestSupportedAttribute (
   //\r
   // Raise TPL to high level to disable timer interrupt while the BAR is probed\r
   //\r
-  OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+  OldTpl       = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+  CommandValue = *Command | *OldCommand;\r
 \r
-  PCI_SET_COMMAND_REGISTER (PciIoDevice, *Command);\r
-  PCI_READ_COMMAND_REGISTER (PciIoDevice, Command);\r
+  PCI_SET_COMMAND_REGISTER (PciIoDevice, CommandValue);\r
+  PCI_READ_COMMAND_REGISTER (PciIoDevice, &CommandValue);\r
 \r
+  *Command = *Command & CommandValue;\r
   //\r
   // Write back the original value\r
   //\r
@@ -819,7 +955,6 @@ PciTestSupportedAttribute (
   gBS->RestoreTPL (OldTpl);\r
 \r
   if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
-\r
     //\r
     // Preserve the original value\r
     //\r
@@ -842,7 +977,6 @@ PciTestSupportedAttribute (
     // Restore TPL to its original level\r
     //\r
     gBS->RestoreTPL (OldTpl);\r
-\r
   } else {\r
     *OldBridgeControl = 0;\r
     *BridgeControl    = 0;\r
@@ -860,10 +994,10 @@ PciTestSupportedAttribute (
 **/\r
 VOID\r
 PciSetDeviceAttribute (\r
-  IN PCI_IO_DEVICE                      *PciIoDevice,\r
-  IN UINT16                             Command,\r
-  IN UINT16                             BridgeControl,\r
-  IN UINTN                              Option\r
+  IN PCI_IO_DEVICE  *PciIoDevice,\r
+  IN UINT16         Command,\r
+  IN UINT16         BridgeControl,\r
+  IN UINTN          Option\r
   )\r
 {\r
   UINT64  Attributes;\r
@@ -902,17 +1036,17 @@ PciSetDeviceAttribute (
   }\r
 \r
   if (Option == EFI_SET_SUPPORTS) {\r
-\r
-    Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE |\r
-                  EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED        |\r
-                  EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE       |\r
-                  EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE      |\r
-                  EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM         |\r
-                  EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE;\r
-\r
-    if ((Attributes & EFI_PCI_IO_ATTRIBUTE_IO) != 0) {\r
+    Attributes |= (UINT64)(EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE |\r
+                           EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED        |\r
+                           EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE       |\r
+                           EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE      |\r
+                           EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM         |\r
+                           EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE);\r
+\r
+    if (IS_PCI_LPC (&PciIoDevice->Pci)) {\r
       Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;\r
-      Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;\r
+      Attributes |= (mReserveIsaAliases ? (UINT64)EFI_PCI_IO_ATTRIBUTE_ISA_IO : \\r
+                     (UINT64)EFI_PCI_IO_ATTRIBUTE_ISA_IO_16);\r
     }\r
 \r
     if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
@@ -921,8 +1055,15 @@ PciSetDeviceAttribute (
       //\r
       Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;\r
       Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;\r
-    } else {\r
 \r
+      if (mReserveVgaAliases) {\r
+        Attributes &= ~(UINT64)(EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 | \\r
+                                EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16);\r
+      } else {\r
+        Attributes &= ~(UINT64)(EFI_PCI_IO_ATTRIBUTE_VGA_IO | \\r
+                                EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO);\r
+      }\r
+    } else {\r
       if (IS_PCI_IDE (&PciIoDevice->Pci)) {\r
         Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;\r
         Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;\r
@@ -930,16 +1071,26 @@ PciSetDeviceAttribute (
 \r
       if (IS_PCI_VGA (&PciIoDevice->Pci)) {\r
         Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;\r
-        Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;\r
+        Attributes |= (mReserveVgaAliases ? (UINT64)EFI_PCI_IO_ATTRIBUTE_VGA_IO : \\r
+                       (UINT64)EFI_PCI_IO_ATTRIBUTE_VGA_IO_16);\r
       }\r
     }\r
 \r
-    PciIoDevice->Supports = Attributes;\r
-    PciIoDevice->Supports &= ( (PciIoDevice->Parent->Supports) | \\r
-                               EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | \\r
-                               EFI_PCI_IO_ATTRIBUTE_BUS_MASTER );\r
-\r
+    PciIoDevice->Supports  = Attributes;\r
+    PciIoDevice->Supports &= ((PciIoDevice->Parent->Supports) | \\r
+                              EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | \\r
+                              EFI_PCI_IO_ATTRIBUTE_BUS_MASTER);\r
   } else {\r
+    //\r
+    // When this attribute is clear, the RomImage and RomSize fields in the PCI IO were\r
+    // initialized based on the PCI option ROM found through the ROM BAR of the PCI controller.\r
+    // When this attribute is set, the PCI option ROM described by the RomImage and RomSize\r
+    // fields is not from the the ROM BAR of the PCI controller.\r
+    //\r
+    if (!PciIoDevice->EmbeddedRom) {\r
+      Attributes |= EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM;\r
+    }\r
+\r
     PciIoDevice->Attributes = Attributes;\r
   }\r
 }\r
@@ -956,19 +1107,19 @@ PciSetDeviceAttribute (
 **/\r
 EFI_STATUS\r
 GetFastBackToBackSupport (\r
-  IN PCI_IO_DEVICE                      *PciIoDevice,\r
-  IN UINT8                              StatusIndex\r
+  IN PCI_IO_DEVICE  *PciIoDevice,\r
+  IN UINT8          StatusIndex\r
   )\r
 {\r
-  EFI_PCI_IO_PROTOCOL *PciIo;\r
-  EFI_STATUS          Status;\r
-  UINT32              StatusRegister;\r
+  EFI_PCI_IO_PROTOCOL  *PciIo;\r
+  EFI_STATUS           Status;\r
+  UINT32               StatusRegister;\r
 \r
   //\r
   // Read the status register\r
   //\r
-  PciIo   = &PciIoDevice->PciIo;\r
-  Status  = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, StatusIndex, 1, &StatusRegister);\r
+  PciIo  = &PciIoDevice->PciIo;\r
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, StatusIndex, 1, &StatusRegister);\r
   if (EFI_ERROR (Status)) {\r
     return EFI_UNSUPPORTED;\r
   }\r
@@ -992,30 +1143,24 @@ GetFastBackToBackSupport (
 **/\r
 VOID\r
 ProcessOptionRomLight (\r
-  IN PCI_IO_DEVICE                      *PciIoDevice\r
+  IN PCI_IO_DEVICE  *PciIoDevice\r
   )\r
 {\r
-  PCI_IO_DEVICE   *Temp;\r
-  LIST_ENTRY      *CurrentLink;\r
+  PCI_IO_DEVICE  *Temp;\r
+  LIST_ENTRY     *CurrentLink;\r
 \r
   //\r
   // For RootBridge, PPB , P2C, go recursively to traverse all its children\r
   //\r
   CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
   while (CurrentLink != NULL && CurrentLink != &PciIoDevice->ChildList) {\r
-\r
     Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
 \r
     if (!IsListEmpty (&Temp->ChildList)) {\r
       ProcessOptionRomLight (Temp);\r
     }\r
 \r
-    PciRomGetImageMapping (Temp);\r
-\r
-    //\r
-    // The OpRom has already been processed in the first round\r
-    //\r
-    Temp->AllOpRomProcessed = TRUE;\r
+    Temp->AllOpRomProcessed = PciRomGetImageMapping (Temp);\r
 \r
     CurrentLink = CurrentLink->ForwardLink;\r
   }\r
@@ -1029,33 +1174,39 @@ ProcessOptionRomLight (
 **/\r
 EFI_STATUS\r
 DetermineDeviceAttribute (\r
-  IN PCI_IO_DEVICE                      *PciIoDevice\r
+  IN PCI_IO_DEVICE  *PciIoDevice\r
   )\r
 {\r
-  UINT16          Command;\r
-  UINT16          BridgeControl;\r
-  UINT16          OldCommand;\r
-  UINT16          OldBridgeControl;\r
-  BOOLEAN         FastB2BSupport;\r
-  PCI_IO_DEVICE   *Temp;\r
-  LIST_ENTRY      *CurrentLink;\r
-  EFI_STATUS      Status;\r
+  UINT16         Command;\r
+  UINT16         BridgeControl;\r
+  UINT16         OldCommand;\r
+  UINT16         OldBridgeControl;\r
+  BOOLEAN        FastB2BSupport;\r
+  PCI_IO_DEVICE  *Temp;\r
+  LIST_ENTRY     *CurrentLink;\r
+  EFI_STATUS     Status;\r
 \r
   //\r
-  // For Root Bridge, just copy it by RootBridgeIo proctocol\r
+  // For Root Bridge, just copy it by RootBridgeIo protocol\r
   // so as to keep consistent with the actual attribute\r
   //\r
   if (PciIoDevice->Parent == NULL) {\r
     Status = PciIoDevice->PciRootBridgeIo->GetAttributes (\r
-                                            PciIoDevice->PciRootBridgeIo,\r
-                                            &PciIoDevice->Supports,\r
-                                            &PciIoDevice->Attributes\r
-                                            );\r
+                                             PciIoDevice->PciRootBridgeIo,\r
+                                             &PciIoDevice->Supports,\r
+                                             &PciIoDevice->Attributes\r
+                                             );\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
-  } else {\r
 \r
+    //\r
+    // Assume the PCI Root Bridge supports DAC\r
+    //\r
+    PciIoDevice->Supports |= (UINT64)(EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE |\r
+                                      EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM |\r
+                                      EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE);\r
+  } else {\r
     //\r
     // Set the attributes to be checked for common PCI devices and PPB or P2C\r
     // Since some devices only support part of them, it is better to set the\r
@@ -1084,9 +1235,11 @@ DetermineDeviceAttribute (
     PciSetDeviceAttribute (PciIoDevice, OldCommand, OldBridgeControl, EFI_SET_ATTRIBUTES);\r
 \r
     //\r
-    // Enable other supported attributes but not defined in PCI_IO_PROTOCOL\r
-    //\r
-    PCI_ENABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE);\r
+    // Enable other PCI supported attributes but not defined in PCI_IO_PROTOCOL\r
+    // For PCI Express devices, Memory Write and Invalidate is hardwired to 0b so only enable it for PCI devices.\r
+    if (!PciIoDevice->IsPciExp) {\r
+      PCI_ENABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE);\r
+    }\r
   }\r
 \r
   FastB2BSupport = TRUE;\r
@@ -1103,14 +1256,14 @@ DetermineDeviceAttribute (
   //\r
   CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
   while (CurrentLink != NULL && CurrentLink != &PciIoDevice->ChildList) {\r
-\r
-    Temp    = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
-    Status  = DetermineDeviceAttribute (Temp);\r
+    Temp   = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+    Status = DetermineDeviceAttribute (Temp);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
+\r
     //\r
-    // Detect Fast Bact to Bact support for the device under the bridge\r
+    // Detect Fast Back to Back support for the device under the bridge\r
     //\r
     Status = GetFastBackToBackSupport (Temp, PCI_PRIMARY_STATUS_OFFSET);\r
     if (FastB2BSupport && EFI_ERROR (Status)) {\r
@@ -1119,13 +1272,12 @@ DetermineDeviceAttribute (
 \r
     CurrentLink = CurrentLink->ForwardLink;\r
   }\r
+\r
   //\r
   // Set or clear Fast Back to Back bit for the whole bridge\r
   //\r
   if (!IsListEmpty (&PciIoDevice->ChildList)) {\r
-\r
     if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {\r
-\r
       Status = GetFastBackToBackSupport (PciIoDevice, PCI_BRIDGE_STATUS_REGISTER_OFFSET);\r
 \r
       if (EFI_ERROR (Status) || (!FastB2BSupport)) {\r
@@ -1148,6 +1300,7 @@ DetermineDeviceAttribute (
       CurrentLink = CurrentLink->ForwardLink;\r
     }\r
   }\r
+\r
   //\r
   // End for IsListEmpty\r
   //\r
@@ -1159,6 +1312,7 @@ DetermineDeviceAttribute (
 \r
   @param PciIoDevice      Input Pci device instance. Output Pci device instance with updated\r
                           Bar information.\r
+  @param IgnoreOptionRom  Output If the option rom of incompatible device need to be ignored.\r
 \r
   @retval EFI_SUCCESS     Successfully updated bar information.\r
   @retval EFI_UNSUPPORTED Given PCI device doesn't belong to incompatible PCI device list.\r
@@ -1166,20 +1320,20 @@ DetermineDeviceAttribute (
 **/\r
 EFI_STATUS\r
 UpdatePciInfo (\r
-  IN OUT PCI_IO_DEVICE    *PciIoDevice\r
+  IN OUT PCI_IO_DEVICE  *PciIoDevice,\r
+  OUT BOOLEAN           *IgnoreOptionRom\r
   )\r
 {\r
-  EFI_STATUS                        Status;\r
-  UINTN                             BarIndex;\r
-  UINTN                             BarEndIndex;\r
-  BOOLEAN                           SetFlag;\r
-  VOID                              *Configuration;\r
-  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
+  EFI_STATUS                         Status;\r
+  UINTN                              BarIndex;\r
+  BOOLEAN                            SetFlag;\r
+  VOID                               *Configuration;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Ptr;\r
 \r
   Configuration = NULL;\r
   Status        = EFI_SUCCESS;\r
 \r
-  if (gEfiIncompatiblePciDeviceSupport == NULL) {\r
+  if (gIncompatiblePciDeviceSupport == NULL) {\r
     //\r
     // It can only be supported after the Incompatible PCI Device\r
     // Support Protocol has been installed\r
@@ -1187,37 +1341,36 @@ UpdatePciInfo (
     Status = gBS->LocateProtocol (\r
                     &gEfiIncompatiblePciDeviceSupportProtocolGuid,\r
                     NULL,\r
-                    (VOID **) &gEfiIncompatiblePciDeviceSupport\r
+                    (VOID **)&gIncompatiblePciDeviceSupport\r
                     );\r
   }\r
-  if (Status == EFI_SUCCESS) {\r
-      //\r
-      // Check whether the device belongs to incompatible devices from protocol or not\r
-      // If it is , then get its special requirement in the ACPI table\r
-      //\r
-      Status = gEfiIncompatiblePciDeviceSupport->CheckDevice (\r
-                                                   gEfiIncompatiblePciDeviceSupport,\r
-                                                   PciIoDevice->Pci.Hdr.VendorId,\r
-                                                   PciIoDevice->Pci.Hdr.DeviceId,\r
-                                                   PciIoDevice->Pci.Hdr.RevisionID,\r
-                                                   PciIoDevice->Pci.Device.SubsystemVendorID,\r
-                                                   PciIoDevice->Pci.Device.SubsystemID,\r
-                                                   &Configuration\r
-                                                   );\r
 \r
+  if (Status == EFI_SUCCESS) {\r
+    //\r
+    // Check whether the device belongs to incompatible devices from protocol or not\r
+    // If it is , then get its special requirement in the ACPI table\r
+    //\r
+    Status = gIncompatiblePciDeviceSupport->CheckDevice (\r
+                                              gIncompatiblePciDeviceSupport,\r
+                                              PciIoDevice->Pci.Hdr.VendorId,\r
+                                              PciIoDevice->Pci.Hdr.DeviceId,\r
+                                              PciIoDevice->Pci.Hdr.RevisionID,\r
+                                              PciIoDevice->Pci.Device.SubsystemVendorID,\r
+                                              PciIoDevice->Pci.Device.SubsystemID,\r
+                                              &Configuration\r
+                                              );\r
   }\r
 \r
-  if (EFI_ERROR (Status) || Configuration == NULL ) {\r
+  if (EFI_ERROR (Status) || (Configuration == NULL)) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
   //\r
   // Update PCI device information from the ACPI table\r
   //\r
-  Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
+  Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Configuration;\r
 \r
   while (Ptr->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
-\r
     if (Ptr->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
       //\r
       // The format is not support\r
@@ -1225,48 +1378,89 @@ UpdatePciInfo (
       break;\r
     }\r
 \r
-    BarIndex    = (UINTN) Ptr->AddrTranslationOffset;\r
-    BarEndIndex = BarIndex;\r
-\r
     //\r
-    // Update all the bars in the device\r
+    // According to "Table 20. ACPI 2.0 & 3.0 QWORD Address Space Descriptor Usage"\r
+    // in PI Spec 1.7, Type-specific flags can be set to 0 when Address Translation\r
+    // Offset == 6 to skip device option ROM (do not probe option rom BAR).\r
     //\r
-    if (BarIndex == PCI_BAR_ALL) {\r
-      BarIndex    = 0;\r
-      BarEndIndex = PCI_MAX_BAR - 1;\r
-    }\r
-\r
-    if (BarIndex > PCI_MAX_BAR) {\r
+    if (((Ptr->AddrTranslationOffset == PCI_MAX_BAR) && (Ptr->SpecificFlag == 0))) {\r
+      *IgnoreOptionRom = TRUE;\r
       Ptr++;\r
       continue;\r
     }\r
 \r
-    for (; BarIndex <= BarEndIndex; BarIndex++) {\r
+    for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex++) {\r
+      if ((Ptr->AddrTranslationOffset != MAX_UINT64) &&\r
+          (Ptr->AddrTranslationOffset != MAX_UINT8) &&\r
+          (Ptr->AddrTranslationOffset != BarIndex)\r
+          )\r
+      {\r
+        //\r
+        // Skip updating when AddrTranslationOffset is not MAX_UINT64 or MAX_UINT8 (wide match).\r
+        // Skip updating when current BarIndex doesn't equal to AddrTranslationOffset.\r
+        // Comparing against MAX_UINT8 is to keep backward compatibility.\r
+        //\r
+        continue;\r
+      }\r
+\r
       SetFlag = FALSE;\r
       switch (Ptr->ResType) {\r
-      case ACPI_ADDRESS_SPACE_TYPE_MEM:\r
+        case ACPI_ADDRESS_SPACE_TYPE_MEM:\r
 \r
-        //\r
-        // Make sure the bar is memory type\r
-        //\r
-        if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeMem)) {\r
-          SetFlag = TRUE;\r
-        }\r
-        break;\r
+          //\r
+          // Make sure the bar is memory type\r
+          //\r
+          if (CheckBarType (PciIoDevice, (UINT8)BarIndex, PciBarTypeMem)) {\r
+            SetFlag = TRUE;\r
+\r
+            //\r
+            // Ignored if granularity is 0.\r
+            // Ignored if PCI BAR is I/O or 32-bit memory.\r
+            // If PCI BAR is 64-bit memory and granularity is 32, then\r
+            // the PCI BAR resource is allocated below 4GB.\r
+            // If PCI BAR is 64-bit memory and granularity is 64, then\r
+            // the PCI BAR resource is allocated above 4GB.\r
+            //\r
+            if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeMem64) {\r
+              switch (Ptr->AddrSpaceGranularity) {\r
+                case 32:\r
+                  PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;\r
+                case 64:\r
+                  PciIoDevice->PciBar[BarIndex].BarTypeFixed = TRUE;\r
+                  break;\r
+                default:\r
+                  break;\r
+              }\r
+            }\r
+\r
+            if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypePMem64) {\r
+              switch (Ptr->AddrSpaceGranularity) {\r
+                case 32:\r
+                  PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;\r
+                case 64:\r
+                  PciIoDevice->PciBar[BarIndex].BarTypeFixed = TRUE;\r
+                  break;\r
+                default:\r
+                  break;\r
+              }\r
+            }\r
+          }\r
 \r
-      case ACPI_ADDRESS_SPACE_TYPE_IO:\r
+          break;\r
 \r
-        //\r
-        // Make sure the bar is IO type\r
-        //\r
-        if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeIo)) {\r
-          SetFlag = TRUE;\r
-        }\r
-        break;\r
+        case ACPI_ADDRESS_SPACE_TYPE_IO:\r
+\r
+          //\r
+          // Make sure the bar is IO type\r
+          //\r
+          if (CheckBarType (PciIoDevice, (UINT8)BarIndex, PciBarTypeIo)) {\r
+            SetFlag = TRUE;\r
+          }\r
+\r
+          break;\r
       }\r
 \r
       if (SetFlag) {\r
-\r
         //\r
         // Update the new alignment for the device\r
         //\r
@@ -1275,7 +1469,7 @@ UpdatePciInfo (
         //\r
         // Update the new length for the device\r
         //\r
-        if (Ptr->AddrLen != PCI_BAR_NOCHANGE) {\r
+        if (Ptr->AddrLen != 0) {\r
           PciIoDevice->PciBar[BarIndex].Length = Ptr->AddrLen;\r
         }\r
       }\r
@@ -1291,6 +1485,8 @@ UpdatePciInfo (
 \r
 /**\r
   This routine will update the alignment with the new alignment.\r
+  Compare with OLD_ALIGN/EVEN_ALIGN/SQUAD_ALIGN/DQUAD_ALIGN is to keep\r
+  backward compatibility.\r
 \r
   @param Alignment    Input Old alignment. Output updated alignment.\r
   @param NewAlignment New alignment.\r
@@ -1298,8 +1494,8 @@ UpdatePciInfo (
 **/\r
 VOID\r
 SetNewAlign (\r
-  IN OUT UINT64     *Alignment,\r
-  IN     UINT64     NewAlignment\r
+  IN OUT UINT64  *Alignment,\r
+  IN     UINT64  NewAlignment\r
   )\r
 {\r
   UINT64  OldAlignment;\r
@@ -1309,42 +1505,44 @@ SetNewAlign (
   // The new alignment is the same as the original,\r
   // so skip it\r
   //\r
-  if (NewAlignment == PCI_BAR_OLD_ALIGN) {\r
-    return ;\r
+  if ((NewAlignment == 0) || (NewAlignment == OLD_ALIGN)) {\r
+    return;\r
   }\r
+\r
   //\r
   // Check the validity of the parameter\r
   //\r
-   if (NewAlignment != PCI_BAR_EVEN_ALIGN  &&\r
-       NewAlignment != PCI_BAR_SQUAD_ALIGN &&\r
-       NewAlignment != PCI_BAR_DQUAD_ALIGN ) {\r
+  if ((NewAlignment != EVEN_ALIGN) &&\r
+      (NewAlignment != SQUAD_ALIGN) &&\r
+      (NewAlignment != DQUAD_ALIGN))\r
+  {\r
     *Alignment = NewAlignment;\r
-    return ;\r
+    return;\r
   }\r
 \r
-  OldAlignment  = (*Alignment) + 1;\r
-  ShiftBit      = 0;\r
+  OldAlignment = (*Alignment) + 1;\r
+  ShiftBit     = 0;\r
 \r
   //\r
   // Get the first non-zero hex value of the length\r
   //\r
   while ((OldAlignment & 0x0F) == 0x00) {\r
     OldAlignment = RShiftU64 (OldAlignment, 4);\r
-    ShiftBit += 4;\r
+    ShiftBit    += 4;\r
   }\r
 \r
   //\r
   // Adjust the alignment to even, quad or double quad boundary\r
   //\r
-  if (NewAlignment == PCI_BAR_EVEN_ALIGN) {\r
+  if (NewAlignment == EVEN_ALIGN) {\r
     if ((OldAlignment & 0x01) != 0) {\r
       OldAlignment = OldAlignment + 2 - (OldAlignment & 0x01);\r
     }\r
-  } else if (NewAlignment == PCI_BAR_SQUAD_ALIGN) {\r
+  } else if (NewAlignment == SQUAD_ALIGN) {\r
     if ((OldAlignment & 0x03) != 0) {\r
       OldAlignment = OldAlignment + 4 - (OldAlignment & 0x03);\r
     }\r
-  } else if (NewAlignment == PCI_BAR_DQUAD_ALIGN) {\r
+  } else if (NewAlignment == DQUAD_ALIGN) {\r
     if ((OldAlignment & 0x07) != 0) {\r
       OldAlignment = OldAlignment + 8 - (OldAlignment & 0x07);\r
     }\r
@@ -1353,10 +1551,10 @@ SetNewAlign (
   //\r
   // Update the old value\r
   //\r
-  NewAlignment  = LShiftU64 (OldAlignment, ShiftBit) - 1;\r
-  *Alignment    = NewAlignment;\r
+  NewAlignment = LShiftU64 (OldAlignment, ShiftBit) - 1;\r
+  *Alignment   = NewAlignment;\r
 \r
-  return ;\r
+  return;\r
 }\r
 \r
 /**\r
@@ -1379,8 +1577,6 @@ PciIovParseVfBar (
   UINT32      Value;\r
   UINT32      OriginalValue;\r
   UINT32      Mask;\r
-  UINT32      Data;\r
-  UINT8       Index;\r
   EFI_STATUS  Status;\r
 \r
   //\r
@@ -1395,11 +1591,11 @@ PciIovParseVfBar (
   Value         = 0;\r
 \r
   Status = VfBarExisted (\r
-            PciIoDevice,\r
-            Offset,\r
-            &Value,\r
-            &OriginalValue\r
-            );\r
+             PciIoDevice,\r
+             Offset,\r
+             &Value,\r
+             &OriginalValue\r
+             );\r
 \r
   if (EFI_ERROR (Status)) {\r
     PciIoDevice->VfPciBar[BarIndex].BaseAddress = 0;\r
@@ -1409,140 +1605,133 @@ PciIovParseVfBar (
     //\r
     // Scan all the BARs anyway\r
     //\r
-    PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16) Offset;\r
+    PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16)Offset;\r
     return Offset + 4;\r
   }\r
 \r
-  PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16) Offset;\r
+  PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16)Offset;\r
   if ((Value & 0x01) != 0) {\r
     //\r
     // Device I/Os. Impossible\r
     //\r
     ASSERT (FALSE);\r
     return Offset + 4;\r
-\r
   } else {\r
-\r
-    Mask  = 0xfffffff0;\r
+    Mask = 0xfffffff0;\r
 \r
     PciIoDevice->VfPciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
 \r
     switch (Value & 0x07) {\r
+      //\r
+      // memory space; anywhere in 32 bit address space\r
+      //\r
+      case 0x00:\r
+        if ((Value & 0x08) != 0) {\r
+          PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem32;\r
+        } else {\r
+          PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem32;\r
+        }\r
 \r
-    //\r
-    //memory space; anywhere in 32 bit address space\r
-    //\r
-    case 0x00:\r
-      if ((Value & 0x08) != 0) {\r
-        PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem32;\r
-      } else {\r
-        PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem32;\r
-      }\r
+        PciIoDevice->VfPciBar[BarIndex].Length    = (~(Value & Mask)) + 1;\r
+        PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
+\r
+        //\r
+        // Adjust Length\r
+        //\r
+        PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs);\r
+        //\r
+        // Adjust Alignment\r
+        //\r
+        if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+          PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+        }\r
 \r
-      PciIoDevice->VfPciBar[BarIndex].Length    = (~(Value & Mask)) + 1;\r
-      PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
+        break;\r
 \r
       //\r
-      // Adjust Length\r
+      // memory space; anywhere in 64 bit address space\r
       //\r
-      PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs);\r
-      //\r
-      // Adjust Alignment\r
-      //\r
-      if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
-        PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
-      }\r
+      case 0x04:\r
+        if ((Value & 0x08) != 0) {\r
+          PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem64;\r
+        } else {\r
+          PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem64;\r
+        }\r
 \r
-      break;\r
+        //\r
+        // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
+        // is regarded as an extension for the first bar. As a result\r
+        // the sizing will be conducted on combined 64 bit value\r
+        // Here just store the masked first 32bit value for future size\r
+        // calculation\r
+        //\r
+        PciIoDevice->VfPciBar[BarIndex].Length    = Value & Mask;\r
+        PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
 \r
-    //\r
-    // memory space; anywhere in 64 bit address space\r
-    //\r
-    case 0x04:\r
-      if ((Value & 0x08) != 0) {\r
-        PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem64;\r
-      } else {\r
-        PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem64;\r
-      }\r
+        if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+          PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+        }\r
 \r
-      //\r
-      // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
-      // is regarded as an extension for the first bar. As a result\r
-      // the sizing will be conducted on combined 64 bit value\r
-      // Here just store the masked first 32bit value for future size\r
-      // calculation\r
-      //\r
-      PciIoDevice->VfPciBar[BarIndex].Length    = Value & Mask;\r
-      PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
+        //\r
+        // Increment the offset to point to next DWORD\r
+        //\r
+        Offset += 4;\r
 \r
-      if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
-        PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
-      }\r
+        Status = VfBarExisted (\r
+                   PciIoDevice,\r
+                   Offset,\r
+                   &Value,\r
+                   &OriginalValue\r
+                   );\r
 \r
-      //\r
-      // Increment the offset to point to next DWORD\r
-      //\r
-      Offset += 4;\r
+        if (EFI_ERROR (Status)) {\r
+          PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+          return Offset + 4;\r
+        }\r
 \r
-      Status = VfBarExisted (\r
-                PciIoDevice,\r
-                Offset,\r
-                &Value,\r
-                &OriginalValue\r
-                );\r
+        //\r
+        // Fix the length to support some special 64 bit BAR\r
+        //\r
+        Value |= ((UINT32)-1 << HighBitSet32 (Value));\r
 \r
-      if (EFI_ERROR (Status)) {\r
-        return Offset + 4;\r
-      }\r
+        //\r
+        // Calculate the size of 64bit bar\r
+        //\r
+        PciIoDevice->VfPciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64)OriginalValue, 32);\r
 \r
-      //\r
-      // Fix the length to support some spefic 64 bit BAR\r
-      //\r
-      Data  = Value;\r
-      Index = 0;\r
-      for (Data = Value; Data != 0; Data >>= 1) {\r
-       Index ++;\r
-      }\r
-      Value |= ((UINT32)(-1) << Index); \r
+        PciIoDevice->VfPciBar[BarIndex].Length    = PciIoDevice->VfPciBar[BarIndex].Length | LShiftU64 ((UINT64)Value, 32);\r
+        PciIoDevice->VfPciBar[BarIndex].Length    = (~(PciIoDevice->VfPciBar[BarIndex].Length)) + 1;\r
+        PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
 \r
-      //\r
-      // Calculate the size of 64bit bar\r
-      //\r
-      PciIoDevice->VfPciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32);\r
+        //\r
+        // Adjust Length\r
+        //\r
+        PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs);\r
+        //\r
+        // Adjust Alignment\r
+        //\r
+        if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+          PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+        }\r
 \r
-      PciIoDevice->VfPciBar[BarIndex].Length    = PciIoDevice->VfPciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);\r
-      PciIoDevice->VfPciBar[BarIndex].Length    = (~(PciIoDevice->VfPciBar[BarIndex].Length)) + 1;\r
-      PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
+        break;\r
 \r
       //\r
-      // Adjust Length\r
-      //\r
-      PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs);\r
+      // reserved\r
       //\r
-      // Adjust Alignment\r
-      //\r
-      if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
-        PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
-      }\r
+      default:\r
+        PciIoDevice->VfPciBar[BarIndex].BarType   = PciBarTypeUnknown;\r
+        PciIoDevice->VfPciBar[BarIndex].Length    = (~(Value & Mask)) + 1;\r
+        PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
 \r
-      break;\r
-\r
-    //\r
-    // reserved\r
-    //\r
-    default:\r
-      PciIoDevice->VfPciBar[BarIndex].BarType   = PciBarTypeUnknown;\r
-      PciIoDevice->VfPciBar[BarIndex].Length    = (~(Value & Mask)) + 1;\r
-      PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
-\r
-      if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
-        PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
-      }\r
+        if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+          PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+        }\r
 \r
-      break;\r
+        break;\r
     }\r
   }\r
-  \r
+\r
   //\r
   // Check the length again so as to keep compatible with some special bars\r
   //\r
@@ -1551,7 +1740,7 @@ PciIovParseVfBar (
     PciIoDevice->VfPciBar[BarIndex].BaseAddress = 0;\r
     PciIoDevice->VfPciBar[BarIndex].Alignment   = 0;\r
   }\r
-  \r
+\r
   //\r
   // Increment number of bar\r
   //\r
@@ -1578,8 +1767,6 @@ PciParseBar (
   UINT32      Value;\r
   UINT32      OriginalValue;\r
   UINT32      Mask;\r
-  UINT32      Data;\r
-  UINT8       Index;\r
   EFI_STATUS  Status;\r
 \r
   OriginalValue = 0;\r
@@ -1600,11 +1787,12 @@ PciParseBar (
     //\r
     // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway\r
     //\r
-    PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
+    PciIoDevice->PciBar[BarIndex].Offset = (UINT8)Offset;\r
     return Offset + 4;\r
   }\r
 \r
-  PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
+  PciIoDevice->PciBar[BarIndex].BarTypeFixed = FALSE;\r
+  PciIoDevice->PciBar[BarIndex].Offset       = (UINT8)Offset;\r
   if ((Value & 0x01) != 0) {\r
     //\r
     // Device I/Os\r
@@ -1618,7 +1806,6 @@ PciParseBar (
       PciIoDevice->PciBar[BarIndex].BarType   = PciBarTypeIo32;\r
       PciIoDevice->PciBar[BarIndex].Length    = ((~(Value & Mask)) + 1);\r
       PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-\r
     } else {\r
       //\r
       // It is a IO16 bar\r
@@ -1626,136 +1813,134 @@ PciParseBar (
       PciIoDevice->PciBar[BarIndex].BarType   = PciBarTypeIo16;\r
       PciIoDevice->PciBar[BarIndex].Length    = 0x0000FFFF & ((~(Value & Mask)) + 1);\r
       PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-\r
     }\r
+\r
     //\r
-    // Workaround. Some platforms inplement IO bar with 0 length\r
+    // Workaround. Some platforms implement IO bar with 0 length\r
     // Need to treat it as no-bar\r
     //\r
     if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
-      PciIoDevice->PciBar[BarIndex].BarType = (PCI_BAR_TYPE) 0;\r
+      PciIoDevice->PciBar[BarIndex].BarType = (PCI_BAR_TYPE)0;\r
     }\r
 \r
-    PciIoDevice->PciBar[BarIndex].Prefetchable  = FALSE;\r
-    PciIoDevice->PciBar[BarIndex].BaseAddress   = OriginalValue & Mask;\r
-\r
+    PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
   } else {\r
-\r
-    Mask  = 0xfffffff0;\r
+    Mask = 0xfffffff0;\r
 \r
     PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
 \r
     switch (Value & 0x07) {\r
+      //\r
+      // memory space; anywhere in 32 bit address space\r
+      //\r
+      case 0x00:\r
+        if ((Value & 0x08) != 0) {\r
+          PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;\r
+        } else {\r
+          PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;\r
+        }\r
 \r
-    //\r
-    //memory space; anywhere in 32 bit address space\r
-    //\r
-    case 0x00:\r
-      if ((Value & 0x08) != 0) {\r
-        PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;\r
-      } else {\r
-        PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;\r
-      }\r
+        PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
+        if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
+          //\r
+          // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
+          //\r
+          PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
+        } else {\r
+          PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+        }\r
+\r
+        break;\r
+\r
+      //\r
+      // memory space; anywhere in 64 bit address space\r
+      //\r
+      case 0x04:\r
+        if ((Value & 0x08) != 0) {\r
+          PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64;\r
+        } else {\r
+          PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64;\r
+        }\r
 \r
-      PciIoDevice->PciBar[BarIndex].Length    = (~(Value & Mask)) + 1;\r
-      if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
         //\r
-        // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
+        // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
+        // is regarded as an extension for the first bar. As a result\r
+        // the sizing will be conducted on combined 64 bit value\r
+        // Here just store the masked first 32bit value for future size\r
+        // calculation\r
         //\r
-        PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
-      } else {\r
+        PciIoDevice->PciBar[BarIndex].Length    = Value & Mask;\r
         PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-      }\r
-      break;\r
 \r
-    //\r
-    // memory space; anywhere in 64 bit address space\r
-    //\r
-    case 0x04:\r
-      if ((Value & 0x08) != 0) {\r
-        PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64;\r
-      } else {\r
-        PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64;\r
-      }\r
+        //\r
+        // Increment the offset to point to next DWORD\r
+        //\r
+        Offset += 4;\r
 \r
-      //\r
-      // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
-      // is regarded as an extension for the first bar. As a result\r
-      // the sizing will be conducted on combined 64 bit value\r
-      // Here just store the masked first 32bit value for future size\r
-      // calculation\r
-      //\r
-      PciIoDevice->PciBar[BarIndex].Length    = Value & Mask;\r
-      PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+        Status = BarExisted (\r
+                   PciIoDevice,\r
+                   Offset,\r
+                   &Value,\r
+                   &OriginalValue\r
+                   );\r
 \r
-      //\r
-      // Increment the offset to point to next DWORD\r
-      //\r
-      Offset += 4;\r
+        if (EFI_ERROR (Status)) {\r
+          //\r
+          // the high 32 bit does not claim any BAR, we need to re-check the low 32 bit BAR again\r
+          //\r
+          if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
+            //\r
+            // some device implement MMIO bar with 0 length, need to treat it as no-bar\r
+            //\r
+            PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+            return Offset + 4;\r
+          }\r
+        }\r
 \r
-      Status = BarExisted (\r
-                 PciIoDevice,\r
-                 Offset,\r
-                 &Value,\r
-                 &OriginalValue\r
-                 );\r
+        //\r
+        // Fix the length to support some special 64 bit BAR\r
+        //\r
+        if (Value == 0) {\r
+          DEBUG ((DEBUG_INFO, "[PciBus]BAR probing for upper 32bit of MEM64 BAR returns 0, change to 0xFFFFFFFF.\n"));\r
+          Value = (UINT32)-1;\r
+        } else {\r
+          Value |= ((UINT32)(-1) << HighBitSet32 (Value));\r
+        }\r
 \r
-      if (EFI_ERROR (Status)) {\r
         //\r
-        // the high 32 bit does not claim any BAR, we need to re-check the low 32 bit BAR again\r
+        // Calculate the size of 64bit bar\r
         //\r
-        if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
+        PciIoDevice->PciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64)OriginalValue, 32);\r
+\r
+        PciIoDevice->PciBar[BarIndex].Length = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64)Value, 32);\r
+        PciIoDevice->PciBar[BarIndex].Length = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1;\r
+        if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
           //\r
-          // some device implement MMIO bar with 0 length, need to treat it as no-bar\r
+          // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
           //\r
-          PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+          PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
+        } else {\r
+          PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
         }\r
-        return Offset + 4;\r
-      }\r
 \r
-      //\r
-      // Fix the length to support some spefic 64 bit BAR\r
-      //\r
-      Data  = Value;\r
-      Index = 0;\r
-      for (Data = Value; Data != 0; Data >>= 1) {\r
-        Index ++;\r
-      }\r
-      Value |= ((UINT32)(-1) << Index);\r
+        break;\r
 \r
       //\r
-      // Calculate the size of 64bit bar\r
+      // reserved\r
       //\r
-      PciIoDevice->PciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32);\r
-\r
-      PciIoDevice->PciBar[BarIndex].Length    = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);\r
-      PciIoDevice->PciBar[BarIndex].Length    = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1;\r
-      if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
-        //\r
-        // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
-        //\r
-        PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
-      } else {\r
-        PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-      }\r
-\r
-      break;\r
+      default:\r
+        PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+        PciIoDevice->PciBar[BarIndex].Length  = (~(Value & Mask)) + 1;\r
+        if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
+          //\r
+          // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
+          //\r
+          PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
+        } else {\r
+          PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+        }\r
 \r
-    //\r
-    // reserved\r
-    //\r
-    default:\r
-      PciIoDevice->PciBar[BarIndex].BarType   = PciBarTypeUnknown;\r
-      PciIoDevice->PciBar[BarIndex].Length    = (~(Value & Mask)) + 1;\r
-      if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
-        //\r
-        // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
-        //\r
-        PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
-      } else {\r
-        PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-      }\r
-      break;\r
+        break;\r
     }\r
   }\r
 \r
@@ -1784,18 +1969,18 @@ PciParseBar (
 **/\r
 VOID\r
 InitializePciDevice (\r
-  IN PCI_IO_DEVICE    *PciIoDevice\r
+  IN PCI_IO_DEVICE  *PciIoDevice\r
   )\r
 {\r
-  EFI_PCI_IO_PROTOCOL *PciIo;\r
-  UINT8               Offset;\r
+  EFI_PCI_IO_PROTOCOL  *PciIo;\r
+  UINT8                Offset;\r
 \r
   PciIo = &(PciIoDevice->PciIo);\r
 \r
   //\r
   // Put all the resource apertures\r
   // Resource base is set to all ones so as to indicate its resource\r
-  // has not been alloacted\r
+  // has not been allocated\r
   //\r
   for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) {\r
     PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllOne);\r
@@ -1810,10 +1995,10 @@ InitializePciDevice (
 **/\r
 VOID\r
 InitializePpb (\r
-  IN PCI_IO_DEVICE    *PciIoDevice\r
+  IN PCI_IO_DEVICE  *PciIoDevice\r
   )\r
 {\r
-  EFI_PCI_IO_PROTOCOL *PciIo;\r
+  EFI_PCI_IO_PROTOCOL  *PciIo;\r
 \r
   PciIo = &(PciIoDevice->PciIo);\r
 \r
@@ -1854,10 +2039,10 @@ InitializePpb (
 **/\r
 VOID\r
 InitializeP2C (\r
-  IN PCI_IO_DEVICE    *PciIoDevice\r
+  IN PCI_IO_DEVICE  *PciIoDevice\r
   )\r
 {\r
-  EFI_PCI_IO_PROTOCOL *PciIo;\r
+  EFI_PCI_IO_PROTOCOL  *PciIo;\r
 \r
   PciIo = &(PciIoDevice->PciIo);\r
 \r
@@ -1885,10 +2070,92 @@ InitializeP2C (
 }\r
 \r
 /**\r
-  Create and initiliaze general PCI I/O device instance for\r
+  Authenticate the PCI device by using DeviceSecurityProtocol.\r
+\r
+  @param PciIoDevice  PCI device.\r
+\r
+  @retval EFI_SUCCESS     The device passes the authentication.\r
+  @return not EFI_SUCCESS The device failes the authentication or\r
+                          unexpected error happen during authentication.\r
+**/\r
+EFI_STATUS\r
+AuthenticatePciDevice (\r
+  IN PCI_IO_DEVICE  *PciIoDevice\r
+  )\r
+{\r
+  EDKII_DEVICE_IDENTIFIER  DeviceIdentifier;\r
+  EFI_STATUS               Status;\r
+\r
+  if (mDeviceSecurityProtocol != NULL) {\r
+    //\r
+    // Prepare the parameter\r
+    //\r
+    DeviceIdentifier.Version = EDKII_DEVICE_IDENTIFIER_REVISION;\r
+    CopyGuid (&DeviceIdentifier.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid);\r
+    DeviceIdentifier.DeviceHandle = NULL;\r
+    Status                        = gBS->InstallMultipleProtocolInterfaces (\r
+                                           &DeviceIdentifier.DeviceHandle,\r
+                                           &gEfiDevicePathProtocolGuid,\r
+                                           PciIoDevice->DevicePath,\r
+                                           &gEdkiiDeviceIdentifierTypePciGuid,\r
+                                           &PciIoDevice->PciIo,\r
+                                           NULL\r
+                                           );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    //\r
+    // Do DeviceAuthentication\r
+    //\r
+    Status = mDeviceSecurityProtocol->DeviceAuthenticate (mDeviceSecurityProtocol, &DeviceIdentifier);\r
+    //\r
+    // Always uninstall, because they are only for Authentication.\r
+    // No need to check return Status.\r
+    //\r
+    gBS->UninstallMultipleProtocolInterfaces (\r
+           DeviceIdentifier.DeviceHandle,\r
+           &gEfiDevicePathProtocolGuid,\r
+           PciIoDevice->DevicePath,\r
+           &gEdkiiDeviceIdentifierTypePciGuid,\r
+           &PciIoDevice->PciIo,\r
+           NULL\r
+           );\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Device Security Protocol is not found, just return success\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Checks if PCI device is Root Bridge.\r
+\r
+  @param PciIoDevice       Instance of PCI device\r
+\r
+  @retval TRUE             Device is Root Bridge\r
+  @retval FALSE            Device is not Root Bridge\r
+\r
+**/\r
+BOOLEAN\r
+IsRootBridge (\r
+  IN PCI_IO_DEVICE  *PciIoDevice\r
+  )\r
+{\r
+  if (PciIoDevice->Parent == NULL) {\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+/**\r
+  Create and initialize general PCI I/O device instance for\r
   PCI device/bridge device/hotplug bridge device.\r
 \r
-  @param PciRootBridgeIo   Pointer to instance of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+  @param Bridge            Parent bridge instance.\r
   @param Pci               Input Pci information block.\r
   @param Bus               Device Bus NO.\r
   @param Device            Device device NO.\r
@@ -1899,11 +2166,11 @@ InitializeP2C (
 **/\r
 PCI_IO_DEVICE *\r
 CreatePciIoDevice (\r
-  IN PCI_IO_DEVICE                    *Bridge,\r
-  IN PCI_TYPE00                       *Pci,\r
-  IN UINT8                            Bus,\r
-  IN UINT8                            Device,\r
-  IN UINT8                            Func\r
+  IN PCI_IO_DEVICE  *Bridge,\r
+  IN PCI_TYPE00     *Pci,\r
+  IN UINT8          Bus,\r
+  IN UINT8          Device,\r
+  IN UINT8          Func\r
   )\r
 {\r
   PCI_IO_DEVICE        *PciIoDevice;\r
@@ -1915,14 +2182,14 @@ CreatePciIoDevice (
     return NULL;\r
   }\r
 \r
-  PciIoDevice->Signature        = PCI_IO_DEVICE_SIGNATURE;\r
-  PciIoDevice->Handle           = NULL;\r
-  PciIoDevice->PciRootBridgeIo  = Bridge->PciRootBridgeIo;\r
-  PciIoDevice->DevicePath       = NULL;\r
-  PciIoDevice->BusNumber        = Bus;\r
-  PciIoDevice->DeviceNumber     = Device;\r
-  PciIoDevice->FunctionNumber   = Func;\r
-  PciIoDevice->Decodes          = 0;\r
+  PciIoDevice->Signature       = PCI_IO_DEVICE_SIGNATURE;\r
+  PciIoDevice->Handle          = NULL;\r
+  PciIoDevice->PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
+  PciIoDevice->DevicePath      = NULL;\r
+  PciIoDevice->BusNumber       = Bus;\r
+  PciIoDevice->DeviceNumber    = Device;\r
+  PciIoDevice->FunctionNumber  = Func;\r
+  PciIoDevice->Decodes         = 0;\r
 \r
   if (gFullEnumeration) {\r
     PciIoDevice->Allocated = FALSE;\r
@@ -1930,13 +2197,13 @@ CreatePciIoDevice (
     PciIoDevice->Allocated = TRUE;\r
   }\r
 \r
-  PciIoDevice->Registered         = FALSE;\r
-  PciIoDevice->Attributes         = 0;\r
-  PciIoDevice->Supports           = 0;\r
-  PciIoDevice->BusOverride        = FALSE;\r
-  PciIoDevice->AllOpRomProcessed  = FALSE;\r
+  PciIoDevice->Registered        = FALSE;\r
+  PciIoDevice->Attributes        = 0;\r
+  PciIoDevice->Supports          = 0;\r
+  PciIoDevice->BusOverride       = FALSE;\r
+  PciIoDevice->AllOpRomProcessed = FALSE;\r
 \r
-  PciIoDevice->IsPciExp           = FALSE;\r
+  PciIoDevice->IsPciExp = FALSE;\r
 \r
   CopyMem (&(PciIoDevice->Pci), Pci, sizeof (PCI_TYPE01));\r
 \r
@@ -1948,21 +2215,48 @@ CreatePciIoDevice (
   InitializePciLoadFile2 (PciIoDevice);\r
   PciIo = &PciIoDevice->PciIo;\r
 \r
+  //\r
+  // Create a device path for this PCI device and store it into its private data\r
+  //\r
+  CreatePciDevicePath (\r
+    Bridge->DevicePath,\r
+    PciIoDevice\r
+    );\r
+\r
   //\r
   // Detect if PCI Express Device\r
   //\r
   PciIoDevice->PciExpressCapabilityOffset = 0;\r
-  Status = LocateCapabilityRegBlock (\r
-             PciIoDevice,\r
-             EFI_PCI_CAPABILITY_ID_PCIEXP,\r
-             &PciIoDevice->PciExpressCapabilityOffset,\r
-             NULL\r
-             );\r
+  Status                                  = LocateCapabilityRegBlock (\r
+                                              PciIoDevice,\r
+                                              EFI_PCI_CAPABILITY_ID_PCIEXP,\r
+                                              &PciIoDevice->PciExpressCapabilityOffset,\r
+                                              NULL\r
+                                              );\r
   if (!EFI_ERROR (Status)) {\r
     PciIoDevice->IsPciExp = TRUE;\r
   }\r
 \r
-  if (PcdGetBool (PcdAriSupport)) {\r
+  //\r
+  // Now we can do the authentication check for the device.\r
+  //\r
+  Status = AuthenticatePciDevice (PciIoDevice);\r
+  //\r
+  // If authentication fails, skip this device.\r
+  //\r
+  if (EFI_ERROR (Status)) {\r
+    if (PciIoDevice->DevicePath != NULL) {\r
+      FreePool (PciIoDevice->DevicePath);\r
+    }\r
+\r
+    FreePool (PciIoDevice);\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Check if device's parent is not Root Bridge\r
+  //\r
+  if (PcdGetBool (PcdAriSupport) && !IsRootBridge (Bridge)) {\r
     //\r
     // Check if the device is an ARI device.\r
     //\r
@@ -1985,50 +2279,43 @@ CreatePciIoDevice (
       //\r
       ParentPciIo = &Bridge->PciIo;\r
       ParentPciIo->Pci.Read (\r
-                          ParentPciIo, \r
-                          EfiPciIoWidthUint32,\r
-                          Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_OFFSET,\r
-                          1,\r
-                          &Data32\r
-                          );\r
+                         ParentPciIo,\r
+                         EfiPciIoWidthUint32,\r
+                         Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_OFFSET,\r
+                         1,\r
+                         &Data32\r
+                         );\r
       if ((Data32 & EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING) != 0) {\r
         //\r
         // ARI forward support in bridge, so enable it.\r
         //\r
         ParentPciIo->Pci.Read (\r
-                            ParentPciIo,\r
-                            EfiPciIoWidthUint32,\r
-                            Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET,\r
-                            1,\r
-                            &Data32\r
-                            );\r
+                           ParentPciIo,\r
+                           EfiPciIoWidthUint32,\r
+                           Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET,\r
+                           1,\r
+                           &Data32\r
+                           );\r
         if ((Data32 & EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING) == 0) {\r
           Data32 |= EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING;\r
           ParentPciIo->Pci.Write (\r
-                              ParentPciIo,\r
-                              EfiPciIoWidthUint32,\r
-                              Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET,\r
-                              1,\r
-                              &Data32\r
-                              );\r
+                             ParentPciIo,\r
+                             EfiPciIoWidthUint32,\r
+                             Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET,\r
+                             1,\r
+                             &Data32\r
+                             );\r
           DEBUG ((\r
-            EFI_D_INFO,\r
-            "PCI B%x.D%x.F%x - ARI forwarding enabled\n",\r
-            (UINTN)Bridge->BusNumber,\r
-            (UINTN)Bridge->DeviceNumber,\r
-            (UINTN)Bridge->FunctionNumber\r
+            DEBUG_INFO,\r
+            " ARI: forwarding enabled for PPB[%02x:%02x:%02x]\n",\r
+            Bridge->BusNumber,\r
+            Bridge->DeviceNumber,\r
+            Bridge->FunctionNumber\r
             ));\r
         }\r
       }\r
 \r
-      DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI ARI B%x.D%x.F%x - ARI Cap offset - 0x%x\n",\r
-        (UINTN)Bus,\r
-        (UINTN)Device,\r
-        (UINTN)Func,\r
-        (UINTN)PciIoDevice->AriCapabilityOffset\r
-        ));\r
+      DEBUG ((DEBUG_INFO, " ARI: CapOffset = 0x%x\n", PciIoDevice->AriCapabilityOffset));\r
     }\r
   }\r
 \r
@@ -2044,16 +2331,17 @@ CreatePciIoDevice (
                NULL\r
                );\r
     if (!EFI_ERROR (Status)) {\r
-      UINT16    VFStride;\r
-      UINT16    FirstVFOffset;\r
-      UINT16    Data16;\r
-      UINT32    PFRid;\r
-      UINT32    LastVF;\r
+      UINT32  SupportedPageSize;\r
+      UINT16  VFStride;\r
+      UINT16  FirstVFOffset;\r
+      UINT16  Data16;\r
+      UINT32  PFRid;\r
+      UINT32  LastVF;\r
 \r
       //\r
       // If the SR-IOV device is an ARI device, then Set ARI Capable Hierarchy for the device.\r
       //\r
-      if (PcdGetBool (PcdAriSupport) && PciIoDevice->AriCapabilityOffset != 0) {\r
+      if (PcdGetBool (PcdAriSupport) && (PciIoDevice->AriCapabilityOffset != 0)) {\r
         PciIo->Pci.Read (\r
                      PciIo,\r
                      EfiPciIoWidthUint16,\r
@@ -2080,18 +2368,9 @@ CreatePciIoDevice (
                    EfiPciIoWidthUint32,\r
                    PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SUPPORTED_PAGE_SIZE,\r
                    1,\r
-                   &PciIoDevice->SystemPageSize\r
+                   &SupportedPageSize\r
                    );\r
-      DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI SR-IOV B%x.D%x.F%x - SupportedPageSize - 0x%x\n",\r
-        (UINTN)Bus,\r
-        (UINTN)Device,\r
-        (UINTN)Func,\r
-        PciIoDevice->SystemPageSize\r
-        ));\r
-\r
-      PciIoDevice->SystemPageSize = (PcdGet32 (PcdSrIovSystemPageSize) & PciIoDevice->SystemPageSize);\r
+      PciIoDevice->SystemPageSize = (PcdGet32 (PcdSrIovSystemPageSize) & SupportedPageSize);\r
       ASSERT (PciIoDevice->SystemPageSize != 0);\r
 \r
       PciIo->Pci.Write (\r
@@ -2101,14 +2380,6 @@ CreatePciIoDevice (
                    1,\r
                    &PciIoDevice->SystemPageSize\r
                    );\r
-      DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI SR-IOV B%x.D%x.F%x - SystemPageSize - 0x%x\n",\r
-        (UINTN)Bus,\r
-        (UINTN)Device,\r
-        (UINTN)Func,\r
-        PciIoDevice->SystemPageSize\r
-        ));\r
       //\r
       // Adjust SystemPageSize for Alignment usage later\r
       //\r
@@ -2128,15 +2399,6 @@ CreatePciIoDevice (
                    1,\r
                    &FirstVFOffset\r
                    );\r
-      DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI SR-IOV B%x.D%x.F%x - FirstVFOffset - 0x%x\n",\r
-        (UINTN)Bus,\r
-        (UINTN)Device,\r
-        (UINTN)Func,\r
-        (UINTN)FirstVFOffset\r
-        ));\r
-\r
       PciIo->Pci.Read (\r
                    PciIo,\r
                    EfiPciIoWidthUint16,\r
@@ -2144,15 +2406,6 @@ CreatePciIoDevice (
                    1,\r
                    &PciIoDevice->InitialVFs\r
                    );\r
-      DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI SR-IOV B%x.D%x.F%x - InitialVFs - 0x%x\n",\r
-        (UINTN)Bus,\r
-        (UINTN)Device,\r
-        (UINTN)Func,\r
-        (UINTN)PciIoDevice->InitialVFs\r
-        ));\r
-\r
       PciIo->Pci.Read (\r
                    PciIo,\r
                    EfiPciIoWidthUint16,\r
@@ -2160,41 +2413,30 @@ CreatePciIoDevice (
                    1,\r
                    &VFStride\r
                    );\r
-      DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI SR-IOV B%x.D%x.F%x - VFStride - 0x%x\n",\r
-        (UINTN)Bus,\r
-        (UINTN)Device,\r
-        (UINTN)Func,\r
-        (UINTN)VFStride\r
-        ));\r
-\r
       //\r
       // Calculate LastVF\r
       //\r
-      PFRid = EFI_PCI_RID(Bus, Device, Func);\r
+      PFRid  = EFI_PCI_RID (Bus, Device, Func);\r
       LastVF = PFRid + FirstVFOffset + (PciIoDevice->InitialVFs - 1) * VFStride;\r
 \r
       //\r
       // Calculate ReservedBusNum for this PF\r
       //\r
       PciIoDevice->ReservedBusNum = (UINT16)(EFI_PCI_BUS_OF_RID (LastVF) - Bus + 1);\r
+\r
       DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI SR-IOV B%x.D%x.F%x - reserved bus number - 0x%x\n",\r
-        (UINTN)Bus,\r
-        (UINTN)Device,\r
-        (UINTN)Func,\r
-        (UINTN)PciIoDevice->ReservedBusNum\r
+        DEBUG_INFO,\r
+        " SR-IOV: SupportedPageSize = 0x%x; SystemPageSize = 0x%x; FirstVFOffset = 0x%x;\n",\r
+        SupportedPageSize,\r
+        PciIoDevice->SystemPageSize >> 12,\r
+        FirstVFOffset\r
         ));\r
-\r
       DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI SR-IOV B%x.D%x.F%x - SRIOV Cap offset - 0x%x\n",\r
-        (UINTN)Bus,\r
-        (UINTN)Device,\r
-        (UINTN)Func,\r
-        (UINTN)PciIoDevice->SrIovCapabilityOffset\r
+        DEBUG_INFO,\r
+        "         InitialVFs = 0x%x; ReservedBusNum = 0x%x; CapOffset = 0x%x\n",\r
+        PciIoDevice->InitialVFs,\r
+        PciIoDevice->ReservedBusNum,\r
+        PciIoDevice->SrIovCapabilityOffset\r
         ));\r
     }\r
   }\r
@@ -2207,14 +2449,32 @@ CreatePciIoDevice (
                NULL\r
                );\r
     if (!EFI_ERROR (Status)) {\r
-      DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI MR-IOV B%x.D%x.F%x - MRIOV Cap offset - 0x%x\n",\r
-        (UINTN)Bus,\r
-        (UINTN)Device,\r
-        (UINTN)Func,\r
-        (UINTN)PciIoDevice->MrIovCapabilityOffset\r
-        ));\r
+      DEBUG ((DEBUG_INFO, " MR-IOV: CapOffset = 0x%x\n", PciIoDevice->MrIovCapabilityOffset));\r
+    }\r
+  }\r
+\r
+  PciIoDevice->ResizableBarOffset = 0;\r
+  if (PcdGetBool (PcdPcieResizableBarSupport)) {\r
+    Status = LocatePciExpressCapabilityRegBlock (\r
+               PciIoDevice,\r
+               PCI_EXPRESS_EXTENDED_CAPABILITY_RESIZABLE_BAR_ID,\r
+               &PciIoDevice->ResizableBarOffset,\r
+               NULL\r
+               );\r
+    if (!EFI_ERROR (Status)) {\r
+      PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CONTROL  ResizableBarControl;\r
+      UINT32                                                   Offset;\r
+      Offset = PciIoDevice->ResizableBarOffset + sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER)\r
+               + sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CAPABILITY),\r
+      PciIo->Pci.Read (\r
+                   PciIo,\r
+                   EfiPciIoWidthUint8,\r
+                   Offset,\r
+                   sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CONTROL),\r
+                   &ResizableBarControl\r
+                   );\r
+      PciIoDevice->ResizableBarNumber = ResizableBarControl.Bits.ResizableBarNumber;\r
+      PciProgramResizableBar (PciIoDevice, PciResizableBarMax);\r
     }\r
   }\r
 \r
@@ -2250,16 +2510,15 @@ CreatePciIoDevice (
 **/\r
 EFI_STATUS\r
 PciEnumeratorLight (\r
-  IN EFI_HANDLE                    Controller\r
+  IN EFI_HANDLE  Controller\r
   )\r
 {\r
-\r
-  EFI_STATUS                        Status;\r
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL   *PciRootBridgeIo;\r
-  PCI_IO_DEVICE                     *RootBridgeDev;\r
-  UINT16                            MinBus;\r
-  UINT16                            MaxBus;\r
-  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
+  EFI_STATUS                         Status;\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *PciRootBridgeIo;\r
+  PCI_IO_DEVICE                      *RootBridgeDev;\r
+  UINT16                             MinBus;\r
+  UINT16                             MaxBus;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *Descriptors;\r
 \r
   MinBus      = 0;\r
   MaxBus      = PCI_MAX_BUS;\r
@@ -2278,23 +2537,22 @@ PciEnumeratorLight (
   Status = gBS->OpenProtocol (\r
                   Controller,\r
                   &gEfiPciRootBridgeIoProtocolGuid,\r
-                  (VOID **) &PciRootBridgeIo,\r
+                  (VOID **)&PciRootBridgeIo,\r
                   gPciBusDriverBinding.DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
                   );\r
-  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
+  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {\r
     return Status;\r
   }\r
 \r
-  Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
+  Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **)&Descriptors);\r
 \r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
   while (PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL) == EFI_SUCCESS) {\r
-\r
     //\r
     // Create a device node for root bridge device with a NULL host bridge controller handle\r
     //\r
@@ -2306,17 +2564,16 @@ PciEnumeratorLight (
     }\r
 \r
     //\r
-    // Record the root bridgeio protocol\r
+    // Record the root bridge-io protocol\r
     //\r
     RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;\r
 \r
     Status = PciPciDeviceInfoCollector (\r
                RootBridgeDev,\r
-               (UINT8) MinBus\r
+               (UINT8)MinBus\r
                );\r
 \r
     if (!EFI_ERROR (Status)) {\r
-\r
       //\r
       // Remove those PCI devices which are rejected when full enumeration\r
       //\r
@@ -2337,9 +2594,8 @@ PciEnumeratorLight (
       //\r
       InsertRootBridge (RootBridgeDev);\r
     } else {\r
-\r
       //\r
-      // If unsuccessly, destroy the entire node\r
+      // If unsuccessfully, destroy the entire node\r
       //\r
       DestroyRootBridge (RootBridgeDev);\r
     }\r
@@ -2373,15 +2629,15 @@ PciGetBusRange (
   while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
     if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {\r
       if (MinBus != NULL) {\r
-        *MinBus = (UINT16) (*Descriptors)->AddrRangeMin;\r
+        *MinBus = (UINT16)(*Descriptors)->AddrRangeMin;\r
       }\r
 \r
       if (MaxBus != NULL) {\r
-        *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax;\r
+        *MaxBus = (UINT16)(*Descriptors)->AddrRangeMax;\r
       }\r
 \r
       if (BusRange != NULL) {\r
-        *BusRange = (UINT16) (*Descriptors)->AddrLen;\r
+        *BusRange = (UINT16)(*Descriptors)->AddrLen;\r
       }\r
 \r
       return EFI_SUCCESS;\r
@@ -2404,12 +2660,12 @@ PciGetBusRange (
 **/\r
 EFI_STATUS\r
 StartManagingRootBridge (\r
-  IN PCI_IO_DEVICE *RootBridgeDev\r
+  IN PCI_IO_DEVICE  *RootBridgeDev\r
   )\r
 {\r
-  EFI_HANDLE                      RootBridgeHandle;\r
-  EFI_STATUS                      Status;\r
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+  EFI_HANDLE                       RootBridgeHandle;\r
+  EFI_STATUS                       Status;\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo;\r
 \r
   //\r
   // Get the root bridge handle\r
@@ -2423,13 +2679,13 @@ StartManagingRootBridge (
   Status = gBS->OpenProtocol (\r
                   RootBridgeHandle,\r
                   &gEfiPciRootBridgeIoProtocolGuid,\r
-                  (VOID **) &PciRootBridgeIo,\r
+                  (VOID **)&PciRootBridgeIo,\r
                   gPciBusDriverBinding.DriverBindingHandle,\r
                   RootBridgeHandle,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
                   );\r
 \r
-  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
+  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {\r
     return Status;\r
   }\r
 \r
@@ -2439,7 +2695,6 @@ StartManagingRootBridge (
   RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;\r
 \r
   return EFI_SUCCESS;\r
-\r
 }\r
 \r
 /**\r
@@ -2453,7 +2708,7 @@ StartManagingRootBridge (
 **/\r
 BOOLEAN\r
 IsPciDeviceRejected (\r
-  IN PCI_IO_DEVICE *PciIoDevice\r
+  IN PCI_IO_DEVICE  *PciIoDevice\r
   )\r
 {\r
   EFI_STATUS  Status;\r
@@ -2474,9 +2729,8 @@ IsPciDeviceRejected (
     // Only test base registers for P2C\r
     //\r
     for (BarOffset = 0x1C; BarOffset <= 0x38; BarOffset += 2 * sizeof (UINT32)) {\r
-\r
-      Mask    = (BarOffset < 0x2C) ? 0xFFFFF000 : 0xFFFFFFFC;\r
-      Status  = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);\r
+      Mask   = (BarOffset < 0x2C) ? 0xFFFFF000 : 0xFFFFFFFC;\r
+      Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);\r
       if (EFI_ERROR (Status)) {\r
         continue;\r
       }\r
@@ -2503,7 +2757,6 @@ IsPciDeviceRejected (
     }\r
 \r
     if ((TestValue & 0x01) != 0) {\r
-\r
       //\r
       // IO Bar\r
       //\r
@@ -2512,9 +2765,7 @@ IsPciDeviceRejected (
       if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
         return TRUE;\r
       }\r
-\r
     } else {\r
-\r
       //\r
       // Mem Bar\r
       //\r
@@ -2522,13 +2773,11 @@ IsPciDeviceRejected (
       TestValue = TestValue & Mask;\r
 \r
       if ((TestValue & 0x07) == 0x04) {\r
-\r
         //\r
         // Mem64 or PMem64\r
         //\r
         BarOffset += sizeof (UINT32);\r
         if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
-\r
           //\r
           // Test its high 32-Bit BAR\r
           //\r
@@ -2537,9 +2786,7 @@ IsPciDeviceRejected (
             return TRUE;\r
           }\r
         }\r
-\r
       } else {\r
-\r
         //\r
         // Mem32 or PMem32\r
         //\r
@@ -2562,24 +2809,23 @@ IsPciDeviceRejected (
 **/\r
 VOID\r
 ResetAllPpbBusNumber (\r
-  IN PCI_IO_DEVICE                      *Bridge,\r
-  IN UINT8                              StartBusNumber\r
+  IN PCI_IO_DEVICE  *Bridge,\r
+  IN UINT8          StartBusNumber\r
   )\r
 {\r
-  EFI_STATUS                      Status;\r
-  PCI_TYPE00                      Pci;\r
-  UINT8                           Device;\r
-  UINT32                          Register;\r
-  UINT8                           Func;\r
-  UINT64                          Address;\r
-  UINT8                           SecondaryBus;\r
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+  EFI_STATUS                       Status;\r
+  PCI_TYPE00                       Pci;\r
+  UINT8                            Device;\r
+  UINT32                           Register;\r
+  UINT8                            Func;\r
+  UINT64                           Address;\r
+  UINT8                            SecondaryBus;\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo;\r
 \r
   PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
 \r
   for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
     for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
-\r
       //\r
       // Check to see whether a pci device is present\r
       //\r
@@ -2591,17 +2837,23 @@ ResetAllPpbBusNumber (
                  Func\r
                  );\r
 \r
-      if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci))) {\r
+      if (EFI_ERROR (Status) && (Func == 0)) {\r
+        //\r
+        // go to next device if there is no Function 0\r
+        //\r
+        break;\r
+      }\r
 \r
-        Register  = 0;\r
-        Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
-        Status    = PciRootBridgeIo->Pci.Read (\r
-                                           PciRootBridgeIo,\r
-                                           EfiPciWidthUint32,\r
-                                           Address,\r
-                                           1,\r
-                                           &Register\r
-                                           );\r
+      if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci))) {\r
+        Register = 0;\r
+        Address  = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
+        Status   = PciRootBridgeIo->Pci.Read (\r
+                                          PciRootBridgeIo,\r
+                                          EfiPciWidthUint32,\r
+                                          Address,\r
+                                          1,\r
+                                          &Register\r
+                                          );\r
         SecondaryBus = (UINT8)(Register >> 8);\r
 \r
         if (SecondaryBus != 0) {\r
@@ -2612,16 +2864,16 @@ ResetAllPpbBusNumber (
         // Reset register 18h, 19h, 1Ah on PCI Bridge\r
         //\r
         Register &= 0xFF000000;\r
-        Status = PciRootBridgeIo->Pci.Write (\r
-                                        PciRootBridgeIo,\r
-                                        EfiPciWidthUint32,\r
-                                        Address,\r
-                                        1,\r
-                                        &Register\r
-                                        );\r
+        Status    = PciRootBridgeIo->Pci.Write (\r
+                                           PciRootBridgeIo,\r
+                                           EfiPciWidthUint32,\r
+                                           Address,\r
+                                           1,\r
+                                           &Register\r
+                                           );\r
       }\r
 \r
-      if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
+      if ((Func == 0) && !IS_PCI_MULTI_FUNC (&Pci)) {\r
         //\r
         // Skip sub functions, this is not a multi function device\r
         //\r
@@ -2630,4 +2882,3 @@ ResetAllPpbBusNumber (
     }\r
   }\r
 }\r
-\r