]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Bus/Pci/PciBus/Dxe/PciLib.c
Fixed some issues for IA32 architecture platform build.
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / PciBus / Dxe / PciLib.c
index c9c46b3adfb9e5aaa5a2930c0bdccbb9a2eb7339..1296836a3089592868fd1055f8195671fb455552 100644 (file)
@@ -1,22 +1,22 @@
 /*++\r
 \r
 /*++\r
 \r
-Copyright (c) 2006, Intel Corporation                                                         \r
-All rights reserved. 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 - 2007, Intel Corporation\r
+All rights reserved. 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
 \r
 Module Name:\r
 \r
 \r
 Module Name:\r
 \r
-  PciLib.c \r
-  \r
+  PciLib.c\r
+\r
 Abstract:\r
 \r
   PCI Bus Driver Lib file\r
 Abstract:\r
 \r
   PCI Bus Driver Lib file\r
-  It abstracts some functions that can be different \r
+  It abstracts some functions that can be different\r
   between light PCI bus driver and full PCI bus driver\r
 \r
 Revision History\r
   between light PCI bus driver and full PCI bus driver\r
 \r
 Revision History\r
@@ -175,7 +175,7 @@ Returns:
   if (!gFullEnumeration) {\r
 \r
     Address = 0;\r
   if (!gFullEnumeration) {\r
 \r
     Address = 0;\r
-    PciIoDevice->PciIo.Pci.Read (\r
+    PciIoRead (\r
                             &(PciIoDevice->PciIo),\r
                             EfiPciIoWidthUint32,\r
                             0x1c,\r
                             &(PciIoDevice->PciIo),\r
                             EfiPciIoWidthUint32,\r
                             0x1c,\r
@@ -188,7 +188,7 @@ Returns:
     (PciIoDevice->PciBar)[P2C_MEM_1].BarType      = PciBarTypeMem32;\r
 \r
     Address = 0;\r
     (PciIoDevice->PciBar)[P2C_MEM_1].BarType      = PciBarTypeMem32;\r
 \r
     Address = 0;\r
-    PciIoDevice->PciIo.Pci.Read (\r
+    PciIoRead (\r
                             &(PciIoDevice->PciIo),\r
                             EfiPciIoWidthUint32,\r
                             0x20,\r
                             &(PciIoDevice->PciIo),\r
                             EfiPciIoWidthUint32,\r
                             0x20,\r
@@ -200,7 +200,7 @@ Returns:
     (PciIoDevice->PciBar)[P2C_MEM_2].BarType      = PciBarTypePMem32;\r
 \r
     Address = 0;\r
     (PciIoDevice->PciBar)[P2C_MEM_2].BarType      = PciBarTypePMem32;\r
 \r
     Address = 0;\r
-    PciIoDevice->PciIo.Pci.Read (\r
+    PciIoRead (\r
                             &(PciIoDevice->PciIo),\r
                             EfiPciIoWidthUint32,\r
                             0x2c,\r
                             &(PciIoDevice->PciIo),\r
                             EfiPciIoWidthUint32,\r
                             0x2c,\r
@@ -212,7 +212,7 @@ Returns:
     (PciIoDevice->PciBar)[P2C_IO_1].BarType     = PciBarTypeIo16;\r
 \r
     Address = 0;\r
     (PciIoDevice->PciBar)[P2C_IO_1].BarType     = PciBarTypeIo16;\r
 \r
     Address = 0;\r
-    PciIoDevice->PciIo.Pci.Read (\r
+    PciIoRead (\r
                             &(PciIoDevice->PciIo),\r
                             EfiPciIoWidthUint32,\r
                             0x34,\r
                             &(PciIoDevice->PciIo),\r
                             EfiPciIoWidthUint32,\r
                             0x34,\r
@@ -276,19 +276,19 @@ Returns:
       // Skip rejection for all PPBs, while detect rejection for others\r
       //\r
       if (IsPciDeviceRejected (Temp)) {\r
       // Skip rejection for all PPBs, while detect rejection for others\r
       //\r
       if (IsPciDeviceRejected (Temp)) {\r
-                \r
+\r
         //\r
         // For P2C, remove all devices on it\r
         //\r
         //\r
         // For P2C, remove all devices on it\r
         //\r
-                \r
+\r
         if (!IsListEmpty (&Temp->ChildList)) {\r
           RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp);\r
         }\r
         if (!IsListEmpty (&Temp->ChildList)) {\r
           RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp);\r
         }\r
-        \r
+\r
         //\r
         // Finally remove itself\r
         //\r
         //\r
         // Finally remove itself\r
         //\r
-        \r
+\r
         LastLink = CurrentLink->BackLink;\r
         RemoveEntryList (CurrentLink);\r
         FreePciDevice (Temp);\r
         LastLink = CurrentLink->BackLink;\r
         RemoveEntryList (CurrentLink);\r
         FreePciDevice (Temp);\r
@@ -316,7 +316,7 @@ PciHostBridgeResourceAllocator (
     return PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport (\r
              PciResAlloc\r
              );\r
     return PciHostBridgeResourceAllocator_WithoutHotPlugDeviceSupport (\r
              PciResAlloc\r
              );\r
-  }  \r
+  }\r
 }\r
 \r
 \r
 }\r
 \r
 \r
@@ -366,7 +366,7 @@ Returns:
   //\r
   // Initialize resource pool\r
   //\r
   //\r
   // Initialize resource pool\r
   //\r
-  \r
+\r
   InitializeResourcePool (&IoPool, PciBarTypeIo16);\r
   InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);\r
   InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);\r
   InitializeResourcePool (&IoPool, PciBarTypeIo16);\r
   InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);\r
   InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);\r
@@ -479,7 +479,7 @@ Returns:
         Mem32Bridge->Alignment = MaxOptionRomSize - 1;\r
       }\r
     }\r
         Mem32Bridge->Alignment = MaxOptionRomSize - 1;\r
       }\r
     }\r
-    \r
+\r
     //\r
     // Based on the all the resource tree, contruct ACPI resource node to\r
     // submit the resource aperture to pci host bridge protocol\r
     //\r
     // Based on the all the resource tree, contruct ACPI resource node to\r
     // submit the resource aperture to pci host bridge protocol\r
@@ -516,8 +516,8 @@ Returns:
     //\r
     // Free acpi resource node\r
     //\r
     //\r
     // Free acpi resource node\r
     //\r
-    if (AcpiConfig) {\r
-      gBS->FreePool (AcpiConfig);\r
+    if (AcpiConfig != NULL) {\r
+      FreePool (AcpiConfig);\r
     }\r
 \r
     if (EFI_ERROR (Status)) {\r
     }\r
 \r
     if (EFI_ERROR (Status)) {\r
@@ -575,7 +575,7 @@ Returns:
     if (RootBridgeDev == NULL) {\r
       return EFI_NOT_FOUND;\r
     }\r
     if (RootBridgeDev == NULL) {\r
       return EFI_NOT_FOUND;\r
     }\r
-    \r
+\r
     //\r
     // Get acpi resource node for all the resource types\r
     //\r
     //\r
     // Get acpi resource node for all the resource types\r
     //\r
@@ -671,7 +671,7 @@ Returns:
       );\r
 \r
     if (AcpiConfig != NULL) {\r
       );\r
 \r
     if (AcpiConfig != NULL) {\r
-      gBS->FreePool (AcpiConfig);\r
+      FreePool (AcpiConfig);\r
     }\r
   }\r
 \r
     }\r
   }\r
 \r
@@ -758,7 +758,7 @@ Returns:
 \r
     //\r
     // Initialize resource pool\r
 \r
     //\r
     // Initialize resource pool\r
-    //    \r
+    //\r
     InitializeResourcePool (&IoPool, PciBarTypeIo16);\r
     InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);\r
     InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);\r
     InitializeResourcePool (&IoPool, PciBarTypeIo16);\r
     InitializeResourcePool (&Mem32Pool, PciBarTypeMem32);\r
     InitializeResourcePool (&PMem32Pool, PciBarTypePMem32);\r
@@ -871,8 +871,8 @@ Returns:
             Mem32Bridge->Alignment = MaxOptionRomSize - 1;\r
           }\r
         }\r
             Mem32Bridge->Alignment = MaxOptionRomSize - 1;\r
           }\r
         }\r
-      }    \r
-      \r
+      }\r
+\r
       //\r
       // Based on the all the resource tree, contruct ACPI resource node to\r
       // submit the resource aperture to pci host bridge protocol\r
       //\r
       // Based on the all the resource tree, contruct ACPI resource node to\r
       // submit the resource aperture to pci host bridge protocol\r
@@ -911,7 +911,7 @@ Returns:
       // Free acpi resource node\r
       //\r
       if (AcpiConfig != NULL) {\r
       // Free acpi resource node\r
       //\r
       if (AcpiConfig != NULL) {\r
-        gBS->FreePool (AcpiConfig);\r
+        FreePool (AcpiConfig);\r
       }\r
 \r
       if (EFI_ERROR (Status)) {\r
       }\r
 \r
       if (EFI_ERROR (Status)) {\r
@@ -930,7 +930,7 @@ Returns:
     //\r
     // Notify pci bus driver starts to program the resource\r
     //\r
     //\r
     // Notify pci bus driver starts to program the resource\r
     //\r
-   \r
+\r
     Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources);\r
 \r
     if (!EFI_ERROR (Status)) {\r
     Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources);\r
 \r
     if (!EFI_ERROR (Status)) {\r
@@ -939,11 +939,11 @@ Returns:
       //\r
       break;\r
     }\r
       //\r
       break;\r
     }\r
-      \r
+\r
     //\r
     // If the resource allocation is unsuccessful, free resources on bridge\r
     //\r
     //\r
     // If the resource allocation is unsuccessful, free resources on bridge\r
     //\r
-            \r
+\r
     RootBridgeDev     = NULL;\r
     RootBridgeHandle  = 0;\r
 \r
     RootBridgeDev     = NULL;\r
     RootBridgeHandle  = 0;\r
 \r
@@ -961,7 +961,7 @@ Returns:
       if (RootBridgeDev == NULL) {\r
         return EFI_NOT_FOUND;\r
       }\r
       if (RootBridgeDev == NULL) {\r
         return EFI_NOT_FOUND;\r
       }\r
\r
+\r
       //\r
       // Get host bridge handle for status report\r
       //\r
       //\r
       // Get host bridge handle for status report\r
       //\r
@@ -994,7 +994,7 @@ Returns:
           &Mem64ResStatus,\r
           &PMem64ResStatus\r
           );\r
           &Mem64ResStatus,\r
           &PMem64ResStatus\r
           );\r
-        gBS->FreePool (AcpiConfig);\r
+        FreePool (AcpiConfig);\r
       }\r
     }\r
     //\r
       }\r
     }\r
     //\r
@@ -1081,7 +1081,7 @@ Returns:
     if (RootBridgeDev == NULL) {\r
       return EFI_NOT_FOUND;\r
     }\r
     if (RootBridgeDev == NULL) {\r
       return EFI_NOT_FOUND;\r
     }\r
-    \r
+\r
     //\r
     // Get acpi resource node for all the resource types\r
     //\r
     //\r
     // Get acpi resource node for all the resource types\r
     //\r
@@ -1209,16 +1209,16 @@ PciScanBus (
 {\r
   if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
     return PciScanBus_WithHotPlugDeviceSupport (\r
 {\r
   if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
     return PciScanBus_WithHotPlugDeviceSupport (\r
-      Bridge, \r
-      StartBusNumber, \r
-      SubBusNumber, \r
+      Bridge,\r
+      StartBusNumber,\r
+      SubBusNumber,\r
       PaddedBusRange\r
       );\r
   } else {\r
     return PciScanBus_WithoutHotPlugDeviceSupport (\r
       PaddedBusRange\r
       );\r
   } else {\r
     return PciScanBus_WithoutHotPlugDeviceSupport (\r
-      Bridge, \r
-      StartBusNumber, \r
-      SubBusNumber, \r
+      Bridge,\r
+      StartBusNumber,\r
+      SubBusNumber,\r
       PaddedBusRange\r
       );\r
   }\r
       PaddedBusRange\r
       );\r
   }\r
@@ -1282,7 +1282,7 @@ Returns:
                 Func\r
                 );\r
 \r
                 Func\r
                 );\r
 \r
-      if (!EFI_ERROR (Status)   && \r
+      if (!EFI_ERROR (Status)   &&\r
           (IS_PCI_BRIDGE (&Pci) ||\r
           IS_CARDBUS_BRIDGE (&Pci))) {\r
 \r
           (IS_PCI_BRIDGE (&Pci) ||\r
           IS_CARDBUS_BRIDGE (&Pci))) {\r
 \r
@@ -1310,8 +1310,9 @@ Returns:
 \r
         Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
 \r
 \r
         Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
 \r
-        Status = PciRootBridgeIo->Pci.Write (\r
+        Status = PciRootBridgeIoWrite (\r
                                         PciRootBridgeIo,\r
                                         PciRootBridgeIo,\r
+                                        &Pci,\r
                                         EfiPciWidthUint16,\r
                                         Address,\r
                                         1,\r
                                         EfiPciWidthUint16,\r
                                         Address,\r
                                         1,\r
@@ -1322,8 +1323,9 @@ Returns:
         // Initialize SubBusNumber to SecondBus\r
         //\r
         Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
         // Initialize SubBusNumber to SecondBus\r
         //\r
         Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
-        Status = PciRootBridgeIo->Pci.Write (\r
+        Status = PciRootBridgeIoWrite (\r
                                         PciRootBridgeIo,\r
                                         PciRootBridgeIo,\r
+                                        &Pci,\r
                                         EfiPciWidthUint8,\r
                                         Address,\r
                                         1,\r
                                         EfiPciWidthUint8,\r
                                         Address,\r
                                         1,\r
@@ -1339,8 +1341,9 @@ Returns:
           //\r
           Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
           Register  = 0xFF;\r
           //\r
           Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
           Register  = 0xFF;\r
-          Status = PciRootBridgeIo->Pci.Write (\r
+          Status = PciRootBridgeIoWrite (\r
                                           PciRootBridgeIo,\r
                                           PciRootBridgeIo,\r
+                                          &Pci,\r
                                           EfiPciWidthUint8,\r
                                           Address,\r
                                           1,\r
                                           EfiPciWidthUint8,\r
                                           Address,\r
                                           1,\r
@@ -1373,8 +1376,9 @@ Returns:
 \r
         Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
 \r
 \r
         Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
 \r
-        Status = PciRootBridgeIo->Pci.Write (\r
+        Status = PciRootBridgeIoWrite (\r
                                         PciRootBridgeIo,\r
                                         PciRootBridgeIo,\r
+                                        &Pci,\r
                                         EfiPciWidthUint8,\r
                                         Address,\r
                                         1,\r
                                         EfiPciWidthUint8,\r
                                         Address,\r
                                         1,\r
@@ -1476,7 +1480,7 @@ Returns:
 \r
         continue;\r
       }\r
 \r
         continue;\r
       }\r
-      \r
+\r
       //\r
       // Get the PCI device information\r
       //\r
       //\r
       // Get the PCI device information\r
       //\r
@@ -1507,7 +1511,7 @@ Returns:
             EfiPciBeforeChildBusEnumeration\r
             );\r
       }\r
             EfiPciBeforeChildBusEnumeration\r
             );\r
       }\r
-      \r
+\r
       //\r
       // For Pci Hotplug controller devcie only\r
       //\r
       //\r
       // For Pci Hotplug controller devcie only\r
       //\r
@@ -1530,14 +1534,14 @@ Returns:
                                         Event,\r
                                         &State\r
                                         );\r
                                         Event,\r
                                         &State\r
                                         );\r
-                                        \r
+\r
             PreprocessController (\r
               PciDevice,\r
               PciDevice->BusNumber,\r
               PciDevice->DeviceNumber,\r
               PciDevice->FunctionNumber,\r
               EfiPciBeforeChildBusEnumeration\r
             PreprocessController (\r
               PciDevice,\r
               PciDevice->BusNumber,\r
               PciDevice->DeviceNumber,\r
               PciDevice->FunctionNumber,\r
               EfiPciBeforeChildBusEnumeration\r
-            );                                        \r
+            );\r
             continue;\r
           }\r
         }\r
             continue;\r
           }\r
         }\r
@@ -1552,7 +1556,7 @@ Returns:
         if (gPciHotPlugInit != NULL) {\r
 \r
           if (IsRootPciHotPlugBus (PciDevice->DevicePath, &HpIndex)) {\r
         if (gPciHotPlugInit != NULL) {\r
 \r
           if (IsRootPciHotPlugBus (PciDevice->DevicePath, &HpIndex)) {\r
-          \r
+\r
             //\r
             // If it is initialized, get the padded bus range\r
             //\r
             //\r
             // If it is initialized, get the padded bus range\r
             //\r
@@ -1593,8 +1597,9 @@ Returns:
         Register  = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r
         Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
 \r
         Register  = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r
         Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
 \r
-        Status = PciRootBridgeIo->Pci.Write (\r
+        Status = PciRootBridgeIoWrite (\r
                                         PciRootBridgeIo,\r
                                         PciRootBridgeIo,\r
+                                        &Pci,\r
                                         EfiPciWidthUint16,\r
                                         Address,\r
                                         1,\r
                                         EfiPciWidthUint16,\r
                                         Address,\r
                                         1,\r
@@ -1606,14 +1611,15 @@ Returns:
         // If it is PPB, resursively search down this bridge\r
         //\r
         if (IS_PCI_BRIDGE (&Pci)) {\r
         // If it is PPB, resursively search down this bridge\r
         //\r
         if (IS_PCI_BRIDGE (&Pci)) {\r
-          \r
+\r
           //\r
           // Initialize SubBusNumber to Maximum bus number\r
           //\r
           Register  = 0xFF;\r
           Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
           //\r
           // Initialize SubBusNumber to Maximum bus number\r
           //\r
           Register  = 0xFF;\r
           Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
-          Status = PciRootBridgeIo->Pci.Write (\r
+          Status = PciRootBridgeIoWrite (\r
                                           PciRootBridgeIo,\r
                                           PciRootBridgeIo,\r
+                                          &Pci,\r
                                           EfiPciWidthUint8,\r
                                           Address,\r
                                           1,\r
                                           EfiPciWidthUint8,\r
                                           Address,\r
                                           1,\r
@@ -1661,8 +1667,9 @@ Returns:
         //\r
         Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
 \r
         //\r
         Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A);\r
 \r
-        Status = PciRootBridgeIo->Pci.Write (\r
+        Status = PciRootBridgeIoWrite (\r
                                         PciRootBridgeIo,\r
                                         PciRootBridgeIo,\r
+                                        &Pci,\r
                                         EfiPciWidthUint8,\r
                                         Address,\r
                                         1,\r
                                         EfiPciWidthUint8,\r
                                         Address,\r
                                         1,\r
@@ -1691,7 +1698,7 @@ PciRootBridgeP2CProcess (
 /*++\r
 \r
 Routine Description:\r
 /*++\r
 \r
 Routine Description:\r
-  \r
+\r
     Process Option Rom on this host bridge\r
 \r
 Arguments:\r
     Process Option Rom on this host bridge\r
 \r
 Arguments:\r
@@ -1719,7 +1726,7 @@ Returns:
     if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {\r
 \r
       if (gPciHotPlugInit && Temp->Allocated) {\r
     if (IS_CARDBUS_BRIDGE (&Temp->Pci)) {\r
 \r
       if (gPciHotPlugInit && Temp->Allocated) {\r
-        \r
+\r
         //\r
         // Raise the EFI_IOB_PCI_HPC_INIT status code\r
         //\r
         //\r
         // Raise the EFI_IOB_PCI_HPC_INIT status code\r
         //\r
@@ -1769,7 +1776,7 @@ PciHostBridgeP2CProcess (
 /*++\r
 \r
 Routine Description:\r
 /*++\r
 \r
 Routine Description:\r
-  \r
+\r
 Arguments:\r
 \r
 Returns:\r
 Arguments:\r
 \r
 Returns:\r
@@ -1821,7 +1828,7 @@ PciHostBridgeEnumerator (
 \r
 Routine Description:\r
 \r
 \r
 Routine Description:\r
 \r
-  This function is used to enumerate the entire host bridge \r
+  This function is used to enumerate the entire host bridge\r
   in a given platform\r
 \r
 Arguments:\r
   in a given platform\r
 \r
 Arguments:\r
@@ -1887,12 +1894,12 @@ Returns:
 \r
   if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
 \r
 \r
   if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {\r
 \r
-    //                                                            \r
+    //\r
     // Notify the bus allocation phase is finished for the first time\r
     // Notify the bus allocation phase is finished for the first time\r
-    //                                                            \r
+    //\r
     NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);\r
     NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);\r
-      \r
-                    \r
+\r
+\r
     if (gPciHotPlugInit != NULL) {\r
       //\r
       // Wait for all HPC initialized\r
     if (gPciHotPlugInit != NULL) {\r
       //\r
       // Wait for all HPC initialized\r
@@ -1907,7 +1914,7 @@ Returns:
       // Notify the bus allocation phase is about to start for the 2nd time\r
       //\r
       NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);\r
       // Notify the bus allocation phase is about to start for the 2nd time\r
       //\r
       NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation);\r
-    \r
+\r
       RootBridgeHandle = NULL;\r
       while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
 \r
       RootBridgeHandle = NULL;\r
       while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {\r
 \r
@@ -1935,7 +1942,7 @@ Returns:
           return Status;\r
         }\r
       }\r
           return Status;\r
         }\r
       }\r
-        \r
+\r
       //\r
       // Notify the bus allocation phase is to end\r
       //\r
       //\r
       // Notify the bus allocation phase is to end\r
       //\r
@@ -2018,3 +2025,860 @@ Returns:
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
+\r
+/**\r
+  Read PCI device configuration register by specified address.\r
+\r
+  This function check the incompatiblilites on PCI device. Return the register\r
+  value.\r
+\r
+  @param  PciRootBridgeIo     A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+  @param  PciIo               A pointer to EFI_PCI_PROTOCOL.\r
+  @param  PciDeviceInfo       A pointer to EFI_PCI_DEVICE_INFO.\r
+  @param  Width               Signifies the width of the memory operations.\r
+  @Param  Address             The address within the PCI configuration space for the PCI controller.\r
+  @param  Buffer              For read operations, the destination buffer to store the results. For\r
+                              write operations, the source buffer to write data from.\r
+\r
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.\r
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.\r
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.\r
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+ReadConfigData (\r
+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *PciRootBridgeIo,  OPTIONAL\r
+  IN       EFI_PCI_IO_PROTOCOL                    *PciIo,            OPTIONAL\r
+  IN       EFI_PCI_DEVICE_INFO                    *PciDeviceInfo,\r
+  IN       UINT64                                 Width,\r
+  IN       UINT64                                 Address,\r
+  IN OUT   VOID                                   *Buffer\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  UINT64                        AccessWidth;\r
+  EFI_PCI_REGISTER_ACCESS_DATA  *PciRegisterAccessData;\r
+  UINT64                        AccessAddress;\r
+  UINTN                         Stride;\r
+  UINT64                        TempBuffer;\r
+  UINT8                         *Pointer;\r
+\r
+  ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL));\r
+\r
+  if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT) {\r
+    //\r
+    // check access compatibility at first time\r
+    //\r
+    Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_READ, Address & 0xff, Width, &PciRegisterAccessData);\r
+\r
+    if (Status == EFI_SUCCESS) {\r
+      //\r
+      // there exist incompatibility on this operation\r
+      //\r
+      AccessWidth = Width;\r
+\r
+      if (PciRegisterAccessData->Width != VALUE_NOCARE) {\r
+        AccessWidth = PciRegisterAccessData->Width;\r
+      }\r
+\r
+      AccessAddress = Address & ~((1 << AccessWidth) - 1);\r
+\r
+      TempBuffer    = 0;\r
+      Stride        = 0;\r
+      Pointer       = (UINT8 *) &TempBuffer;\r
+\r
+      while (1) {\r
+\r
+        if (PciRootBridgeIo != NULL) {\r
+          Status = PciRootBridgeIo->Pci.Read (\r
+                         PciRootBridgeIo,\r
+                         (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) AccessWidth,\r
+                         AccessAddress,\r
+                         1,\r
+                         Pointer\r
+                         );\r
+        } else if (PciIo != NULL) {\r
+          Status = PciIo->Pci.Read (\r
+                         PciIo,\r
+                         (EFI_PCI_IO_PROTOCOL_WIDTH) AccessWidth,\r
+                         (UINT32) AccessAddress,\r
+                         1,\r
+                         Pointer\r
+                         );\r
+        }\r
+\r
+        if (Status != EFI_SUCCESS) {\r
+          return Status;\r
+        }\r
+\r
+       Stride = 1 << AccessWidth;\r
+        AccessAddress += Stride;\r
+        if (AccessAddress >= (Address + (1 << Width))) {\r
+          //\r
+          // if all datas have been read, exist\r
+          //\r
+          break;\r
+        }\r
+\r
+        Pointer += Stride;\r
+\r
+        if ((AccessAddress & 0xff) < PciRegisterAccessData->EndOffset) {\r
+          //\r
+          // if current offset doesn't reach the end\r
+          //\r
+          continue;\r
+        }\r
+\r
+        FreePool (PciRegisterAccessData);\r
+\r
+        //\r
+        // continue checking access incompatibility\r
+        //\r
+        Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_READ, AccessAddress & 0xff, AccessWidth, &PciRegisterAccessData);\r
+        if (Status == EFI_SUCCESS) {\r
+          if (PciRegisterAccessData->Width != VALUE_NOCARE) {\r
+            AccessWidth = PciRegisterAccessData->Width;\r
+          }\r
+        }\r
+      }\r
+\r
+      FreePool (PciRegisterAccessData);\r
+\r
+      switch (Width) {\r
+      case EfiPciWidthUint8:\r
+        * (UINT8 *) Buffer = (UINT8) TempBuffer;\r
+        break;\r
+      case EfiPciWidthUint16:\r
+        * (UINT16 *) Buffer = (UINT16) TempBuffer;\r
+        break;\r
+      case EfiPciWidthUint32:\r
+        * (UINT32 *) Buffer = (UINT32) TempBuffer;\r
+        break;\r
+      default:\r
+        return EFI_UNSUPPORTED;\r
+      }\r
+\r
+      return Status;\r
+    }\r
+  }\r
+  //\r
+  // AccessWidth incompatible check not supportted\r
+  // or, there doesn't exist incompatibility on this operation\r
+  //\r
+  if (PciRootBridgeIo != NULL) {\r
+    Status = PciRootBridgeIo->Pci.Read (\r
+                     PciRootBridgeIo,\r
+                     (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+                     Address,\r
+                     1,\r
+                     Buffer\r
+                     );\r
+\r
+  } else {\r
+    Status = PciIo->Pci.Read (\r
+                     PciIo,\r
+                     (EFI_PCI_IO_PROTOCOL_WIDTH) Width,\r
+                     (UINT32) Address,\r
+                     1,\r
+                     Buffer\r
+                     );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Update register value by checking PCI device incompatibility.\r
+\r
+  This function check register value incompatibilites on PCI device. Return the register\r
+  value.\r
+\r
+  @param  PciDeviceInfo       A pointer to EFI_PCI_DEVICE_INFO.\r
+  @param  AccessType          Access type, READ or WRITE.\r
+  @Param  Address             The address within the PCI configuration space.\r
+  @param  Buffer              Store the register data.\r
+\r
+  @retval EFI_SUCCESS         The data has been updated.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+UpdateConfigData (\r
+  IN       EFI_PCI_DEVICE_INFO                    *PciDeviceInfo,\r
+  IN       UINT64                                 AccessType,\r
+  IN       UINT64                                 Width,\r
+  IN       UINT64                                 Address,\r
+  IN OUT   VOID                                   *Buffer\r
+)\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_PCI_REGISTER_VALUE_DATA   *PciRegisterData;\r
+  UINT64                        TempValue;\r
+\r
+  //\r
+  // check register value incompatibility\r
+  //\r
+  Status = PciRegisterUpdateCheck (PciDeviceInfo, AccessType, Address & 0xff, &PciRegisterData);\r
+\r
+  if (Status == EFI_SUCCESS) {\r
+\r
+    TempValue = * (UINT32 *) Buffer;\r
+\r
+    switch (Width) {\r
+    case EfiPciWidthUint8:\r
+      * (UINT8 *) Buffer = (UINT8) TempValue;\r
+      break;\r
+    case EfiPciWidthUint16:\r
+      * (UINT16 *) Buffer = (UINT16) TempValue;\r
+      break;\r
+    case EfiPciWidthUint32:\r
+      * (UINT32 *) Buffer = (UINT32) TempValue;\r
+      break;\r
+\r
+    default:\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+\r
+    FreePool (PciRegisterData);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Write PCI device configuration register by specified address.\r
+\r
+  This function check the incompatiblilites on PCI device, and write date\r
+  into register.\r
+\r
+  @param  PciRootBridgeIo     A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+  @param  PciIo               A pointer to EFI_PCI_PROTOCOL.\r
+  @param  PciDeviceInfo       A pointer to EFI_PCI_DEVICE_INFO.\r
+  @param  Width               Signifies the width of the memory operations.\r
+  @Param  Address             The address within the PCI configuration space for the PCI controller.\r
+  @param  Buffer              For read operations, the destination buffer to store the results. For\r
+                              write operations, the source buffer to write data from.\r
+\r
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.\r
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.\r
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.\r
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+WriteConfigData (\r
+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *PciRootBridgeIo,  OPTIONAL\r
+  IN       EFI_PCI_IO_PROTOCOL                    *PciIo,            OPTIONAL\r
+  IN       EFI_PCI_DEVICE_INFO                    *PciDeviceInfo,\r
+  IN       UINT64                                 Width,\r
+  IN       UINT64                                 Address,\r
+  IN       VOID                                   *Buffer\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  UINT64                        AccessWidth;\r
+  EFI_PCI_REGISTER_ACCESS_DATA  *PciRegisterAccessData;\r
+  UINT64                        AccessAddress;\r
+  UINTN                         Stride;\r
+  UINT8                         *Pointer;\r
+  UINT64                        Data;\r
+  UINTN                         Shift;\r
+\r
+  ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL));\r
+\r
+  if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_ACCESS_WIDTH_SUPPORT) {\r
+    //\r
+    // check access compatibility at first time\r
+    //\r
+    Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_WRITE, Address & 0xff, Width, &PciRegisterAccessData);\r
+\r
+    if (Status == EFI_SUCCESS) {\r
+      //\r
+      // there exist incompatibility on this operation\r
+      //\r
+      AccessWidth = Width;\r
+\r
+      if (PciRegisterAccessData->Width != VALUE_NOCARE) {\r
+        AccessWidth = PciRegisterAccessData->Width;\r
+      }\r
+\r
+      AccessAddress = Address & ~((1 << AccessWidth) - 1);\r
+\r
+      Stride        = 0;\r
+      Pointer       = (UINT8 *) &Buffer;\r
+      Data          = * (UINT64 *) Buffer;\r
+\r
+      while (1) {\r
+\r
+        if (AccessWidth > Width) {\r
+          //\r
+          // if actual access width is larger than orignal one, additional data need to be read back firstly\r
+          //\r
+          Status = ReadConfigData (PciRootBridgeIo, PciIo, PciDeviceInfo, AccessWidth, AccessAddress, &Data);\r
+          if (Status != EFI_SUCCESS) {\r
+            return Status;\r
+          }\r
+\r
+          //\r
+          // check data read incompatibility\r
+          //\r
+          UpdateConfigData (PciDeviceInfo, PCI_REGISTER_READ, AccessWidth, AccessAddress & 0xff, &Data);\r
+\r
+          Shift = (UINTN) ((Address - AccessAddress) * 8);\r
+          switch (Width) {\r
+          case EfiPciWidthUint8:\r
+            Data = (* (UINT8 *) Buffer) << Shift | (Data & ~(0xff << Shift));\r
+            break;\r
+\r
+          case EfiPciWidthUint16:\r
+            Data = (* (UINT16 *) Buffer) << Shift | (Data & ~(0xffff << Shift));\r
+            break;\r
+          }\r
+\r
+          //\r
+          // check data write incompatibility\r
+          //\r
+          UpdateConfigData (PciDeviceInfo, PCI_REGISTER_WRITE, AccessWidth, AccessAddress * 0xff, &Data);\r
+        }\r
+\r
+        if (PciRootBridgeIo != NULL) {\r
+          Status = PciRootBridgeIo->Pci.Write (\r
+                         PciRootBridgeIo,\r
+                         (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) AccessWidth,\r
+                         AccessAddress,\r
+                         1,\r
+                         &Data\r
+                         );\r
+        } else {\r
+          Status = PciIo->Pci.Write (\r
+                         PciIo,\r
+                         (EFI_PCI_IO_PROTOCOL_WIDTH) AccessWidth,\r
+                         (UINT32) AccessAddress,\r
+                         1,\r
+                         &Data\r
+                         );\r
+        }\r
+\r
+        if (Status != EFI_SUCCESS) {\r
+          return Status;\r
+        }\r
+\r
+        Data = Data >> ((1 << AccessWidth) * 8);\r
+\r
+        Stride = 1 << AccessWidth;\r
+        AccessAddress += Stride;\r
+        if (AccessAddress >= (Address + (1 << Width))) {\r
+          //\r
+          // if all datas have been written, exist\r
+          //\r
+          break;\r
+        }\r
+\r
+        Pointer += Stride;\r
+\r
+        if ((AccessAddress & 0xff) < PciRegisterAccessData->EndOffset) {\r
+          //\r
+          // if current offset doesn't reach the end\r
+          //\r
+          continue;\r
+        }\r
+\r
+        FreePool (PciRegisterAccessData);\r
+\r
+        //\r
+        // continue checking access incompatibility\r
+        //\r
+        Status = PciRegisterAccessCheck (PciDeviceInfo, PCI_REGISTER_WRITE, AccessAddress & 0xff, AccessWidth, &PciRegisterAccessData);\r
+        if (Status == EFI_SUCCESS) {\r
+          if (PciRegisterAccessData->Width != VALUE_NOCARE) {\r
+            AccessWidth = PciRegisterAccessData->Width;\r
+          }\r
+        }\r
+      };\r
+\r
+      FreePool (PciRegisterAccessData);\r
+\r
+      return Status;\r
+    }\r
+\r
+  }\r
+  //\r
+  // AccessWidth incompatible check not supportted\r
+  // or, there doesn't exist incompatibility on this operation\r
+  //\r
+  if (PciRootBridgeIo != NULL) {\r
+    Status = PciRootBridgeIo->Pci.Write (\r
+                     PciRootBridgeIo,\r
+                     (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+                     Address,\r
+                     1,\r
+                     Buffer\r
+                     );\r
+  } else {\r
+    Status = PciIo->Pci.Write (\r
+                   PciIo,\r
+                   (EFI_PCI_IO_PROTOCOL_WIDTH) Width,\r
+                   (UINT32) Address,\r
+                   1,\r
+                   Buffer\r
+                   );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Abstract PCI device device information.\r
+\r
+  @param  PciRootBridgeIo     A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+  @param  PciIo               A pointer to EFI_PCI_PROTOCOL.\r
+  @param  Pci                 A pointer to PCI_TYPE00.\r
+  @Param  Address             The address within the PCI configuration space for the PCI controller.\r
+  @param  PciDeviceInfo       A pointer to EFI_PCI_DEVICE_INFO.\r
+\r
+  @retval EFI_SUCCESS         Pci device device information has been abstracted.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+GetPciDeviceDeviceInfo (\r
+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *PciRootBridgeIo,  OPTIONAL\r
+  IN       EFI_PCI_IO_PROTOCOL                    *PciIo,            OPTIONAL\r
+  IN       PCI_TYPE00                             *Pci,              OPTIONAL\r
+  IN       UINT64                                 Address,           OPTIONAL\r
+  OUT      EFI_PCI_DEVICE_INFO                    *PciDeviceInfo\r
+)\r
+{\r
+  EFI_STATUS                    Status;\r
+  UINT64                        PciAddress;\r
+  UINT32                        PciConfigData;\r
+  PCI_IO_DEVICE                 *PciIoDevice;\r
+\r
+  ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL));\r
+\r
+  if (PciIo != NULL) {\r
+    PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);\r
+\r
+    //\r
+    // get pointer to PCI_TYPE00 from PciIoDevice\r
+    //\r
+    Pci = &PciIoDevice->Pci;\r
+  }\r
+\r
+  if (Pci == NULL) {\r
+    //\r
+    // while PCI_TYPE00 hasn't been gotten, read PCI device device information directly\r
+    //\r
+    PciAddress = Address & 0xffffffffffffff00ULL;\r
+    Status = PciRootBridgeIo->Pci.Read (\r
+                                    PciRootBridgeIo,\r
+                                    EfiPciWidthUint32,\r
+                                    PciAddress,\r
+                                    1,\r
+                                    &PciConfigData\r
+                                    );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    if ((PciConfigData & 0xffff) == 0xffff) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+\r
+    PciDeviceInfo->VendorID = PciConfigData & 0xffff;\r
+    PciDeviceInfo->DeviceID = PciConfigData >> 16;\r
+\r
+    Status = PciRootBridgeIo->Pci.Read (\r
+                                    PciRootBridgeIo,\r
+                                    EfiPciWidthUint32,\r
+                                    PciAddress + 8,\r
+                                    1,\r
+                                    &PciConfigData\r
+                                    );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    PciDeviceInfo->RevisionID = PciConfigData & 0xf;\r
+\r
+    Status = PciRootBridgeIo->Pci.Read (\r
+                                    PciRootBridgeIo,\r
+                                    EfiPciWidthUint32,\r
+                                    PciAddress + 0x2c,\r
+                                    1,\r
+                                    &PciConfigData\r
+                                    );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    PciDeviceInfo->SubsystemVendorID = PciConfigData & 0xffff;\r
+    PciDeviceInfo->SubsystemID = PciConfigData >> 16;\r
+\r
+  } else {\r
+    PciDeviceInfo->VendorID          = Pci->Hdr.VendorId;\r
+    PciDeviceInfo->DeviceID          = Pci->Hdr.DeviceId;\r
+    PciDeviceInfo->RevisionID        = Pci->Hdr.RevisionID;\r
+    PciDeviceInfo->SubsystemVendorID = Pci->Device.SubsystemVendorID;\r
+    PciDeviceInfo->SubsystemID       = Pci->Device.SubsystemID;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Read PCI configuration space with incompatibility check.\r
+\r
+  @param  PciRootBridgeIo     A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+  @param  PciIo               A pointer to the EFI_PCI_IO_PROTOCOL.\r
+  @param  Pci                 A pointer to PCI_TYPE00.\r
+  @param  Width               Signifies the width of the memory operations.\r
+  @Param  Address             The address within the PCI configuration space for the PCI controller.\r
+  @param  Buffer              For read operations, the destination buffer to store the results. For\r
+                              write operations, the source buffer to write data from.\r
+\r
+  @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.\r
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.\r
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+PciIncompatibilityCheckRead (\r
+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *PciRootBridgeIo,   OPTIONAL\r
+  IN       EFI_PCI_IO_PROTOCOL                    *PciIo,             OPTIONAL\r
+  IN       PCI_TYPE00                             *Pci,               OPTIONAL\r
+  IN       UINTN                                  Width,\r
+  IN       UINT64                                 Address,\r
+  IN       UINTN                                  Count,\r
+  IN OUT   VOID                                   *Buffer\r
+)\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_PCI_DEVICE_INFO           PciDeviceInfo;\r
+  UINT32                        Stride;\r
+\r
+  ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL));\r
+\r
+  //\r
+  // get PCI device device information\r
+  //\r
+  Status = GetPciDeviceDeviceInfo (PciRootBridgeIo, PciIo, Pci, Address, &PciDeviceInfo);\r
+  if (Status != EFI_SUCCESS) {\r
+    return Status;\r
+  }\r
+\r
+  Stride = 1 << Width;\r
+\r
+  for (; Count > 0; Count--, Address += Stride, Buffer = (UINT8 *)Buffer + Stride) {\r
+\r
+    //\r
+    // read configuration register\r
+    //\r
+    Status = ReadConfigData (PciRootBridgeIo, PciIo, &PciDeviceInfo, (UINT64) Width, Address, Buffer);\r
+\r
+    if (Status != EFI_SUCCESS) {\r
+      return Status;\r
+    }\r
+\r
+    //\r
+    // update the data read from configuration register\r
+    //\r
+    if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_REGISTER_UPDATE_SUPPORT) {\r
+      UpdateConfigData (&PciDeviceInfo, PCI_REGISTER_READ, Width, Address & 0xff, Buffer);\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Write PCI configuration space with incompatibility check.\r
+\r
+  @param  PciRootBridgeIo     A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+  @param  PciIo               A pointer to the EFI_PCI_IO_PROTOCOL.\r
+  @param  Pci                 A pointer to PCI_TYPE00.\r
+  @param  Width               Signifies the width of the memory operations.\r
+  @Param  Address             The address within the PCI configuration space for the PCI controller.\r
+  @param  Buffer              For read operations, the destination buffer to store the results. For\r
+                              write operations, the source buffer to write data from.\r
+\r
+  @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.\r
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.\r
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+PciIncompatibilityCheckWrite (\r
+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *PciRootBridgeIo,   OPTIONAL\r
+  IN       EFI_PCI_IO_PROTOCOL                    *PciIo,             OPTIONAL\r
+  IN       PCI_TYPE00                             *Pci,               OPTIONAL\r
+  IN       UINTN                                  Width,\r
+  IN       UINT64                                 Address,\r
+  IN       UINTN                                  Count,\r
+  IN OUT   VOID                                   *Buffer\r
+)\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_PCI_DEVICE_INFO           PciDeviceInfo;\r
+  UINT32                        Stride;\r
+  UINT64                        Data;\r
+\r
+  ASSERT ((PciRootBridgeIo == NULL) ^ (PciIo == NULL));\r
+\r
+  //\r
+  // get PCI device device information\r
+  //\r
+  Status = GetPciDeviceDeviceInfo (PciRootBridgeIo, PciIo, Pci, Address, &PciDeviceInfo);\r
+  if (Status != EFI_SUCCESS) {\r
+    return Status;\r
+  }\r
+\r
+  Stride = 1 << Width;\r
+\r
+  for (; Count > 0; Count--, Address += Stride, Buffer = (UINT8 *) Buffer + Stride) {\r
+\r
+    Data = 0;\r
+\r
+    switch (Width) {\r
+    case EfiPciWidthUint8:\r
+      Data = * (UINT8 *) Buffer;\r
+      break;\r
+    case EfiPciWidthUint16:\r
+      Data = * (UINT16 *) Buffer;\r
+      break;\r
+\r
+    case EfiPciWidthUint32:\r
+      Data = * (UINT32 *) Buffer;\r
+      break;\r
+\r
+    default:\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+\r
+    //\r
+    // update the data writen into configuration register\r
+    //\r
+    if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_REGISTER_UPDATE_SUPPORT) {\r
+      UpdateConfigData (&PciDeviceInfo, PCI_REGISTER_WRITE, Width, Address & 0xff, &Data);\r
+    }\r
+\r
+    //\r
+    // write configuration register\r
+    //\r
+    Status = WriteConfigData (PciRootBridgeIo, PciIo, &PciDeviceInfo, Width, Address, &Data);\r
+\r
+    if (Status != EFI_SUCCESS) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Read PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+\r
+  @param  PciRootBridgeIo     A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+  @param  Pci                 A pointer to PCI_TYPE00.\r
+  @param  Width               Signifies the width of the memory operations.\r
+  @Param  Address             The address within the PCI configuration space for the PCI controller.\r
+  @param  Buffer              For read operations, the destination buffer to store the results. For\r
+                              write operations, the source buffer to write data from.\r
+\r
+  @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.\r
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.\r
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+PciRootBridgeIoRead (\r
+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *PciRootBridgeIo,\r
+  IN       PCI_TYPE00                             *Pci,            OPTIONAL\r
+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
+  IN       UINT64                                 Address,\r
+  IN       UINTN                                  Count,\r
+  IN OUT   VOID                                   *Buffer\r
+  )\r
+{\r
+  if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_READ_SUPPORT) {\r
+    //\r
+    // if PCI incompatibility check enabled\r
+    //\r
+    return PciIncompatibilityCheckRead (\r
+                   PciRootBridgeIo,\r
+                   NULL,\r
+                   Pci,\r
+                   (UINTN) Width,\r
+                   Address,\r
+                   Count,\r
+                   Buffer\r
+                   );\r
+  } else {\r
+    return PciRootBridgeIo->Pci.Read (\r
+                   PciRootBridgeIo,\r
+                   Width,\r
+                   Address,\r
+                   Count,\r
+                   Buffer\r
+                   );\r
+  }\r
+}\r
+\r
+/**\r
+  Write PCI configuration space through EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+\r
+  @param  PciRootBridgeIo     A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+  @param  Pci                 A pointer to PCI_TYPE00.\r
+  @param  Width               Signifies the width of the memory operations.\r
+  @Param  Address             The address within the PCI configuration space for the PCI controller.\r
+  @param  Buffer              For read operations, the destination buffer to store the results. For\r
+                              write operations, the source buffer to write data from.\r
+\r
+  @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.\r
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.\r
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+PciRootBridgeIoWrite (\r
+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *PciRootBridgeIo,\r
+  IN       PCI_TYPE00                             *Pci,\r
+  IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
+  IN       UINT64                                 Address,\r
+  IN       UINTN                                  Count,\r
+  IN OUT   VOID                                   *Buffer\r
+  )\r
+{\r
+  if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_WRITE_SUPPORT) {\r
+    //\r
+    // if PCI incompatibility check enabled\r
+    //\r
+    return  PciIncompatibilityCheckWrite (\r
+                   PciRootBridgeIo,\r
+                   NULL,\r
+                   Pci,\r
+                   Width,\r
+                   Address,\r
+                   Count,\r
+                   Buffer\r
+                   );\r
+\r
+  } else {\r
+    return  PciRootBridgeIo->Pci.Write (\r
+                   PciRootBridgeIo,\r
+                   Width,\r
+                   Address,\r
+                   Count,\r
+                   Buffer\r
+                   );\r
+  }\r
+}\r
+\r
+/**\r
+  Read PCI configuration space through EFI_PCI_IO_PROTOCOL.\r
+\r
+  @param  PciIo               A pointer to the EFI_PCI_O_PROTOCOL.\r
+  @param  Width               Signifies the width of the memory operations.\r
+  @Param  Address             The address within the PCI configuration space for the PCI controller.\r
+  @param  Buffer              For read operations, the destination buffer to store the results. For\r
+                              write operations, the source buffer to write data from.\r
+\r
+  @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.\r
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.\r
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+PciIoRead (\r
+  IN       EFI_PCI_IO_PROTOCOL                    *PciIo,\r
+  IN       EFI_PCI_IO_PROTOCOL_WIDTH              Width,\r
+  IN       UINT32                                 Address,\r
+  IN       UINTN                                  Count,\r
+  IN OUT   VOID                                   *Buffer\r
+  )\r
+{\r
+  if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_READ_SUPPORT) {\r
+    //\r
+    // if PCI incompatibility check enabled\r
+    //\r
+    return PciIncompatibilityCheckRead (\r
+                   NULL,\r
+                   PciIo,\r
+                   NULL,\r
+                   (UINTN) Width,\r
+                   Address,\r
+                   Count,\r
+                   Buffer\r
+                   );\r
+  } else {\r
+    return PciIo->Pci.Read (\r
+                   PciIo,\r
+                   Width,\r
+                   Address,\r
+                   Count,\r
+                   Buffer\r
+                   );\r
+  }\r
+}\r
+\r
+/**\r
+  Write PCI configuration space through EFI_PCI_IO_PROTOCOL.\r
+\r
+  @param  PciIo               A pointer to the EFI_PCI_O_PROTOCOL.\r
+  @param  Width               Signifies the width of the memory operations.\r
+  @Param  Address             The address within the PCI configuration space for the PCI controller.\r
+  @param  Buffer              For read operations, the destination buffer to store the results. For\r
+                              write operations, the source buffer to write data from.\r
+\r
+  @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.\r
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.\r
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+PciIoWrite (\r
+  IN       EFI_PCI_IO_PROTOCOL                    *PciIo,\r
+  IN       EFI_PCI_IO_PROTOCOL_WIDTH              Width,\r
+  IN       UINT32                                 Address,\r
+  IN       UINTN                                  Count,\r
+  IN OUT   VOID                                   *Buffer\r
+  )\r
+{\r
+  if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask) & PCI_INCOMPATIBLE_WRITE_SUPPORT) {\r
+\r
+    //\r
+    // if PCI incompatibility check enabled\r
+    //\r
+    return  PciIncompatibilityCheckWrite (\r
+                   NULL,\r
+                   PciIo,\r
+                   NULL,\r
+                   Width,\r
+                   Address,\r
+                   Count,\r
+                   Buffer\r
+                   );\r
+\r
+  } else {\r
+    return PciIo->Pci.Write (\r
+                   PciIo,\r
+                   Width,\r
+                   Address,\r
+                   Count,\r
+                   Buffer\r
+                   );\r
+  }\r
+}\r