]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
MdeModulePkg/PciBus: Accept Spec values as BarIndex and Alignment
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciEnumeratorSupport.c
index a6ade26e3a09786970dc0a46fc0684d8e3c76a0a..ecda088814a3c846f17615876314f8036b2de2ca 100644 (file)
@@ -1,7 +1,7 @@
 /** @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
@@ -17,6 +17,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \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
@@ -164,6 +169,14 @@ PciPciDeviceInfoCollector (
             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
@@ -591,14 +604,14 @@ GatherPpbInfo (
 \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
@@ -1327,8 +1340,8 @@ UpdatePciInfo (
   )\r
 {\r
   EFI_STATUS                        Status;\r
-  UINT                            BarIndex;\r
-  UINT                            BarEndIndex;\r
+  UINT64                            BarIndex;\r
+  UINT64                            BarEndIndex;\r
   BOOLEAN                           SetFlag;\r
   VOID                              *Configuration;\r
   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
@@ -1336,7 +1349,7 @@ UpdatePciInfo (
   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
@@ -1344,7 +1357,7 @@ UpdatePciInfo (
     Status = gBS->LocateProtocol (\r
                     &gEfiIncompatiblePciDeviceSupportProtocolGuid,\r
                     NULL,\r
-                    (VOID **) &gEfiIncompatiblePciDeviceSupport\r
+                    (VOID **) &gIncompatiblePciDeviceSupport\r
                     );\r
   }\r
   if (Status == EFI_SUCCESS) {\r
@@ -1352,15 +1365,15 @@ UpdatePciInfo (
       // 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
@@ -1382,18 +1395,19 @@ UpdatePciInfo (
       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
@@ -1408,6 +1422,38 @@ UpdatePciInfo (
         //\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
@@ -1432,7 +1478,7 @@ UpdatePciInfo (
         //\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
@@ -1448,6 +1494,8 @@ UpdatePciInfo (
 \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
@@ -1466,15 +1514,15 @@ SetNewAlign (
   // 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
@@ -1493,15 +1541,15 @@ SetNewAlign (
   //\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
@@ -1752,6 +1800,7 @@ PciParseBar (
     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
@@ -1784,7 +1833,6 @@ PciParseBar (
       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