/** @file\r
PCI emumeration support functions implementation for PCI Bus module.\r
\r
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\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
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
// 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
)\r
{\r
EFI_STATUS Status;\r
- UINTN BarIndex;\r
- UINTN BarEndIndex;\r
+ UINT64 BarIndex;\r
+ UINT64 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
+ BarIndex = Ptr->AddrTranslationOffset;\r
BarEndIndex = BarIndex;\r
\r
//\r
// Update all the bars in the device\r
+ // Compare against 0xFF is to keep backward compatibility.\r
//\r
- if (BarIndex == PCI_BAR_ALL) {\r
+ if ((BarIndex == MAX_UINT64) || (BarIndex == 0xFF)) {\r
BarIndex = 0;\r
BarEndIndex = PCI_MAX_BAR - 1;\r
}\r
\r
- if (BarIndex > PCI_MAX_BAR) {\r
+ if (BarIndex >= PCI_MAX_BAR) {\r
Ptr++;\r
continue;\r
}\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
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
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