]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/PciBus: Count multiple hotplug resource paddings
authorRuiyu Ni <ruiyu.ni@intel.com>
Sat, 30 Sep 2017 05:10:08 +0000 (13:10 +0800)
committerRuiyu Ni <ruiyu.ni@intel.com>
Mon, 9 Oct 2017 02:41:29 +0000 (10:41 +0800)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=720

The current implementation assumes there is only one hotplug resource
padding for each resource type. It's not true considering
DegradeResource(): MEM64 resource could be degraded to MEM32
resource.

The patch treat the resource paddings using the same logic as
treating typical/actual resources and the total resource of a bridge
is set to the MAX of typical/actual resources and resource paddings.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c

index e93134613b488aad1b8c4fa5069500760769d562..8dbe9a00380f253873f245d2bcb98269d5e5f314 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   PCI resouces support functions implemntation for PCI Bus module.\r
 \r
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2017, 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
@@ -343,14 +343,9 @@ CalculateResourceAperture (
   IN PCI_RESOURCE_NODE    *Bridge\r
   )\r
 {\r
-  UINT64            Aperture;\r
+  UINT64            Aperture[2];\r
   LIST_ENTRY        *CurrentLink;\r
   PCI_RESOURCE_NODE *Node;\r
-  UINT64            PaddingAperture;\r
-  UINT64            Offset;\r
-\r
-  Aperture        = 0;\r
-  PaddingAperture = 0;\r
 \r
   if (Bridge == NULL) {\r
     return ;\r
@@ -362,6 +357,8 @@ CalculateResourceAperture (
     return ;\r
   }\r
 \r
+  Aperture[PciResUsageTypical] = 0;\r
+  Aperture[PciResUsagePadding] = 0;\r
   //\r
   // Assume the bridge is aligned\r
   //\r
@@ -369,58 +366,30 @@ CalculateResourceAperture (
       ; !IsNull (&Bridge->ChildList, CurrentLink)\r
       ; CurrentLink = GetNextNode (&Bridge->ChildList, CurrentLink)\r
       ) {\r
-\r
     Node = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
-    if (Node->ResourceUsage == PciResUsagePadding) {\r
-      ASSERT (PaddingAperture == 0);\r
-      PaddingAperture = Node->Length;\r
-      continue;\r
-    }\r
 \r
     //\r
-    // Apply padding resource if available\r
+    // It's possible for a bridge to contain multiple padding resource\r
+    // nodes due to DegradeResource().\r
     //\r
-    Offset = Aperture & (Node->Alignment);\r
-\r
-    if (Offset != 0) {\r
-\r
-      Aperture = Aperture + (Node->Alignment + 1) - Offset;\r
-\r
-    }\r
-\r
+    ASSERT ((Node->ResourceUsage == PciResUsageTypical) ||\r
+            (Node->ResourceUsage == PciResUsagePadding));\r
+    ASSERT (Node->ResourceUsage < ARRAY_SIZE (Aperture));\r
     //\r
     // Recode current aperture as a offset\r
-    // this offset will be used in future real allocation\r
+    // Apply padding resource to meet alignment requirement\r
+    // Node offset will be used in future real allocation\r
     //\r
-    Node->Offset = Aperture;\r
+    Node->Offset = ALIGN_VALUE (Aperture[Node->ResourceUsage], Node->Alignment + 1);\r
 \r
     //\r
-    // Increment aperture by the length of node\r
+    // Record the total aperture.\r
     //\r
-    Aperture += Node->Length;\r
-  }\r
-\r
-  //\r
-  // At last, adjust the aperture with the bridge's\r
-  // alignment\r
-  //\r
-  Offset = Aperture & (Bridge->Alignment);\r
-  if (Offset != 0) {\r
-    Aperture = Aperture + (Bridge->Alignment + 1) - Offset;\r
+    Aperture[Node->ResourceUsage] = Node->Offset + Node->Length;\r
   }\r
 \r
   //\r
-  // If the bridge has already padded the resource and the\r
-  // amount of padded resource is larger, then keep the\r
-  // padded resource\r
-  //\r
-  if (Bridge->Length < Aperture) {\r
-    Bridge->Length = Aperture;\r
-  }\r
-\r
-  //\r
-  // Adjust the bridge's alignment to the first child's alignment\r
-  // if the bridge has at least one child\r
+  // Adjust the bridge's alignment to the MAX (first) alignment of all children.\r
   //\r
   CurrentLink = Bridge->ChildList.ForwardLink;\r
   if (CurrentLink != &Bridge->ChildList) {\r
@@ -430,11 +399,17 @@ CalculateResourceAperture (
     }\r
   }\r
 \r
+  //\r
+  // At last, adjust the aperture with the bridge's alignment\r
+  //\r
+  Aperture[PciResUsageTypical] = ALIGN_VALUE (Aperture[PciResUsageTypical], Bridge->Alignment + 1);\r
+  Aperture[PciResUsagePadding] = ALIGN_VALUE (Aperture[PciResUsagePadding], Bridge->Alignment + 1);\r
+\r
   //\r
   // Hotplug controller needs padding resources.\r
   // Use the larger one between the padding resource and actual occupied resource.\r
   //\r
-  Bridge->Length = MAX (Bridge->Length, PaddingAperture);\r
+  Bridge->Length = MAX (Aperture[PciResUsageTypical], Aperture[PciResUsagePadding]);\r
 }\r
 \r
 /**\r