]> git.proxmox.com Git - mirror_edk2.git/blobdiff - PcAtChipsetPkg/PciHostBridgeDxe/PciRootBridgeIo.c
Add generic HPET Timer DXE Driver and support libraries
[mirror_edk2.git] / PcAtChipsetPkg / PciHostBridgeDxe / PciRootBridgeIo.c
index 9230434185048aeaa356068132ca69cdad1e7a15..512a5049c117fe46337dd06a1d7f171578fa47ba 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   PCI Root Bridge Io Protocol implementation\r
 \r
-Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved. <BR> \r
+Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials are\r
 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
@@ -145,7 +145,7 @@ RootBridgeIoMemRead (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 Address,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *Buffer\r
+  OUT    VOID                                   *Buffer\r
   );\r
 \r
 /**\r
@@ -162,7 +162,7 @@ RootBridgeIoMemRead (
                           responsible for aligning the Address if required.\r
    @param[in]   Count     The number of memory operations to perform. Bytes moved is\r
                           Width size * Count, starting at Address.\r
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For\r
+   @param[in]   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
@@ -177,7 +177,7 @@ RootBridgeIoMemWrite (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 Address,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *Buffer\r
+  IN     VOID                                   *Buffer\r
   );\r
 \r
 /**\r
@@ -185,11 +185,11 @@ RootBridgeIoMemWrite (
 \r
    @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
    @param[in]   Width       Signifies the width of the memory operations.\r
-   @param[in]   Address     The base address of the I/O operation. The caller is responsible for\r
+   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for\r
                             aligning the Address if required.\r
    @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width\r
                             size * Count, starting at Address.\r
-   @param[out]  Buffer      For read operations, the destination buffer to store the results. For\r
+   @param[out]  UserBuffer  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
@@ -205,7 +205,7 @@ RootBridgeIoIoRead (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 UserAddress,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *UserBuffer\r
+  OUT    VOID                                   *UserBuffer\r
   );\r
 \r
 /**\r
@@ -213,11 +213,11 @@ RootBridgeIoIoRead (
 \r
    @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
    @param[in]   Width       Signifies the width of the memory operations.\r
-   @param[in]   Address     The base address of the I/O operation. The caller is responsible for\r
+   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for\r
                             aligning the Address if required.\r
    @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width\r
                             size * Count, starting at Address.\r
-   @param[out]  Buffer      For read operations, the destination buffer to store the results. For\r
+   @param[in]   UserBuffer  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
@@ -233,7 +233,7 @@ RootBridgeIoIoWrite (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 UserAddress,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *UserBuffer\r
+  IN     VOID                                   *UserBuffer\r
   );\r
 \r
 /**\r
@@ -300,7 +300,7 @@ RootBridgeIoPciRead (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 Address,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *Buffer\r
+  OUT    VOID                                   *Buffer\r
   );\r
 \r
 /**\r
@@ -317,7 +317,7 @@ RootBridgeIoPciRead (
    @param[in]   Address   The address within the PCI configuration space for the PCI controller.\r
    @param[in]   Count     The number of PCI configuration operations to perform. Bytes\r
                           moved is Width size * Count, starting at Address.\r
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For\r
+   @param[in]   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
@@ -333,7 +333,7 @@ RootBridgeIoPciWrite (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 Address,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *Buffer\r
+  IN     VOID                                   *Buffer\r
   );\r
 \r
 /**\r
@@ -346,7 +346,7 @@ RootBridgeIoPciWrite (
    @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
    @param[in]       Operation       Indicates if the bus master is going to read or write to system memory.\r
    @param[in]       HostAddress     The system memory address to map to the PCI controller.\r
-   @param[in][out]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.\r
+   @param[inout]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.\r
    @param[out]      DeviceAddress   The resulting map address for the bus master PCI controller to use\r
                                     to access the system memory's HostAddress.\r
    @param[out]      Mapping         The value to pass to Unmap() when the bus master DMA operation is complete.\r
@@ -523,9 +523,9 @@ RootBridgeIoGetAttributes (
                                     MEMORY_WRITE_COMBINE, MEMORY_CACHED, and\r
                                     MEMORY_DISABLE are not set, then ResourceBase and\r
                                     ResourceLength are ignored, and may be NULL.\r
-   @param[in][out]  ResourceBase    A pointer to the base address of the resource range to be modified\r
+   @param[inout]  ResourceBase    A pointer to the base address of the resource range to be modified\r
                                     by the attributes specified by Attributes.\r
-   @param[in][out]  ResourceLength  A pointer to the length of the resource range to be modified by the\r
+   @param[inout]  ResourceLength  A pointer to the length of the resource range to be modified by the\r
                                     attributes specified by Attributes.\r
    \r
    @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.\r
@@ -573,41 +573,45 @@ RootBridgeIoConfiguration (
   );\r
 \r
 //\r
-// Sub Function Prototypes\r
+// Memory Controller Pci Root Bridge Io Module Variables\r
 //\r
-/**\r
-   Internal help function for read and write PCI configuration space.\r
-\r
-   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
-   @param[in]   Write         Switch value for Read or Write.\r
-   @param[in]   Width         Signifies the width of the memory operations.\r
-   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.\r
-   @param[in]   Count         The number of PCI configuration operations to perform. Bytes\r
-                              moved is Width size * Count, starting at Address.\r
-   @param[out]  UserBuffer    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
+EFI_METRONOME_ARCH_PROTOCOL *mMetronome;\r
 \r
-**/\r
-EFI_STATUS\r
-RootBridgeIoPciRW (\r
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,\r
-  IN     BOOLEAN                                Write,\r
-  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
-  IN     UINT64                                 UserAddress,\r
-  IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *UserBuffer\r
-  );\r
+//\r
+// Lookup table for increment values based on transfer widths\r
+//\r
+UINT8 mInStride[] = {\r
+  1, // EfiPciWidthUint8\r
+  2, // EfiPciWidthUint16\r
+  4, // EfiPciWidthUint32\r
+  8, // EfiPciWidthUint64\r
+  0, // EfiPciWidthFifoUint8\r
+  0, // EfiPciWidthFifoUint16\r
+  0, // EfiPciWidthFifoUint32\r
+  0, // EfiPciWidthFifoUint64\r
+  1, // EfiPciWidthFillUint8\r
+  2, // EfiPciWidthFillUint16\r
+  4, // EfiPciWidthFillUint32\r
+  8  // EfiPciWidthFillUint64\r
+};\r
 \r
 //\r
-// Memory Controller Pci Root Bridge Io Module Variables\r
+// Lookup table for increment values based on transfer widths\r
 //\r
-EFI_METRONOME_ARCH_PROTOCOL *mMetronome;\r
-EFI_CPU_IO2_PROTOCOL *mCpuIo;\r
+UINT8 mOutStride[] = {\r
+  1, // EfiPciWidthUint8\r
+  2, // EfiPciWidthUint16\r
+  4, // EfiPciWidthUint32\r
+  8, // EfiPciWidthUint64\r
+  1, // EfiPciWidthFifoUint8\r
+  2, // EfiPciWidthFifoUint16\r
+  4, // EfiPciWidthFifoUint32\r
+  8, // EfiPciWidthFifoUint64\r
+  0, // EfiPciWidthFillUint8\r
+  0, // EfiPciWidthFillUint16\r
+  0, // EfiPciWidthFillUint32\r
+  0  // EfiPciWidthFillUint64\r
+};\r
 \r
 /**\r
 \r
@@ -665,15 +669,16 @@ RootBridgeConstructor (
     PrivateData->ResAllocNode[Index].Status    = ResNone;\r
   }\r
   \r
-\r
-  EfiInitializeLock (&PrivateData->PciLock, TPL_HIGH_LEVEL);\r
   PrivateData->PciAddress = 0xCF8;\r
   PrivateData->PciData    = 0xCFC;\r
 \r
   PrivateData->RootBridgeAttrib = Attri;\r
   \r
-  PrivateData->Attributes  = 0;\r
-  PrivateData->Supports    = 0;\r
+  PrivateData->Supports    = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | \\r
+                             EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | \\r
+                             EFI_PCI_ATTRIBUTE_VGA_MEMORY | \\r
+                             EFI_PCI_ATTRIBUTE_VGA_IO_16  | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;\r
+  PrivateData->Attributes  = PrivateData->Supports;\r
 \r
   Protocol->ParentHandle   = HostBridgeHandle;\r
   \r
@@ -706,15 +711,433 @@ RootBridgeConstructor (
 \r
   Protocol->SegmentNumber  = 0;\r
 \r
-  Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **)&mCpuIo);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
   Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **)&mMetronome);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Check parameters for IO,MMIO,PCI read/write services of PCI Root Bridge IO.\r
+\r
+  The I/O operations are carried out exactly as requested. The caller is responsible \r
+  for satisfying any alignment and I/O width restrictions that a PI System on a \r
+  platform might require. For example on some platforms, width requests of \r
+  EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will \r
+  be handled by the driver.\r
+  \r
+  @param[in] This           A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+  @param[in] OperationType  I/O operation type: IO/MMIO/PCI.\r
+  @param[in] Width          Signifies the width of the I/O or Memory operation.\r
+  @param[in] Address        The base address of the I/O operation. \r
+  @param[in] Count          The number of I/O operations to perform. The number of  \r
+                            bytes moved is Width size * Count, starting at Address.\r
+  @param[in] Buffer         For read operations, the destination buffer to store the results.\r
+                            For write operations, the source buffer from which to write data.\r
+\r
+  @retval EFI_SUCCESS            The parameters for this request pass the checks.\r
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.\r
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.\r
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.\r
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width, \r
+                                 and Count is not valid for this PI system.\r
+\r
+**/\r
+EFI_STATUS\r
+RootBridgeIoCheckParameter (\r
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,\r
+  IN OPERATION_TYPE                         OperationType,\r
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
+  IN UINT64                                 Address,\r
+  IN UINTN                                  Count,\r
+  IN VOID                                   *Buffer\r
+  )\r
+{\r
+  PCI_ROOT_BRIDGE_INSTANCE                     *PrivateData;\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS  *PciRbAddr;\r
+  UINT64                                       MaxCount;\r
+  UINT64                                       Base;\r
+  UINT64                                       Limit;\r
+\r
+  //\r
+  // Check to see if Buffer is NULL\r
+  //\r
+  if (Buffer == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Check to see if Width is in the valid range\r
+  //\r
+  if (Width < EfiPciWidthUint8 || Width >= EfiPciWidthMaximum) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // For FIFO type, the target address won't increase during the access,\r
+  // so treat Count as 1\r
+  //\r
+  if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {\r
+    Count = 1;\r
+  }\r
+\r
+  //\r
+  // Check to see if Width is in the valid range for I/O Port operations\r
+  //\r
+  Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
+  if ((OperationType != MemOperation) && (Width == EfiPciWidthUint64)) {\r
+    ASSERT (FALSE);\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Check to see if Address is aligned\r
+  //\r
+  if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
+\r
+  //\r
+  // Check to see if any address associated with this transfer exceeds the maximum \r
+  // allowed address.  The maximum address implied by the parameters passed in is\r
+  // Address + Size * Count.  If the following condition is met, then the transfer\r
+  // is not supported.\r
+  //\r
+  //    Address + Size * Count > Limit + 1\r
+  //\r
+  // Since Limit can be the maximum integer value supported by the CPU and Count \r
+  // can also be the maximum integer value supported by the CPU, this range\r
+  // check must be adjusted to avoid all oveflow conditions.\r
+  //   \r
+  // The following form of the range check is equivalent but assumes that \r
+  // Limit is of the form (2^n - 1).\r
+  //\r
+  if (OperationType == IoOperation) {\r
+    Base = PrivateData->IoBase;\r
+    Limit = PrivateData->IoLimit;\r
+  } else if (OperationType == MemOperation) {\r
+    Base = PrivateData->MemBase;\r
+    Limit = PrivateData->MemLimit;\r
+  } else {\r
+    PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;\r
+    if (PciRbAddr->Bus < PrivateData->BusBase || PciRbAddr->Bus > PrivateData->BusLimit) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if (PciRbAddr->Device > MAX_PCI_DEVICE_NUMBER || PciRbAddr->Function > MAX_PCI_FUNCTION_NUMBER) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if (PciRbAddr->ExtendedRegister != 0) {\r
+      Address = PciRbAddr->ExtendedRegister;\r
+    } else {\r
+      Address = PciRbAddr->Register;\r
+    }\r
+    Base = 0;\r
+    Limit = MAX_PCI_REG_ADDRESS;\r
+  }\r
+\r
+  if (Address < Base) {\r
+      return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Count == 0) {\r
+    if (Address > Limit) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+  } else {  \r
+    MaxCount = RShiftU64 (Limit, Width);\r
+    if (MaxCount < (Count - 1)) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+    if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+   Internal help function for read and write memory space.\r
+\r
+   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+   @param[in]   Write         Switch value for Read or Write.\r
+   @param[in]   Width         Signifies the width of the memory operations.\r
+   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.\r
+   @param[in]   Count         The number of PCI configuration operations to perform. Bytes\r
+                              moved is Width size * Count, starting at Address.\r
+   @param[in, out] UserBuffer 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
+RootBridgeIoMemRW (\r
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,\r
+  IN     BOOLEAN                                Write,\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
+  EFI_STATUS                             Status;\r
+  UINT8                                  InStride;\r
+  UINT8                                  OutStride;\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  OperationWidth;\r
+  UINT8                                  *Uint8Buffer;\r
+\r
+  Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address, Count, Buffer);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  InStride = mInStride[Width];\r
+  OutStride = mOutStride[Width];\r
+  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {\r
+    if (Write) {\r
+      switch (OperationWidth) {\r
+        case EfiPciWidthUint8:\r
+          MmioWrite8 ((UINTN)Address, *Uint8Buffer);\r
+          break;\r
+        case EfiPciWidthUint16:\r
+          MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));\r
+          break;\r
+        case EfiPciWidthUint32:\r
+          MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));\r
+          break;\r
+        case EfiPciWidthUint64:\r
+          MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));\r
+          break;\r
+        default:\r
+          //\r
+          // The RootBridgeIoCheckParameter call above will ensure that this\r
+          // path is not taken.\r
+          //\r
+          ASSERT (FALSE);\r
+          break;\r
+      }\r
+    } else {\r
+      switch (OperationWidth) {\r
+        case EfiPciWidthUint8:\r
+          *Uint8Buffer = MmioRead8 ((UINTN)Address);\r
+          break;\r
+        case EfiPciWidthUint16:\r
+          *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);\r
+          break;\r
+        case EfiPciWidthUint32:\r
+          *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);\r
+          break;\r
+        case EfiPciWidthUint64:\r
+          *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);\r
+          break;\r
+        default:\r
+          //\r
+          // The RootBridgeIoCheckParameter call above will ensure that this\r
+          // path is not taken.\r
+          //\r
+          ASSERT (FALSE);\r
+          break;\r
+      }\r
+    }\r
+  }\r
+  return EFI_SUCCESS;  \r
+}\r
+\r
+/**\r
+   Internal help function for read and write IO space.\r
+\r
+   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+   @param[in]   Write         Switch value for Read or Write.\r
+   @param[in]   Width         Signifies the width of the memory operations.\r
+   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.\r
+   @param[in]   Count         The number of PCI configuration operations to perform. Bytes\r
+                              moved is Width size * Count, starting at Address.\r
+   @param[in, out] UserBuffer 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
+RootBridgeIoIoRW (\r
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,\r
+  IN     BOOLEAN                                Write,\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
+  EFI_STATUS                             Status;\r
+  UINT8                                  InStride;\r
+  UINT8                                  OutStride;\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  OperationWidth;\r
+  UINT8                                  *Uint8Buffer;\r
+\r
+  Status = RootBridgeIoCheckParameter (This, IoOperation, Width, Address, Count, Buffer);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  InStride = mInStride[Width];\r
+  OutStride = mOutStride[Width];\r
+  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {\r
+    if (Write) {\r
+      switch (OperationWidth) {\r
+        case EfiPciWidthUint8:\r
+          IoWrite8 ((UINTN)Address, *Uint8Buffer);\r
+          break;\r
+        case EfiPciWidthUint16:\r
+          IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));\r
+          break;\r
+        case EfiPciWidthUint32:\r
+          IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));\r
+          break;\r
+        default:\r
+          //\r
+          // The RootBridgeIoCheckParameter call above will ensure that this\r
+          // path is not taken.\r
+          //\r
+          ASSERT (FALSE);\r
+          break;\r
+      }\r
+    } else {\r
+      switch (OperationWidth) {\r
+        case EfiPciWidthUint8:\r
+          *Uint8Buffer = IoRead8 ((UINTN)Address);\r
+          break;\r
+        case EfiPciWidthUint16:\r
+          *((UINT16 *)Uint8Buffer) = IoRead16 ((UINTN)Address);\r
+          break;\r
+        case EfiPciWidthUint32:\r
+          *((UINT32 *)Uint8Buffer) = IoRead32 ((UINTN)Address);\r
+          break;\r
+        default:\r
+          //\r
+          // The RootBridgeIoCheckParameter call above will ensure that this\r
+          // path is not taken.\r
+          //\r
+          ASSERT (FALSE);\r
+          break;\r
+      }\r
+    }\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+   Internal help function for read and write PCI configuration space.\r
+\r
+   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+   @param[in]   Write         Switch value for Read or Write.\r
+   @param[in]   Width         Signifies the width of the memory operations.\r
+   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.\r
+   @param[in]   Count         The number of PCI configuration operations to perform. Bytes\r
+                              moved is Width size * Count, starting at Address.\r
+   @param[in, out] UserBuffer 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
+RootBridgeIoPciRW (\r
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,\r
+  IN BOOLEAN                                Write,\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
+  EFI_STATUS                                   Status;\r
+  UINT8                                        InStride;\r
+  UINT8                                        OutStride;\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH        OperationWidth;\r
+  UINT8                                        *Uint8Buffer;\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS  *PciRbAddr;\r
+  UINTN                                        PcieRegAddr;\r
+\r
+  Status = RootBridgeIoCheckParameter (This, PciOperation, Width, Address, Count, Buffer);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;\r
+\r
+  PcieRegAddr = (UINTN) PCI_LIB_ADDRESS (\r
+                          PciRbAddr->Bus,\r
+                          PciRbAddr->Device,\r
+                          PciRbAddr->Function,\r
+                          (PciRbAddr->ExtendedRegister != 0) ? \\r
+                            PciRbAddr->ExtendedRegister :\r
+                            PciRbAddr->Register\r
+                          );\r
+\r
+  InStride = mInStride[Width];\r
+  OutStride = mOutStride[Width];\r
+  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
+  for (Uint8Buffer = Buffer; Count > 0; PcieRegAddr += InStride, Uint8Buffer += OutStride, Count--) {\r
+    if (Write) {\r
+      switch (OperationWidth) {\r
+        case EfiPciWidthUint8:\r
+          PciWrite8 (PcieRegAddr, *Uint8Buffer);\r
+          break;\r
+        case EfiPciWidthUint16:\r
+          PciWrite16 (PcieRegAddr, *((UINT16 *)Uint8Buffer));\r
+          break;\r
+        case EfiPciWidthUint32:\r
+          PciWrite32 (PcieRegAddr, *((UINT32 *)Uint8Buffer));\r
+          break;\r
+        default:\r
+          //\r
+          // The RootBridgeIoCheckParameter call above will ensure that this\r
+          // path is not taken.\r
+          //\r
+          ASSERT (FALSE);\r
+          break;\r
+      }\r
+    } else {\r
+      switch (OperationWidth) {\r
+        case EfiPciWidthUint8:\r
+          *Uint8Buffer = PciRead8 (PcieRegAddr);\r
+          break;\r
+        case EfiPciWidthUint16:\r
+          *((UINT16 *)Uint8Buffer) = PciRead16 (PcieRegAddr);\r
+          break;\r
+        case EfiPciWidthUint32:\r
+          *((UINT32 *)Uint8Buffer) = PciRead32 (PcieRegAddr);\r
+          break;\r
+        default:\r
+          //\r
+          // The RootBridgeIoCheckParameter call above will ensure that this\r
+          // path is not taken.\r
+          //\r
+          ASSERT (FALSE);\r
+          break;\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
    Polls an address in memory mapped I/O space until an exit condition is met, or \r
    a timeout occurs. \r
@@ -799,7 +1222,7 @@ RootBridgeIoPollMem (
     }\r
     NumberOfTicks += 1;\r
   \r
-    while (NumberOfTicks) {\r
+    while (NumberOfTicks != 0) {\r
 \r
       mMetronome->WaitForTick (mMetronome, 1);\r
     \r
@@ -900,7 +1323,7 @@ RootBridgeIoPollIo (
     }\r
     NumberOfTicks += 1;\r
   \r
-    while (NumberOfTicks) {\r
+    while (NumberOfTicks != 0) {\r
 \r
       mMetronome->WaitForTick (mMetronome, 1);\r
     \r
@@ -949,45 +1372,10 @@ RootBridgeIoMemRead (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 Address,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *Buffer\r
+  OUT    VOID                                   *Buffer\r
   )\r
 {\r
-  PCI_ROOT_BRIDGE_INSTANCE                 *PrivateData;\r
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    OldWidth;\r
-  UINTN                                    OldCount;\r
-  \r
-  if (Buffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Width < 0 || Width >= EfiPciWidthMaximum) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);\r
-\r
-  //\r
-  // Check memory access limit\r
-  //\r
-  if (Address < PrivateData->MemBase) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  OldWidth = Width;\r
-  OldCount = Count;\r
-\r
-  if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {\r
-    Count = 1;\r
-  }\r
-\r
-  Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);\r
-\r
-  if (Address + (((UINTN)1 << Width) * Count) - 1 > PrivateData->MemLimit) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  return mCpuIo->Mem.Read (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) OldWidth, \r
-                       Address, OldCount, Buffer);\r
+  return RootBridgeIoMemRW (This, FALSE, Width, Address, Count, Buffer);\r
 }\r
 \r
 /**\r
@@ -1004,7 +1392,7 @@ RootBridgeIoMemRead (
                           responsible for aligning the Address if required.\r
    @param[in]   Count     The number of memory operations to perform. Bytes moved is\r
                           Width size * Count, starting at Address.\r
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For\r
+   @param[in]   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
@@ -1019,44 +1407,10 @@ RootBridgeIoMemWrite (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 Address,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *Buffer\r
+  IN     VOID                                   *Buffer\r
   )\r
 {\r
-  PCI_ROOT_BRIDGE_INSTANCE                    *PrivateData;\r
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH       OldWidth;\r
-  UINTN                                       OldCount;\r
-\r
-  if (Buffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Width < 0 || Width >= EfiPciWidthMaximum) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);\r
-\r
-  //\r
-  // Check memory access limit\r
-  //\r
-  if (Address < PrivateData->MemBase) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  OldWidth = Width;\r
-  OldCount = Count;\r
-  if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {\r
-    Count = 1;\r
-  }\r
-\r
-  Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);\r
-\r
-  if (Address + (((UINTN)1 << Width) * Count) - 1 > PrivateData->MemLimit) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  return mCpuIo->Mem.Write (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) OldWidth, \r
-                       Address, OldCount, Buffer);\r
+  return RootBridgeIoMemRW (This, TRUE, Width, Address, Count, Buffer);  \r
 }\r
 \r
 /**\r
@@ -1084,55 +1438,10 @@ RootBridgeIoIoRead (
   IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN     UINT64                                 Address,\r
   IN     UINTN                                  Count,\r
-  IN OUT VOID                                   *Buffer\r
+  OUT    VOID                                   *Buffer\r
   )\r
 {\r
-  \r
-  \r
-  UINTN                                    AlignMask;\r
-  PCI_ROOT_BRIDGE_INSTANCE                 *PrivateData;\r
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH    OldWidth;\r
-  UINTN                                    OldCount;\r
-\r
-  if (Buffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  \r
-  if (Width < 0 || Width >= EfiPciWidthMaximum) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  \r
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);\r
-\r
-  //AlignMask = (1 << Width) - 1;\r
-  AlignMask = (1 << (Width & 0x03)) - 1;\r
-\r
-  //\r
-  // check Io access limit\r
-  //\r
-  if (Address < PrivateData->IoBase) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  OldWidth = Width;\r
-  OldCount = Count;\r
-  if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {\r
-    Count = 1;\r
-  }\r
-\r
-  Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);\r
-  \r
-  if (Address + (((UINTN)1 << Width) * Count) - 1 >= PrivateData->IoLimit) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Address & AlignMask) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  return mCpuIo->Io.Read (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) OldWidth, \r
-                      Address, OldCount, Buffer);\r
-\r
+  return RootBridgeIoIoRW (This, FALSE, Width, Address, Count, Buffer);  \r
 }\r
 \r
 /**\r
@@ -1144,7 +1453,7 @@ RootBridgeIoIoRead (
                             aligning the Address if required.\r
    @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width\r
                             size * Count, starting at Address.\r
-   @param[out]  Buffer      For read operations, the destination buffer to store the results. For\r
+   @param[in]   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
@@ -1160,53 +1469,10 @@ RootBridgeIoIoWrite (
   IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH   Width,\r
   IN       UINT64                                  Address,\r
   IN       UINTN                                   Count,\r
-  IN OUT   VOID                                    *Buffer\r
+  IN       VOID                                    *Buffer\r
   )\r
 {\r
-  UINTN                                         AlignMask;\r
-  PCI_ROOT_BRIDGE_INSTANCE                      *PrivateData;\r
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH         OldWidth;\r
-  UINTN                                         OldCount;\r
-\r
-  if (Buffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Width < 0 || Width >= EfiPciWidthMaximum) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);\r
-\r
-  //AlignMask = (1 << Width) - 1;\r
-  AlignMask = (1 << (Width & 0x03)) - 1;\r
-\r
-  //\r
-  // Check Io access limit\r
-  //\r
-  if (Address < PrivateData->IoBase) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  OldWidth = Width;\r
-  OldCount = Count;\r
-  if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {\r
-    Count = 1;\r
-  }\r
-\r
-  Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);\r
-  \r
-  if (Address + (((UINTN)1 << Width) * Count) - 1 >= PrivateData->IoLimit) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Address & AlignMask) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  return mCpuIo->Io.Write (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) OldWidth, \r
-                      Address, OldCount, Buffer);\r
-\r
+  return RootBridgeIoIoRW (This, TRUE, Width, Address, Count, Buffer);  \r
 }\r
 \r
 /**\r
@@ -1236,7 +1502,7 @@ RootBridgeIoIoWrite (
 EFI_STATUS\r
 EFIAPI\r
 RootBridgeIoCopyMem (\r
-  IN struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL      *This,\r
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL              *This,\r
   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH        Width,\r
   IN UINT64                                       DestAddress,\r
   IN UINT64                                       SrcAddress,\r
@@ -1328,20 +1594,9 @@ RootBridgeIoPciRead (
   IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN       UINT64                                 Address,\r
   IN       UINTN                                  Count,\r
-  IN OUT   VOID                                   *Buffer\r
+  OUT      VOID                                   *Buffer\r
   )\r
 {\r
-  \r
-  if (Buffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Width < 0 || Width >= EfiPciWidthMaximum) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Read Pci configuration space\r
-  //\r
   return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);\r
 }\r
 \r
@@ -1359,7 +1614,7 @@ RootBridgeIoPciRead (
    @param[in]   Address   The address within the PCI configuration space for the PCI controller.\r
    @param[in]   Count     The number of PCI configuration operations to perform. Bytes\r
                           moved is Width size * Count, starting at Address.\r
-   @param[out]  Buffer    For read operations, the destination buffer to store the results. For\r
+   @param[in]   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
@@ -1375,20 +1630,9 @@ RootBridgeIoPciWrite (
   IN       EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
   IN       UINT64                                 Address,\r
   IN       UINTN                                  Count,\r
-  IN OUT   VOID                                   *Buffer\r
+  IN       VOID                                   *Buffer\r
   )\r
 {\r
-  \r
-  if (Buffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Width < 0 || Width >= EfiPciWidthMaximum) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Write Pci configuration space\r
-  //\r
   return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);\r
 }\r
 \r
@@ -1402,7 +1646,7 @@ RootBridgeIoPciWrite (
    @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
    @param[in]       Operation       Indicates if the bus master is going to read or write to system memory.\r
    @param[in]       HostAddress     The system memory address to map to the PCI controller.\r
-   @param[in][out]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.\r
+   @param[inout]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.\r
    @param[out]      DeviceAddress   The resulting map address for the bus master PCI controller to use\r
                                     to access the system memory's HostAddress.\r
    @param[out]      Mapping         The value to pass to Unmap() when the bus master DMA operation is complete.\r
@@ -1631,7 +1875,7 @@ RootBridgeIoAllocateBuffer (
   //\r
   // Validate Attributes\r
   //\r
-  if (Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) {\r
+  if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -1759,11 +2003,11 @@ RootBridgeIoGetAttributes (
   //\r
   // Set the return value for Supported and Attributes\r
   //\r
-  if (Supported) {\r
+  if (Supported != NULL) {\r
     *Supported  = PrivateData->Supports; \r
   }\r
 \r
-  if (Attributes) {\r
+  if (Attributes != NULL) {\r
     *Attributes = PrivateData->Attributes;\r
   }\r
   \r
@@ -1790,9 +2034,9 @@ RootBridgeIoGetAttributes (
                                     MEMORY_WRITE_COMBINE, MEMORY_CACHED, and\r
                                     MEMORY_DISABLE are not set, then ResourceBase and\r
                                     ResourceLength are ignored, and may be NULL.\r
-   @param[in][out]  ResourceBase    A pointer to the base address of the resource range to be modified\r
+   @param[inout]  ResourceBase    A pointer to the base address of the resource range to be modified\r
                                     by the attributes specified by Attributes.\r
-   @param[in][out]  ResourceLength  A pointer to the length of the resource range to be modified by the\r
+   @param[inout]  ResourceLength  A pointer to the length of the resource range to be modified by the\r
                                     attributes specified by Attributes.\r
    \r
    @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.\r
@@ -1813,7 +2057,7 @@ RootBridgeIoSetAttributes (
   \r
   PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);\r
   \r
-  if (Attributes) {\r
+  if (Attributes != 0) {\r
     if ((Attributes & (~(PrivateData->Supports))) != 0) {\r
       return EFI_UNSUPPORTED;\r
     }\r
@@ -1879,111 +2123,3 @@ RootBridgeIoConfiguration (
   return EFI_SUCCESS;\r
 }\r
 \r
-//\r
-// Internal function\r
-//\r
-/**\r
-   Internal help function for read and write PCI configuration space.\r
-\r
-   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
-   @param[in]   Write         Switch value for Read or Write.\r
-   @param[in]   Width         Signifies the width of the memory operations.\r
-   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.\r
-   @param[in]   Count         The number of PCI configuration operations to perform. Bytes\r
-                              moved is Width size * Count, starting at Address.\r
-   @param[out]  UserBuffer    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
-RootBridgeIoPciRW (\r
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,\r
-  IN BOOLEAN                                Write,\r
-  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,\r
-  IN UINT64                                 UserAddress,\r
-  IN UINTN                                  Count,\r
-  IN OUT VOID                               *UserBuffer\r
-  )\r
-{\r
-  PCI_CONFIG_ACCESS_CF8             Pci;\r
-  PCI_CONFIG_ACCESS_CF8             PciAligned;\r
-  UINT32                            InStride;\r
-  UINT32                            OutStride;\r
-  UINTN                             PciData;\r
-  UINTN                             PciDataStride;\r
-  PCI_ROOT_BRIDGE_INSTANCE     *PrivateData;\r
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS  PciAddress;\r
-\r
-  if (Width < 0 || Width >= EfiPciWidthMaximum) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  \r
-  if ((Width & 0x03) >= EfiPciWidthUint64) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  \r
-  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);\r
-\r
-  InStride    = 1 << (Width & 0x03);\r
-  OutStride   = InStride;\r
-  if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {\r
-    InStride = 0;\r
-  }\r
-\r
-  if (Width >= EfiCpuIoWidthFillUint8 && Width <= EfiCpuIoWidthFillUint64) {\r
-    OutStride = 0;\r
-  }\r
-\r
-  CopyMem (&PciAddress, &UserAddress, sizeof(UINT64));\r
-\r
-  if (PciAddress.ExtendedRegister > 0xFF) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  if (PciAddress.ExtendedRegister != 0) {\r
-    Pci.Bits.Reg = PciAddress.ExtendedRegister & 0xFF;\r
-  } else {\r
-    Pci.Bits.Reg = PciAddress.Register;\r
-  }\r
-\r
-  Pci.Bits.Func     = PciAddress.Function;\r
-  Pci.Bits.Dev      = PciAddress.Device;\r
-  Pci.Bits.Bus      = PciAddress.Bus;\r
-  Pci.Bits.Reserved = 0;\r
-  Pci.Bits.Enable   = 1;\r
-\r
-  //\r
-  // PCI Config access are all 32-bit alligned, but by accessing the\r
-  //  CONFIG_DATA_REGISTER (0xcfc) with different widths more cycle types\r
-  //  are possible on PCI.\r
-  //\r
-  // To read a byte of PCI config space you load 0xcf8 and \r
-  //  read 0xcfc, 0xcfd, 0xcfe, 0xcff\r
-  //\r
-  PciDataStride = Pci.Bits.Reg & 0x03;\r
-\r
-  while (Count) {\r
-    CopyMem (&PciAligned, &Pci, sizeof (PciAligned));\r
-    PciAligned.Bits.Reg &= 0xfc;\r
-    PciData = (UINTN)PrivateData->PciData + PciDataStride;\r
-    EfiAcquireLock(&PrivateData->PciLock);\r
-    This->Io.Write (This, EfiPciWidthUint32, PrivateData->PciAddress, 1, &PciAligned);\r
-    if (Write) {\r
-      This->Io.Write (This, Width, PciData, 1, UserBuffer);\r
-    } else {\r
-      This->Io.Read (This, Width, PciData, 1, UserBuffer);\r
-    }\r
-    EfiReleaseLock(&PrivateData->PciLock);\r
-    UserBuffer = ((UINT8 *)UserBuffer) + OutStride;\r
-    PciDataStride = (PciDataStride + InStride) % 4;\r
-    Pci.Bits.Reg += InStride;\r
-    Count -= 1;\r
-  }\r
-  \r
-  return EFI_SUCCESS;\r
-}\r