]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c
Add PciBus & IdeBus
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / PciBus / Dxe / PciIo.c
diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c b/IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c
new file mode 100644 (file)
index 0000000..a636d4f
--- /dev/null
@@ -0,0 +1,1980 @@
+/*++\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
+\r
+Module Name:\r
+\r
+  PciIo.c\r
+  \r
+Abstract:\r
+\r
+  PCI I/O Abstraction Driver\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "pcibus.h"\r
+\r
+//\r
+// Internal use only\r
+//\r
+STATIC\r
+EFI_STATUS\r
+ReportErrorStatusCode (\r
+  IN PCI_IO_DEVICE               *PciIoDevice,\r
+  IN EFI_STATUS_CODE_VALUE       Code\r
+  );\r
+\r
+//\r
+// PCI I/O Support Function Prototypes\r
+//\r
+//\r
+//\r
+// Pci Io Protocol Interface\r
+//\r
+static EFI_PCI_IO_PROTOCOL  PciIoInterface = {\r
+  PciIoPollMem,\r
+  PciIoPollIo,\r
+  {\r
+    PciIoMemRead,\r
+    PciIoMemWrite\r
+  },\r
+  {\r
+    PciIoIoRead,\r
+    PciIoIoWrite\r
+  },\r
+  {\r
+    PciIoConfigRead,\r
+    PciIoConfigWrite\r
+  },\r
+  PciIoCopyMem,\r
+  PciIoMap,\r
+  PciIoUnmap,\r
+  PciIoAllocateBuffer,\r
+  PciIoFreeBuffer,\r
+  PciIoFlush,\r
+  PciIoGetLocation,\r
+  PciIoAttributes,\r
+  PciIoGetBarAttributes,\r
+  PciIoSetBarAttributes,\r
+  0,\r
+  NULL\r
+};\r
+\r
+STATIC\r
+EFI_STATUS\r
+ReportErrorStatusCode (\r
+  IN PCI_IO_DEVICE               *PciIoDevice,\r
+  IN EFI_STATUS_CODE_VALUE       Code\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  report a error Status code of PCI bus driver controller\r
+\r
+Arguments:\r
+  \r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciIoDevice - add argument and description to function comment\r
+// TODO:    Code - add argument and description to function comment\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
+EFI_STATUS\r
+InitializePciIoInstance (\r
+  PCI_IO_DEVICE  *PciIoDevice\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initializes a PCI I/O Instance\r
+\r
+Arguments:\r
+  \r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciIoDevice - add argument and description to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  CopyMem (&PciIoDevice->PciIo, &PciIoInterface, sizeof (EFI_PCI_IO_PROTOCOL));\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciIoVerifyBarAccess (\r
+  PCI_IO_DEVICE                   *PciIoDevice,\r
+  UINT8                           BarIndex,\r
+  PCI_BAR_TYPE                    Type,\r
+  IN EFI_PCI_IO_PROTOCOL_WIDTH    Width,\r
+  IN UINTN                        Count,\r
+  UINT64                          *Offset\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Verifies access to a PCI Base Address Register (BAR)\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciIoDevice - add argument and description to function comment\r
+// TODO:    BarIndex - add argument and description to function comment\r
+// TODO:    Type - add argument and description to function comment\r
+// TODO:    Width - add argument and description to function comment\r
+// TODO:    Count - add argument and description to function comment\r
+// TODO:    Offset - add argument and description to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (BarIndex == EFI_PCI_IO_PASS_THROUGH_BAR) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // BarIndex 0-5 is legal\r
+  //\r
+  if (BarIndex >= PCI_MAX_BAR) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (!CheckBarType (PciIoDevice, BarIndex, Type)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // 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
+    Count = 1;\r
+  }\r
+\r
+  Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
+\r
+  if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PciIoDevice->PciBar[BarIndex].Length) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *Offset = *Offset + PciIoDevice->PciBar[BarIndex].BaseAddress;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PciIoVerifyConfigAccess (\r
+  PCI_IO_DEVICE                 *PciIoDevice,\r
+  IN EFI_PCI_IO_PROTOCOL_WIDTH  Width,\r
+  IN UINTN                      Count,\r
+  IN UINT64                     *Offset\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Verifies access to a PCI Config Header\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciIoDevice - add argument and description to function comment\r
+// TODO:    Width - add argument and description to function comment\r
+// TODO:    Count - add argument and description to function comment\r
+// TODO:    Offset - add argument and description to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  UINT64  ExtendOffset;\r
+\r
+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX\r
+  //\r
+  Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
+\r
+  if (PciIoDevice->IsPciExp) {\r
+    if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_EXP_MAX_CONFIG_OFFSET) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+\r
+    ExtendOffset  = LShiftU64 (*Offset, 32);\r
+    *Offset       = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0);\r
+    *Offset       = (*Offset) | ExtendOffset;\r
+\r
+  } else {\r
+    if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_MAX_CONFIG_OFFSET) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+\r
+    *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, *Offset);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoPollMem (\r
+  IN  EFI_PCI_IO_PROTOCOL        *This,\r
+  IN  EFI_PCI_IO_PROTOCOL_WIDTH  Width,\r
+  IN  UINT8                      BarIndex,\r
+  IN  UINT64                     Offset,\r
+  IN  UINT64                     Mask,\r
+  IN  UINT64                     Value,\r
+  IN  UINT64                     Delay,\r
+  OUT UINT64                     *Result\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Poll PCI Memmory\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Width - add argument and description to function comment\r
+// TODO:    BarIndex - add argument and description to function comment\r
+// TODO:    Offset - add argument and description to function comment\r
+// TODO:    Mask - add argument and description to function comment\r
+// TODO:    Value - add argument and description to function comment\r
+// TODO:    Delay - add argument and description to function comment\r
+// TODO:    Result - add argument and description to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, 1, &Offset);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (Width > EfiPciIoWidthUint64) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = PciIoDevice->PciRootBridgeIo->PollMem (\r
+                                          PciIoDevice->PciRootBridgeIo,\r
+                                          (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+                                          Offset,\r
+                                          Mask,\r
+                                          Value,\r
+                                          Delay,\r
+                                          Result\r
+                                          );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoPollIo (\r
+  IN  EFI_PCI_IO_PROTOCOL        *This,\r
+  IN  EFI_PCI_IO_PROTOCOL_WIDTH  Width,\r
+  IN  UINT8                      BarIndex,\r
+  IN  UINT64                     Offset,\r
+  IN  UINT64                     Mask,\r
+  IN  UINT64                     Value,\r
+  IN  UINT64                     Delay,\r
+  OUT UINT64                     *Result\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Poll PCI IO\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Width - add argument and description to function comment\r
+// TODO:    BarIndex - add argument and description to function comment\r
+// TODO:    Offset - add argument and description to function comment\r
+// TODO:    Mask - add argument and description to function comment\r
+// TODO:    Value - add argument and description to function comment\r
+// TODO:    Delay - add argument and description to function comment\r
+// TODO:    Result - add argument and description to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  if (Width < 0 || Width > EfiPciIoWidthUint64) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, 1, &Offset);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = PciIoDevice->PciRootBridgeIo->PollIo (\r
+                                          PciIoDevice->PciRootBridgeIo,\r
+                                          (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+                                          Offset,\r
+                                          Mask,\r
+                                          Value,\r
+                                          Delay,\r
+                                          Result\r
+                                          );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoMemRead (\r
+  IN     EFI_PCI_IO_PROTOCOL        *This,\r
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,\r
+  IN     UINT8                      BarIndex,\r
+  IN     UINT64                     Offset,\r
+  IN     UINTN                      Count,\r
+  IN OUT VOID                       *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Performs a PCI Memory Read Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Width - add argument and description to function comment\r
+// TODO:    BarIndex - add argument and description to function comment\r
+// TODO:    Offset - add argument and description to function comment\r
+// TODO:    Count - add argument and description to function comment\r
+// TODO:    Buffer - add argument and description to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = PciIoDevice->PciRootBridgeIo->Mem.Read (\r
+                                              PciIoDevice->PciRootBridgeIo,\r
+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+                                              Offset,\r
+                                              Count,\r
+                                              Buffer\r
+                                              );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoMemWrite (\r
+  IN     EFI_PCI_IO_PROTOCOL        *This,\r
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,\r
+  IN     UINT8                      BarIndex,\r
+  IN     UINT64                     Offset,\r
+  IN     UINTN                      Count,\r
+  IN OUT VOID                       *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Performs a PCI Memory Write Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Width - add argument and description to function comment\r
+// TODO:    BarIndex - add argument and description to function comment\r
+// TODO:    Offset - add argument and description to function comment\r
+// TODO:    Count - add argument and description to function comment\r
+// TODO:    Buffer - add argument and description to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = PciIoDevice->PciRootBridgeIo->Mem.Write (\r
+                                              PciIoDevice->PciRootBridgeIo,\r
+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+                                              Offset,\r
+                                              Count,\r
+                                              Buffer\r
+                                              );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoIoRead (\r
+  IN     EFI_PCI_IO_PROTOCOL        *This,\r
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,\r
+  IN     UINT8                      BarIndex,\r
+  IN     UINT64                     Offset,\r
+  IN     UINTN                      Count,\r
+  IN OUT VOID                       *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Performs a PCI I/O Read Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Width - add argument and description to function comment\r
+// TODO:    BarIndex - add argument and description to function comment\r
+// TODO:    Offset - add argument and description to function comment\r
+// TODO:    Count - add argument and description to function comment\r
+// TODO:    Buffer - add argument and description to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = PciIoDevice->PciRootBridgeIo->Io.Read (\r
+                                              PciIoDevice->PciRootBridgeIo,\r
+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+                                              Offset,\r
+                                              Count,\r
+                                              Buffer\r
+                                              );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoIoWrite (\r
+  IN     EFI_PCI_IO_PROTOCOL        *This,\r
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,\r
+  IN     UINT8                      BarIndex,\r
+  IN     UINT64                     Offset,\r
+  IN     UINTN                      Count,\r
+  IN OUT VOID                       *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Performs a PCI I/O Write Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Width - add argument and description to function comment\r
+// TODO:    BarIndex - add argument and description to function comment\r
+// TODO:    Offset - add argument and description to function comment\r
+// TODO:    Count - add argument and description to function comment\r
+// TODO:    Buffer - add argument and description to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = PciIoDevice->PciRootBridgeIo->Io.Write (\r
+                                              PciIoDevice->PciRootBridgeIo,\r
+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+                                              Offset,\r
+                                              Count,\r
+                                              Buffer\r
+                                              );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoConfigRead (\r
+  IN     EFI_PCI_IO_PROTOCOL        *This,\r
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,\r
+  IN     UINT32                     Offset,\r
+  IN     UINTN                      Count,\r
+  IN OUT VOID                       *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Performs a PCI Configuration Read Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Width - add argument and description to function comment\r
+// TODO:    Offset - add argument and description to function comment\r
+// TODO:    Count - add argument and description to function comment\r
+// TODO:    Buffer - add argument and description to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+  UINT64        Address;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  Address     = Offset;\r
+  Status      = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = PciIoDevice->PciRootBridgeIo->Pci.Read (\r
+                                              PciIoDevice->PciRootBridgeIo,\r
+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+                                              Address,\r
+                                              Count,\r
+                                              Buffer\r
+                                              );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoConfigWrite (\r
+  IN     EFI_PCI_IO_PROTOCOL        *This,\r
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH  Width,\r
+  IN     UINT32                     Offset,\r
+  IN     UINTN                      Count,\r
+  IN OUT VOID                       *Buffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Performs a PCI Configuration Write Cycle\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Width - add argument and description to function comment\r
+// TODO:    Offset - add argument and description to function comment\r
+// TODO:    Count - add argument and description to function comment\r
+// TODO:    Buffer - add argument and description to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+  UINT64        Address;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  Address     = Offset;\r
+  Status      = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = PciIoDevice->PciRootBridgeIo->Pci.Write (\r
+                                              PciIoDevice->PciRootBridgeIo,\r
+                                              (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+                                              Address,\r
+                                              Count,\r
+                                              Buffer\r
+                                              );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoCopyMem (\r
+  IN EFI_PCI_IO_PROTOCOL              *This,\r
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH    Width,\r
+  IN     UINT8                        DestBarIndex,\r
+  IN     UINT64                       DestOffset,\r
+  IN     UINT8                        SrcBarIndex,\r
+  IN     UINT64                       SrcOffset,\r
+  IN     UINTN                        Count\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Copy PCI Memory\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Width - add argument and description to function comment\r
+// TODO:    DestBarIndex - add argument and description to function comment\r
+// TODO:    DestOffset - add argument and description to function comment\r
+// TODO:    SrcBarIndex - add argument and description to function comment\r
+// TODO:    SrcOffset - add argument and description to function comment\r
+// TODO:    Count - add argument and description to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Width == EfiPciIoWidthFifoUint8  ||\r
+      Width == EfiPciIoWidthFifoUint16 ||\r
+      Width == EfiPciIoWidthFifoUint32 ||\r
+      Width == EfiPciIoWidthFifoUint64 ||\r
+      Width == EfiPciIoWidthFillUint8  ||\r
+      Width == EfiPciIoWidthFillUint16 ||\r
+      Width == EfiPciIoWidthFillUint32 ||\r
+      Width == EfiPciIoWidthFillUint64) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = PciIoVerifyBarAccess (PciIoDevice, DestBarIndex, PciBarTypeMem, Width, Count, &DestOffset);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = PciIoVerifyBarAccess (PciIoDevice, SrcBarIndex, PciBarTypeMem, Width, Count, &SrcOffset);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = PciIoDevice->PciRootBridgeIo->CopyMem (\r
+                                          PciIoDevice->PciRootBridgeIo,\r
+                                          (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
+                                          DestOffset,\r
+                                          SrcOffset,\r
+                                          Count\r
+                                          );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoMap (\r
+  IN     EFI_PCI_IO_PROTOCOL            *This,\r
+  IN     EFI_PCI_IO_PROTOCOL_OPERATION  Operation,\r
+  IN     VOID                           *HostAddress,\r
+  IN OUT UINTN                          *NumberOfBytes,\r
+  OUT    EFI_PHYSICAL_ADDRESS           *DeviceAddress,\r
+  OUT    VOID                           **Mapping\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Maps a memory region for DMA\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Operation - add argument and description to function comment\r
+// TODO:    HostAddress - add argument and description to function comment\r
+// TODO:    NumberOfBytes - add argument and description to function comment\r
+// TODO:    DeviceAddress - add argument and description to function comment\r
+// TODO:    Mapping - add argument and description to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  if (Operation < 0 || Operation >= EfiPciIoOperationMaximum) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {\r
+    Operation = (EFI_PCI_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
+                                          HostAddress,\r
+                                          NumberOfBytes,\r
+                                          DeviceAddress,\r
+                                          Mapping\r
+                                          );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoUnmap (\r
+  IN  EFI_PCI_IO_PROTOCOL  *This,\r
+  IN  VOID                 *Mapping\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Unmaps a memory region for DMA\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Mapping - add argument and description to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\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
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoAllocateBuffer (\r
+  IN  EFI_PCI_IO_PROTOCOL   *This,\r
+  IN  EFI_ALLOCATE_TYPE     Type,\r
+  IN  EFI_MEMORY_TYPE       MemoryType,\r
+  IN  UINTN                 Pages,\r
+  OUT VOID                  **HostAddress,\r
+  IN  UINT64                Attributes\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Allocates a common buffer for DMA\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Type - add argument and description to function comment\r
+// TODO:    MemoryType - add argument and description to function comment\r
+// TODO:    Pages - add argument and description to function comment\r
+// TODO:    HostAddress - add argument and description to function comment\r
+// TODO:    Attributes - add argument and description to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+\r
+  if (Attributes &\r
+      (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED))) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {\r
+    Attributes |= EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE;\r
+  }\r
+\r
+  Status = PciIoDevice->PciRootBridgeIo->AllocateBuffer (\r
+                                          PciIoDevice->PciRootBridgeIo,\r
+                                          Type,\r
+                                          MemoryType,\r
+                                          Pages,\r
+                                          HostAddress,\r
+                                          Attributes\r
+                                          );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoFreeBuffer (\r
+  IN  EFI_PCI_IO_PROTOCOL   *This,\r
+  IN  UINTN                 Pages,\r
+  IN  VOID                  *HostAddress\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Frees a common buffer \r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Pages - add argument and description to function comment\r
+// TODO:    HostAddress - add argument and description to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  Status = PciIoDevice->PciRootBridgeIo->FreeBuffer (\r
+                                          PciIoDevice->PciRootBridgeIo,\r
+                                          Pages,\r
+                                          HostAddress\r
+                                          );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoFlush (\r
+  IN  EFI_PCI_IO_PROTOCOL  *This\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Flushes a DMA buffer\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  Status = PciIoDevice->PciRootBridgeIo->Flush (\r
+                                           PciIoDevice->PciRootBridgeIo\r
+                                           );\r
+  if (EFI_ERROR (Status)) {\r
+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoGetLocation (\r
+  IN  EFI_PCI_IO_PROTOCOL  *This,\r
+  OUT UINTN                *Segment,\r
+  OUT UINTN                *Bus,\r
+  OUT UINTN                *Device,\r
+  OUT UINTN                *Function\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Gets a PCI device's current bus number, device number, and function number.\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Segment - add argument and description to function comment\r
+// TODO:    Bus - add argument and description to function comment\r
+// TODO:    Device - add argument and description to function comment\r
+// TODO:    Function - add argument and description to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  if (Segment == NULL || Bus == NULL || Device == NULL || Function == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *Segment  = PciIoDevice->PciRootBridgeIo->SegmentNumber;\r
+  *Bus      = PciIoDevice->BusNumber;\r
+  *Device   = PciIoDevice->DeviceNumber;\r
+  *Function = PciIoDevice->FunctionNumber;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+CheckBarType (\r
+  IN PCI_IO_DEVICE       *PciIoDevice,\r
+  UINT8                  BarIndex,\r
+  PCI_BAR_TYPE           BarType\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Sets a PCI controllers attributes on a resource range\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciIoDevice - add argument and description to function comment\r
+// TODO:    BarIndex - add argument and description to function comment\r
+// TODO:    BarType - add argument and description to function comment\r
+{\r
+  switch (BarType) {\r
+\r
+  case PciBarTypeMem:\r
+\r
+    if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem32  &&\r
+        PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem32 &&\r
+        PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem64 &&\r
+        PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem64    ) {\r
+      return FALSE;\r
+    }\r
+\r
+    return TRUE;\r
+\r
+  case PciBarTypeIo:\r
+    if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo32 &&\r
+        PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo16){\r
+      return FALSE;\r
+    }\r
+\r
+    return TRUE;\r
+\r
+  default:\r
+    break;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+EFI_STATUS\r
+ModifyRootBridgeAttributes (\r
+  IN  PCI_IO_DEVICE                            *PciIoDevice,\r
+  IN  UINT64                                   Attributes,\r
+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set new attributes to a Root Bridge\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciIoDevice - add argument and description to function comment\r
+// TODO:    Attributes - add argument and description to function comment\r
+// TODO:    Operation - add argument and description to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  UINT64      PciRootBridgeSupports;\r
+  UINT64      PciRootBridgeAttributes;\r
+  UINT64      NewPciRootBridgeAttributes;\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Get the current attributes of this PCI device's PCI Root Bridge\r
+  //\r
+  Status = PciIoDevice->PciRootBridgeIo->GetAttributes (\r
+                                          PciIoDevice->PciRootBridgeIo,\r
+                                          &PciRootBridgeSupports,\r
+                                          &PciRootBridgeAttributes\r
+                                          );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  \r
+  //\r
+  // Record the new attribute of the Root Bridge\r
+  //\r
+  if (Operation == EfiPciIoAttributeOperationEnable) {\r
+    NewPciRootBridgeAttributes = PciRootBridgeAttributes | Attributes;\r
+  } else {\r
+    NewPciRootBridgeAttributes = PciRootBridgeAttributes & (~Attributes);\r
+  }\r
\r
+  //\r
+  // Call the PCI Root Bridge to attempt to modify the attributes\r
+  //\r
+  if (NewPciRootBridgeAttributes ^ PciRootBridgeAttributes) {\r
+\r
+    Status = PciIoDevice->PciRootBridgeIo->SetAttributes (\r
+                                            PciIoDevice->PciRootBridgeIo,\r
+                                            NewPciRootBridgeAttributes,\r
+                                            NULL,\r
+                                            NULL\r
+                                            );\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // The PCI Root Bridge could not modify the attributes, so return the error.\r
+      //\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+  }\r
+    \r
+  //\r
+  // Also update the attributes for this Root Bridge structure\r
+  //\r
+  PciIoDevice->Attributes = NewPciRootBridgeAttributes;\r
+  return EFI_SUCCESS;\r
+\r
+}\r
+\r
+EFI_STATUS\r
+SupportPaletteSnoopAttributes (\r
+  IN  PCI_IO_DEVICE                            *PciIoDevice,\r
+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check whether this device can be enable/disable to snoop\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciIoDevice - add argument and description to function comment\r
+// TODO:    Operation - add argument and description to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  PCI_IO_DEVICE *Temp;\r
+  UINT16        VGACommand;\r
+\r
+  //\r
+  // Snoop attribute can be only modified by GFX\r
+  //\r
+  if (!IS_PCI_GFX (&PciIoDevice->Pci)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Get the boot VGA on the same segement\r
+  //\r
+  Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);\r
+\r
+  if (!Temp) {\r
+    //\r
+    // If there is no VGA device on the segement, set\r
+    // this graphics card to decode the palette range\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+  \r
+  //\r
+  // Check these two agents are on the same path\r
+  //\r
+  if (!PciDevicesOnTheSamePath (Temp, PciIoDevice)) {\r
+    //\r
+    // they are not on the same path, so snoop can be enabled or disabled\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+  //\r
+  // Check if they are on the same bus\r
+  //\r
+  if (Temp->Parent == PciIoDevice->Parent) {\r
+\r
+    PciReadCommandRegister (Temp, &VGACommand);\r
+\r
+    //\r
+    // If they are on the same bus, either one can\r
+    // be set to snoop, the other set to decode\r
+    //\r
+    if (VGACommand & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {\r
+      //\r
+      // VGA has set to snoop, so GFX can be only set to disable snoop\r
+      //\r
+      if (Operation == EfiPciIoAttributeOperationEnable) {\r
+        return EFI_UNSUPPORTED;\r
+      }\r
+    } else {\r
+      //\r
+      // VGA has disabled to snoop, so GFX can be only enabled\r
+      //\r
+      if (Operation == EfiPciIoAttributeOperationDisable) {\r
+        return EFI_UNSUPPORTED;\r
+      }\r
+    }\r
+\r
+    return EFI_SUCCESS;\r
+  }\r
+  \r
+  //\r
+  // If they are on  the same path but on the different bus\r
+  // The first agent is set to snoop, the second one set to\r
+  // decode\r
+  //\r
+            \r
+  if (Temp->BusNumber < PciIoDevice->BusNumber) {\r
+    //\r
+    // GFX should be set to decode\r
+    //\r
+    if (Operation == EfiPciIoAttributeOperationDisable) {\r
+      PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
+      Temp->Attributes |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
+    } else {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+\r
+  } else {\r
+    //\r
+    // GFX should be set to snoop\r
+    //\r
+    if (Operation == EfiPciIoAttributeOperationEnable) {\r
+      PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
+      Temp->Attributes &= (~EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
+    } else {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoAttributes (\r
+  IN EFI_PCI_IO_PROTOCOL                       * This,\r
+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation,\r
+  IN  UINT64                                   Attributes,\r
+  OUT UINT64                                   *Result OPTIONAL\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Operation - add argument and description to function comment\r
+// TODO:    Attributes - add argument and description to function comment\r
+// TODO:    Result - add argument and description to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+  PCI_IO_DEVICE *UpStreamBridge;\r
+  PCI_IO_DEVICE *Temp;\r
+\r
+  UINT64        Supports;\r
+  UINT64        UpStreamAttributes;\r
+  UINT16        BridgeControl;\r
+  UINT16        Command;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  switch (Operation) {\r
+  case EfiPciIoAttributeOperationGet:\r
+    if (Result == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    *Result = PciIoDevice->Attributes;\r
+    return EFI_SUCCESS;\r
+\r
+  case EfiPciIoAttributeOperationSupported:\r
+    if (Result == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    *Result = PciIoDevice->Supports;\r
+    return EFI_SUCCESS;\r
+\r
+  case EfiPciIoAttributeOperationSet:\r
+    Status = PciIoDevice->PciIo.Attributes (\r
+                                  &(PciIoDevice->PciIo),\r
+                                  EfiPciIoAttributeOperationEnable,\r
+                                  Attributes,\r
+                                  NULL\r
+                                  );\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+\r
+    Status = PciIoDevice->PciIo.Attributes (\r
+                                  &(PciIoDevice->PciIo),\r
+                                  EfiPciIoAttributeOperationDisable,\r
+                                  (~Attributes) & (PciIoDevice->Supports),\r
+                                  NULL\r
+                                  );\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+\r
+    return EFI_SUCCESS;\r
+\r
+  case EfiPciIoAttributeOperationEnable:\r
+  case EfiPciIoAttributeOperationDisable:\r
+    break;\r
+\r
+  default:\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Just a trick for ENABLE attribute\r
+  //\r
+  if ((Attributes & EFI_PCI_DEVICE_ENABLE) == EFI_PCI_DEVICE_ENABLE) {\r
+    Attributes &= (PciIoDevice->Supports);\r
+\r
+    //\r
+    // Raise the EFI_P_PC_ENABLE Status code\r
+    //\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_PROGRESS_CODE,\r
+      EFI_IO_BUS_PCI | EFI_P_PC_ENABLE,\r
+      PciIoDevice->DevicePath\r
+      );\r
+  }\r
+\r
+  //\r
+  // If no attributes can be supported, then return.\r
+  // Otherwise, set the attributes that it can support.\r
+  //\r
+  Supports = (PciIoDevice->Supports) & Attributes;\r
+  if (Supports != Attributes) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+   \r
+  //\r
+  // For Root Bridge, just call RootBridgeIo to set attributes;\r
+  //\r
+  if (!PciIoDevice->Parent) {\r
+    Status = ModifyRootBridgeAttributes (PciIoDevice, Attributes, Operation);\r
+    return Status;\r
+  }\r
+\r
+  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)         &&\r
+       (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16))         ||\r
+      ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO)         &&\r
+       (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) ||\r
+      ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) &&\r
+       (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16))         ||\r
+      ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) &&\r
+       (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) ) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // For PPB & P2C, set relevant attribute bits\r
+  //\r
+  if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
+\r
+    if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) {\r
+      BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA;\r
+    }\r
+\r
+    if (Attributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO) {\r
+      BridgeControl |= EFI_PCI_BRIDGE_CONTROL_ISA;\r
+    }\r
+\r
+    if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) {\r
+      Command |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
+    }\r
+\r
+    if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) {\r
+      BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA_16;\r
+    }\r
+\r
+  } else {\r
+    //\r
+    // Do with the attributes on VGA\r
+    // Only for VGA's legacy resource, we just can enable once.\r
+    //\r
+    if (Attributes &\r
+        (EFI_PCI_IO_ATTRIBUTE_VGA_IO    |\r
+         EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 |\r
+         EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY)) {\r
+      //\r
+      // Check if a VGA has been enabled before enabling a new one\r
+      //\r
+      if (Operation == EfiPciIoAttributeOperationEnable) {\r
+        //\r
+        // Check if there have been an active VGA device on the same segment\r
+        //\r
+        Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);\r
+        if (Temp && Temp != PciIoDevice) {\r
+          //\r
+          // An active VGA has been detected, so can not enable another\r
+          //\r
+          return EFI_UNSUPPORTED;\r
+        }\r
+      }\r
+    }\r
+    \r
+    //\r
+    // Do with the attributes on GFX\r
+    //\r
+    if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) {\r
+\r
+      if (Operation == EfiPciIoAttributeOperationEnable) {\r
+        //\r
+        // Check if snoop can be enabled in current configuration\r
+        //\r
+        Status = SupportPaletteSnoopAttributes (PciIoDevice, Operation);\r
+\r
+        if (EFI_ERROR (Status)) {\r
+        \r
+          //\r
+          // Enable operation is forbidden, so mask the bit in attributes\r
+          // so as to keep consistent with the actual Status\r
+          //\r
+          // Attributes &= (~EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO);\r
+          //\r
+          //\r
+          //\r
+          return EFI_UNSUPPORTED;\r
+\r
+        }\r
+      }\r
+\r
+      //\r
+      // It can be supported, so get ready to set the bit\r
+      //\r
+      Command |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
+    }\r
+  }\r
+\r
+  if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) {\r
+    Command |= EFI_PCI_COMMAND_IO_SPACE;\r
+  }\r
+\r
+  if (Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) {\r
+    Command |= EFI_PCI_COMMAND_MEMORY_SPACE;\r
+  }\r
+\r
+  if (Attributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) {\r
+    Command |= EFI_PCI_COMMAND_BUS_MASTER;\r
+  }\r
+  //\r
+  // The upstream bridge should be also set to revelant attribute\r
+  // expect for IO, Mem and BusMaster\r
+  //\r
+  UpStreamAttributes = Attributes & \r
+                       (~(EFI_PCI_IO_ATTRIBUTE_IO     |\r
+                          EFI_PCI_IO_ATTRIBUTE_MEMORY |\r
+                          EFI_PCI_IO_ATTRIBUTE_BUS_MASTER\r
+                          )\r
+                        );\r
+  UpStreamBridge = PciIoDevice->Parent;\r
+\r
+  if (Operation == EfiPciIoAttributeOperationEnable) {\r
+    //\r
+    // Enable relevant attributes to command register and bridge control register\r
+    //\r
+    Status = PciEnableCommandRegister (PciIoDevice, Command);\r
+    if (BridgeControl) {\r
+      Status = PciEnableBridgeControlRegister (PciIoDevice, BridgeControl);\r
+    }\r
+\r
+    PciIoDevice->Attributes |= Attributes;\r
+\r
+    //\r
+    // Enable attributes of the upstream bridge\r
+    //\r
+    Status = UpStreamBridge->PciIo.Attributes (\r
+                                    &(UpStreamBridge->PciIo),\r
+                                    EfiPciIoAttributeOperationEnable,\r
+                                    UpStreamAttributes,\r
+                                    NULL\r
+                                    );\r
+  } else {\r
+    \r
+    //\r
+    // Disable relevant attributes to command register and bridge control register\r
+    //\r
+    Status = PciDisableCommandRegister (PciIoDevice, Command);\r
+    if (BridgeControl) {\r
+      Status = PciDisableBridgeControlRegister (PciIoDevice, BridgeControl);\r
+    }\r
+\r
+    PciIoDevice->Attributes &= (~Attributes);\r
+    Status = EFI_SUCCESS;\r
+\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoGetBarAttributes (\r
+  IN EFI_PCI_IO_PROTOCOL             * This,\r
+  IN  UINT8                          BarIndex,\r
+  OUT UINT64                         *Supports, OPTIONAL\r
+  OUT VOID                           **Resources OPTIONAL\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    BarIndex - add argument and description to function comment\r
+// TODO:    Supports - add argument and description to function comment\r
+// TODO:    Resources - add argument and description to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\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
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  if (Supports == NULL && Resources == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (BarIndex >= PCI_MAX_BAR) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // This driver does not support modifications to the WRITE_COMBINE or\r
+  // CACHED attributes for BAR ranges.\r
+  //\r
+  if (Supports != NULL) {\r
+    *Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;\r
+  }\r
+\r
+  if (Resources != NULL) {\r
+\r
+    if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeUnknown) {\r
+      NumConfig = 1;\r
+    }\r
+\r
+    Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
+    if (Configuration == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    ZeroMem (\r
+      Configuration,\r
+      sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)\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          = 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
+\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
+\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
+\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
+\r
+      default:\r
+        break;\r
+      }\r
+\r
+      Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\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
+\r
+    *Resources        = Configuration;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PciIoSetBarAttributes (\r
+  IN EFI_PCI_IO_PROTOCOL              *This,\r
+  IN     UINT64                       Attributes,\r
+  IN     UINT8                        BarIndex,\r
+  IN OUT UINT64                       *Offset,\r
+  IN OUT UINT64                       *Length\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    This - add argument and description to function comment\r
+// TODO:    Attributes - add argument and description to function comment\r
+// TODO:    BarIndex - add argument and description to function comment\r
+// TODO:    Offset - add argument and description to function comment\r
+// TODO:    Length - add argument and description to function comment\r
+// TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_UNSUPPORTED - add return value to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  EFI_STATUS    Status;\r
+  PCI_IO_DEVICE *PciIoDevice;\r
+  UINT64        NonRelativeOffset;\r
+  UINT64        Supports;\r
+\r
+  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
+\r
+  //\r
+  // Make sure Offset and Length are not NULL\r
+  //\r
+  if (Offset == NULL || Length == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeUnknown) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  //\r
+  // This driver does not support setting the WRITE_COMBINE or the CACHED attributes.\r
+  // If Attributes is not 0, then return EFI_UNSUPPORTED.\r
+  //\r
+  Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;\r
+\r
+  if (Attributes != (Attributes & Supports)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  //\r
+  // Attributes must be supported.  Make sure the BAR range describd by BarIndex, Offset, and\r
+  // Length are valid for this PCI device.\r
+  //\r
+  NonRelativeOffset = *Offset;\r
+  Status = PciIoVerifyBarAccess (\r
+            PciIoDevice,\r
+            BarIndex,\r
+            PciBarTypeMem,\r
+            EfiPciIoWidthUint8,\r
+            (UINT32) *Length,\r
+            &NonRelativeOffset\r
+            );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\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
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciIoDevice - add argument and description to function comment\r
+// TODO:    Operation - add argument and description to function comment\r
+// TODO:    Attributes - add argument and description to function comment\r
+// TODO:    EFI_SUCCESS - add return value to function comment\r
+{\r
+  PCI_IO_DEVICE       *Parent;\r
+  EFI_PCI_IO_PROTOCOL *PciIo;\r
+\r
+  Parent = PciIoDevice->Parent;\r
+\r
+  while (Parent && 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
+BOOLEAN\r
+PciDevicesOnTheSamePath (\r
+  IN PCI_IO_DEVICE        *PciDevice1,\r
+  IN PCI_IO_DEVICE        *PciDevice2\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+// TODO:    PciDevice1 - add argument and description to function comment\r
+// TODO:    PciDevice2 - add argument and description to function comment\r
+{\r
+  BOOLEAN   Existed1;\r
+  BOOLEAN   Existed2;\r
+\r
+  if (PciDevice1->Parent == PciDevice2->Parent) {\r
+    return TRUE;\r
+  }\r
+\r
+  Existed1 = PciDeviceExisted (PciDevice1->Parent, PciDevice2);\r
+  Existed2 = PciDeviceExisted (PciDevice2->Parent, PciDevice1);\r
+\r
+  return (BOOLEAN) (Existed1 || Existed2);\r
+}\r