From: "Javeed, Ashraf" <ashraf.javeed@intel.com>
To: devel@edk2.groups.io
Cc: Ray Ni <ray.ni@intel.com>, Jian J Wang <jian.j.wang@intel.com>,
Hao A Wu <hao.a.wu@intel.com>
Subject: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 06/15] MdeModulePkg/PciBusDxe: Add the framework to init PCIe features
Date: Sun, 10 May 2020 21:44:03 +0530 [thread overview]
Message-ID: <20200510161412.13832-7-ashraf.javeed@intel.com> (raw)
In-Reply-To: <20200510161412.13832-1-ashraf.javeed@intel.com>
REF:
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
The framework introduces two phases for PCIe feature initialization.
The "Scan" phase is optional and only needed by those features that
requires alignment in the entire hierarchy under the root port, such
as MaxPayloadSize. "Scan" phase only reads the device capability and
calculate the aligned setting with the consideration of the device
specific policy returned from platform.
The "Program" phase is mandatory and is to program the settings to
the PCIe configuration.
The first and last phases are fixed ones. First is to call
PciePlatform::GetDevicePolicy() for each device. Last is to call
PciePlatform::NotifyDeviceState() for each device.
Signed-off-by: Ashraf Javeed <ashraf.javeed@intel.com>
Signed-off-by: Ray Ni <ray.ni@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>
Cc: Ashraf Javeed <ashraf.javeed@intel.com>
---
MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 1 +
MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c | 7 ++++++-
MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.h | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 570 insertions(+), 1 deletion(-)
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
index ccf9ffa..c176c05 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
@@ -287,6 +287,7 @@ struct _PCI_IO_DEVICE {
// This field is used to support this case.
//
UINT16 BridgeIoAlignment;
+ EFI_PCI_EXPRESS_DEVICE_POLICY DeviceState;
};
#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
index 62ef184..c110993 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
@@ -831,7 +831,12 @@ StartPciDevicesOnBridge (
// the platform is required to indicate its requirement for the initialization
// of PCI Express features by publishing its protocol
//
-
+ if (gFullEnumeration && (mPciePlatformProtocol != NULL)) {
+ Status = PcieGetPolicy ();
+ if (!EFI_ERROR (Status)) {
+ Status = EnumerateRootBridgePcieFeatures (RootBridge);
+ }
+ }
//
// finally enable those PCI bridges
//
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
index 13d0e0b..20ef0e8 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
@@ -9,6 +9,293 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "PciBus.h"
#include "PcieFeatureSupport.h"
EFI_PCI_EXPRESS_PLATFORM_PROTOCOL *mPciePlatformProtocol;
+GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mPcieFeatureConfigurePhaseStr[] = { L"Scan", L"Program" };
+
+EFI_PCI_EXPRESS_DEVICE_POLICY mPcieDevicePolicyTemplate = {
+ EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO,
+ EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO,
+ EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO,
+ EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO,
+ EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO,
+ EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO,
+ EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO,
+ EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO,
+ EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO,
+ EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO,
+ EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO,
+ EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO,
+ EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mPcieFeatureStr[] = {
+ L"Maximum Payload Size",
+ L"Maximum Read Request Size",
+ L"Extended Tag",
+ L"Relaxed Ordering",
+ L"No-Snoop",
+ L"ASPM",
+ L"Common Clock Configuration",
+ L"Atomic Op",
+ L"LTR",
+ L"PTM",
+ L"Completion Timeout",
+ L"Clock Power Management",
+ L"L1 PM Substates"
+};
+STATIC_ASSERT (
+ ARRAY_SIZE (mPcieFeatureStr) == sizeof (EFI_PCI_EXPRESS_PLATFORM_POLICY), "mPcieFeatureStr doesn't cover all PCI-E features!"
+ );
+
+PCIE_FEATURE_ENTRY mPcieFeatures[] = {
+ { 0, FALSE } // a dummy feature to pass build.
+};
+
+/**
+ Formalizes the device policies by defaulting as NOT_APPLICABLE to the invalid
+ policy values.
+
+ @param DevicePolicy A pointer to the EFI_PCI_EXPRESS_DEVICE_POLICY.
+**/
+VOID
+FormalizeDevicePolicy (
+ EFI_PCI_EXPRESS_DEVICE_POLICY *DevicePolicy
+ )
+{
+ if ((DevicePolicy->MaxPayloadSize > PCIE_MAX_PAYLOAD_SIZE_4096B) &&
+ (DevicePolicy->MaxPayloadSize != EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) &&
+ (DevicePolicy->MaxPayloadSize != EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE)) {
+ //
+ // Treat invalid values as NOT_APPLICABLE.
+ //
+ DevicePolicy->MaxPayloadSize = EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE;
+ }
+
+ if ((DevicePolicy->MaxReadRequestSize > PCIE_MAX_READ_REQ_SIZE_4096B) &&
+ (DevicePolicy->MaxReadRequestSize != EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) &&
+ (DevicePolicy->MaxReadRequestSize != EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE)) {
+ //
+ // Treat invalid values as NOT_APPLICABLE.
+ //
+ DevicePolicy->MaxReadRequestSize = EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE;
+ }
+ if ((DevicePolicy->RelaxedOrdering > 1) &&
+ (DevicePolicy->RelaxedOrdering != EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) &&
+ (DevicePolicy->RelaxedOrdering != EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE)) {
+ //
+ // Treat invalid values as NOT_APPLICABLE.
+ //
+ DevicePolicy->RelaxedOrdering = EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE;
+ }
+ if ((DevicePolicy->NoSnoop > 1) &&
+ (DevicePolicy->NoSnoop != EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) &&
+ (DevicePolicy->NoSnoop != EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE)) {
+ //
+ // Treat invalid values as NOT_APPLICABLE.
+ //
+ DevicePolicy->NoSnoop = EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE;
+ }
+ if ((DevicePolicy->CompletionTimeout > 0x1F) && // Interpret the policy value as BIT[0:4]
+ (DevicePolicy->CompletionTimeout != EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) &&
+ (DevicePolicy->CompletionTimeout != EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE)) {
+ //
+ // Treat invalid values as NOT_APPLICABLE.
+ //
+ DevicePolicy->CompletionTimeout = EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE;
+ }
+ if ((DevicePolicy->Ltr > 1) &&
+ (DevicePolicy->Ltr != EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) &&
+ (DevicePolicy->Ltr != EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE)) {
+ //
+ // Treat invalid values as NOT_APPLICABLE.
+ //
+ DevicePolicy->Ltr = EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE;
+ }
+ if ((DevicePolicy->AtomicOp > 1) &&
+ (DevicePolicy->AtomicOp != EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) &&
+ (DevicePolicy->AtomicOp != EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE)) {
+ //
+ // Treat invalid values as NOT_APPLICABLE.
+ //
+ DevicePolicy->AtomicOp = EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE;
+ }
+ if ((DevicePolicy->ExtendedTag > 2) &&
+ (DevicePolicy->ExtendedTag != EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) &&
+ (DevicePolicy->ExtendedTag != EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE)) {
+ //
+ // Treat invalid values as NOT_APPLICABLE.
+ //
+ DevicePolicy->ExtendedTag = EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE;
+ }
+ if ((DevicePolicy->CommonClockConfiguration != EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) &&
+ (DevicePolicy->CommonClockConfiguration != EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE)) {
+ //
+ // Treat invalid values as NOT_APPLICABLE.
+ //
+ DevicePolicy->CommonClockConfiguration = EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE;
+ }
+}
+
+/**
+ Gets the PCI device-specific platform policy from the PCI Express Platform Protocol.
+ If no PCI Platform protocol is published than setup the PCI feature to predetermined
+ defaults, in order to align all the PCI devices in the PCI hierarchy, as applicable.
+
+ @param PciIoDevice A pointer to PCI_IO_DEVICE
+ @param Level not used
+ @param Context A pointer to the VOID*, which inputs the Root Bridge handle
+
+ @retval EFI_STATUS The direct status from the PCI Express Platform Protocol.
+ The platform returns EFI_SUCCESS along with device policy.
+ The platform returns EFI_UNSUPPORTED when device found but no
+ device policy.
+ The platform returns EFI_INVALID_PARAMETER when device is not
+ found.
+**/
+EFI_STATUS
+PcieGetDevicePolicy (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINTN Level,
+ IN VOID **Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress;
+ EFI_HANDLE RootBridgeHandle;
+
+ ASSERT (Context != NULL);
+ ASSERT (*Context != NULL);
+ RootBridgeHandle = (EFI_HANDLE) *Context;
+
+ PciAddress.Bus = PciIoDevice->BusNumber;
+ PciAddress.Device = PciIoDevice->DeviceNumber;
+ PciAddress.Function = PciIoDevice->FunctionNumber;
+ PciAddress.Register = 0;
+ PciAddress.ExtendedRegister = 0;
+
+ CopyMem (&PciIoDevice->DeviceState, &mPcieDevicePolicyTemplate, sizeof (mPcieDevicePolicyTemplate));
+ Status = mPciePlatformProtocol->GetDevicePolicy (
+ mPciePlatformProtocol,
+ RootBridgeHandle,
+ PciAddress,
+ sizeof (PciIoDevice->DeviceState),
+ &PciIoDevice->DeviceState
+ );
+ // " Device MPS MRRS RO NS CTO LTR\n"
+ DEBUG ((
+ DEBUG_INFO, " %02x|%02x|%02x %03x %04x %02x %02x %03x %03x %08x %06x %03x\n",
+ PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber,
+ PciIoDevice->DeviceState.MaxPayloadSize,
+ PciIoDevice->DeviceState.MaxReadRequestSize,
+ PciIoDevice->DeviceState.RelaxedOrdering,
+ PciIoDevice->DeviceState.NoSnoop,
+ PciIoDevice->DeviceState.CompletionTimeout,
+ PciIoDevice->DeviceState.Ltr,
+ PciIoDevice->DeviceState.AtomicOp,
+ PciIoDevice->DeviceState.ExtendedTag,
+ PciIoDevice->DeviceState.CommonClockConfiguration
+ ));
+ FormalizeDevicePolicy (&PciIoDevice->DeviceState);
+ return Status;
+}
+
+/**
+ Notifies the platform about the current PCI Express state of the device.
+
+ @param PciIoDevice A pointer to PCI_IO_DEVICE
+ @param Level not used
+ @param Context A pointer to the VOID*, not used
+
+ @retval EFI_STATUS The direct status from the PCI Express Platform Protocol
+ @retval EFI_UNSUPPORTED returns when the PCI Express Platform Protocol or its
+ alias PCI Express OVerride Protocol is not present.
+**/
+EFI_STATUS
+PcieNotifyDeviceState (
+ IN PCI_IO_DEVICE *PciIoDevice,
+ IN UINTN Level,
+ IN VOID **Context
+ )
+{
+ EFI_PCI_EXPRESS_DEVICE_STATE PcieDeviceState;
+
+ CopyMem (&PcieDeviceState, &PciIoDevice->DeviceState, sizeof (PciIoDevice->DeviceState));
+
+ return mPciePlatformProtocol->NotifyDeviceState (
+ mPciePlatformProtocol,
+ PciIoDevice->Handle,
+ sizeof (PcieDeviceState),
+ &PcieDeviceState
+ );
+}
+
+/**
+ Updates the default device policy for the PCIe feature.
+
+ @param PlatformPolicyOffset value defines of device policy in the EFI_PCI_EXPRESS_PLATFORM_POLICY
+ @param Enable value TRUE or FALSE.
+**/
+VOID
+EnablePcieFeature (
+ UINTN PlatformPolicyOffset,
+ BOOLEAN Enable
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < ARRAY_SIZE (mPcieFeatures); Index++) {
+ if (mPcieFeatures[Index].PlatformPolicyOffset == PlatformPolicyOffset) {
+ mPcieFeatures[Index].Enable = Enable;
+ break;
+ }
+ }
+
+ //
+ // Update the default device policy based on platform policy.
+ // For disabled features, the device policy is set to EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE;
+ // For enabled features, the device policy is set to EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO.
+ //
+ switch (PlatformPolicyOffset) {
+ case OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, MaxPayloadSize):
+ mPcieDevicePolicyTemplate.MaxPayloadSize = (Enable ? EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO : EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE);
+ break;
+ case OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, MaxReadRequestSize):
+ mPcieDevicePolicyTemplate.MaxReadRequestSize = (Enable ? EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO : EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE);
+ break;
+ case OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, ExtendedTag):
+ mPcieDevicePolicyTemplate.ExtendedTag = (Enable ? EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO : EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE);
+ break;
+ case OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, RelaxedOrdering):
+ mPcieDevicePolicyTemplate.RelaxedOrdering = (Enable ? EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO : EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE);
+ break;
+ case OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, NoSnoop):
+ mPcieDevicePolicyTemplate.NoSnoop = (Enable ? EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO : EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE);
+ break;
+ case OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, Aspm):
+ mPcieDevicePolicyTemplate.AspmControl = (Enable ? EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO : EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE);
+ break;
+ case OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, CommonClockConfiguration):
+ mPcieDevicePolicyTemplate.CommonClockConfiguration = (Enable ? EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO : EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE);
+ break;
+ case OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, AtomicOp):
+ mPcieDevicePolicyTemplate.AtomicOp = (Enable ? EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO : EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE);
+ break;
+ case OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, Ltr):
+ mPcieDevicePolicyTemplate.Ltr = (Enable ? EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO : EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE);
+ break;
+ case OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, Ptm):
+ mPcieDevicePolicyTemplate.Ptm = (Enable ? EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO : EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE);
+ break;
+ case OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, CompletionTimeout):
+ mPcieDevicePolicyTemplate.CompletionTimeout = (Enable ? EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO : EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE);
+ break;
+ case OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, ClockPowerManagement):
+ mPcieDevicePolicyTemplate.ClockPowerManagement = (Enable ? EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO : EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE);
+ break;
+ case OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, L1PmSubstates):
+ mPcieDevicePolicyTemplate.L1PmSubstates = (Enable ? EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO : EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE);;
+ break;
+ }
+}
/**
This function retrieves the PCI Express Platform Protocols published by platform
@@ -42,3 +329,228 @@ InitializePciExpressProtocols (
return Status;
}
+/**
+ The routine calls EFI_PCI_EXPRESS_PLATFORM_PROTOCOL::GetPolicy() to get platform policy
+ regarding which PCI-E features are required to initialize by PCI core (PCI BUS) driver.
+
+ @retval EFI_STATUS Returns the status from the EFI_PCI_EXPRESS_PLATFORM_PROTOCOL::GetPolicy().
+ The protocol returns EFI_SUCCESS along with the platform policy of the list
+ of PCIe features to be initialized.
+ The protocol returns EFI_INVALID_PARAMETER if the input parameters are not
+ correct.
+**/
+EFI_STATUS
+PcieGetPolicy (
+ VOID
+ )
+{
+ UINTN Index;
+ EFI_STATUS Status;
+ EFI_PCI_EXPRESS_PLATFORM_POLICY PciePolicy;
+ EFI_PCI_EXPRESS_PLATFORM_POLICY PciePlatformPolicy;
+
+ ASSERT (mPciePlatformProtocol != NULL);
+ //
+ // Init PciePolicy to all disabled.
+ //
+ ZeroMem (&PciePolicy, sizeof (PciePolicy));
+
+ //
+ // Get PciBus driver's capability
+ //
+ for (Index = 0; Index < ARRAY_SIZE (mPcieFeatures); Index++) {
+ if (mPcieFeatures[Index].PlatformPolicyOffset != sizeof (PciePolicy)) {
+ ASSERT (mPcieFeatures[Index].PlatformPolicyOffset < sizeof (PciePolicy));
+ ((BOOLEAN *) &PciePolicy)[mPcieFeatures[Index].PlatformPolicyOffset] = mPcieFeatures[Index].Enable;
+ }
+ }
+
+ CopyMem (&PciePlatformPolicy, &PciePolicy, sizeof (PciePolicy));
+ Status = mPciePlatformProtocol->GetPolicy (
+ mPciePlatformProtocol,
+ sizeof (PciePlatformPolicy),
+ &PciePlatformPolicy
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Follow platform policy for PCIE features that PciBus driver supports.
+ // Ignore platform policy for PCIE features that PciBus driver doesn't support.
+ //
+ for (Index = 0; Index < sizeof (PciePolicy); Index++) {
+ if (((BOOLEAN *) &PciePolicy)[Index]) {
+ ((BOOLEAN *) &PciePolicy)[Index] = ((BOOLEAN *) &PciePlatformPolicy)[Index];
+ DEBUG ((
+ DEBUG_INFO, "PCIE: PciePlatform::GetPolicy() %s %s\n",
+ ((BOOLEAN *) &PciePlatformPolicy)[Index] ? L"enabled " : L"disabled",
+ mPcieFeatureStr[Index]
+ ));
+
+ } else {
+ if (((BOOLEAN *) &PciePlatformPolicy)[Index]) {
+ DEBUG ((DEBUG_ERROR, "PCIE: %s is NOT supported but enabled by PciePlatform::GetPolicy()! Keep it as disabled.\n", mPcieFeatureStr[Index]));
+ }
+ }
+ }
+
+ EnablePcieFeature (OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, MaxPayloadSize), PciePlatformPolicy.MaxPayloadSize);
+ EnablePcieFeature (OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, MaxReadRequestSize), PciePlatformPolicy.MaxReadRequestSize);
+ EnablePcieFeature (OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, ExtendedTag), PciePlatformPolicy.ExtendedTag);
+ EnablePcieFeature (OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, RelaxedOrdering), PciePlatformPolicy.RelaxedOrdering);
+ EnablePcieFeature (OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, NoSnoop), PciePlatformPolicy.NoSnoop);
+ EnablePcieFeature (OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, Aspm), PciePlatformPolicy.Aspm);
+ EnablePcieFeature (OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, CommonClockConfiguration), PciePlatformPolicy.CommonClockConfiguration);
+ EnablePcieFeature (OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, AtomicOp), PciePlatformPolicy.AtomicOp);
+ EnablePcieFeature (OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, Ltr), PciePlatformPolicy.Ltr);
+ EnablePcieFeature (OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, Ptm), PciePlatformPolicy.Ptm);
+ EnablePcieFeature (OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, CompletionTimeout), PciePlatformPolicy.CompletionTimeout);
+ EnablePcieFeature (OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, ClockPowerManagement), PciePlatformPolicy.ClockPowerManagement);
+ EnablePcieFeature (OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, L1PmSubstates), PciePlatformPolicy.L1PmSubstates);
+ }
+ return Status;
+}
+
+/**
+ Enumerates the PCIe devices in pre-order (parent to child) or in post-order
+ (child first than parent) path.
+
+ @param Bridge A pointer to the PCI_IO_DEVICE.
+ @param PreOrder value TRUE is for pre-order and FALSE for post-order.
+ @param Routine A pointer to the function of PCIE_FEATURE_CONFIGURE, for phase scan and program.
+ @param Level value advance by 1 for recursive calls.
+ @param Context A pointer to the VOID pointer.
+
+**/
+VOID
+EnumeratePcieDevices (
+ PCI_IO_DEVICE *Bridge,
+ BOOLEAN PreOrder,
+ PCIE_FEATURE_CONFIGURE Routine,
+ UINTN Level,
+ VOID **Context
+)
+{
+ LIST_ENTRY *Link;
+ PCI_IO_DEVICE *PciIoDevice;
+
+ if (PreOrder) {
+ Routine (Bridge, Level, Context);
+ }
+
+ for ( Link = GetFirstNode (&Bridge->ChildList)
+ ; !IsNull (&Bridge->ChildList, Link)
+ ; Link = GetNextNode (&Bridge->ChildList, Link)
+ ) {
+ PciIoDevice = PCI_IO_DEVICE_FROM_LINK (Link);
+ if (PciIoDevice->IsPciExp) {
+ EnumeratePcieDevices (PciIoDevice, PreOrder, Routine, Level + 1, Context);
+ }
+ }
+
+ if (!PreOrder) {
+ Routine (Bridge, Level, Context);
+ }
+}
+
+/**
+ 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
+EnumerateRootBridgePcieFeatures (
+ IN PCI_IO_DEVICE *RootBridge
+ )
+{
+ UINTN Index;
+ LIST_ENTRY *Link;
+ PCI_IO_DEVICE *PciDevice;
+ VOID *Context[ARRAY_SIZE (mPcieFeatures)];
+ PCIE_FEATURE_CONFIGURATION_PHASE Phase;
+
+ DEBUG_CODE (
+ CHAR16 *Str;
+ Str = ConvertDevicePathToText (RootBridge->DevicePath, FALSE, FALSE);
+ DEBUG ((DEBUG_INFO, "%a: %s ...\n", __FUNCTION__, Str != NULL ? Str : L"<no-devicepath>"));
+
+ if (Str != NULL) {
+ FreePool (Str);
+ }
+ );
+
+ for ( Link = GetFirstNode (&RootBridge->ChildList)
+ ; !IsNull (&RootBridge->ChildList, Link)
+ ; Link = GetNextNode (&RootBridge->ChildList, Link)
+ ) {
+ PciDevice = PCI_IO_DEVICE_FROM_LINK (Link);
+ if (!PciDevice->IsPciExp) {
+ continue;
+ }
+
+ //
+ // Some features such as MaxPayloadSize requires the settings in the heirarchy are aligned.
+ // Context[Index] holds the feature specific settings in current heirarchy/device-tree.
+ //
+ SetMem (&Context[0], ARRAY_SIZE (mPcieFeatures) * sizeof (VOID*), 0);
+ //
+ // First feature is not a real PCIE feature, but to query device policy.
+ // RootBridge handle is Context passed in.
+ //
+ DEBUG ((
+ DEBUG_INFO,
+ " GetDevicePolicy phase ...\n"
+ " Device MPS MRRS RO NS CTO LTR AtomicOp ExtTag CCC\n"
+ ));
+ EnumeratePcieDevices (PciDevice, TRUE, PcieGetDevicePolicy, 0, &RootBridge->Handle);
+
+ DEBUG ((DEBUG_INFO, "PCIE[%02x|%02x|%02x] ...\n", PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber));
+ //
+ // For each heirachy/device-tree, firstly scan recursively to align the settings then program
+ // the aligned settings recursively.
+ //
+ for (Phase = PcieFeatureScan; Phase < PcieFeatureConfigurationPhaseMax; Phase++) {
+ DEBUG ((DEBUG_INFO, " %s phase ...\n", mPcieFeatureConfigurePhaseStr[Phase]));
+ for (Index = 0; Index < ARRAY_SIZE (mPcieFeatures); Index++) {
+ if (!mPcieFeatures[Index].Enable) {
+ continue;
+ }
+
+ if (mPcieFeatures[Index].Configure[Phase] == NULL) {
+ continue;
+ }
+ //DEBUG ((DEBUG_INFO, " PCIe %s feature...\n", mPcieFeatureStr[Index]));
+ EnumeratePcieDevices (
+ PciDevice,
+ mPcieFeatures[Index].PreOrder[Phase],
+ mPcieFeatures[Index].Configure[Phase],
+ 0,
+ &Context[Index]
+ );
+ }
+ }
+
+ for (Index = 0; Index < ARRAY_SIZE (mPcieFeatures); Index++) {
+ if (Context[Index] != NULL) {
+ FreePool (Context[Index]);
+ }
+ }
+
+ //
+ // Report device state for all devices in the same heirarchy.
+ //
+ DEBUG ((DEBUG_INFO, " NotifyDeviceState phase ...\n"));
+ EnumeratePcieDevices (PciDevice, TRUE, PcieNotifyDeviceState, 0, NULL);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.h
index 5d15e0a..7aff123 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.h
@@ -9,6 +9,27 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#ifndef __PCIE_FEATURE_SUPPORT_H__
#define __PCIE_FEATURE_SUPPORT_H__
+typedef
+EFI_STATUS
+(* PCIE_FEATURE_CONFIGURE) (
+ IN PCI_IO_DEVICE *PciDevice,
+ IN UINTN Level,
+ IN VOID **Context
+ );
+
+typedef enum {
+ PcieFeatureScan,
+ PcieFeatureProgram,
+ PcieFeatureConfigurationPhaseMax
+} PCIE_FEATURE_CONFIGURATION_PHASE;
+
+typedef struct {
+ UINTN PlatformPolicyOffset;
+ BOOLEAN Enable;
+ BOOLEAN PreOrder[PcieFeatureConfigurationPhaseMax];
+ PCIE_FEATURE_CONFIGURE Configure[PcieFeatureConfigurationPhaseMax];
+} PCIE_FEATURE_ENTRY;
+
extern EFI_PCI_EXPRESS_PLATFORM_PROTOCOL *mPciePlatformProtocol;
/**
This function retrieves the PCI Express Platform Protocols published by platform
@@ -22,4 +43,34 @@ InitializePciExpressProtocols (
);
+/**
+ The routine calls EFI_PCI_EXPRESS_PLATFORM_PROTOCOL::GetPolicy() to get platform policy
+ regarding which PCI-E features are required to initialize by PCI core (PCI BUS) driver.
+**/
+EFI_STATUS
+PcieGetPolicy (
+ VOID
+ );
+
+/**
+ 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 among 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
+EnumerateRootBridgePcieFeatures (
+ IN PCI_IO_DEVICE *RootBridge
+ );
+
#endif
--
2.21.0.windows.1
next prev parent reply other threads:[~2020-05-10 16:14 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20200510161412.13832-1-ashraf.javeed@intel.com>
2020-05-10 16:13 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 01/15] MdePkg/Protocols: Deprecated the EFI encoded macros Javeed, Ashraf
2020-05-13 8:21 ` Ni, Ray
2020-05-10 16:13 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 02/15] MdeModulePkg/PciBusDxe: PciBusDxe Code refactor Javeed, Ashraf
2020-05-13 6:31 ` Ni, Ray
2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 03/15] MdeModulePkg/PciBus: Rename Cache PCIe Capability Structure Javeed, Ashraf
2020-05-13 6:31 ` Ni, Ray
2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 04/15] MdeModulePkg/PciBusDxe: Refactor the PCIe Bridge enable Javeed, Ashraf
2020-05-13 6:31 ` Ni, Ray
2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 05/15] MdeModulePkg/PciBusDxe: Locate PciePlatform/PcieOverride protocol Javeed, Ashraf
2020-05-13 6:31 ` Ni, Ray
2020-05-10 16:14 ` Javeed, Ashraf [this message]
2020-05-13 6:39 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 06/15] MdeModulePkg/PciBusDxe: Add the framework to init PCIe features Ni, Ray
2020-05-13 6:46 ` Javeed, Ashraf
2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 07/15] MdeModulePkg/PciBusDxe: Enable MaxPayloadSize feature Javeed, Ashraf
2020-05-13 6:45 ` Ni, Ray
2020-05-13 6:54 ` Javeed, Ashraf
2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 08/15] MdeModulePkg/PciBusDxe: Enable MaxReadRequestSize feature Javeed, Ashraf
2020-05-13 6:49 ` Ni, Ray
2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 09/15] MdeModulePkg/PciBusDxe: Enable RelaxedOrdering feature Javeed, Ashraf
2020-05-13 6:49 ` Ni, Ray
2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 10/15] MdeModulePkg/PciBusDxe: Enable NoSnoop feature Javeed, Ashraf
2020-05-13 6:49 ` Ni, Ray
2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 11/15] MdeModulePkg/PciBusDxe: Enable CompletionTimeout feature Javeed, Ashraf
2020-05-13 6:49 ` Ni, Ray
2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 12/15] MdeModulePkg/PciBusDxe: Enable LTR feature Javeed, Ashraf
2020-05-13 6:49 ` Ni, Ray
2020-05-13 7:10 ` Javeed, Ashraf
2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 13/15] MdeModulePkg/PciBusDxe: Enable AtomicOp feature Javeed, Ashraf
2020-05-13 6:51 ` [edk2-devel] " Ni, Ray
2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 14/15] MdeModulePkg/PciBusDxe: Enable ExtendedTag feature Javeed, Ashraf
2020-05-13 8:09 ` [edk2-devel] " Ni, Ray
2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 15/15] MdeModulePkg/PciBusDxe: Enable CommonClockConfiguration feature Javeed, Ashraf
2020-05-13 8:19 ` Ni, Ray
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200510161412.13832-7-ashraf.javeed@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox