]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
Fix the bug in PciBus driver to correct parse the 64bit BAR.
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciEnumeratorSupport.c
index c8689c042137ec45097b1c2642c118a643b8eac4..a1627807e57ed88710a11130da3241832de3fb71 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   PCI emumeration support functions implementation for PCI Bus module.\r
 \r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, 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
@@ -14,6 +14,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "PciBus.h"\r
 \r
+extern CHAR16  *mBarTypeStr[];\r
+\r
 /**\r
   This routine is used to check whether the pci device is present.\r
 \r
@@ -211,6 +213,15 @@ PciSearchDevice (
 \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
@@ -304,6 +315,46 @@ PciSearchDevice (
   return EFI_SUCCESS;\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%x;\tLength = 0x%x;\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%x;\tLength = 0x%x;\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
@@ -377,6 +428,8 @@ GatherDeviceInfo (
       Offset = PciIovParseVfBar (PciIoDevice, Offset, BarIndex);\r
     }\r
   }\r
+\r
+  DEBUG_CODE (DumpPciBars (PciIoDevice););\r
   return PciIoDevice;\r
 }\r
 \r
@@ -406,6 +459,9 @@ GatherPpbInfo (
   UINT8                           Value;\r
   EFI_PCI_IO_PROTOCOL             *PciIo;\r
   UINT8                           Temp;\r
+  UINT32                          PMemBaseLimit;\r
+  UINT16                          PrefetchableMemoryBase;\r
+  UINT16                          PrefetchableMemoryLimit;\r
 \r
   PciIoDevice = CreatePciIoDevice (\r
                   Bridge,\r
@@ -499,14 +555,22 @@ GatherPpbInfo (
             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
@@ -529,6 +593,8 @@ GatherPpbInfo (
 \r
   GetResourcePaddingPpb (PciIoDevice);\r
 \r
+  DEBUG_CODE (DumpPciBars (PciIoDevice););\r
+\r
   return PciIoDevice;\r
 }\r
 \r
@@ -598,6 +664,8 @@ GatherP2CInfo (
                          EFI_BRIDGE_PMEM32_DECODE_SUPPORTED |\r
                          EFI_BRIDGE_IO32_DECODE_SUPPORTED;\r
 \r
+  DEBUG_CODE (DumpPciBars (PciIoDevice););\r
+\r
   return PciIoDevice;\r
 }\r
 \r
@@ -910,9 +978,10 @@ PciSetDeviceAttribute (
                   EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM         |\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 ? EFI_PCI_IO_ATTRIBUTE_ISA_IO : \\r
+                                            EFI_PCI_IO_ATTRIBUTE_ISA_IO_16);\r
     }\r
 \r
     if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
@@ -921,6 +990,14 @@ PciSetDeviceAttribute (
       //\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
@@ -930,7 +1007,8 @@ PciSetDeviceAttribute (
 \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 ? EFI_PCI_IO_ATTRIBUTE_VGA_IO : \\r
+                                            EFI_PCI_IO_ATTRIBUTE_VGA_IO_16);\r
       }\r
     }\r
 \r
@@ -1063,8 +1141,12 @@ DetermineDeviceAttribute (
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
+    //\r
+    // Assume the PCI Root Bridge supports DAC\r
+    //\r
     PciIoDevice->Supports |= (EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE |\r
-                              EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM);\r
+                              EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM |\r
+                              EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE);\r
 \r
   } else {\r
 \r
@@ -1391,8 +1473,6 @@ PciIovParseVfBar (
   UINT32      Value;\r
   UINT32      OriginalValue;\r
   UINT32      Mask;\r
-  UINT32      Data;\r
-  UINT8       Index;\r
   EFI_STATUS  Status;\r
 \r
   //\r
@@ -1510,12 +1590,7 @@ PciIovParseVfBar (
       //\r
       // Fix the length to support some spefic 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
@@ -1590,8 +1665,6 @@ PciParseBar (
   UINT32      Value;\r
   UINT32      OriginalValue;\r
   UINT32      Mask;\r
-  UINT32      Data;\r
-  UINT8       Index;\r
   EFI_STATUS  Status;\r
 \r
   OriginalValue = 0;\r
@@ -1728,12 +1801,7 @@ PciParseBar (
       //\r
       // Fix the length to support some spefic 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
@@ -2025,22 +2093,15 @@ CreatePciIoDevice (
                               );\r
           DEBUG ((\r
             EFI_D_INFO,\r
-            "PCI B%x.D%x.F%x - ARI forwarding enabled\n",\r
-            (UINTN)Bridge->BusNumber,\r
-            (UINTN)Bridge->DeviceNumber,\r
-            (UINTN)Bridge->FunctionNumber\r
+            " ARI: forwarding enabled for PPB[%02x:%02x:%02x]\n",\r
+            Bridge->BusNumber,\r
+            Bridge->DeviceNumber,\r
+            Bridge->FunctionNumber\r
             ));\r
         }\r
       }\r
 \r
-      DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI ARI 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
+      DEBUG ((EFI_D_INFO, " ARI: CapOffset = 0x%x\n", PciIoDevice->AriCapabilityOffset));\r
     }\r
   }\r
 \r
@@ -2056,6 +2117,7 @@ CreatePciIoDevice (
                NULL\r
                );\r
     if (!EFI_ERROR (Status)) {\r
+      UINT32    SupportedPageSize;\r
       UINT16    VFStride;\r
       UINT16    FirstVFOffset;\r
       UINT16    Data16;\r
@@ -2092,18 +2154,9 @@ CreatePciIoDevice (
                    EfiPciIoWidthUint32,\r
                    PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SUPPORTED_PAGE_SIZE,\r
                    1,\r
-                   &PciIoDevice->SystemPageSize\r
+                   &SupportedPageSize\r
                    );\r
-      DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI SR-IOV B%x.D%x.F%x - SupportedPageSize - 0x%x\n",\r
-        (UINTN)Bus,\r
-        (UINTN)Device,\r
-        (UINTN)Func,\r
-        PciIoDevice->SystemPageSize\r
-        ));\r
-\r
-      PciIoDevice->SystemPageSize = (PcdGet32 (PcdSrIovSystemPageSize) & PciIoDevice->SystemPageSize);\r
+      PciIoDevice->SystemPageSize = (PcdGet32 (PcdSrIovSystemPageSize) & SupportedPageSize);\r
       ASSERT (PciIoDevice->SystemPageSize != 0);\r
 \r
       PciIo->Pci.Write (\r
@@ -2113,14 +2166,6 @@ CreatePciIoDevice (
                    1,\r
                    &PciIoDevice->SystemPageSize\r
                    );\r
-      DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI SR-IOV B%x.D%x.F%x - SystemPageSize - 0x%x\n",\r
-        (UINTN)Bus,\r
-        (UINTN)Device,\r
-        (UINTN)Func,\r
-        PciIoDevice->SystemPageSize\r
-        ));\r
       //\r
       // Adjust SystemPageSize for Alignment usage later\r
       //\r
@@ -2140,15 +2185,6 @@ CreatePciIoDevice (
                    1,\r
                    &FirstVFOffset\r
                    );\r
-      DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI SR-IOV B%x.D%x.F%x - FirstVFOffset - 0x%x\n",\r
-        (UINTN)Bus,\r
-        (UINTN)Device,\r
-        (UINTN)Func,\r
-        (UINTN)FirstVFOffset\r
-        ));\r
-\r
       PciIo->Pci.Read (\r
                    PciIo,\r
                    EfiPciIoWidthUint16,\r
@@ -2156,15 +2192,6 @@ CreatePciIoDevice (
                    1,\r
                    &PciIoDevice->InitialVFs\r
                    );\r
-      DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI SR-IOV B%x.D%x.F%x - InitialVFs - 0x%x\n",\r
-        (UINTN)Bus,\r
-        (UINTN)Device,\r
-        (UINTN)Func,\r
-        (UINTN)PciIoDevice->InitialVFs\r
-        ));\r
-\r
       PciIo->Pci.Read (\r
                    PciIo,\r
                    EfiPciIoWidthUint16,\r
@@ -2172,15 +2199,6 @@ CreatePciIoDevice (
                    1,\r
                    &VFStride\r
                    );\r
-      DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI SR-IOV B%x.D%x.F%x - VFStride - 0x%x\n",\r
-        (UINTN)Bus,\r
-        (UINTN)Device,\r
-        (UINTN)Func,\r
-        (UINTN)VFStride\r
-        ));\r
-\r
       //\r
       // Calculate LastVF\r
       //\r
@@ -2191,22 +2209,16 @@ CreatePciIoDevice (
       // 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
-        "PCI SR-IOV B%x.D%x.F%x - reserved bus number - 0x%x\n",\r
-        (UINTN)Bus,\r
-        (UINTN)Device,\r
-        (UINTN)Func,\r
-        (UINTN)PciIoDevice->ReservedBusNum\r
+        " SR-IOV: SupportedPageSize = 0x%x; SystemPageSize = 0x%x; FirstVFOffset = 0x%x;\n",\r
+        SupportedPageSize, PciIoDevice->SystemPageSize >> 12, FirstVFOffset\r
         ));\r
-\r
       DEBUG ((\r
         EFI_D_INFO,\r
-        "PCI SR-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
+        "         InitialVFs = 0x%x; ReservedBusNum = 0x%x; CapOffset = 0x%x\n",\r
+        PciIoDevice->InitialVFs, PciIoDevice->ReservedBusNum, PciIoDevice->SrIovCapabilityOffset\r
         ));\r
     }\r
   }\r
@@ -2219,14 +2231,7 @@ CreatePciIoDevice (
                NULL\r
                );\r
     if (!EFI_ERROR (Status)) {\r
-      DEBUG ((\r
-        EFI_D_INFO,\r
-        "PCI MR-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, " MR-IOV: CapOffset = 0x%x\n", PciIoDevice->MrIovCapabilityOffset));\r
     }\r
   }\r
 \r