]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c
Print resource allocation/bar programming when PciBus driver does PCI BUS enumeration.
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciResourceSupport.c
index 2cacd441c8830f40c82711f36f143bde87f6c25c..e17f4bae4466b3af40f391630d8c40bc12a14e8b 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   PCI resouces support functions implemntation for PCI Bus module.\r
 \r
-Copyright (c) 2006 - 2009, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2011, 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
@@ -14,6 +14,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "PciBus.h"\r
 \r
+//\r
+// The default policy for the PCI bus driver is NOT to reserve I/O ranges for both ISA aliases and VGA aliases.\r
+//\r
+BOOLEAN mReserveIsaAliases = FALSE;\r
+BOOLEAN mReserveVgaAliases = FALSE;\r
+BOOLEAN mPolicyDetermined  = FALSE;\r
+\r
 /**\r
   The function is used to skip VGA range.\r
 \r
@@ -188,46 +195,37 @@ CalculateApertureIo16 (
   LIST_ENTRY              *CurrentLink;\r
   PCI_RESOURCE_NODE       *Node;\r
   UINT64                  Offset;\r
-  BOOLEAN                 IsaEnable;\r
-  BOOLEAN                 VGAEnable;\r
   EFI_PCI_PLATFORM_POLICY PciPolicy;\r
 \r
-  //\r
-  // Always assume there is ISA device and VGA device on the platform\r
-  // will be customized later\r
-  //\r
-  IsaEnable = FALSE;\r
-  VGAEnable = FALSE;\r
+  if (!mPolicyDetermined) {\r
+    //\r
+    // Check PciPlatform policy\r
+    //\r
+    Status = EFI_NOT_FOUND;\r
+    PciPolicy = 0;\r
+    if (gPciPlatformProtocol != NULL) {\r
+      Status = gPciPlatformProtocol->GetPlatformPolicy (\r
+                                       gPciPlatformProtocol,\r
+                                       &PciPolicy\r
+                                       );\r
+    }\r
 \r
-  //\r
-  // Check PciPlatform policy\r
-  //\r
-  if (gPciPlatformProtocol != NULL) {\r
-    Status = gPciPlatformProtocol->GetPlatformPolicy (\r
-                                     gPciPlatformProtocol,\r
-                                     &PciPolicy\r
-                                     );\r
-    if (!EFI_ERROR (Status)) {\r
-      if ((PciPolicy & EFI_RESERVE_ISA_IO_ALIAS) != 0) {\r
-        IsaEnable = TRUE;\r
-      }\r
-      if ((PciPolicy & EFI_RESERVE_VGA_IO_ALIAS) != 0) {\r
-        VGAEnable = TRUE;\r
-      }\r
+    if (EFI_ERROR (Status) && gPciOverrideProtocol != NULL) {\r
+      Status = gPciOverrideProtocol->GetPlatformPolicy (\r
+                                       gPciOverrideProtocol,\r
+                                       &PciPolicy\r
+                                       );\r
     }\r
-  } else if (gPciOverrideProtocol != NULL) {\r
-    Status = gPciOverrideProtocol->GetPlatformPolicy (\r
-                                     gPciOverrideProtocol,\r
-                                     &PciPolicy\r
-                                     );\r
+\r
     if (!EFI_ERROR (Status)) {\r
       if ((PciPolicy & EFI_RESERVE_ISA_IO_ALIAS) != 0) {\r
-        IsaEnable = TRUE;\r
+        mReserveIsaAliases = TRUE;\r
       }\r
       if ((PciPolicy & EFI_RESERVE_VGA_IO_ALIAS) != 0) {\r
-        VGAEnable = TRUE;\r
+        mReserveVgaAliases = TRUE;\r
       }\r
     }\r
+    mPolicyDetermined = TRUE;\r
   }\r
 \r
   Aperture = 0;\r
@@ -261,13 +259,13 @@ CalculateApertureIo16 (
     // If both of them are enabled, then the IO resource would\r
     // become too limited to meet the requirement of most of devices.\r
     //\r
-    if (IsaEnable || VGAEnable) {\r
+    if (mReserveIsaAliases || mReserveVgaAliases) {\r
       if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci)) && !IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) {\r
         //\r
         // Check if there is need to support ISA/VGA decoding\r
         // If so, we need to avoid isa/vga aliasing range\r
         //\r
-        if (IsaEnable) {\r
+        if (mReserveIsaAliases) {\r
           SkipIsaAliasAperture (\r
             &Aperture,\r
             Node->Length\r
@@ -276,7 +274,7 @@ CalculateApertureIo16 (
           if (Offset != 0) {\r
             Aperture = Aperture + (Node->Alignment + 1) - Offset;\r
           }\r
-        } else if (VGAEnable) {\r
+        } else if (mReserveVgaAliases) {\r
           SkipVGAAperture (\r
             &Aperture,\r
             Node->Length\r
@@ -726,17 +724,6 @@ CreateVfResourceNode (
 {\r
   PCI_RESOURCE_NODE *Node;\r
 \r
-  DEBUG ((\r
-    EFI_D_INFO,\r
-    "PCI-IOV B%x.D%x.F%x - VfResource (Bar - 0x%x) (Type - 0x%x) (Length - 0x%x)\n",\r
-    (UINTN)PciDev->BusNumber,\r
-    (UINTN)PciDev->DeviceNumber,\r
-    (UINTN)PciDev->FunctionNumber,\r
-    (UINTN)Bar,\r
-    (UINTN)ResType,\r
-    (UINTN)Length\r
-    ));\r
-\r
   Node = CreateResourceNode (PciDev, Length, Alignment, Bar, ResType, ResUsage);\r
   if (Node == NULL) {\r
     return Node;\r
@@ -803,14 +790,12 @@ CreateResourceMap (
       //\r
       // If the device has children, create a bridge resource node for this PPB\r
       // Note: For PPB, memory aperture is aligned with 1MB and IO aperture\r
-      // is aligned with 4KB\r
-      // This device is typically a bridge device like PPB and P2C\r
-      // Note: 0x1000 aligned\r
+      // is aligned with 4KB (smaller alignments may be supported).\r
       //\r
       IoBridge = CreateResourceNode (\r
                    Temp,\r
                    0,\r
-                   0xFFF,\r
+                   Temp->BridgeIoAlignment,\r
                    PPB_IO_RANGE,\r
                    PciBarTypeIo16,\r
                    PciResUsageTypical\r
@@ -1049,31 +1034,63 @@ DegradeResource (
   IN PCI_RESOURCE_NODE *PMem64Node\r
   )\r
 {\r
-  BOOLEAN              HasOprom;\r
   PCI_IO_DEVICE        *Temp;\r
-  LIST_ENTRY           *CurrentLink;\r
+  LIST_ENTRY           *ChildDeviceLink;\r
+  LIST_ENTRY           *ChildNodeLink;\r
+  LIST_ENTRY           *NextChildNodeLink;\r
+  PCI_RESOURCE_NODE    *TempNode;\r
 \r
   //\r
-  // For RootBridge, PPB , P2C, go recursively to traverse all its children\r
-  // to find if this bridge and downstream has OptionRom.\r
+  // If any child device has both option ROM and 64-bit BAR, degrade its PMEM64/MEM64\r
+  // requests in case that if a legacy option ROM image can not access 64-bit resources.\r
   //\r
-  HasOprom = FALSE;\r
-  CurrentLink = Bridge->ChildList.ForwardLink;\r
-  while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) {\r
-\r
-    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+  ChildDeviceLink = Bridge->ChildList.ForwardLink;\r
+  while (ChildDeviceLink != NULL && ChildDeviceLink != &Bridge->ChildList) {\r
+    Temp = PCI_IO_DEVICE_FROM_LINK (ChildDeviceLink);\r
     if (Temp->RomSize != 0) {\r
-      HasOprom = TRUE;\r
-      break;\r
+      if (!IsListEmpty (&Mem64Node->ChildList)) {      \r
+        ChildNodeLink = Mem64Node->ChildList.ForwardLink;\r
+        while (ChildNodeLink != &Mem64Node->ChildList) {\r
+          TempNode = RESOURCE_NODE_FROM_LINK (ChildNodeLink);\r
+          NextChildNodeLink = ChildNodeLink->ForwardLink;\r
+\r
+          if (TempNode->PciDev == Temp) {\r
+            RemoveEntryList (ChildNodeLink);\r
+            InsertResourceNode (Mem32Node, TempNode);\r
+          }\r
+          ChildNodeLink = NextChildNodeLink;\r
+        }        \r
+      }\r
+\r
+      if (!IsListEmpty (&PMem64Node->ChildList)) {      \r
+        ChildNodeLink = PMem64Node->ChildList.ForwardLink;\r
+        while (ChildNodeLink != &PMem64Node->ChildList) {\r
+          TempNode = RESOURCE_NODE_FROM_LINK (ChildNodeLink);\r
+          NextChildNodeLink = ChildNodeLink->ForwardLink;\r
+\r
+          if (TempNode->PciDev == Temp) {\r
+            RemoveEntryList (ChildNodeLink);\r
+            InsertResourceNode (PMem32Node, TempNode);\r
+          }\r
+          ChildNodeLink = NextChildNodeLink;\r
+        }        \r
+      }\r
+\r
     }\r
-    CurrentLink = CurrentLink->ForwardLink;\r
+    ChildDeviceLink = ChildDeviceLink->ForwardLink;\r
   }\r
 \r
   //\r
-  // If bridge doesn't support Prefetchable\r
-  // memory64, degrade it to Prefetchable memory32\r
+  // If firmware is in 32-bit mode,\r
+  // then degrade PMEM64/MEM64 requests\r
   //\r
-  if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) {\r
+  if (sizeof (UINTN) <= 4) {\r
+    MergeResourceTree (\r
+      Mem32Node,\r
+      Mem64Node,\r
+      TRUE\r
+      );\r
+\r
     MergeResourceTree (\r
       PMem32Node,\r
       PMem64Node,\r
@@ -1081,31 +1098,38 @@ DegradeResource (
       );\r
   } else {\r
     //\r
-    // if no PMem32 request and no OptionRom request, still keep PMem64. Otherwise degrade to PMem32\r
+    // if the bridge does not support MEM64, degrade MEM64 to MEM32\r
     //\r
-    if ((PMem32Node != NULL && (PMem32Node->Length != 0 && Bridge->Parent != NULL)) || HasOprom) {\r
-      //\r
-      // Fixed the issue that there is no resource for 64-bit (above 4G)\r
-      //\r
+    if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) {\r
+        MergeResourceTree (\r
+          Mem32Node,\r
+          Mem64Node,\r
+          TRUE\r
+          );\r
+    }\r
+\r
+    //\r
+    // if the bridge does not support PMEM64, degrade PMEM64 to PMEM32\r
+    //\r
+    if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) {\r
       MergeResourceTree (\r
         PMem32Node,\r
         PMem64Node,\r
         TRUE\r
         );\r
-    }\r
-  }\r
+    } \r
 \r
-\r
-  //\r
-  // If bridge doesn't support Mem64\r
-  // degrade it to mem32\r
-  //\r
-  if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) {\r
-    MergeResourceTree (\r
-      Mem32Node,\r
-      Mem64Node,\r
-      TRUE\r
-      );\r
+    //\r
+    // if both PMEM64 and PMEM32 requests from child devices, which can not be satisfied\r
+    // by a P2P bridge simultaneously, keep PMEM64 and degrade PMEM32 to MEM32.\r
+    //\r
+    if (!IsListEmpty (&PMem64Node->ChildList) && Bridge->Parent != NULL) {\r
+      MergeResourceTree (\r
+        Mem32Node,\r
+        PMem32Node,\r
+        TRUE\r
+        );\r
+    }\r
   }\r
 \r
   //\r
@@ -1121,7 +1145,7 @@ DegradeResource (
   }\r
 \r
   //\r
-  // if bridge supports combined Pmem Mem decoding\r
+  // if root bridge supports combined Pmem Mem decoding\r
   // merge these two type of resource\r
   //\r
   if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) {\r
@@ -1131,6 +1155,11 @@ DegradeResource (
       FALSE\r
       );\r
 \r
+    //\r
+    // No need to check if to degrade MEM64 after merge, because\r
+    // if there are PMEM64 still here, 64-bit decode should be supported\r
+    // by the root bride.\r
+    //\r
     MergeResourceTree (\r
       Mem64Node,\r
       PMem64Node,\r
@@ -1249,6 +1278,7 @@ ProgramBar (
   //\r
   if (Node->Virtual) {\r
     ProgramVfBar (Base, Node);\r
+    return;\r
   }\r
 \r
   Address = 0;\r
@@ -1362,17 +1392,6 @@ ProgramVfBar (
                 );\r
 \r
     Node->PciDev->VfPciBar[Node->Bar].BaseAddress = Address;\r
-\r
-    DEBUG ((\r
-      EFI_D_INFO,\r
-      "PCI-IOV B%x.D%x.F%x - VF Bar (Offset - 0x%x) 32Mem (Address - 0x%x)\n",\r
-      (UINTN)Node->PciDev->BusNumber,\r
-      (UINTN)Node->PciDev->DeviceNumber,\r
-      (UINTN)Node->PciDev->FunctionNumber,\r
-      (UINTN)(Node->PciDev->VfPciBar[Node->Bar]).Offset,\r
-      (UINTN)Address\r
-      ));\r
-\r
     break;\r
 \r
   case PciBarTypeMem64:\r
@@ -1399,17 +1418,6 @@ ProgramVfBar (
                 );\r
 \r
     Node->PciDev->VfPciBar[Node->Bar].BaseAddress = Address;\r
-\r
-    DEBUG ((\r
-      EFI_D_INFO,\r
-      "PCI-IOV B%x.D%x.F%x - VF Bar (Offset - 0x%x) 64Mem (Address - 0x%lx)\n",\r
-      (UINTN)Node->PciDev->BusNumber,\r
-      (UINTN)Node->PciDev->DeviceNumber,\r
-      (UINTN)Node->PciDev->FunctionNumber,\r
-      (UINTN)(Node->PciDev->VfPciBar[Node->Bar]).Offset,\r
-      (UINT64)Address\r
-      ));\r
-\r
     break;\r
 \r
   case PciBarTypeIo16:\r
@@ -1686,123 +1694,6 @@ InitializeResourcePool (
   InitializeListHead (&ResourcePool->ChildList);\r
 }\r
 \r
-\r
-/**\r
-  Get all resource information for given Pci device.\r
-\r
-  @param PciDev         Pci device instance.\r
-  @param IoBridge       Io resource node.\r
-  @param Mem32Bridge    32-bit memory node.\r
-  @param PMem32Bridge   32-bit Pmemory node.\r
-  @param Mem64Bridge    64-bit memory node.\r
-  @param PMem64Bridge   64-bit PMemory node.\r
-  @param IoPool         Link list header for Io resource.\r
-  @param Mem32Pool      Link list header for 32-bit memory.\r
-  @param PMem32Pool     Link list header for 32-bit Prefetchable memory.\r
-  @param Mem64Pool      Link list header for 64-bit memory.\r
-  @param PMem64Pool     Link list header for 64-bit Prefetchable memory.\r
-\r
-**/\r
-VOID\r
-GetResourceMap (\r
-  IN PCI_IO_DEVICE      *PciDev,\r
-  IN PCI_RESOURCE_NODE  **IoBridge,\r
-  IN PCI_RESOURCE_NODE  **Mem32Bridge,\r
-  IN PCI_RESOURCE_NODE  **PMem32Bridge,\r
-  IN PCI_RESOURCE_NODE  **Mem64Bridge,\r
-  IN PCI_RESOURCE_NODE  **PMem64Bridge,\r
-  IN PCI_RESOURCE_NODE  *IoPool,\r
-  IN PCI_RESOURCE_NODE  *Mem32Pool,\r
-  IN PCI_RESOURCE_NODE  *PMem32Pool,\r
-  IN PCI_RESOURCE_NODE  *Mem64Pool,\r
-  IN PCI_RESOURCE_NODE  *PMem64Pool\r
-  )\r
-{\r
-\r
-  PCI_RESOURCE_NODE *Temp;\r
-  LIST_ENTRY        *CurrentLink;\r
-\r
-  CurrentLink = IoPool->ChildList.ForwardLink;\r
-\r
-  //\r
-  // Get Io resource map\r
-  //\r
-  while (CurrentLink != &IoPool->ChildList) {\r
-\r
-    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
-    if (Temp->PciDev == PciDev) {\r
-      *IoBridge = Temp;\r
-    }\r
-\r
-    CurrentLink = CurrentLink->ForwardLink;\r
-  }\r
-\r
-  //\r
-  // Get Mem32 resource map\r
-  //\r
-  CurrentLink = Mem32Pool->ChildList.ForwardLink;\r
-\r
-  while (CurrentLink != &Mem32Pool->ChildList) {\r
-\r
-    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
-    if (Temp->PciDev == PciDev) {\r
-      *Mem32Bridge = Temp;\r
-    }\r
-\r
-    CurrentLink = CurrentLink->ForwardLink;\r
-  }\r
-\r
-  //\r
-  // Get Pmem32 resource map\r
-  //\r
-  CurrentLink = PMem32Pool->ChildList.ForwardLink;\r
-\r
-  while (CurrentLink != &PMem32Pool->ChildList) {\r
-\r
-    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
-    if (Temp->PciDev == PciDev) {\r
-      *PMem32Bridge = Temp;\r
-    }\r
-\r
-    CurrentLink = CurrentLink->ForwardLink;\r
-  }\r
-\r
-  //\r
-  // Get Mem64 resource map\r
-  //\r
-  CurrentLink = Mem64Pool->ChildList.ForwardLink;\r
-\r
-  while (CurrentLink != &Mem64Pool->ChildList) {\r
-\r
-    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
-    if (Temp->PciDev == PciDev) {\r
-      *Mem64Bridge = Temp;\r
-    }\r
-\r
-    CurrentLink = CurrentLink->ForwardLink;\r
-  }\r
-\r
-  //\r
-  // Get Pmem64 resource map\r
-  //\r
-  CurrentLink = PMem64Pool->ChildList.ForwardLink;\r
-\r
-  while (CurrentLink != &PMem64Pool->ChildList) {\r
-\r
-    Temp = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-\r
-    if (Temp->PciDev == PciDev) {\r
-      *PMem64Bridge = Temp;\r
-    }\r
-\r
-    CurrentLink = CurrentLink->ForwardLink;\r
-  }\r
-}\r
-\r
 /**\r
   Destory given resource tree.\r
 \r