/** @file\r
PCI emumeration support functions implementation for PCI Bus module.\r
\r
-Copyright (c) 2006 - 2010, 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
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "PciBus.h"\r
\r
+extern CHAR16 *mBarTypeStr[];\r
+\r
+#define OLD_ALIGN 0xFFFFFFFFFFFFFFFFULL\r
+#define EVEN_ALIGN 0xFFFFFFFFFFFFFFFEULL\r
+#define SQUAD_ALIGN 0xFFFFFFFFFFFFFFFDULL\r
+#define DQUAD_ALIGN 0xFFFFFFFFFFFFFFFCULL\r
+\r
/**\r
This routine is used to check whether the pci device is present.\r
\r
root bridge will then be created.\r
\r
@param Bridge Parent bridge instance.\r
- @param StartBusNumber Bus number of begining.\r
+ @param StartBusNumber Bus number of beginning.\r
\r
@retval EFI_SUCCESS PCI device is found.\r
@retval other Some error occurred when reading PCI bridge information.\r
(UINT8) Device,\r
(UINT8) Func\r
);\r
+\r
+ if (EFI_ERROR (Status) && Func == 0) {\r
+ //\r
+ // go to next device if there is no Function 0\r
+ //\r
+ break;\r
+ }\r
+\r
if (!EFI_ERROR (Status)) {\r
\r
//\r
return Status;\r
}\r
\r
+ //\r
+ // Ensure secondary bus number is greater than the primary bus number to avoid\r
+ // any potential dead loop when PcdPciDisableBusEnumeration is set to TRUE\r
+ //\r
+ if (SecBus <= StartBusNumber) {\r
+ break;\r
+ }\r
+\r
//\r
// Get resource padding for PPB\r
//\r
}\r
\r
/**\r
- Seach required device and create PCI device instance.\r
+ Search required device and create PCI device instance.\r
\r
@param Bridge Parent bridge instance.\r
@param Pci Input PCI device information block.\r
\r
PciIoDevice = NULL;\r
\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ "PciBus: Discovered %s @ [%02x|%02x|%02x]\n",\r
+ IS_PCI_BRIDGE (Pci) ? L"PPB" :\r
+ IS_CARDBUS_BRIDGE (Pci) ? L"P2C" :\r
+ L"PCI",\r
+ Bus, Device, Func\r
+ ));\r
+\r
if (!IS_PCI_BRIDGE (Pci)) {\r
\r
if (IS_CARDBUS_BRIDGE (Pci)) {\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Dump the PPB padding resource information.\r
+\r
+ @param PciIoDevice PCI IO instance.\r
+ @param ResourceType The desired resource type to dump.\r
+ PciBarTypeUnknown means to dump all types of resources.\r
+**/\r
+VOID\r
+DumpPpbPaddingResource (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN PCI_BAR_TYPE ResourceType\r
+ )\r
+{\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;\r
+ PCI_BAR_TYPE Type;\r
+\r
+ if (PciIoDevice->ResourcePaddingDescriptors == NULL) {\r
+ return;\r
+ }\r
+\r
+ if (ResourceType == PciBarTypeIo16 || ResourceType == PciBarTypeIo32) {\r
+ ResourceType = PciBarTypeIo;\r
+ }\r
+\r
+ for (Descriptor = PciIoDevice->ResourcePaddingDescriptors; Descriptor->Desc != ACPI_END_TAG_DESCRIPTOR; Descriptor++) {\r
+\r
+ Type = PciBarTypeUnknown;\r
+ if (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) {\r
+ Type = PciBarTypeIo;\r
+ } else if (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {\r
+\r
+ if (Descriptor->AddrSpaceGranularity == 32) {\r
+ //\r
+ // prefetchable\r
+ //\r
+ if (Descriptor->SpecificFlag == EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) {\r
+ Type = PciBarTypePMem32;\r
+ }\r
+\r
+ //\r
+ // Non-prefetchable\r
+ //\r
+ if (Descriptor->SpecificFlag == 0) {\r
+ Type = PciBarTypeMem32;\r
+ }\r
+ }\r
+\r
+ if (Descriptor->AddrSpaceGranularity == 64) {\r
+ //\r
+ // prefetchable\r
+ //\r
+ if (Descriptor->SpecificFlag == EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) {\r
+ Type = PciBarTypePMem64;\r
+ }\r
+\r
+ //\r
+ // Non-prefetchable\r
+ //\r
+ if (Descriptor->SpecificFlag == 0) {\r
+ Type = PciBarTypeMem64;\r
+ }\r
+ }\r
+ }\r
+\r
+ if ((Type != PciBarTypeUnknown) && ((ResourceType == PciBarTypeUnknown) || (ResourceType == Type))) {\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ " Padding: Type = %s; Alignment = 0x%lx;\tLength = 0x%lx\n",\r
+ mBarTypeStr[Type], Descriptor->AddrRangeMax, Descriptor->AddrLen\r
+ ));\r
+ }\r
+ }\r
+\r
+}\r
+\r
+/**\r
+ Dump the PCI BAR information.\r
+\r
+ @param PciIoDevice PCI IO instance.\r
+**/\r
+VOID\r
+DumpPciBars (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ for (Index = 0; Index < PCI_MAX_BAR; Index++) {\r
+ if (PciIoDevice->PciBar[Index].BarType == PciBarTypeUnknown) {\r
+ continue;\r
+ }\r
+\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ " BAR[%d]: Type = %s; Alignment = 0x%lx;\tLength = 0x%lx;\tOffset = 0x%02x\n",\r
+ Index, mBarTypeStr[MIN (PciIoDevice->PciBar[Index].BarType, PciBarTypeMaxType)],\r
+ PciIoDevice->PciBar[Index].Alignment, PciIoDevice->PciBar[Index].Length, PciIoDevice->PciBar[Index].Offset\r
+ ));\r
+ }\r
+\r
+ for (Index = 0; Index < PCI_MAX_BAR; Index++) {\r
+ if ((PciIoDevice->VfPciBar[Index].BarType == PciBarTypeUnknown) && (PciIoDevice->VfPciBar[Index].Length == 0)) {\r
+ continue;\r
+ }\r
+\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ " VFBAR[%d]: Type = %s; Alignment = 0x%lx;\tLength = 0x%lx;\tOffset = 0x%02x\n",\r
+ Index, mBarTypeStr[MIN (PciIoDevice->VfPciBar[Index].BarType, PciBarTypeMaxType)],\r
+ PciIoDevice->VfPciBar[Index].Alignment, PciIoDevice->VfPciBar[Index].Length, PciIoDevice->VfPciBar[Index].Offset\r
+ ));\r
+ }\r
+ DEBUG ((EFI_D_INFO, "\n"));\r
+}\r
+\r
/**\r
Create PCI device instance for PCI device.\r
\r
UINTN Offset;\r
UINTN BarIndex;\r
PCI_IO_DEVICE *PciIoDevice;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
\r
- PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
PciIoDevice = CreatePciIoDevice (\r
- PciRootBridgeIo,\r
+ Bridge,\r
Pci,\r
Bus,\r
Device,\r
return NULL;\r
}\r
\r
- //\r
- // Create a device path for this PCI device and store it into its private data\r
- //\r
- CreatePciDevicePath (\r
- Bridge->DevicePath,\r
- PciIoDevice\r
- );\r
-\r
//\r
// If it is a full enumeration, disconnect the device in advance\r
//\r
//\r
// Parse the SR-IOV VF bars\r
//\r
- if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {\r
+ if (PcdGetBool (PcdSrIovSupport) && PciIoDevice->SrIovCapabilityOffset != 0) {\r
for (Offset = PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR0, BarIndex = 0;\r
Offset <= PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR5;\r
BarIndex++) {\r
Offset = PciIovParseVfBar (PciIoDevice, Offset, BarIndex);\r
}\r
}\r
+\r
+ DEBUG_CODE (DumpPciBars (PciIoDevice););\r
return PciIoDevice;\r
}\r
\r
IN UINT8 Func\r
)\r
{\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
PCI_IO_DEVICE *PciIoDevice;\r
EFI_STATUS Status;\r
UINT8 Value;\r
EFI_PCI_IO_PROTOCOL *PciIo;\r
UINT8 Temp;\r
+ UINT32 PMemBaseLimit;\r
+ UINT16 PrefetchableMemoryBase;\r
+ UINT16 PrefetchableMemoryLimit;\r
\r
- PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
PciIoDevice = CreatePciIoDevice (\r
- PciRootBridgeIo,\r
+ Bridge,\r
Pci,\r
Bus,\r
Device,\r
return NULL;\r
}\r
\r
- //\r
- // Create a device path for this PCI device and store it into its private data\r
- //\r
- CreatePciDevicePath (\r
- Bridge->DevicePath,\r
- PciIoDevice\r
- );\r
-\r
if (gFullEnumeration) {\r
PCI_DISABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
\r
//\r
- // Initalize the bridge control register\r
+ // Initialize the bridge control register\r
//\r
PCI_DISABLE_BRIDGE_CONTROL_REGISTER (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED);\r
\r
\r
//\r
// if PcdPciBridgeIoAlignmentProbe is TRUE, PCI bus driver probes\r
- // PCI bridge supporting non-stardard I/O window alignment less than 4K.\r
+ // PCI bridge supporting non-standard I/O window alignment less than 4K.\r
//\r
\r
PciIoDevice->BridgeIoAlignment = 0xFFF;\r
if (FeaturePcdGet (PcdPciBridgeIoAlignmentProbe)) {\r
//\r
// Check any bits of bit 3-1 of I/O Base Register are writable.\r
- // if so, it is assumed non-stardard I/O window alignment is supported by this bridge.\r
+ // if so, it is assumed non-standard I/O window alignment is supported by this bridge.\r
// Per spec, bit 3-1 of I/O Base Register are reserved bits, so its content can't be assumed.\r
//\r
Value = (UINT8)(Temp ^ (BIT3 | BIT2 | BIT1));\r
PciIoDevice,\r
0x24,\r
NULL,\r
- NULL\r
+ &PMemBaseLimit\r
);\r
\r
//\r
// Test if it supports 64 memory or not\r
//\r
- if (!EFI_ERROR (Status)) {\r
-\r
+ // The bottom 4 bits of both the Prefetchable Memory Base and Prefetchable Memory Limit\r
+ // registers:\r
+ // 0 - the bridge supports only 32 bit addresses.\r
+ // 1 - the bridge supports 64-bit addresses.\r
+ //\r
+ PrefetchableMemoryBase = (UINT16)(PMemBaseLimit & 0xffff);\r
+ PrefetchableMemoryLimit = (UINT16)(PMemBaseLimit >> 16);\r
+ if (!EFI_ERROR (Status) &&\r
+ (PrefetchableMemoryBase & 0x000f) == 0x0001 &&\r
+ (PrefetchableMemoryLimit & 0x000f) == 0x0001) {\r
Status = BarExisted (\r
PciIoDevice,\r
0x28,\r
\r
GetResourcePaddingPpb (PciIoDevice);\r
\r
+ DEBUG_CODE (\r
+ DumpPpbPaddingResource (PciIoDevice, PciBarTypeUnknown);\r
+ DumpPciBars (PciIoDevice);\r
+ );\r
+\r
return PciIoDevice;\r
}\r
\r
IN UINT8 Func\r
)\r
{\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
PCI_IO_DEVICE *PciIoDevice;\r
\r
- PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
PciIoDevice = CreatePciIoDevice (\r
- PciRootBridgeIo,\r
+ Bridge,\r
Pci,\r
Bus,\r
Device,\r
return NULL;\r
}\r
\r
- //\r
- // Create a device path for this PCI device and store it into its private data\r
- //\r
- CreatePciDevicePath (\r
- Bridge->DevicePath,\r
- PciIoDevice\r
- );\r
-\r
if (gFullEnumeration) {\r
PCI_DISABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
\r
//\r
- // Initalize the bridge control register\r
+ // Initialize the bridge control register\r
//\r
PCI_DISABLE_BRIDGE_CONTROL_REGISTER (PciIoDevice, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED);\r
}\r
EFI_BRIDGE_PMEM32_DECODE_SUPPORTED |\r
EFI_BRIDGE_IO32_DECODE_SUPPORTED;\r
\r
+ DEBUG_CODE (DumpPciBars (PciIoDevice););\r
+\r
return PciIoDevice;\r
}\r
\r
/**\r
- Create device path for pci deivce.\r
+ Create device path for pci device.\r
\r
@param ParentDevicePath Parent bridge's path.\r
@param PciIoDevice Pci device instance.\r
@param PciIoDevice Pci device instance.\r
@param Command Input command register value, and\r
returned supported register value.\r
- @param BridgeControl Inout bridge control value for PPB or P2C, and\r
+ @param BridgeControl Input bridge control value for PPB or P2C, and\r
returned supported bridge control value.\r
@param OldCommand Returned and stored old command register offset.\r
@param OldBridgeControl Returned and stored old Bridge control value for PPB or P2C.\r
\r
if (Option == EFI_SET_SUPPORTS) {\r
\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE |\r
+ Attributes |= (UINT64) (EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE |\r
EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED |\r
EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE |\r
EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE |\r
EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM |\r
- EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE;\r
+ EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE);\r
\r
- if ((Attributes & EFI_PCI_IO_ATTRIBUTE_IO) != 0) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;\r
+ if (IS_PCI_LPC (&PciIoDevice->Pci)) {\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;\r
+ Attributes |= (mReserveIsaAliases ? (UINT64) EFI_PCI_IO_ATTRIBUTE_ISA_IO : \\r
+ (UINT64) EFI_PCI_IO_ATTRIBUTE_ISA_IO_16);\r
}\r
\r
if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
//\r
Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;\r
Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;\r
+\r
+ if (mReserveVgaAliases) {\r
+ Attributes &= ~(UINT64)(EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 | \\r
+ EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16);\r
+ } else {\r
+ Attributes &= ~(UINT64)(EFI_PCI_IO_ATTRIBUTE_VGA_IO | \\r
+ EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO);\r
+ }\r
} else {\r
\r
if (IS_PCI_IDE (&PciIoDevice->Pci)) {\r
\r
if (IS_PCI_VGA (&PciIoDevice->Pci)) {\r
Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;\r
+ Attributes |= (mReserveVgaAliases ? (UINT64) EFI_PCI_IO_ATTRIBUTE_VGA_IO : \\r
+ (UINT64) EFI_PCI_IO_ATTRIBUTE_VGA_IO_16);\r
}\r
}\r
\r
EFI_PCI_IO_ATTRIBUTE_BUS_MASTER );\r
\r
} else {\r
+ //\r
+ // When this attribute is clear, the RomImage and RomSize fields in the PCI IO were\r
+ // initialized based on the PCI option ROM found through the ROM BAR of the PCI controller.\r
+ // When this attribute is set, the PCI option ROM described by the RomImage and RomSize\r
+ // fields is not from the the ROM BAR of the PCI controller.\r
+ //\r
+ if (!PciIoDevice->EmbeddedRom) {\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM;\r
+ }\r
PciIoDevice->Attributes = Attributes;\r
}\r
}\r
EFI_STATUS Status;\r
\r
//\r
- // For Root Bridge, just copy it by RootBridgeIo proctocol\r
+ // For Root Bridge, just copy it by RootBridgeIo protocol\r
// so as to keep consistent with the actual attribute\r
//\r
if (PciIoDevice->Parent == NULL) {\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+ //\r
+ // Assume the PCI Root Bridge supports DAC\r
+ //\r
+ PciIoDevice->Supports |= (UINT64)(EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE |\r
+ EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM |\r
+ EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE);\r
+\r
} else {\r
\r
//\r
PciSetDeviceAttribute (PciIoDevice, OldCommand, OldBridgeControl, EFI_SET_ATTRIBUTES);\r
\r
//\r
- // Enable other supported attributes but not defined in PCI_IO_PROTOCOL\r
- //\r
- PCI_ENABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE);\r
+ // Enable other PCI supported attributes but not defined in PCI_IO_PROTOCOL\r
+ // For PCI Express devices, Memory Write and Invalidate is hardwired to 0b so only enable it for PCI devices.\r
+ if (!PciIoDevice->IsPciExp) {\r
+ PCI_ENABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE);\r
+ }\r
}\r
\r
FastB2BSupport = TRUE;\r
return Status;\r
}\r
//\r
- // Detect Fast Bact to Bact support for the device under the bridge\r
+ // Detect Fast Back to Back support for the device under the bridge\r
//\r
Status = GetFastBackToBackSupport (Temp, PCI_PRIMARY_STATUS_OFFSET);\r
if (FastB2BSupport && EFI_ERROR (Status)) {\r
{\r
EFI_STATUS Status;\r
UINTN BarIndex;\r
- UINTN BarEndIndex;\r
BOOLEAN SetFlag;\r
VOID *Configuration;\r
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
Configuration = NULL;\r
Status = EFI_SUCCESS;\r
\r
- if (gEfiIncompatiblePciDeviceSupport == NULL) {\r
+ if (gIncompatiblePciDeviceSupport == NULL) {\r
//\r
// It can only be supported after the Incompatible PCI Device\r
// Support Protocol has been installed\r
Status = gBS->LocateProtocol (\r
&gEfiIncompatiblePciDeviceSupportProtocolGuid,\r
NULL,\r
- (VOID **) &gEfiIncompatiblePciDeviceSupport\r
+ (VOID **) &gIncompatiblePciDeviceSupport\r
);\r
}\r
if (Status == EFI_SUCCESS) {\r
// Check whether the device belongs to incompatible devices from protocol or not\r
// If it is , then get its special requirement in the ACPI table\r
//\r
- Status = gEfiIncompatiblePciDeviceSupport->CheckDevice (\r
- gEfiIncompatiblePciDeviceSupport,\r
- PciIoDevice->Pci.Hdr.VendorId,\r
- PciIoDevice->Pci.Hdr.DeviceId,\r
- PciIoDevice->Pci.Hdr.RevisionID,\r
- PciIoDevice->Pci.Device.SubsystemVendorID,\r
- PciIoDevice->Pci.Device.SubsystemID,\r
- &Configuration\r
- );\r
+ Status = gIncompatiblePciDeviceSupport->CheckDevice (\r
+ gIncompatiblePciDeviceSupport,\r
+ PciIoDevice->Pci.Hdr.VendorId,\r
+ PciIoDevice->Pci.Hdr.DeviceId,\r
+ PciIoDevice->Pci.Hdr.RevisionID,\r
+ PciIoDevice->Pci.Device.SubsystemVendorID,\r
+ PciIoDevice->Pci.Device.SubsystemID,\r
+ &Configuration\r
+ );\r
\r
}\r
\r
break;\r
}\r
\r
- BarIndex = (UINTN) Ptr->AddrTranslationOffset;\r
- BarEndIndex = BarIndex;\r
-\r
- //\r
- // Update all the bars in the device\r
- //\r
- if (BarIndex == PCI_BAR_ALL) {\r
- BarIndex = 0;\r
- BarEndIndex = PCI_MAX_BAR - 1;\r
- }\r
-\r
- if (BarIndex > PCI_MAX_BAR) {\r
- Ptr++;\r
- continue;\r
- }\r
+ for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex++) {\r
+ if ((Ptr->AddrTranslationOffset != MAX_UINT64) &&\r
+ (Ptr->AddrTranslationOffset != MAX_UINT8) &&\r
+ (Ptr->AddrTranslationOffset != BarIndex)\r
+ ) {\r
+ //\r
+ // Skip updating when AddrTranslationOffset is not MAX_UINT64 or MAX_UINT8 (wide match).\r
+ // Skip updating when current BarIndex doesn't equal to AddrTranslationOffset.\r
+ // Comparing against MAX_UINT8 is to keep backward compatibility.\r
+ //\r
+ continue;\r
+ }\r
\r
- for (; BarIndex <= BarEndIndex; BarIndex++) {\r
SetFlag = FALSE;\r
switch (Ptr->ResType) {\r
case ACPI_ADDRESS_SPACE_TYPE_MEM:\r
//\r
if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeMem)) {\r
SetFlag = TRUE;\r
+\r
+ //\r
+ // Ignored if granularity is 0.\r
+ // Ignored if PCI BAR is I/O or 32-bit memory.\r
+ // If PCI BAR is 64-bit memory and granularity is 32, then\r
+ // the PCI BAR resource is allocated below 4GB.\r
+ // If PCI BAR is 64-bit memory and granularity is 64, then\r
+ // the PCI BAR resource is allocated above 4GB.\r
+ //\r
+ if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeMem64) {\r
+ switch (Ptr->AddrSpaceGranularity) {\r
+ case 32:\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;\r
+ case 64:\r
+ PciIoDevice->PciBar[BarIndex].BarTypeFixed = TRUE;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypePMem64) {\r
+ switch (Ptr->AddrSpaceGranularity) {\r
+ case 32:\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;\r
+ case 64:\r
+ PciIoDevice->PciBar[BarIndex].BarTypeFixed = TRUE;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
}\r
break;\r
\r
//\r
// Update the new length for the device\r
//\r
- if (Ptr->AddrLen != PCI_BAR_NOCHANGE) {\r
+ if (Ptr->AddrLen != 0) {\r
PciIoDevice->PciBar[BarIndex].Length = Ptr->AddrLen;\r
}\r
}\r
\r
/**\r
This routine will update the alignment with the new alignment.\r
+ Compare with OLD_ALIGN/EVEN_ALIGN/SQUAD_ALIGN/DQUAD_ALIGN is to keep\r
+ backward compatibility.\r
\r
@param Alignment Input Old alignment. Output updated alignment.\r
@param NewAlignment New alignment.\r
// The new alignment is the same as the original,\r
// so skip it\r
//\r
- if (NewAlignment == PCI_BAR_OLD_ALIGN) {\r
+ if ((NewAlignment == 0) || (NewAlignment == OLD_ALIGN)) {\r
return ;\r
}\r
//\r
// Check the validity of the parameter\r
//\r
- if (NewAlignment != PCI_BAR_EVEN_ALIGN &&\r
- NewAlignment != PCI_BAR_SQUAD_ALIGN &&\r
- NewAlignment != PCI_BAR_DQUAD_ALIGN ) {\r
+ if (NewAlignment != EVEN_ALIGN &&\r
+ NewAlignment != SQUAD_ALIGN &&\r
+ NewAlignment != DQUAD_ALIGN ) {\r
*Alignment = NewAlignment;\r
return ;\r
}\r
//\r
// Adjust the alignment to even, quad or double quad boundary\r
//\r
- if (NewAlignment == PCI_BAR_EVEN_ALIGN) {\r
+ if (NewAlignment == EVEN_ALIGN) {\r
if ((OldAlignment & 0x01) != 0) {\r
OldAlignment = OldAlignment + 2 - (OldAlignment & 0x01);\r
}\r
- } else if (NewAlignment == PCI_BAR_SQUAD_ALIGN) {\r
+ } else if (NewAlignment == SQUAD_ALIGN) {\r
if ((OldAlignment & 0x03) != 0) {\r
OldAlignment = OldAlignment + 4 - (OldAlignment & 0x03);\r
}\r
- } else if (NewAlignment == PCI_BAR_DQUAD_ALIGN) {\r
+ } else if (NewAlignment == DQUAD_ALIGN) {\r
if ((OldAlignment & 0x07) != 0) {\r
OldAlignment = OldAlignment + 8 - (OldAlignment & 0x07);\r
}\r
UINT32 Value;\r
UINT32 OriginalValue;\r
UINT32 Mask;\r
- UINT32 Data;\r
- UINT8 Index;\r
EFI_STATUS Status;\r
\r
//\r
//\r
// Scan all the BARs anyway\r
//\r
- PciIoDevice->VfPciBar[BarIndex].Offset = (UINT8) Offset;\r
+ PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16) Offset;\r
return Offset + 4;\r
}\r
\r
- PciIoDevice->VfPciBar[BarIndex].Offset = (UINT8) Offset;\r
+ PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16) Offset;\r
if ((Value & 0x01) != 0) {\r
//\r
// Device I/Os. Impossible\r
}\r
\r
//\r
- // Fix the length to support some spefic 64 bit BAR\r
+ // Fix the length to support some special 64 bit BAR\r
//\r
- Data = Value;\r
- Index = 0;\r
- for (Data = Value; Data != 0; Data >>= 1) {\r
- Index ++;\r
- }\r
- Value |= ((UINT32)(-1) << Index); \r
+ Value |= ((UINT32) -1 << HighBitSet32 (Value));\r
\r
//\r
// Calculate the size of 64bit bar\r
break;\r
}\r
}\r
- \r
+\r
//\r
// Check the length again so as to keep compatible with some special bars\r
//\r
PciIoDevice->VfPciBar[BarIndex].BaseAddress = 0;\r
PciIoDevice->VfPciBar[BarIndex].Alignment = 0;\r
}\r
- \r
+\r
//\r
// Increment number of bar\r
//\r
UINT32 Value;\r
UINT32 OriginalValue;\r
UINT32 Mask;\r
- UINT32 Data;\r
- UINT8 Index;\r
EFI_STATUS Status;\r
\r
OriginalValue = 0;\r
return Offset + 4;\r
}\r
\r
+ PciIoDevice->PciBar[BarIndex].BarTypeFixed = FALSE;\r
PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
if ((Value & 0x01) != 0) {\r
//\r
\r
}\r
//\r
- // Workaround. Some platforms inplement IO bar with 0 length\r
+ // Workaround. Some platforms implement IO bar with 0 length\r
// Need to treat it as no-bar\r
//\r
if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
PciIoDevice->PciBar[BarIndex].BarType = (PCI_BAR_TYPE) 0;\r
}\r
\r
- PciIoDevice->PciBar[BarIndex].Prefetchable = FALSE;\r
PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
\r
} else {\r
// some device implement MMIO bar with 0 length, need to treat it as no-bar\r
//\r
PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+ return Offset + 4;\r
}\r
- return Offset + 4;\r
}\r
\r
//\r
- // Fix the length to support some spefic 64 bit BAR\r
+ // Fix the length to support some special 64 bit BAR\r
//\r
- Data = Value;\r
- Index = 0;\r
- for (Data = Value; Data != 0; Data >>= 1) {\r
- Index ++;\r
+ if (Value == 0) {\r
+ DEBUG ((EFI_D_INFO, "[PciBus]BAR probing for upper 32bit of MEM64 BAR returns 0, change to 0xFFFFFFFF.\n"));\r
+ Value = (UINT32) -1;\r
+ } else {\r
+ Value |= ((UINT32)(-1) << HighBitSet32 (Value));\r
}\r
- Value |= ((UINT32)(-1) << Index);\r
\r
//\r
// Calculate the size of 64bit bar\r
//\r
// Put all the resource apertures\r
// Resource base is set to all ones so as to indicate its resource\r
- // has not been alloacted\r
+ // has not been allocated\r
//\r
for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) {\r
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllOne);\r
}\r
\r
/**\r
- Create and initiliaze general PCI I/O device instance for\r
+ Create and initialize general PCI I/O device instance for\r
PCI device/bridge device/hotplug bridge device.\r
\r
- @param PciRootBridgeIo Pointer to instance of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+ @param Bridge Parent bridge instance.\r
@param Pci Input Pci information block.\r
@param Bus Device Bus NO.\r
@param Device Device device NO.\r
**/\r
PCI_IO_DEVICE *\r
CreatePciIoDevice (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ IN PCI_IO_DEVICE *Bridge,\r
IN PCI_TYPE00 *Pci,\r
IN UINT8 Bus,\r
IN UINT8 Device,\r
IN UINT8 Func\r
)\r
{\r
- PCI_IO_DEVICE *PciIoDevice;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
EFI_PCI_IO_PROTOCOL *PciIo;\r
EFI_STATUS Status;\r
\r
\r
PciIoDevice->Signature = PCI_IO_DEVICE_SIGNATURE;\r
PciIoDevice->Handle = NULL;\r
- PciIoDevice->PciRootBridgeIo = PciRootBridgeIo;\r
+ PciIoDevice->PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
PciIoDevice->DevicePath = NULL;\r
PciIoDevice->BusNumber = Bus;\r
PciIoDevice->DeviceNumber = Device;\r
InitializePciLoadFile2 (PciIoDevice);\r
PciIo = &PciIoDevice->PciIo;\r
\r
+ //\r
+ // Create a device path for this PCI device and store it into its private data\r
+ //\r
+ CreatePciDevicePath (\r
+ Bridge->DevicePath,\r
+ PciIoDevice\r
+ );\r
+\r
//\r
// Detect if PCI Express Device\r
//\r
PciIoDevice->IsPciExp = TRUE;\r
}\r
\r
- //\r
- // Initialize for PCI IOV\r
- //\r
-\r
- //\r
- // Check ARI for function 0 only\r
- //\r
- Status = LocatePciExpressCapabilityRegBlock (\r
- PciIoDevice,\r
- EFI_PCIE_CAPABILITY_ID_ARI,\r
- &PciIoDevice->AriCapabilityOffset,\r
- NULL\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- DEBUG ((\r
- EFI_D_INFO,\r
- "PCI-IOV B%x.D%x.F%x - ARI Cap offset - 0x%x\n",\r
- (UINTN)Bus,\r
- (UINTN)Device,\r
- (UINTN)Func,\r
- (UINTN)PciIoDevice->AriCapabilityOffset\r
- ));\r
- }\r
+ if (PcdGetBool (PcdAriSupport)) {\r
+ //\r
+ // Check if the device is an ARI device.\r
+ //\r
+ Status = LocatePciExpressCapabilityRegBlock (\r
+ PciIoDevice,\r
+ EFI_PCIE_CAPABILITY_ID_ARI,\r
+ &PciIoDevice->AriCapabilityOffset,\r
+ NULL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // We need to enable ARI feature before calculate BusReservation,\r
+ // because FirstVFOffset and VFStride may change after that.\r
+ //\r
+ EFI_PCI_IO_PROTOCOL *ParentPciIo;\r
+ UINT32 Data32;\r
\r
- Status = LocatePciExpressCapabilityRegBlock (\r
- PciIoDevice,\r
- EFI_PCIE_CAPABILITY_ID_SRIOV,\r
- &PciIoDevice->SrIovCapabilityOffset,\r
- NULL\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- DEBUG ((\r
- EFI_D_INFO,\r
- "PCI-IOV B%x.D%x.F%x - SRIOV Cap offset - 0x%x\n",\r
- (UINTN)Bus,\r
- (UINTN)Device,\r
- (UINTN)Func,\r
- (UINTN)PciIoDevice->SrIovCapabilityOffset\r
- ));\r
- }\r
+ //\r
+ // Check if its parent supports ARI forwarding.\r
+ //\r
+ ParentPciIo = &Bridge->PciIo;\r
+ ParentPciIo->Pci.Read (\r
+ ParentPciIo,\r
+ EfiPciIoWidthUint32,\r
+ Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_OFFSET,\r
+ 1,\r
+ &Data32\r
+ );\r
+ if ((Data32 & EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING) != 0) {\r
+ //\r
+ // ARI forward support in bridge, so enable it.\r
+ //\r
+ ParentPciIo->Pci.Read (\r
+ ParentPciIo,\r
+ EfiPciIoWidthUint32,\r
+ Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET,\r
+ 1,\r
+ &Data32\r
+ );\r
+ if ((Data32 & EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING) == 0) {\r
+ Data32 |= EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING;\r
+ ParentPciIo->Pci.Write (\r
+ ParentPciIo,\r
+ EfiPciIoWidthUint32,\r
+ Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET,\r
+ 1,\r
+ &Data32\r
+ );\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ " ARI: forwarding enabled for PPB[%02x:%02x:%02x]\n",\r
+ Bridge->BusNumber,\r
+ Bridge->DeviceNumber,\r
+ Bridge->FunctionNumber\r
+ ));\r
+ }\r
+ }\r
\r
- Status = LocatePciExpressCapabilityRegBlock (\r
- PciIoDevice,\r
- EFI_PCIE_CAPABILITY_ID_MRIOV,\r
- &PciIoDevice->MrIovCapabilityOffset,\r
- NULL\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- DEBUG ((\r
- EFI_D_INFO,\r
- "PCI-IOV B%x.D%x.F%x - MRIOV Cap offset - 0x%x\n",\r
- (UINTN)Bus,\r
- (UINTN)Device,\r
- (UINTN)Func,\r
- (UINTN)PciIoDevice->MrIovCapabilityOffset\r
- ));\r
+ DEBUG ((EFI_D_INFO, " ARI: CapOffset = 0x%x\n", PciIoDevice->AriCapabilityOffset));\r
+ }\r
}\r
\r
//\r
- // Calculate SystemPageSize\r
+ // Initialization for SR-IOV\r
//\r
- if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {\r
\r
- PciIo->Pci.Read (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SUPPORTED_PAGE_SIZE,\r
- 1,\r
- &PciIoDevice->SystemPageSize\r
- );\r
- DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - SupportedPageSize - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, PciIoDevice->SystemPageSize));\r
+ if (PcdGetBool (PcdSrIovSupport)) {\r
+ Status = LocatePciExpressCapabilityRegBlock (\r
+ PciIoDevice,\r
+ EFI_PCIE_CAPABILITY_ID_SRIOV,\r
+ &PciIoDevice->SrIovCapabilityOffset,\r
+ NULL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ UINT32 SupportedPageSize;\r
+ UINT16 VFStride;\r
+ UINT16 FirstVFOffset;\r
+ UINT16 Data16;\r
+ UINT32 PFRid;\r
+ UINT32 LastVF;\r
\r
- PciIoDevice->SystemPageSize = (FixedPcdGet32(PcdSrIovSystemPageSize) & PciIoDevice->SystemPageSize);\r
- ASSERT (PciIoDevice->SystemPageSize != 0);\r
+ //\r
+ // If the SR-IOV device is an ARI device, then Set ARI Capable Hierarchy for the device.\r
+ //\r
+ if (PcdGetBool (PcdAriSupport) && PciIoDevice->AriCapabilityOffset != 0) {\r
+ PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL,\r
+ 1,\r
+ &Data16\r
+ );\r
+ Data16 |= EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL_ARI_HIERARCHY;\r
+ PciIo->Pci.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL,\r
+ 1,\r
+ &Data16\r
+ );\r
+ }\r
\r
- PciIo->Pci.Write (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SYSTEM_PAGE_SIZE,\r
- 1,\r
- &PciIoDevice->SystemPageSize\r
- );\r
- DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - SystemPageSize - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, PciIoDevice->SystemPageSize));\r
- //\r
- // Adjust SystemPageSize for Alignment usage later\r
- //\r
- PciIoDevice->SystemPageSize <<= 12;\r
- }\r
+ //\r
+ // Calculate SystemPageSize\r
+ //\r
\r
- // Calculate BusReservation for PCI IOV\r
- //\r
- if ((PciIoDevice->SrIovCapabilityOffset != 0) && ((FeaturePcdGet(PcdSrIovSupport)& EFI_PCI_IOV_POLICY_SRIOV) != 0)) {\r
- UINT16 VFStride;\r
- UINT16 FirstVFOffset;\r
- UINT32 PFRid;\r
- UINT32 LastVF;\r
+ PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SUPPORTED_PAGE_SIZE,\r
+ 1,\r
+ &SupportedPageSize\r
+ );\r
+ PciIoDevice->SystemPageSize = (PcdGet32 (PcdSrIovSystemPageSize) & SupportedPageSize);\r
+ ASSERT (PciIoDevice->SystemPageSize != 0);\r
+\r
+ PciIo->Pci.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SYSTEM_PAGE_SIZE,\r
+ 1,\r
+ &PciIoDevice->SystemPageSize\r
+ );\r
+ //\r
+ // Adjust SystemPageSize for Alignment usage later\r
+ //\r
+ PciIoDevice->SystemPageSize <<= 12;\r
\r
- //\r
- // Read First FirstVFOffset, InitialVFs, and VFStride\r
- //\r
- PciIo->Pci.Read (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_FIRSTVF,\r
- 1,\r
- &FirstVFOffset\r
- );\r
- DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - FirstVFOffset - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, (UINTN)FirstVFOffset));\r
-\r
- PciIo->Pci.Read (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_INITIALVFS,\r
- 1,\r
- &PciIoDevice->InitialVFs\r
- );\r
- DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - InitialVFs - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, (UINTN)PciIoDevice->InitialVFs));\r
-\r
- PciIo->Pci.Read (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_VFSTRIDE,\r
- 1,\r
- &VFStride\r
- );\r
- DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - VFStride - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, (UINTN)VFStride));\r
+ //\r
+ // Calculate BusReservation for PCI IOV\r
+ //\r
\r
- //\r
- // Calculate LastVF\r
- //\r
- PFRid = EFI_PCI_RID(Bus, Device, Func);\r
- LastVF = PFRid + FirstVFOffset + (PciIoDevice->InitialVFs - 1) * VFStride;\r
+ //\r
+ // Read First FirstVFOffset, InitialVFs, and VFStride\r
+ //\r
+ PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_FIRSTVF,\r
+ 1,\r
+ &FirstVFOffset\r
+ );\r
+ PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_INITIALVFS,\r
+ 1,\r
+ &PciIoDevice->InitialVFs\r
+ );\r
+ PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_VFSTRIDE,\r
+ 1,\r
+ &VFStride\r
+ );\r
+ //\r
+ // Calculate LastVF\r
+ //\r
+ PFRid = EFI_PCI_RID(Bus, Device, Func);\r
+ LastVF = PFRid + FirstVFOffset + (PciIoDevice->InitialVFs - 1) * VFStride;\r
\r
- //\r
- // Calculate ReservedBusNum for this PF\r
- //\r
- PciIoDevice->ReservedBusNum = (UINT16)(EFI_PCI_BUS_OF_RID (LastVF) - Bus + 1);\r
- DEBUG ((EFI_D_INFO, "PCI-IOV B%x.D%x.F%x - reserved bus number - 0x%x\n", (UINTN)Bus, (UINTN)Device, (UINTN)Func, (UINTN)PciIoDevice->ReservedBusNum));\r
+ //\r
+ // Calculate ReservedBusNum for this PF\r
+ //\r
+ PciIoDevice->ReservedBusNum = (UINT16)(EFI_PCI_BUS_OF_RID (LastVF) - Bus + 1);\r
+\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ " SR-IOV: SupportedPageSize = 0x%x; SystemPageSize = 0x%x; FirstVFOffset = 0x%x;\n",\r
+ SupportedPageSize, PciIoDevice->SystemPageSize >> 12, FirstVFOffset\r
+ ));\r
+ DEBUG ((\r
+ EFI_D_INFO,\r
+ " InitialVFs = 0x%x; ReservedBusNum = 0x%x; CapOffset = 0x%x\n",\r
+ PciIoDevice->InitialVFs, PciIoDevice->ReservedBusNum, PciIoDevice->SrIovCapabilityOffset\r
+ ));\r
+ }\r
}\r
\r
+ if (PcdGetBool (PcdMrIovSupport)) {\r
+ Status = LocatePciExpressCapabilityRegBlock (\r
+ PciIoDevice,\r
+ EFI_PCIE_CAPABILITY_ID_MRIOV,\r
+ &PciIoDevice->MrIovCapabilityOffset,\r
+ NULL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_INFO, " MR-IOV: CapOffset = 0x%x\n", PciIoDevice->MrIovCapabilityOffset));\r
+ }\r
+ }\r
\r
//\r
// Initialize the reserved resource list\r
}\r
\r
//\r
- // Record the root bridgeio protocol\r
+ // Record the root bridge-io protocol\r
//\r
RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;\r
\r
} else {\r
\r
//\r
- // If unsuccessly, destroy the entire node\r
+ // If unsuccessfully, destroy the entire node\r
//\r
DestroyRootBridge (RootBridgeDev);\r
}\r
Func\r
);\r
\r
+ if (EFI_ERROR (Status) && Func == 0) {\r
+ //\r
+ // go to next device if there is no Function 0\r
+ //\r
+ break;\r
+ }\r
+\r
if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci))) {\r
\r
Register = 0;\r