--- /dev/null
+/*++\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