]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciIo.c
index 0969407831d85fd48414dd542235fbea3cb0787e..40171f9ed5136325caf6c6dd36581822fbda4900 100644 (file)
@@ -1,19 +1,15 @@
 /** @file\r
   EFI PCI IO protocol functions implementation for PCI Bus module.\r
 \r
-Copyright (c) 2006 - 2009, 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 - 2019, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "PciBus.h"\r
 \r
+extern EDKII_IOMMU_PROTOCOL                          *mIoMmuProtocol;\r
+\r
 //\r
 // Pci Io Protocol Interface\r
 //\r
@@ -46,26 +42,6 @@ EFI_PCI_IO_PROTOCOL  mPciIoInterface = {
   NULL\r
 };\r
 \r
-/**\r
-  Report a error Status code of PCI bus driver controller.\r
-\r
-  @param PciIoDevice Pci device instance.\r
-  @param Code        Status code value.\r
-\r
-**/\r
-EFI_STATUS\r
-ReportErrorStatusCode (\r
-  IN PCI_IO_DEVICE               *PciIoDevice,\r
-  IN EFI_STATUS_CODE_VALUE       Code\r
-  )\r
-{\r
-  return REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-          EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-          Code,\r
-          PciIoDevice->DevicePath\r
-          );\r
-}\r
-\r
 /**\r
   Initializes a PCI I/O Instance.\r
 \r
@@ -105,7 +81,7 @@ PciIoVerifyBarAccess (
   IN UINT64                          *Offset\r
   )\r
 {\r
-  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -128,7 +104,7 @@ PciIoVerifyBarAccess (
   // If Width is EfiPciIoWidthFifoUintX then convert to EfiPciIoWidthUintX\r
   // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX\r
   //\r
-  if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {\r
+  if (Width >= EfiPciIoWidthFifoUint8 && Width <= EfiPciIoWidthFifoUint64) {\r
     Count = 1;\r
   }\r
 \r
@@ -166,7 +142,7 @@ PciIoVerifyConfigAccess (
 {\r
   UINT64  ExtendOffset;\r
 \r
-  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -235,7 +211,7 @@ PciIoPollMem (
 \r
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
 \r
-  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -248,6 +224,39 @@ PciIoPollMem (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //\r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Status  = PciIoMemRead (This, Width, BarIndex, Offset, 1, Result);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      if ((*Result & Mask) == Value || Delay == 0) {\r
+        return EFI_SUCCESS;\r
+      }\r
+      do {\r
+        //\r
+        // Stall 10 us = 100 * 100ns\r
+        //\r
+        gBS->Stall (10);\r
+\r
+        Status  = PciIoMemRead (This, Width, BarIndex, Offset, 1, Result);\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
+        if ((*Result & Mask) == Value) {\r
+          return EFI_SUCCESS;\r
+        }\r
+        if (Delay <= 100) {\r
+          return EFI_TIMEOUT;\r
+        }\r
+        Delay -= 100;\r
+      } while (TRUE);\r
+    }\r
+  }\r
+\r
   Status = PciIoDevice->PciRootBridgeIo->PollMem (\r
                                            PciIoDevice->PciRootBridgeIo,\r
                                            (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -259,7 +268,11 @@ PciIoPollMem (
                                            );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR,\r
+      PciIoDevice->DevicePath\r
+      );\r
   }\r
 \r
   return Status;\r
@@ -305,7 +318,7 @@ PciIoPollIo (
 \r
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
 \r
-  if (Width < 0 || Width > EfiPciIoWidthUint64) {\r
+  if ((UINT32)Width > EfiPciIoWidthUint64) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -314,6 +327,39 @@ PciIoPollIo (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //\r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Status  = PciIoIoRead (This, Width, BarIndex, Offset, 1, Result);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      if ((*Result & Mask) == Value || Delay == 0) {\r
+        return EFI_SUCCESS;\r
+      }\r
+      do {\r
+        //\r
+        // Stall 10 us = 100 * 100ns\r
+        //\r
+        gBS->Stall (10);\r
+\r
+        Status  = PciIoIoRead (This, Width, BarIndex, Offset, 1, Result);\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
+        if ((*Result & Mask) == Value) {\r
+          return EFI_SUCCESS;\r
+        }\r
+        if (Delay <= 100) {\r
+          return EFI_TIMEOUT;\r
+        }\r
+        Delay -= 100;\r
+      } while (TRUE);\r
+    }\r
+  }\r
+\r
   Status = PciIoDevice->PciRootBridgeIo->PollIo (\r
                                            PciIoDevice->PciRootBridgeIo,\r
                                            (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -325,7 +371,11 @@ PciIoPollIo (
                                            );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR,\r
+      PciIoDevice->DevicePath\r
+      );\r
   }\r
 \r
   return Status;\r
@@ -367,7 +417,7 @@ PciIoMemRead (
 \r
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
 \r
-  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -380,6 +430,17 @@ PciIoMemRead (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //\r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Count *=  (UINTN)(1 << (Width & 0x03));\r
+      Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));\r
+    }\r
+  }\r
+\r
+\r
   Status = PciIoDevice->PciRootBridgeIo->Mem.Read (\r
                                               PciIoDevice->PciRootBridgeIo,\r
                                               (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -389,7 +450,11 @@ PciIoMemRead (
                                               );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR,\r
+      PciIoDevice->DevicePath\r
+      );\r
   }\r
 \r
   return Status;\r
@@ -431,7 +496,7 @@ PciIoMemWrite (
 \r
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
 \r
-  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -444,6 +509,16 @@ PciIoMemWrite (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //\r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Count *=  (UINTN)(1 << (Width & 0x03));\r
+      Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));\r
+    }\r
+  }\r
+\r
   Status = PciIoDevice->PciRootBridgeIo->Mem.Write (\r
                                               PciIoDevice->PciRootBridgeIo,\r
                                               (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -453,7 +528,11 @@ PciIoMemWrite (
                                               );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR,\r
+      PciIoDevice->DevicePath\r
+      );\r
   }\r
 \r
   return Status;\r
@@ -495,7 +574,7 @@ PciIoIoRead (
 \r
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
 \r
-  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -508,6 +587,16 @@ PciIoIoRead (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //\r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Count *=  (UINTN)(1 << (Width & 0x03));\r
+      Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));\r
+    }\r
+  }\r
+\r
   Status = PciIoDevice->PciRootBridgeIo->Io.Read (\r
                                               PciIoDevice->PciRootBridgeIo,\r
                                               (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -517,7 +606,11 @@ PciIoIoRead (
                                               );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR,\r
+      PciIoDevice->DevicePath\r
+      );\r
   }\r
 \r
   return Status;\r
@@ -559,7 +652,7 @@ PciIoIoWrite (
 \r
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
 \r
-  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -572,6 +665,16 @@ PciIoIoWrite (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //\r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Count *=  (UINTN)(1 << (Width & 0x03));\r
+      Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));\r
+    }\r
+  }\r
+\r
   Status = PciIoDevice->PciRootBridgeIo->Io.Write (\r
                                               PciIoDevice->PciRootBridgeIo,\r
                                               (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -581,7 +684,11 @@ PciIoIoWrite (
                                               );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR,\r
+      PciIoDevice->DevicePath\r
+      );\r
   }\r
 \r
   return Status;\r
@@ -627,6 +734,16 @@ PciIoConfigRead (
     return Status;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //\r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Count *=  (UINTN)(1 << (Width & 0x03));\r
+      Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));\r
+    }\r
+  }\r
+\r
   Status = PciIoDevice->PciRootBridgeIo->Pci.Read (\r
                                                PciIoDevice->PciRootBridgeIo,\r
                                                (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -636,7 +753,11 @@ PciIoConfigRead (
                                                );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR,\r
+      PciIoDevice->DevicePath\r
+      );\r
   }\r
 \r
   return Status;\r
@@ -682,6 +803,16 @@ PciIoConfigWrite (
     return Status;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //\r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Count *=  (UINTN)(1 << (Width & 0x03));\r
+      Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));\r
+    }\r
+  }\r
+\r
   Status = PciIoDevice->PciRootBridgeIo->Pci.Write (\r
                                               PciIoDevice->PciRootBridgeIo,\r
                                               (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -691,7 +822,11 @@ PciIoConfigWrite (
                                               );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR,\r
+      PciIoDevice->DevicePath\r
+      );\r
   }\r
 \r
   return Status;\r
@@ -742,7 +877,7 @@ PciIoCopyMem (
 \r
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
 \r
-  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+  if ((UINT32)Width >= EfiPciIoWidthMaximum) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -767,6 +902,16 @@ PciIoCopyMem (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  //\r
+  // If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
+  //\r
+  if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
+    if ((SrcOffset & ((1 << (Width & 0x03)) - 1)) != 0 || (DestOffset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
+      Count *=  (UINTN)(1 << (Width & 0x03));\r
+      Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));\r
+    }\r
+  }\r
+\r
   Status = PciIoDevice->PciRootBridgeIo->CopyMem (\r
                                           PciIoDevice->PciRootBridgeIo,\r
                                           (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
@@ -776,7 +921,11 @@ PciIoCopyMem (
                                           );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR,\r
+      PciIoDevice->DevicePath\r
+      );\r
   }\r
 \r
   return Status;\r
@@ -812,12 +961,14 @@ PciIoMap (
   OUT    VOID                           **Mapping\r
   )\r
 {\r
-  EFI_STATUS    Status;\r
-  PCI_IO_DEVICE *PciIoDevice;\r
+  EFI_STATUS                                 Status;\r
+  PCI_IO_DEVICE                              *PciIoDevice;\r
+  UINT64                                     IoMmuAttribute;\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  RootBridgeIoOperation;\r
 \r
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
 \r
-  if (Operation < 0 || Operation >= EfiPciIoOperationMaximum) {\r
+  if ((UINT32)Operation >= EfiPciIoOperationMaximum) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -825,13 +976,14 @@ PciIoMap (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  RootBridgeIoOperation = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION)Operation;\r
   if ((PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) != 0) {\r
-    Operation = (EFI_PCI_IO_PROTOCOL_OPERATION) (Operation + EfiPciOperationBusMasterRead64);\r
+    RootBridgeIoOperation = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION)(Operation + EfiPciOperationBusMasterRead64);\r
   }\r
 \r
   Status = PciIoDevice->PciRootBridgeIo->Map (\r
                                           PciIoDevice->PciRootBridgeIo,\r
-                                          (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,\r
+                                          RootBridgeIoOperation,\r
                                           HostAddress,\r
                                           NumberOfBytes,\r
                                           DeviceAddress,\r
@@ -839,7 +991,36 @@ PciIoMap (
                                           );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR,\r
+      PciIoDevice->DevicePath\r
+      );\r
+  }\r
+\r
+  if (mIoMmuProtocol != NULL) {\r
+    if (!EFI_ERROR (Status)) {\r
+      switch (Operation) {\r
+      case EfiPciIoOperationBusMasterRead:\r
+        IoMmuAttribute = EDKII_IOMMU_ACCESS_READ;\r
+        break;\r
+      case EfiPciIoOperationBusMasterWrite:\r
+        IoMmuAttribute = EDKII_IOMMU_ACCESS_WRITE;\r
+        break;\r
+      case EfiPciIoOperationBusMasterCommonBuffer:\r
+        IoMmuAttribute = EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE;\r
+        break;\r
+      default:\r
+        ASSERT(FALSE);\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+      mIoMmuProtocol->SetAttribute (\r
+                        mIoMmuProtocol,\r
+                        PciIoDevice->Handle,\r
+                        *Mapping,\r
+                        IoMmuAttribute\r
+                        );\r
+    }\r
   }\r
 \r
   return Status;\r
@@ -867,13 +1048,26 @@ PciIoUnmap (
 \r
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
 \r
+  if (mIoMmuProtocol != NULL) {\r
+    mIoMmuProtocol->SetAttribute (\r
+                      mIoMmuProtocol,\r
+                      PciIoDevice->Handle,\r
+                      Mapping,\r
+                      0\r
+                      );\r
+  }\r
+\r
   Status = PciIoDevice->PciRootBridgeIo->Unmap (\r
                                           PciIoDevice->PciRootBridgeIo,\r
                                           Mapping\r
                                           );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR,\r
+      PciIoDevice->DevicePath\r
+      );\r
   }\r
 \r
   return Status;\r
@@ -881,7 +1075,7 @@ PciIoUnmap (
 \r
 /**\r
   Allocates pages that are suitable for an EfiPciIoOperationBusMasterCommonBuffer\r
-  mapping.\r
+  or EfiPciOperationBusMasterCommonBuffer64 mapping.\r
 \r
   @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
   @param  Type                  This parameter is not used and must be ignored.\r
@@ -894,7 +1088,7 @@ PciIoUnmap (
 \r
   @retval EFI_SUCCESS           The requested memory pages were allocated.\r
   @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal attribute bits are\r
-                                MEMORY_WRITE_COMBINE and MEMORY_CACHED.\r
+                                MEMORY_WRITE_COMBINE, MEMORY_CACHED and DUAL_ADDRESS_CYCLE.\r
   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
   @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.\r
 \r
@@ -934,7 +1128,11 @@ PciIoAllocateBuffer (
                                           );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR,\r
+      PciIoDevice->DevicePath\r
+      );\r
   }\r
 \r
   return Status;\r
@@ -972,7 +1170,11 @@ PciIoFreeBuffer (
                                           );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR,\r
+      PciIoDevice->DevicePath\r
+      );\r
   }\r
 \r
   return Status;\r
@@ -1004,7 +1206,11 @@ PciIoFlush (
                                            PciIoDevice->PciRootBridgeIo\r
                                            );\r
   if (EFI_ERROR (Status)) {\r
-    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR,\r
+      PciIoDevice->DevicePath\r
+      );\r
   }\r
 \r
   return Status;\r
@@ -1104,7 +1310,7 @@ CheckBarType (
   @param  Operation    Set or Disable.\r
 \r
   @retval  EFI_UNSUPPORTED  If root bridge does not support change attribute.\r
-  @retval  EFI_SUCCESS      Successfully set new attributs.\r
+  @retval  EFI_SUCCESS      Successfully set new attributes.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1131,6 +1337,13 @@ ModifyRootBridgeAttributes (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  //\r
+  // Mask off attributes not supported by PCI root bridge.\r
+  //\r
+  Attributes &= ~(UINT64)(EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE |\r
+                          EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM |\r
+                          EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE);\r
+\r
   //\r
   // Record the new attribute of the Root Bridge\r
   //\r
@@ -1194,13 +1407,13 @@ SupportPaletteSnoopAttributes (
   }\r
 \r
   //\r
-  // Get the boot VGA on the same segement\r
+  // Get the boot VGA on the same Host Bridge\r
   //\r
-  Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);\r
+  Temp = LocateVgaDeviceOnHostBridge (PciIoDevice->PciRootBridgeIo->ParentHandle);\r
 \r
   if (Temp == NULL) {\r
     //\r
-    // If there is no VGA device on the segement, set\r
+    // If there is no VGA device on the segment, set\r
     // this graphics card to decode the palette range\r
     //\r
     return EFI_SUCCESS;\r
@@ -1268,7 +1481,7 @@ SupportPaletteSnoopAttributes (
     //\r
     if (Operation == EfiPciIoAttributeOperationEnable) {\r
       PCI_DISABLE_COMMAND_REGISTER (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
-      Temp->Attributes &= (~EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
+      Temp->Attributes &= (~(UINT64)EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
     } else {\r
       return EFI_UNSUPPORTED;\r
     }\r
@@ -1369,7 +1582,7 @@ PciIoAttributes (
   //\r
   // Just a trick for ENABLE attribute\r
   // EFI_PCI_DEVICE_ENABLE is not defined in UEFI spec, which is the internal usage.\r
-  // So, this logic doesn't confrom to UEFI spec, which should be removed.\r
+  // So, this logic doesn't conform to UEFI spec, which should be removed.\r
   // But this trick logic is still kept for some binary drivers that depend on it.\r
   //\r
   if ((Attributes & EFI_PCI_DEVICE_ENABLE) == EFI_PCI_DEVICE_ENABLE) {\r
@@ -1385,6 +1598,15 @@ PciIoAttributes (
       );\r
   }\r
 \r
+  //\r
+  // Check VGA and VGA16, they can not be set at the same time\r
+  //\r
+  if ((Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO)) != 0) {\r
+    if ((Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) != 0) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+  }\r
+\r
   //\r
   // If no attributes can be supported, then return.\r
   // Otherwise, set the attributes that it can support.\r
@@ -1405,20 +1627,6 @@ PciIoAttributes (
   Command       = 0;\r
   BridgeControl = 0;\r
 \r
-  //\r
-  // Check VGA and VGA16, they can not be set at the same time\r
-  //\r
-  if (((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) != 0         &&\r
-       (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16) != 0)         ||\r
-      ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) != 0         &&\r
-       (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16) != 0) ||\r
-      ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) != 0 &&\r
-       (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16) != 0)         ||\r
-      ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) != 0 &&\r
-       (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16) != 0) ) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
   //\r
   // For PPB & P2C, set relevant attribute bits\r
   //\r
@@ -1454,9 +1662,9 @@ PciIoAttributes (
       //\r
       if (Operation == EfiPciIoAttributeOperationEnable) {\r
         //\r
-        // Check if there have been an active VGA device on the same segment\r
+        // Check if there have been an active VGA device on the same Host Bridge\r
         //\r
-        Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);\r
+        Temp = LocateVgaDeviceOnHostBridge (PciIoDevice->PciRootBridgeIo->ParentHandle);\r
         if (Temp != NULL && Temp != PciIoDevice) {\r
           //\r
           // An active VGA has been detected, so can not enable another\r
@@ -1511,7 +1719,7 @@ PciIoAttributes (
     Command |= EFI_PCI_COMMAND_BUS_MASTER;\r
   }\r
   //\r
-  // The upstream bridge should be also set to revelant attribute\r
+  // The upstream bridge should be also set to relevant attribute\r
   // expect for IO, Mem and BusMaster\r
   //\r
   UpStreamAttributes = Attributes &\r
@@ -1558,12 +1766,67 @@ PciIoAttributes (
   }\r
 \r
   if (EFI_ERROR (Status)) {\r
-    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR,\r
+      PciIoDevice->DevicePath\r
+      );\r
   }\r
 \r
   return Status;\r
 }\r
 \r
+/**\r
+  Retrieve the AddrTranslationOffset from RootBridgeIo for the\r
+  specified range.\r
+\r
+  @param RootBridgeIo    Root Bridge IO instance.\r
+  @param AddrRangeMin    The base address of the MMIO.\r
+  @param AddrLen         The length of the MMIO.\r
+\r
+  @retval The AddrTranslationOffset from RootBridgeIo for the\r
+          specified range, or (UINT64) -1 if the range is not\r
+          found in RootBridgeIo.\r
+**/\r
+UINT64\r
+GetMmioAddressTranslationOffset (\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL   *RootBridgeIo,\r
+  UINT64                            AddrRangeMin,\r
+  UINT64                            AddrLen\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration;\r
+\r
+  Status = RootBridgeIo->Configuration (\r
+                           RootBridgeIo,\r
+                           (VOID **) &Configuration\r
+                           );\r
+  if (EFI_ERROR (Status)) {\r
+    return (UINT64) -1;\r
+  }\r
+\r
+  // According to UEFI 2.7, EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL::Configuration()\r
+  // returns host address instead of device address, while AddrTranslationOffset\r
+  // is not zero, and device address = host address + AddrTranslationOffset, so\r
+  // we convert host address to device address for range compare.\r
+  while (Configuration->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
+    if ((Configuration->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) &&\r
+        (Configuration->AddrRangeMin + Configuration->AddrTranslationOffset <= AddrRangeMin) &&\r
+        (Configuration->AddrRangeMin + Configuration->AddrLen + Configuration->AddrTranslationOffset >= AddrRangeMin + AddrLen)\r
+        ) {\r
+      return Configuration->AddrTranslationOffset;\r
+    }\r
+    Configuration++;\r
+  }\r
+\r
+  //\r
+  // The resource occupied by BAR should be in the range reported by RootBridge.\r
+  //\r
+  ASSERT (FALSE);\r
+  return (UINT64) -1;\r
+}\r
+\r
 /**\r
   Gets the attributes that this PCI controller supports setting on a BAR using\r
   SetBarAttributes(), and retrieves the list of resource descriptors for a BAR.\r
@@ -1573,12 +1836,12 @@ PciIoAttributes (
                                 base address for resource range. The legal range for this field is 0..5.\r
   @param  Supports              A pointer to the mask of attributes that this PCI controller supports\r
                                 setting for this BAR with SetBarAttributes().\r
-  @param  Resources             A pointer to the ACPI 2.0 resource descriptors that describe the current\r
+  @param  Resources             A pointer to the resource descriptors that describe the current\r
                                 configuration of this BAR of the PCI controller.\r
 \r
   @retval EFI_SUCCESS           If Supports is not NULL, then the attributes that the PCI\r
                                 controller supports are returned in Supports. If Resources\r
-                                is not NULL, then the ACPI 2.0 resource descriptors that the PCI\r
+                                is not NULL, then the resource descriptors that the PCI\r
                                 controller is currently using are returned in Resources.\r
   @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.\r
   @retval EFI_UNSUPPORTED       BarIndex not valid for this PCI controller.\r
@@ -1595,14 +1858,9 @@ PciIoGetBarAttributes (
   OUT VOID                           **Resources OPTIONAL\r
   )\r
 {\r
-\r
-  UINT8                             *Configuration;\r
-  UINT8                             NumConfig;\r
   PCI_IO_DEVICE                     *PciIoDevice;\r
-  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
-  EFI_ACPI_END_TAG_DESCRIPTOR       *PtrEnd;\r
-\r
-  NumConfig   = 0;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;\r
+  EFI_ACPI_END_TAG_DESCRIPTOR       *End;\r
 \r
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
 \r
@@ -1610,7 +1868,7 @@ PciIoGetBarAttributes (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (BarIndex >= PCI_MAX_BAR) {\r
+  if ((BarIndex >= PCI_MAX_BAR) || (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeUnknown)) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -1623,102 +1881,95 @@ PciIoGetBarAttributes (
   }\r
 \r
   if (Resources != NULL) {\r
-\r
-    if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeUnknown) {\r
-      NumConfig = 1;\r
-    }\r
-\r
-    Configuration = AllocateZeroPool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
-    if (Configuration == NULL) {\r
+    Descriptor = AllocateZeroPool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
+    if (Descriptor == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
-    Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
-\r
-    if (NumConfig == 1) {\r
-      Ptr->Desc         = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
-      Ptr->Len          = (UINT16) (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3);\r
-\r
-      Ptr->AddrRangeMin = PciIoDevice->PciBar[BarIndex].BaseAddress;\r
-      Ptr->AddrLen      = PciIoDevice->PciBar[BarIndex].Length;\r
-      Ptr->AddrRangeMax = PciIoDevice->PciBar[BarIndex].Alignment;\r
-\r
-      switch (PciIoDevice->PciBar[BarIndex].BarType) {\r
-      case PciBarTypeIo16:\r
-      case PciBarTypeIo32:\r
-        //\r
-        // Io\r
-        //\r
-        Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;\r
-        break;\r
-\r
-      case PciBarTypeMem32:\r
-        //\r
-        // Mem\r
-        //\r
-        Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
-        //\r
-        // 32 bit\r
-        //\r
-        Ptr->AddrSpaceGranularity = 32;\r
-        break;\r
+    *Resources   = Descriptor;\r
 \r
-      case PciBarTypePMem32:\r
-        //\r
-        // Mem\r
-        //\r
-        Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
-        //\r
-        // prefechable\r
-        //\r
-        Ptr->SpecificFlag = 0x6;\r
-        //\r
-        // 32 bit\r
-        //\r
-        Ptr->AddrSpaceGranularity = 32;\r
-        break;\r
+    Descriptor->Desc         = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
+    Descriptor->Len          = (UINT16) (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3);\r
+    Descriptor->AddrRangeMin = PciIoDevice->PciBar[BarIndex].BaseAddress;\r
+    Descriptor->AddrLen      = PciIoDevice->PciBar[BarIndex].Length;\r
+    Descriptor->AddrRangeMax = PciIoDevice->PciBar[BarIndex].Alignment;\r
 \r
-      case PciBarTypeMem64:\r
-        //\r
-        // Mem\r
-        //\r
-        Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
-        //\r
-        // 64 bit\r
-        //\r
-        Ptr->AddrSpaceGranularity = 64;\r
-        break;\r
+    switch (PciIoDevice->PciBar[BarIndex].BarType) {\r
+    case PciBarTypeIo16:\r
+    case PciBarTypeIo32:\r
+      //\r
+      // Io\r
+      //\r
+      Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;\r
+      break;\r
 \r
-      case PciBarTypePMem64:\r
-        //\r
-        // Mem\r
-        //\r
-        Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
-        //\r
-        // prefechable\r
-        //\r
-        Ptr->SpecificFlag = 0x6;\r
-        //\r
-        // 64 bit\r
-        //\r
-        Ptr->AddrSpaceGranularity = 64;\r
-        break;\r
+    case PciBarTypePMem32:\r
+      //\r
+      // prefetchable\r
+      //\r
+      Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;\r
+      //\r
+      // Fall through\r
+      //\r
+    case PciBarTypeMem32:\r
+      //\r
+      // Mem\r
+      //\r
+      Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+      //\r
+      // 32 bit\r
+      //\r
+      Descriptor->AddrSpaceGranularity = 32;\r
+      break;\r
 \r
-      default:\r
-        break;\r
-      }\r
+    case PciBarTypePMem64:\r
+      //\r
+      // prefetchable\r
+      //\r
+      Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;\r
+      //\r
+      // Fall through\r
+      //\r
+    case PciBarTypeMem64:\r
+      //\r
+      // Mem\r
+      //\r
+      Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
+      //\r
+      // 64 bit\r
+      //\r
+      Descriptor->AddrSpaceGranularity = 64;\r
+      break;\r
 \r
-      Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
+    default:\r
+      break;\r
     }\r
 \r
     //\r
     // put the checksum\r
     //\r
-    PtrEnd            = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);\r
-    PtrEnd->Desc      = ACPI_END_TAG_DESCRIPTOR;\r
-    PtrEnd->Checksum  = 0;\r
+    End           = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Descriptor + 1);\r
+    End->Desc     = ACPI_END_TAG_DESCRIPTOR;\r
+    End->Checksum = 0;\r
 \r
-    *Resources        = Configuration;\r
+    //\r
+    // Get the Address Translation Offset\r
+    //\r
+    if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {\r
+      Descriptor->AddrTranslationOffset = GetMmioAddressTranslationOffset (\r
+                                            PciIoDevice->PciRootBridgeIo,\r
+                                            Descriptor->AddrRangeMin,\r
+                                            Descriptor->AddrLen\r
+                                            );\r
+      if (Descriptor->AddrTranslationOffset == (UINT64) -1) {\r
+        FreePool (Descriptor);\r
+        return EFI_UNSUPPORTED;\r
+      }\r
+    }\r
+\r
+    // According to UEFI spec 2.7, we need return host address for\r
+    // PciIo->GetBarAttributes, and host address = device address - translation.\r
+    Descriptor->AddrRangeMin -= Descriptor->AddrTranslationOffset;\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -1785,7 +2036,7 @@ PciIoSetBarAttributes (
     return EFI_UNSUPPORTED;\r
   }\r
   //\r
-  // Attributes must be supported.  Make sure the BAR range describd by BarIndex, Offset, and\r
+  // Attributes must be supported.  Make sure the BAR range described by BarIndex, Offset, and\r
   // Length are valid for this PCI device.\r
   //\r
   NonRelativeOffset = *Offset;\r
@@ -1804,47 +2055,6 @@ PciIoSetBarAttributes (
   return EFI_SUCCESS;\r
 }\r
 \r
-/**\r
-  Program parent bridge's attribute recurrently.\r
-\r
-  @param PciIoDevice  Child Pci device instance\r
-  @param Operation    The operation to perform on the attributes for this PCI controller.\r
-  @param Attributes   The mask of attributes that are used for Set, Enable, and Disable\r
-                      operations.\r
-\r
-  @retval EFI_SUCCESS           The operation on the PCI controller's attributes was completed.\r
-  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
-  @retval EFI_UNSUPPORTED       one or more of the bits set in\r
-                                Attributes are not supported by this PCI controller or one of\r
-                                its parent bridges when Operation is Set, Enable or Disable.\r
-\r
-**/\r
-EFI_STATUS\r
-UpStreamBridgesAttributes (\r
-  IN PCI_IO_DEVICE                            *PciIoDevice,\r
-  IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation,\r
-  IN UINT64                                   Attributes\r
-  )\r
-{\r
-  PCI_IO_DEVICE       *Parent;\r
-  EFI_PCI_IO_PROTOCOL *PciIo;\r
-\r
-  Parent = PciIoDevice->Parent;\r
-\r
-  while (Parent != NULL && IS_PCI_BRIDGE (&Parent->Pci)) {\r
-\r
-    //\r
-    // Get the PciIo Protocol\r
-    //\r
-    PciIo = &Parent->PciIo;\r
-\r
-    PciIo->Attributes (PciIo, Operation, Attributes, NULL);\r
-\r
-    Parent = Parent->Parent;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
 \r
 /**\r
   Test whether two Pci devices has same parent bridge.\r