Revision: 18821
          http://sourceforge.net/p/edk2/code/18821
Author:   vanjeff
Date:     2015-11-16 08:19:27 +0000 (Mon, 16 Nov 2015)
Log Message:
-----------
MdeModulePkg: Fix a PCI resource dumping bug in PciBusDxe driver

The resource dumping logic contains a bug which cannot dump the
resource for hot plug controller correctly. The patch fixes this
bug.

(Sync patch r18718 from main trunk.)

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <[email protected]>
Reviewed-by: Feng Tian <[email protected]>

Revision Links:
--------------
    http://sourceforge.net/p/edk2/code/18718

Modified Paths:
--------------
    branches/UDK2015/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
    branches/UDK2015/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h
    branches/UDK2015/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c

Modified: branches/UDK2015/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
===================================================================
--- branches/UDK2015/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c      
2015-11-16 08:18:40 UTC (rev 18820)
+++ branches/UDK2015/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c      
2015-11-16 08:19:27 UTC (rev 18821)
@@ -316,6 +316,81 @@
 }
 
 /**
+  Dump the PPB padding resource information.
+
+  @param PciIoDevice     PCI IO instance.
+  @param ResourceType    The desired resource type to dump.
+                         PciBarTypeUnknown means to dump all types of 
resources.
+**/
+VOID
+DumpPpbPaddingResource (
+  IN PCI_IO_DEVICE                    *PciIoDevice,
+  IN PCI_BAR_TYPE                     ResourceType
+  )
+{
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
+  PCI_BAR_TYPE                      Type;
+
+  if (PciIoDevice->ResourcePaddingDescriptors == NULL) {
+    return;
+  }
+
+  if (ResourceType == PciBarTypeIo16 || ResourceType == PciBarTypeIo32) {
+    ResourceType = PciBarTypeIo;
+  }
+
+  for (Descriptor = PciIoDevice->ResourcePaddingDescriptors; Descriptor->Desc 
!= ACPI_END_TAG_DESCRIPTOR; Descriptor++) {
+
+    Type = PciBarTypeUnknown;
+    if (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && 
Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) {
+      Type = PciBarTypeIo;
+    } else if (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && 
Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
+
+      if (Descriptor->AddrSpaceGranularity == 32) {
+        //
+        // prefechable
+        //
+        if (Descriptor->SpecificFlag == 
EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) {
+          Type = PciBarTypePMem32;
+        }
+
+        //
+        // Non-prefechable
+        //
+        if (Descriptor->SpecificFlag == 0) {
+          Type = PciBarTypeMem32;
+        }
+      }
+
+      if (Descriptor->AddrSpaceGranularity == 64) {
+        //
+        // prefechable
+        //
+        if (Descriptor->SpecificFlag == 
EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) {
+          Type = PciBarTypePMem64;
+        }
+
+        //
+        // Non-prefechable
+        //
+        if (Descriptor->SpecificFlag == 0) {
+          Type = PciBarTypeMem64;
+        }
+      }
+    }
+
+    if ((Type != PciBarTypeUnknown) && ((ResourceType == PciBarTypeUnknown) || 
(ResourceType == Type))) {
+      DEBUG ((
+        EFI_D_INFO,
+        "   Padding: Type = %s; Alignment = 0x%lx;\tLength = 0x%lx\n",
+        mBarTypeStr[Type], Descriptor->AddrRangeMax, Descriptor->AddrLen
+        ));
+    }
+  }
+
+}
+
+/**
   Dump the PCI BAR information.
 
   @param PciIoDevice     PCI IO instance.
@@ -577,7 +652,10 @@
 
   GetResourcePaddingPpb (PciIoDevice);
 
-  DEBUG_CODE (DumpPciBars (PciIoDevice););
+  DEBUG_CODE (
+    DumpPpbPaddingResource (PciIoDevice, PciBarTypeUnknown);
+    DumpPciBars (PciIoDevice);
+  );
 
   return PciIoDevice;
 }

Modified: branches/UDK2015/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h
===================================================================
--- branches/UDK2015/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h      
2015-11-16 08:18:40 UTC (rev 18820)
+++ branches/UDK2015/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h      
2015-11-16 08:19:27 UTC (rev 18821)
@@ -1,7 +1,7 @@
 /** @file
   PCI emumeration support functions declaration for PCI Bus module.
 
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD 
License
 which accompanies this distribution.  The full text of the license may be 
found at
@@ -460,4 +460,17 @@
   IN UINT8                              StartBusNumber
   );
 
+/**
+  Dump the PPB padding resource information.
+
+  @param PciIoDevice     PCI IO instance.
+  @param ResourceType    The desired resource type to dump.
+                         PciBarTypeUnknown means to dump all types of 
resources.
+**/
+VOID
+DumpPpbPaddingResource (
+  IN PCI_IO_DEVICE                    *PciIoDevice,
+  IN PCI_BAR_TYPE                     ResourceType
+  );
+
 #endif

Modified: branches/UDK2015/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
===================================================================
--- branches/UDK2015/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c    2015-11-16 
08:18:40 UTC (rev 18820)
+++ branches/UDK2015/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c    2015-11-16 
08:19:27 UTC (rev 18821)
@@ -1,7 +1,8 @@
 /** @file
   Internal library implementation for PCI Bus module.
 
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD 
License
 which accompanies this distribution.  The full text of the license may be 
found at
@@ -187,19 +188,21 @@
       BridgeResource->PciDev->PciBar[BridgeResource->Bar].BaseAddress,
       BridgeResource->Length, BridgeResource->Alignment
       ));
-    for ( Link = BridgeResource->ChildList.ForwardLink
-        ; Link != &BridgeResource->ChildList
-        ; Link = Link->ForwardLink
+    for ( Link = GetFirstNode (&BridgeResource->ChildList)
+        ; !IsNull (&BridgeResource->ChildList, Link)
+        ; Link = GetNextNode (&BridgeResource->ChildList, Link)
         ) {
       Resource = RESOURCE_NODE_FROM_LINK (Link);
       if (Resource->ResourceUsage == PciResUsageTypical) {
         Bar = Resource->Virtual ? Resource->PciDev->VfPciBar : 
Resource->PciDev->PciBar;
         DEBUG ((
-          EFI_D_INFO, " Base = 0x%lx;\tLength = 0x%lx;\tAlignment = 
0x%lx;\tOwner = %s ",
+          EFI_D_INFO, "   Base = 0x%lx;\tLength = 0x%lx;\tAlignment = 
0x%lx;\tOwner = %s [%02x|%02x|%02x:",
           Bar[Resource->Bar].BaseAddress, Resource->Length, 
Resource->Alignment,
           IS_PCI_BRIDGE (&Resource->PciDev->Pci)     ? L"PPB" :
           IS_CARDBUS_BRIDGE (&Resource->PciDev->Pci) ? L"P2C" :
-                                                       L"PCI"
+                                                       L"PCI",
+          Resource->PciDev->BusNumber, Resource->PciDev->DeviceNumber,
+          Resource->PciDev->FunctionNumber
           ));
 
         if ((!IS_PCI_BRIDGE (&Resource->PciDev->Pci) && !IS_CARDBUS_BRIDGE 
(&Resource->PciDev->Pci)) ||
@@ -209,24 +212,20 @@
           //
           // The resource requirement comes from the device itself.
           //
-          DEBUG ((
-            EFI_D_INFO, " [%02x|%02x|%02x:%02x]\n",
-            Resource->PciDev->BusNumber, Resource->PciDev->DeviceNumber,
-            Resource->PciDev->FunctionNumber, Bar[Resource->Bar].Offset
-            ));
+          DEBUG ((EFI_D_INFO, "%02x]", Bar[Resource->Bar].Offset));
         } else {
           //
           // The resource requirement comes from the subordinate devices.
           //
-          DEBUG ((
-            EFI_D_INFO, " [%02x|%02x|%02x:**]\n",
-            Resource->PciDev->BusNumber, Resource->PciDev->DeviceNumber,
-            Resource->PciDev->FunctionNumber
-            ));
+          DEBUG ((EFI_D_INFO, "**]"));
         }
       } else {
-        DEBUG ((EFI_D_INFO, " Padding:Length = 0x%lx;\tAlignment = 0x%lx\n", 
Resource->Length, Resource->Alignment));
+        DEBUG ((EFI_D_INFO, "   Base = Padding;\tLength = 0x%lx;\tAlignment = 
0x%lx", Resource->Length, Resource->Alignment));
       }
+      if (BridgeResource->ResType != Resource->ResType) {
+        DEBUG ((EFI_D_INFO, "; Type = %s", mBarTypeStr[MIN (Resource->ResType, 
PciBarTypeMaxType)]));
+      }
+      DEBUG ((EFI_D_INFO, "\n"));
     }
   }
 }
@@ -234,63 +233,61 @@
 /**
   Find the corresponding resource node for the Device in child list of 
BridgeResource.
   
-  @param[in] Device         Pointer to PCI_IO_DEVICE.
-  @param[in] BridgeResource Pointer to PCI_RESOURCE_NODE.
+  @param[in]  Device          Pointer to PCI_IO_DEVICE.
+  @param[in]  BridgeResource  Pointer to PCI_RESOURCE_NODE.
+  @param[out] DeviceResources Pointer to a buffer to receive resources for the 
Device.
   
-  @return !NULL  The corresponding resource node for the Device.
-  @return NULL   No corresponding resource node for the Device.
+  @return Count of the resource descriptors returned.
 **/
-PCI_RESOURCE_NODE *
+UINTN
 FindResourceNode (
-  IN PCI_IO_DEVICE     *Device,
-  IN PCI_RESOURCE_NODE *BridgeResource
+  IN  PCI_IO_DEVICE     *Device,
+  IN  PCI_RESOURCE_NODE *BridgeResource,
+  OUT PCI_RESOURCE_NODE **DeviceResources OPTIONAL
   )
 {
   LIST_ENTRY               *Link;
   PCI_RESOURCE_NODE        *Resource;
+  UINTN                    Count;
 
+  Count = 0;
   for ( Link = BridgeResource->ChildList.ForwardLink
       ; Link != &BridgeResource->ChildList
       ; Link = Link->ForwardLink
       ) {
     Resource = RESOURCE_NODE_FROM_LINK (Link);
     if (Resource->PciDev == Device) {
-      return Resource;
+      if (DeviceResources != NULL) {
+        DeviceResources[Count] = Resource;
+      }
+      Count++;
     }
   }
 
-  return NULL;
+  return Count;
 }
 
 /**
   Dump the resource map of all the devices under Bridge.
   
-  @param[in] Bridge     Bridge device instance.
-  @param[in] IoNode     IO resource descriptor for the bridge device.
-  @param[in] Mem32Node  Mem32 resource descriptor for the bridge device.
-  @param[in] PMem32Node PMem32 resource descriptor for the bridge device.
-  @param[in] Mem64Node  Mem64 resource descriptor for the bridge device.
-  @param[in] PMem64Node PMem64 resource descriptor for the bridge device.
+  @param[in] Bridge        Bridge device instance.
+  @param[in] Resources     Resource descriptors for the bridge device.
+  @param[in] ResourceCount Count of resource descriptors.
 **/
 VOID
 DumpResourceMap (
   IN PCI_IO_DEVICE     *Bridge,
-  IN PCI_RESOURCE_NODE *IoNode,
-  IN PCI_RESOURCE_NODE *Mem32Node,
-  IN PCI_RESOURCE_NODE *PMem32Node,
-  IN PCI_RESOURCE_NODE *Mem64Node,
-  IN PCI_RESOURCE_NODE *PMem64Node
+  IN PCI_RESOURCE_NODE **Resources,
+  IN UINTN             ResourceCount
   )
 {
-  EFI_STATUS                       Status;
-  LIST_ENTRY                       *Link;
-  PCI_IO_DEVICE                    *Device;
-  PCI_RESOURCE_NODE                *ChildIoNode;
-  PCI_RESOURCE_NODE                *ChildMem32Node;
-  PCI_RESOURCE_NODE                *ChildPMem32Node;
-  PCI_RESOURCE_NODE                *ChildMem64Node;
-  PCI_RESOURCE_NODE                *ChildPMem64Node;
-  CHAR16                           *Str;
+  EFI_STATUS           Status;
+  LIST_ENTRY           *Link;
+  PCI_IO_DEVICE        *Device;
+  UINTN                Index;
+  CHAR16               *Str;
+  PCI_RESOURCE_NODE    **ChildResources;
+  UINTN                ChildResourceCount;
 
   DEBUG ((EFI_D_INFO, "PciBus: Resource Map for "));
 
@@ -319,11 +316,9 @@
     }
   }
 
-  DumpBridgeResource (IoNode);
-  DumpBridgeResource (Mem32Node);
-  DumpBridgeResource (PMem32Node);
-  DumpBridgeResource (Mem64Node);
-  DumpBridgeResource (PMem64Node);
+  for (Index = 0; Index < ResourceCount; Index++) {
+    DumpBridgeResource (Resources[Index]);
+  }
   DEBUG ((EFI_D_INFO, "\n"));
 
   for ( Link = Bridge->ChildList.ForwardLink
@@ -333,20 +328,19 @@
     Device = PCI_IO_DEVICE_FROM_LINK (Link);
     if (IS_PCI_BRIDGE (&Device->Pci)) {
 
-      ChildIoNode     = (IoNode     == NULL ? NULL : FindResourceNode (Device, 
IoNode));
-      ChildMem32Node  = (Mem32Node  == NULL ? NULL : FindResourceNode (Device, 
Mem32Node));
-      ChildPMem32Node = (PMem32Node == NULL ? NULL : FindResourceNode (Device, 
PMem32Node));
-      ChildMem64Node  = (Mem64Node  == NULL ? NULL : FindResourceNode (Device, 
Mem64Node));
-      ChildPMem64Node = (PMem64Node == NULL ? NULL : FindResourceNode (Device, 
PMem64Node));
+      ChildResourceCount = 0;
+      for (Index = 0; Index < ResourceCount; Index++) {
+        ChildResourceCount += FindResourceNode (Device, Resources[Index], 
NULL);
+      }
+      ChildResources = AllocatePool (sizeof (PCI_RESOURCE_NODE *) * 
ChildResourceCount);
+      ASSERT (ChildResources != NULL);
+      ChildResourceCount = 0;
+      for (Index = 0; Index < ResourceCount; Index++) {
+        ChildResourceCount += FindResourceNode (Device, Resources[Index], 
&ChildResources[ChildResourceCount]);
+      }
 
-      DumpResourceMap (
-        Device,
-        ChildIoNode,
-        ChildMem32Node,
-        ChildPMem32Node,
-        ChildMem64Node,
-        ChildPMem64Node
-        );
+      DumpResourceMap (Device, ChildResources, ChildResourceCount);
+      FreePool (ChildResources);
     }
   }
 }
@@ -806,11 +800,11 @@
     // Create the entire system resource map from the information collected by
     // enumerator. Several resource tree was created
     //
-    IoBridge     = FindResourceNode (RootBridgeDev, &IoPool);
-    Mem32Bridge  = FindResourceNode (RootBridgeDev, &Mem32Pool);
-    PMem32Bridge = FindResourceNode (RootBridgeDev, &PMem32Pool);
-    Mem64Bridge  = FindResourceNode (RootBridgeDev, &Mem64Pool);
-    PMem64Bridge = FindResourceNode (RootBridgeDev, &PMem64Pool);
+    FindResourceNode (RootBridgeDev, &IoPool, &IoBridge);
+    FindResourceNode (RootBridgeDev, &Mem32Pool, &Mem32Bridge);
+    FindResourceNode (RootBridgeDev, &PMem32Pool, &PMem32Bridge);
+    FindResourceNode (RootBridgeDev, &Mem64Pool, &Mem64Bridge);
+    FindResourceNode (RootBridgeDev, &PMem64Pool, &PMem64Bridge);
 
     ASSERT (IoBridge     != NULL);
     ASSERT (Mem32Bridge  != NULL);
@@ -868,14 +862,13 @@
     // Dump the resource map for current root bridge
     //
     DEBUG_CODE (
-      DumpResourceMap (
-        RootBridgeDev,
-        IoBridge,
-        Mem32Bridge,
-        PMem32Bridge,
-        Mem64Bridge,
-        PMem64Bridge
-        );
+      PCI_RESOURCE_NODE *Resources[5];
+      Resources[0] = IoBridge;
+      Resources[1] = Mem32Bridge;
+      Resources[2] = PMem32Bridge;
+      Resources[3] = Mem64Bridge;
+      Resources[4] = PMem64Bridge;
+      DumpResourceMap (RootBridgeDev, Resources, sizeof (Resources) / sizeof 
(Resources[0]));
     );
 
     FreePool (AcpiConfig);
@@ -1022,6 +1015,13 @@
                 Func
                 );
 
+      if (EFI_ERROR (Status) && Func == 0) {
+        //
+        // go to next device if there is no Function 0
+        //
+        break;
+      }
+
       if (EFI_ERROR (Status)) {
         continue;
       }


------------------------------------------------------------------------------
Presto, an open source distributed SQL query engine for big data, initially
developed by Facebook, enables you to easily query your data on Hadoop in a 
more interactive manner. Teradata is also now providing full enterprise
support for Presto. Download a free open source copy now.
http://pubads.g.doubleclick.net/gampad/clk?id=250295911&iu=/4140
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to