/** @file\r
EFI PCI IO protocol functions implementation for PCI Bus module.\r
\r
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
\r
//\r
// If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
- // \r
+ //\r
if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
Status = PciIoMemRead (This, Width, BarIndex, Offset, 1, Result);\r
} while (TRUE);\r
}\r
}\r
- \r
+\r
Status = PciIoDevice->PciRootBridgeIo->PollMem (\r
PciIoDevice->PciRootBridgeIo,\r
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
\r
//\r
// If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
- // \r
+ //\r
if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
Status = PciIoIoRead (This, Width, BarIndex, Offset, 1, Result);\r
} while (TRUE);\r
}\r
}\r
- \r
+\r
Status = PciIoDevice->PciRootBridgeIo->PollIo (\r
PciIoDevice->PciRootBridgeIo,\r
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
\r
//\r
// If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
- // \r
+ //\r
if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
Count *= (UINTN)(1 << (Width & 0x03));\r
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));\r
}\r
- } \r
- \r
+ }\r
+\r
\r
Status = PciIoDevice->PciRootBridgeIo->Mem.Read (\r
PciIoDevice->PciRootBridgeIo,\r
\r
//\r
// If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
- // \r
+ //\r
if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
Count *= (UINTN)(1 << (Width & 0x03));\r
\r
//\r
// If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
- // \r
+ //\r
if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
Count *= (UINTN)(1 << (Width & 0x03));\r
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));\r
}\r
- } \r
+ }\r
\r
Status = PciIoDevice->PciRootBridgeIo->Io.Read (\r
PciIoDevice->PciRootBridgeIo,\r
\r
//\r
// If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
- // \r
+ //\r
if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
Count *= (UINTN)(1 << (Width & 0x03));\r
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));\r
}\r
- } \r
+ }\r
\r
Status = PciIoDevice->PciRootBridgeIo->Io.Write (\r
PciIoDevice->PciRootBridgeIo,\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- \r
+\r
//\r
// If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
- // \r
+ //\r
if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
Count *= (UINTN)(1 << (Width & 0x03));\r
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));\r
}\r
- } \r
+ }\r
\r
Status = PciIoDevice->PciRootBridgeIo->Pci.Read (\r
PciIoDevice->PciRootBridgeIo,\r
\r
//\r
// If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
- // \r
+ //\r
if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
Count *= (UINTN)(1 << (Width & 0x03));\r
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));\r
}\r
- } \r
- \r
+ }\r
+\r
Status = PciIoDevice->PciRootBridgeIo->Pci.Write (\r
PciIoDevice->PciRootBridgeIo,\r
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
\r
//\r
// If request is not aligned, then convert request to EfiPciIoWithXXXUint8\r
- // \r
+ //\r
if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {\r
if ((SrcOffset & ((1 << (Width & 0x03)) - 1)) != 0 || (DestOffset & ((1 << (Width & 0x03)) - 1)) != 0) {\r
Count *= (UINTN)(1 << (Width & 0x03));\r
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));\r
}\r
- } \r
+ }\r
\r
Status = PciIoDevice->PciRootBridgeIo->CopyMem (\r
PciIoDevice->PciRootBridgeIo,\r
\r
/**\r
Allocates pages that are suitable for an EfiPciIoOperationBusMasterCommonBuffer\r
- mapping.\r
+ or EfiPciOperationBusMasterCommonBuffer64 mapping.\r
\r
@param This A pointer to the EFI_PCI_IO_PROTOCOL instance.\r
@param Type This parameter is not used and must be ignored.\r
\r
@retval EFI_SUCCESS The requested memory pages were allocated.\r
@retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are\r
- MEMORY_WRITE_COMBINE and MEMORY_CACHED.\r
+ MEMORY_WRITE_COMBINE, MEMORY_CACHED and DUAL_ADDRESS_CYCLE.\r
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
@retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
\r
@param Operation Set or Disable.\r
\r
@retval EFI_UNSUPPORTED If root bridge does not support change attribute.\r
- @retval EFI_SUCCESS Successfully set new attributs.\r
+ @retval EFI_SUCCESS Successfully set new attributes.\r
\r
**/\r
EFI_STATUS\r
}\r
\r
//\r
- // Get the boot VGA on the same segement\r
+ // Get the boot VGA on the same Host Bridge\r
//\r
- Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);\r
+ Temp = LocateVgaDeviceOnHostBridge (PciIoDevice->PciRootBridgeIo->ParentHandle);\r
\r
if (Temp == NULL) {\r
//\r
- // If there is no VGA device on the segement, set\r
+ // If there is no VGA device on the segment, set\r
// this graphics card to decode the palette range\r
//\r
return EFI_SUCCESS;\r
//\r
// Just a trick for ENABLE attribute\r
// EFI_PCI_DEVICE_ENABLE is not defined in UEFI spec, which is the internal usage.\r
- // So, this logic doesn't confrom to UEFI spec, which should be removed.\r
+ // So, this logic doesn't conform to UEFI spec, which should be removed.\r
// But this trick logic is still kept for some binary drivers that depend on it.\r
//\r
if ((Attributes & EFI_PCI_DEVICE_ENABLE) == EFI_PCI_DEVICE_ENABLE) {\r
//\r
if (Operation == EfiPciIoAttributeOperationEnable) {\r
//\r
- // Check if there have been an active VGA device on the same segment\r
+ // Check if there have been an active VGA device on the same Host Bridge\r
//\r
- Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);\r
+ Temp = LocateVgaDeviceOnHostBridge (PciIoDevice->PciRootBridgeIo->ParentHandle);\r
if (Temp != NULL && Temp != PciIoDevice) {\r
//\r
// An active VGA has been detected, so can not enable another\r
Command |= EFI_PCI_COMMAND_BUS_MASTER;\r
}\r
//\r
- // The upstream bridge should be also set to revelant attribute\r
+ // The upstream bridge should be also set to relevant attribute\r
// expect for IO, Mem and BusMaster\r
//\r
UpStreamAttributes = Attributes &\r
@param AddrRangeMin The base address of the MMIO.\r
@param AddrLen The length of the MMIO.\r
\r
- @retval The AddrTranslationOffset from RootBridgeIo for the \r
+ @retval The AddrTranslationOffset from RootBridgeIo for the\r
specified range, or (UINT64) -1 if the range is not\r
found in RootBridgeIo.\r
**/\r
return (UINT64) -1;\r
}\r
\r
+ // According to UEFI 2.7, EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL::Configuration()\r
+ // returns host address instead of device address, while AddrTranslationOffset\r
+ // is not zero, and device address = host address + AddrTranslationOffset, so\r
+ // we convert host address to device address for range compare.\r
while (Configuration->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
if ((Configuration->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) &&\r
- (Configuration->AddrRangeMin <= AddrRangeMin) &&\r
- (Configuration->AddrRangeMin + Configuration->AddrLen >= AddrRangeMin + AddrLen)\r
+ (Configuration->AddrRangeMin + Configuration->AddrTranslationOffset <= AddrRangeMin) &&\r
+ (Configuration->AddrRangeMin + Configuration->AddrLen + Configuration->AddrTranslationOffset >= AddrRangeMin + AddrLen)\r
) {\r
return Configuration->AddrTranslationOffset;\r
}\r
base address for resource range. The legal range for this field is 0..5.\r
@param Supports A pointer to the mask of attributes that this PCI controller supports\r
setting for this BAR with SetBarAttributes().\r
- @param Resources A pointer to the ACPI 2.0 resource descriptors that describe the current\r
+ @param Resources A pointer to the resource descriptors that describe the current\r
configuration of this BAR of the PCI controller.\r
\r
@retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI\r
controller supports are returned in Supports. If Resources\r
- is not NULL, then the ACPI 2.0 resource descriptors that the PCI\r
+ is not NULL, then the resource descriptors that the PCI\r
controller is currently using are returned in Resources.\r
@retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.\r
@retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller.\r
\r
case PciBarTypePMem32:\r
//\r
- // prefechable\r
+ // prefetchable\r
//\r
Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;\r
//\r
\r
case PciBarTypePMem64:\r
//\r
- // prefechable\r
+ // prefetchable\r
//\r
Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;\r
//\r
return EFI_UNSUPPORTED;\r
}\r
}\r
+\r
+ // According to UEFI spec 2.7, we need return host address for\r
+ // PciIo->GetBarAttributes, and host address = device address - translation.\r
+ Descriptor->AddrRangeMin -= Descriptor->AddrTranslationOffset;\r
}\r
\r
return EFI_SUCCESS;\r
return EFI_UNSUPPORTED;\r
}\r
//\r
- // Attributes must be supported. Make sure the BAR range describd by BarIndex, Offset, and\r
+ // Attributes must be supported. Make sure the BAR range described by BarIndex, Offset, and\r
// Length are valid for this PCI device.\r
//\r
NonRelativeOffset = *Offset;\r
return EFI_SUCCESS;\r
}\r
\r
-/**\r
- Program parent bridge's attribute recurrently.\r
-\r
- @param PciIoDevice Child Pci device instance\r
- @param Operation The operation to perform on the attributes for this PCI controller.\r
- @param Attributes The mask of attributes that are used for Set, Enable, and Disable\r
- operations.\r
-\r
- @retval EFI_SUCCESS The operation on the PCI controller's attributes was completed.\r
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
- @retval EFI_UNSUPPORTED one or more of the bits set in\r
- Attributes are not supported by this PCI controller or one of\r
- its parent bridges when Operation is Set, Enable or Disable.\r
-\r
-**/\r
-EFI_STATUS\r
-UpStreamBridgesAttributes (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
- IN UINT64 Attributes\r
- )\r
-{\r
- PCI_IO_DEVICE *Parent;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
-\r
- Parent = PciIoDevice->Parent;\r
-\r
- while (Parent != NULL && IS_PCI_BRIDGE (&Parent->Pci)) {\r
-\r
- //\r
- // Get the PciIo Protocol\r
- //\r
- PciIo = &Parent->PciIo;\r
-\r
- PciIo->Attributes (PciIo, Operation, Attributes, NULL);\r
-\r
- Parent = Parent->Parent;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
\r
/**\r
Test whether two Pci devices has same parent bridge.\r