[edk2-devel] [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 02/12] MdeModulePkg/PciBusDxe: Setup PCI Express init phase

Javeed, Ashraf posted 12 patches 4 years, 9 months ago
[edk2-devel] [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 02/12] MdeModulePkg/PciBusDxe: Setup PCI Express init phase
Posted by Javeed, Ashraf 4 years, 9 months ago
References:-
  https://bugzilla.tianocore.org/show_bug.cgi?id=1954
  https://bugzilla.tianocore.org/show_bug.cgi?id=2194
  https://bugzilla.tianocore.org/show_bug.cgi?id=2313
  https://bugzilla.tianocore.org/show_bug.cgi?id=2499
  https://bugzilla.tianocore.org/show_bug.cgi?id=2500

This code change represents the preparation of phase for initializing
the PCI Express features at the end of PCI enumeration phase.

Signed-off-by: Ashraf Javeed <ashraf.javeed@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
---
 MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c  | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
 MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h |  23 +++++++++++++++++++++++
 2 files changed, 169 insertions(+), 35 deletions(-)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
index b7832c6..07ee9ba 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
@@ -1,7 +1,7 @@
 /** @file
   Supporting functions implementation for PCI devices management.
 
-Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
 (C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -597,7 +597,7 @@ DeRegisterPciDevice (
 }
 
 /**
-  Start to manage the PCI device on the specified root bridge or PCI-PCI Bridge.
+  Start the PCI root Ports or PCI-PCI Bridge only.
 
   @param Controller          The root bridge handle.
   @param RootBridge          A pointer to the PCI_IO_DEVICE.
@@ -612,7 +612,82 @@ DeRegisterPciDevice (
 
 **/
 EFI_STATUS
-StartPciDevicesOnBridge (
+EnablePciBridges (
+  IN EFI_HANDLE                          Controller,
+  IN PCI_IO_DEVICE                       *RootBridge
+  )
+
+{
+  PCI_IO_DEVICE             *PciIoDevice;
+  EFI_STATUS                Status;
+  LIST_ENTRY                *CurrentLink;
+  UINT64                    Supports;
+
+  PciIoDevice = NULL;
+  CurrentLink = RootBridge->ChildList.ForwardLink;
+
+  while (CurrentLink != NULL && CurrentLink != &RootBridge->ChildList) {
+
+    PciIoDevice = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
+
+    //
+    // check if the device has been assigned with required resource
+    // and registered
+    //
+    if (!PciIoDevice->Registered && !PciIoDevice->Allocated) {
+      return EFI_NOT_READY;
+    }
+
+    if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {
+      Status = EnablePciBridges (
+                 Controller,
+                 PciIoDevice
+                 );
+
+      PciIoDevice->PciIo.Attributes (
+                           &(PciIoDevice->PciIo),
+                           EfiPciIoAttributeOperationSupported,
+                           0,
+                           &Supports
+                         );
+      Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
+      PciIoDevice->PciIo.Attributes (
+                           &(PciIoDevice->PciIo),
+                           EfiPciIoAttributeOperationEnable,
+                           Supports,
+                           NULL
+                         );
+
+    }
+
+    CurrentLink = CurrentLink->ForwardLink;
+  }
+
+  if (PciIoDevice == NULL) {
+    return EFI_NOT_FOUND;
+  } else {
+    return EFI_SUCCESS;
+  }
+}
+
+
+/**
+  Register to manage the PCI device on the specified root bridge or PCI-PCI Bridge.
+
+  @param Controller          The root bridge handle.
+  @param RootBridge          A pointer to the PCI_IO_DEVICE.
+  @param RemainingDevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL.
+  @param NumberOfChildren    Children number.
+  @param ChildHandleBuffer   A pointer to the child handle buffer.
+
+  @retval EFI_NOT_READY   Device is not allocated.
+  @retval EFI_UNSUPPORTED Device only support PCI-PCI bridge.
+  @retval EFI_NOT_FOUND   Can not find the specific device.
+  @retval EFI_SUCCESS     Success to start Pci devices on bridge.
+
+**/
+EFI_STATUS
+RegisterPciDevicesOnBridge (
   IN EFI_HANDLE                          Controller,
   IN PCI_IO_DEVICE                       *RootBridge,
   IN EFI_DEVICE_PATH_PROTOCOL            *RemainingDevicePath,
@@ -626,7 +701,6 @@ StartPciDevicesOnBridge (
   EFI_DEVICE_PATH_PROTOCOL  *CurrentDevicePath;
   EFI_STATUS                Status;
   LIST_ENTRY                *CurrentLink;
-  UINT64                    Supports;
 
   PciIoDevice = NULL;
   CurrentLink = RootBridge->ChildList.ForwardLink;
@@ -681,7 +755,7 @@ StartPciDevicesOnBridge (
       // If it is a PPB
       //
       if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {
-        Status = StartPciDevicesOnBridge (
+        Status = RegisterPciDevicesOnBridge (
                    Controller,
                    PciIoDevice,
                    CurrentDevicePath,
@@ -689,20 +763,6 @@ StartPciDevicesOnBridge (
                    ChildHandleBuffer
                    );
 
-        PciIoDevice->PciIo.Attributes (
-                             &(PciIoDevice->PciIo),
-                             EfiPciIoAttributeOperationSupported,
-                             0,
-                             &Supports
-                             );
-        Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
-        PciIoDevice->PciIo.Attributes (
-                             &(PciIoDevice->PciIo),
-                             EfiPciIoAttributeOperationEnable,
-                             Supports,
-                             NULL
-                             );
-
         return Status;
       } else {
 
@@ -733,28 +793,13 @@ StartPciDevicesOnBridge (
       }
 
       if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {
-        Status = StartPciDevicesOnBridge (
+        Status = RegisterPciDevicesOnBridge (
                    Controller,
                    PciIoDevice,
                    RemainingDevicePath,
                    NumberOfChildren,
                    ChildHandleBuffer
                    );
-
-        PciIoDevice->PciIo.Attributes (
-                             &(PciIoDevice->PciIo),
-                             EfiPciIoAttributeOperationSupported,
-                             0,
-                             &Supports
-                             );
-        Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
-        PciIoDevice->PciIo.Attributes (
-                             &(PciIoDevice->PciIo),
-                             EfiPciIoAttributeOperationEnable,
-                             Supports,
-                             NULL
-                             );
-
       }
 
       CurrentLink = CurrentLink->ForwardLink;
@@ -768,6 +813,72 @@ StartPciDevicesOnBridge (
   }
 }
 
+/**
+  Start to manage the PCI device on the specified root bridge or PCI-PCI Bridge.
+
+  @param Controller          The root bridge handle.
+  @param RootBridge          A pointer to the PCI_IO_DEVICE.
+  @param RemainingDevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL.
+  @param NumberOfChildren    Children number.
+  @param ChildHandleBuffer   A pointer to the child handle buffer.
+
+  @retval EFI_NOT_READY   Device is not allocated.
+  @retval EFI_UNSUPPORTED Device only support PCI-PCI bridge.
+  @retval EFI_NOT_FOUND   Can not find the specific device.
+  @retval EFI_SUCCESS     Success to start Pci devices on bridge.
+
+**/
+EFI_STATUS
+StartPciDevicesOnBridge (
+  IN EFI_HANDLE                          Controller,
+  IN PCI_IO_DEVICE                       *RootBridge,
+  IN EFI_DEVICE_PATH_PROTOCOL            *RemainingDevicePath,
+  IN OUT UINT8                           *NumberOfChildren,
+  IN OUT EFI_HANDLE                      *ChildHandleBuffer
+  )
+
+{
+  EFI_STATUS                Status;
+
+  //
+  // first register all the PCI devices
+  //
+  Status = RegisterPciDevicesOnBridge (
+             Controller,
+             RootBridge,
+             RemainingDevicePath,
+             NumberOfChildren,
+             ChildHandleBuffer
+             );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  } else {
+    //
+    // the late configuration of PCI Express features
+    // the platform is required to indicate its requirement for the initialization
+    // of PCI Express features by publishing its protocol
+    //
+    if (
+        gFullEnumeration
+        && IsPciExpressProtocolPresent ()
+    ) {
+
+      Status = EnumeratePciExpressFeatures (
+                Controller,
+                RootBridge
+                );
+    }
+    //
+    // finally start those PCI bridge port devices only
+    //
+    return EnablePciBridges (
+             Controller,
+             RootBridge
+             );
+  }
+}
+
 /**
   Start to manage all the PCI devices it found previously under
   the entire host bridge.
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h
index 2eff8aa..9b7e51f 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h
@@ -223,4 +223,27 @@ typedef struct {
 }PCI_EXPRESS_FEATURE_INITIALIZATION_POINT;
 
 
+
+/**
+  Enumerate all the nodes of the specified root bridge or PCI-PCI Bridge, to
+  configure the other PCI features.
+
+  @param RootBridge          A pointer to the PCI_IO_DEVICE.
+
+  @retval EFI_SUCCESS           The other PCI features configuration during enumeration
+                                of all the nodes of the PCI root bridge instance were
+                                programmed in PCI-compliance pattern along with the
+                                device-specific policy, as applicable.
+  @retval EFI_UNSUPPORTED       One of the override operation maong the nodes of
+                                the PCI hierarchy resulted in a incompatible address
+                                range.
+  @retval EFI_INVALID_PARAMETER The override operation is performed with invalid input
+                                parameters.
+**/
+EFI_STATUS
+EnumeratePciExpressFeatures (
+  IN EFI_HANDLE             Controller,
+  IN PCI_IO_DEVICE          *RootBridge
+  );
+
 #endif
-- 
2.21.0.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#54065): https://edk2.groups.io/g/devel/message/54065
Mute This Topic: https://groups.io/mt/71063074/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-