This patch can also be viewed in the following repo:- https://github.com/ashrafj/edk2-staging/commit/b44091c0f18fd578dbdaf2091145367042bdfba5
Thanks Ashraf > -----Original Message----- > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Javeed, > Ashraf > Sent: Saturday, February 8, 2020 1:35 AM > To: devel@edk2.groups.io > Cc: Wang, Jian J <jian.j.w...@intel.com>; Wu, Hao A <hao.a...@intel.com>; > Ni, Ray <ray...@intel.com> > Subject: [edk2-devel] [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 11/12] > PciBusDxe: New PCI Express feature ASPM support > > BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2500 > > This code change is to enable the common ASPM state for all the connected > devices, as per the PCI Express Base Specification 5, Revision 1. > This feature is not applicable to RCiEP, and to a vacant bridge device. > The device policy request from platform is applied if that is applicable as > per its > Link Capability register. Since all the connected devices have to have common > applicable ASPM value, it would be overuled as per PCI Ex- press Base > Specification. > The device L0s/L1 Acceptance Latency is used to measure against the L0s/L1 > Exit > Latencies comprising from Root Bridge to all its EP devices. If not applicable > ASPM would be disabled for all the devices. > > This programming of ASPM, gets the device-specific platform policy using the > new PCI Express Platform Protocol interface (ECR version 0.8), defined in the > below feature request:- > https://bugzilla.tianocore.org/show_bug.cgi?id=1954 > > Signed-off-by: Ashraf Javeed <ashraf.jav...@intel.com> > Cc: Jian J Wang <jian.j.w...@intel.com> > Cc: Hao A Wu <hao.a...@intel.com> > Cc: Ray Ni <ray...@intel.com> > --- > MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 1 + > MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c | 391 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > + > MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h | 52 > ++++++++++++++++++++++++++++++++++++++++++++++++++++ > MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c | 23 > ++++++++++++++++++++++- > MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h | 14 ++++++++++++++ > MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c | 45 > +++++++++++++++++++++++++++++++++++++++++++++ > 6 files changed, 525 insertions(+), 1 deletion(-) > > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > index 6a6f648..b5caffe 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > @@ -298,6 +298,7 @@ struct _PCI_IO_DEVICE { > EFI_PCI_EXPRESS_ATOMIC_OP SetupAtomicOp; > BOOLEAN SetupLtr; > UINT8 SetupExtTag; > + UINT8 SetupAspm; > }; > > #define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \ diff --git > a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c > index eaef3d3..5e350e7 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c > @@ -1518,3 +1518,394 @@ ProgramExtTag ( > return Status; > } > > +/** > + Set the ASPM device policy as per the device's link capability. > +**/ > +UINT8 > +SetAspmPolicy ( > + IN UINT8 PciExpressLinkCapAspm > + ) > +{ > + switch (PciExpressLinkCapAspm) { > + case 0: > + // > + // cannot support ASPM state, disable > + // > + return EFI_PCI_EXPRESS_ASPM_DISABLE; > + case 1: > + // > + // supports only ASPM L0s state > + // > + return EFI_PCI_EXPRESS_ASPM_L0s_SUPPORT; > + case 2: > + // > + // supports only ASPM L1 state > + // > + return EFI_PCI_EXPRESS_ASPM_L1_SUPPORT; > + case 3: > + // > + // supports both L0s and L1 ASPM states > + // > + return EFI_PCI_EXPRESS_ASPM_L0S_L1_SUPPORT; > + } > + return EFI_PCI_EXPRESS_ASPM_DISABLE; > +} > + > +/** > + The main routine to setup the PCI Express feature ASPM as per the > + device-specific platform policy, as well as in complaince with the > +PCI Express > + Base specification Revision 5. > + > + @param PciDevice A pointer to the PCI_IO_DEVICE. > + @param PciExpressConfigurationTable pointer to > + PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE > + > + @retval EFI_SUCCESS setup of PCI feature LTR is > successful. > +**/ > +EFI_STATUS > +SetupAspm ( > + IN PCI_IO_DEVICE *PciDevice, > + IN PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE > +*PciExpressConfigurationTable > + ) > +{ > + PCI_REG_PCIE_LINK_CAPABILITY PciExLinkCap; > + PCI_REG_PCIE_DEVICE_CAPABILITY PciExpressDeviceCapability; > + BOOLEAN AlignAspmPolicy; > + > + PciExLinkCap.Uint32 = > + PciDevice->PciExpressCapabilityStructure.LinkCapability.Uint32; > + PciExpressDeviceCapability.Uint32 = > + PciDevice->PciExpressCapabilityStructure.DeviceCapability.Uint32; > + // > + // ASPM support is only applicable to root bridge and its child > + devices. Not // applicable to empty bridge devices or RCiEP devices > + // if (PciExpressConfigurationTable) { > + PciExpressConfigurationTable->L0sExitLatency = MAX ( > + PciExpressConfigurationTable->L0sExitLatency, > + (UINT8)PciExLinkCap.Bits.L0sExitLatency > + ); > + PciExpressConfigurationTable->L1ExitLatency = MAX ( > + PciExpressConfigurationTable->L1ExitLatency, > + (UINT8)PciExLinkCap.Bits.L1ExitLatency > + ); > + if (PciDevice->SetupAspm == EFI_PCI_EXPRESS_ASPM_AUTO) { > + // > + // set the ASPM support as per device's link capability > + // > + PciDevice->SetupAspm = SetAspmPolicy ((UINT8)PciExLinkCap.Bits.Aspm); > + } else { > + // > + // Check the ASPM device policy is applicable to the link capability. > + // In case of invalid device policy, there are 2 options: > + // (1) ASPM disable -> platform request rightly denied, and no ASPM > + // (2) set as per the device capability -> platform request rightly > denied, > + // but still set applicable power management > + // this implementation shall take option 2 to overule invalid platform > request > + // and go with applicable policy as per device capability > + // > + switch (SetAspmPolicy ((UINT8)PciExLinkCap.Bits.Aspm)) { > + case EFI_PCI_EXPRESS_ASPM_DISABLE: > + PciDevice->SetupAspm = EFI_PCI_EXPRESS_ASPM_DISABLE; > + break; > + case EFI_PCI_EXPRESS_ASPM_L1_SUPPORT: > + if (PciDevice->SetupAspm == EFI_PCI_EXPRESS_ASPM_L0s_SUPPORT) { > + // > + // not applicable, set as per device's link capability > + // > + PciDevice->SetupAspm = EFI_PCI_EXPRESS_ASPM_L1_SUPPORT; > + } > + break; > + case EFI_PCI_EXPRESS_ASPM_L0s_SUPPORT: > + if (PciDevice->SetupAspm == EFI_PCI_EXPRESS_ASPM_L1_SUPPORT) { > + // > + // not applicable, set as per device's link capability > + // > + PciDevice->SetupAspm = EFI_PCI_EXPRESS_ASPM_L0s_SUPPORT; > + } > + break; > + } > + } > + // > + // set the ASPM policy to minimum state among all the devices links > + // > + PciExpressConfigurationTable->AspmSupport = MIN ( > + > PciExpressConfigurationTable->AspmSupport, > + PciDevice->SetupAspm > + ); > + // > + // check the common ASPM value applicable as per this device capability, > if > + // not applicable disable the ASPM for all the devices > + // > + if ( > + (PciExpressConfigurationTable->AspmSupport == > EFI_PCI_EXPRESS_ASPM_L0s_SUPPORT > + && SetAspmPolicy ((UINT8)PciExLinkCap.Bits.Aspm) == > EFI_PCI_EXPRESS_ASPM_L1_SUPPORT) > + || > + (PciExpressConfigurationTable->AspmSupport == > EFI_PCI_EXPRESS_ASPM_L1_SUPPORT > + && SetAspmPolicy ((UINT8)PciExLinkCap.Bits.Aspm) == > EFI_PCI_EXPRESS_ASPM_L0s_SUPPORT) > + ) { > + // > + // disable the ASPM > + // > + PciExpressConfigurationTable->AspmSupport = > EFI_PCI_EXPRESS_ASPM_DISABLE; > + PciDevice->SetupAspm = PciExpressConfigurationTable->AspmSupport; > + } > + > + if (PciExpressConfigurationTable->AspmSupport != > EFI_PCI_EXPRESS_ASPM_DISABLE) { > + // > + // in case of ASPM policy is not to disable the ASPM support, check > other > + // condition of EP device L0s/L1 acceptance latency with the L0s/L1 > exit > + // latencies comprising from this endpoint all the way up to root > complex > + // root port, to determine whether the ASPM L0s/L1 entry can be used > with > + // no loss of performance > + // > + if (!IS_PCI_BRIDGE (&PciDevice->Pci)) { > + > + switch (PciExpressConfigurationTable->AspmSupport) { > + case EFI_PCI_EXPRESS_ASPM_L0S_L1_SUPPORT: > + if ( > + PciExpressDeviceCapability.Bits.EndpointL0sAcceptableLatency > >= > PciExpressConfigurationTable->L0sExitLatency > + && > PciExpressDeviceCapability.Bits.EndpointL1AcceptableLatency >= > PciExpressConfigurationTable->L1ExitLatency > + ) { > + // > + // both the L0s & L1 acceptance of this endpoint device is > greater > + // than or equal to all of the comprised L0s & L1 exit > latencies > + // thus good to set the ASPM to L0s & L1 state > + // > + AlignAspmPolicy = TRUE; > + } else { > + // > + // in case the EP device L0s and L1 Acceptance latency does > not match > + // with the comprised L0s & L1 exit latencies than disable the > ASPM > + // state > + // > + AlignAspmPolicy = FALSE; > + } > + break; > + > + case EFI_PCI_EXPRESS_ASPM_L1_SUPPORT: > + if ( > + PciExpressDeviceCapability.Bits.EndpointL1AcceptableLatency > >= > PciExpressConfigurationTable->L1ExitLatency > + ) { > + // > + // the endpoint device L1 acceptance latency meets the all the > + // comprised L1 exit latencies of all the devices from the > bridge > + // hence ASPM L1 is applicable state for the PCI tree > + // > + AlignAspmPolicy = TRUE; > + } else { > + // > + // in case the EP device L1 Acceptance latency does not match > + // with the comprised L1 exit latencies than disable the ASPM > + // state > + // > + AlignAspmPolicy = FALSE; > + } > + break; > + > + case EFI_PCI_EXPRESS_ASPM_L0s_SUPPORT: > + if ( > + PciExpressDeviceCapability.Bits.EndpointL0sAcceptableLatency > >= > PciExpressConfigurationTable->L0sExitLatency > + ) { > + // > + // the endpoint device L0s acceptance latency meets the all the > + // comprised L0s exit latencies of all the devices from the > bridge > + // hence ASPM L0s is applicable state for the PCI tree > + // > + AlignAspmPolicy = TRUE; > + } else { > + // > + // in case the EP device L0s Acceptance latency does not match > + // with the comprised L0s exit latencies than disable the ASPM > + // state > + // > + AlignAspmPolicy = FALSE; > + } > + break; > + } > + } else { > + // > + // align the bridge with the global common ASPM value > + // > + AlignAspmPolicy = TRUE; > + } > + } else { > + // > + // ASPM is disabled for all the devices > + // > + AlignAspmPolicy = FALSE; > + } > + > + if (AlignAspmPolicy) { > + // > + // reset the device's ASPM policy to common minimum value > + // > + if (PciDevice->SetupAspm != PciExpressConfigurationTable->AspmSupport) > { > + PciDevice->SetupAspm = PciExpressConfigurationTable->AspmSupport; > + } > + } else { > + // > + // disable the ASPM > + // > + PciExpressConfigurationTable->AspmSupport = > EFI_PCI_EXPRESS_ASPM_DISABLE; > + PciDevice->SetupAspm = PciExpressConfigurationTable->AspmSupport; > + } > + DEBUG (( > + DEBUG_INFO, > + "Aspm: %d [cap:%d],", > + PciDevice->SetupAspm, > + (PciExLinkCap.Bits.Aspm + 1) > + )); > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Setup of PCI Express feature ASPM in the > +PciExpressFeatureEntendedSetupPhase > +**/ > +EFI_STATUS > +AlignAspm ( > + IN PCI_IO_DEVICE *PciDevice, > + IN PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE > +*PciExpressConfigurationTable > + ) > +{ > + // > + // ASPM support is only applicable to root bridge and its child > +devices. Not > + // applicable to empty bridge devices or RCiEP devices > + // > + if (PciExpressConfigurationTable) { > + // > + // reset the device's ASPM policy to common minimum ASPM value > + // > + if (PciDevice->SetupAspm != PciExpressConfigurationTable->AspmSupport) { > + PciDevice->SetupAspm = PciExpressConfigurationTable->AspmSupport; > + } > + DEBUG (( > + DEBUG_INFO, > + "Aspm: %d,", > + PciDevice->SetupAspm > + )); > + } > + > + return EFI_SUCCESS; > +} > + > + > +/** > + Get the ASPM value from the ASPM device policy. > +**/ > +UINT8 > +GetAspmValue ( > + IN UINT8 AspmPolicy > + ) > +{ > + switch (AspmPolicy) { > + case EFI_PCI_EXPRESS_ASPM_DISABLE: > + // > + // ASPM disable > + // > + return 0; > + case EFI_PCI_EXPRESS_ASPM_L0s_SUPPORT: > + // > + // ASPM L0s state > + // > + return 1; > + case EFI_PCI_EXPRESS_ASPM_L1_SUPPORT: > + // > + // ASPM L1 state > + // > + return 2; > + case EFI_PCI_EXPRESS_ASPM_L0S_L1_SUPPORT: > + // > + // L0s and L1 ASPM states > + // > + return 3; > + } > + return 0; > +} > + > +/** > + Program the PCIe Link Control register ASPM Control field; if > + the hardware value is different than the intended value. > + > + @param PciDevice A pointer to the PCI_IO_DEVICE instance. > + > + @retval EFI_SUCCESS The data was read from or written to the PCI > device. > + @retval EFI_UNSUPPORTED The address range specified by Offset, Width, > and Count is not > + valid for the PCI configuration header of > the PCI controller. > + @retval EFI_INVALID_PARAMETER Buffer is NULL or Width is invalid. > + > +**/ > +EFI_STATUS > +ProgramAspm ( > + IN PCI_IO_DEVICE *PciDevice, > + IN VOID *PciExFeatureConfiguration > + ) > +{ > + PCI_REG_PCIE_LINK_CONTROL LinkCtl; > + UINT32 Offset; > + EFI_STATUS Status; > + EFI_TPL OldTpl; > + UINT8 AspmValue; > + > + // > + // ASPM support is only applicable to root bridge and its child > + devices. Not // applicable to empty bridge devices or RCiEP devices > + // if (!PciExFeatureConfiguration) { > + return EFI_SUCCESS; > + } > + > + // > + // read the link Control register for the ASPM Control // > + LinkCtl.Uint16 = 0; > + Offset = PciDevice->PciExpressCapabilityOffset + > + OFFSET_OF (PCI_CAPABILITY_PCIEXP, LinkControl); Status = > + PciDevice->PciIo.Pci.Read ( > + &PciDevice->PciIo, > + EfiPciIoWidthUint16, > + Offset, > + 1, > + &LinkCtl.Uint16 > + ); > + ASSERT (Status == EFI_SUCCESS); > + > + AspmValue = GetAspmValue (PciDevice->SetupAspm); if (AspmValue != > + LinkCtl.Bits.AspmControl) { > + DEBUG (( > + DEBUG_INFO, > + "Aspm: %d,", > + AspmValue > + )); > + // > + // Raise TPL to high level to disable timer interrupt while the write > operation > completes > + // > + OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); > + > + Status = PciDevice->PciIo.Pci.Write ( > + &PciDevice->PciIo, > + EfiPciIoWidthUint16, > + Offset, > + 1, > + &LinkCtl.Uint16 > + ); > + // > + // Restore TPL to its original level > + // > + gBS->RestoreTPL (OldTpl); > + > + if (!EFI_ERROR (Status)) { > + PciDevice->PciExpressCapabilityStructure.LinkControl.Uint16 = > LinkCtl.Uint16; > + } else { > + ReportPciWriteError (PciDevice->BusNumber, PciDevice->DeviceNumber, > PciDevice->FunctionNumber, Offset); > + return Status; > + } > + } else { > + DEBUG (( > + DEBUG_INFO, > + "No Aspm (%d),", > + AspmValue > + )); > + } > + return EFI_SUCCESS; > +} > + > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h > index 1cfca54..351c61e 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h > @@ -9,6 +9,15 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #ifndef > _EFI_PCI_EXPRESS_FEATURES_H_ #define _EFI_PCI_EXPRESS_FEATURES_H_ > > +// > +// PCIe L0s Exit Latencies declarations // > +#define PCIE_LINK_CAPABILITY_L0S_EXIT_LATENCY_64NS 0 // less than 64ns > + > +// > +// PCIe L1 Exit latencies declarations > +// > +#define PCIE_LINK_CAPABILITY_L1_EXIT_LATENCY_1US 0 // less than 1us > > /** > The main routine which process the PCI feature Max_Payload_Size as per the > @@ -293,4 +302,47 @@ ProgramExtTag ( > IN VOID *PciExFeatureConfiguration > ); > > +/** > + The main routine to setup the PCI Express feature ASPM as per the > + device-specific platform policy, as well as in complaince with the > +PCI Express > + Base specification Revision 5. > + > + @param PciDevice A pointer to the PCI_IO_DEVICE. > + @param PciFeaturesConfigurationTable pointer to > + PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE > + > + @retval EFI_SUCCESS setup of PCI feature LTR is > successful. > +**/ > +EFI_STATUS > +SetupAspm ( > + IN PCI_IO_DEVICE *PciDevice, > + IN PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE > +*PciFeaturesConfigurationTable > + ); > + > +/** > + Setup of PCI Express feature ASPM in the > +PciExpressFeatureEntendedSetupPhase > +**/ > +EFI_STATUS > +AlignAspm ( > + IN PCI_IO_DEVICE *PciDevice, > + IN PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE > +*PciFeaturesConfigurationTable > + ); > + > +/** > + Program the PCIe Link Control register ASPM Control field; if > + the hardware value is different than the intended value. > + > + @param PciDevice A pointer to the PCI_IO_DEVICE instance. > + > + @retval EFI_SUCCESS The data was read from or written to the PCI > device. > + @retval EFI_UNSUPPORTED The address range specified by Offset, Width, > and Count is not > + valid for the PCI configuration header of > the PCI controller. > + @retval EFI_INVALID_PARAMETER Buffer is NULL or Width is invalid. > + > +**/ > +EFI_STATUS > +ProgramAspm ( > + IN PCI_IO_DEVICE *PciDevice, > + IN VOID *PciExFeatureConfiguration > + ); > + > #endif > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c > index 58d3780..24781c6 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c > @@ -50,7 +50,7 @@ EFI_PCI_EXPRESS_PLATFORM_POLICY > mPciExpressPlatformPolicy = { > // > // support for PCI Express feature - ASPM state > // > - FALSE, > + TRUE, > // > // support for PCI Express feature - Common Clock Configuration > // > @@ -96,6 +96,15 @@ BOOLEAN mPciExpressGetPlatformPolicyComplete = > FALSE; > // > PCI_EXPRESS_FEATURE_INITIALIZATION_POINT > mPciExpressFeatureInitializationList[] = { > > + { > + PciExpressFeatureSetupPhase, PciExpressAspm, SetupAspm > + }, > + { > + PciExpressFeatureEntendedSetupPhase, PciExpressAspm, AlignAspm > + }, > + { > + PciExpressFeatureProgramPhase, PciExpressAspm, ProgramAspm > + }, > { > PciExpressFeatureSetupPhase, PciExpressMps, > SetupMaxPayloadSize > }, > @@ -688,6 +697,18 @@ CreatePciRootBridgeDeviceNode ( > // start by assuming the Extended Tag is 10b Requester capable > // > PciConfigTable->ExtendedTag = > EFI_PCI_EXPRESS_EXTENDED_TAG_10BIT; > + // > + // initial state set to ASPM L0s and L1 both > + // > + PciConfigTable->AspmSupport = > EFI_PCI_EXPRESS_ASPM_L0S_L1_SUPPORT; > + // > + // start by assuming less than 64ns of L0s Exit Latency > + // > + PciConfigTable->L0sExitLatency = > PCIE_LINK_CAPABILITY_L0S_EXIT_LATENCY_64NS; > + // > + // start by assuming less than 1us of L1 Exit Latency > + // > + PciConfigTable->L1ExitLatency = > PCIE_LINK_CAPABILITY_L1_EXIT_LATENCY_1US; > } > > RootBridgeNode->PciExFeaturesConfigurationTable = PciConfigTable; diff -- > git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h > index c7cc7e5..5e0f43b 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h > @@ -98,6 +98,20 @@ struct > _PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE { > // to configure a common extended tag size for all the childs of a root > port > // > UINT8 ExtendedTag; > + // > + // to configure common ASPM state for all the devices link // > + UINT8 AspmSupport; > + // > + // to record maximum L0s Exit Latency among all the devices starting > + from root // bridge device to its downstream bridge and its endpoint > + device // > + UINT8 L0sExitLatency; > + // > + // to record maximum L1 Exit Latency among all the devices starting > + from root // bridge device to its downstream bridge and its endpoint > + device // > + UINT8 L1ExitLatency; > }; > > // > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c > index 98d9875..f301557 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c > @@ -374,6 +374,16 @@ SetupDefaultPciExpressDevicePolicy ( > PciDevice->SetupExtTag = EFI_PCI_EXPRESS_NOT_APPLICABLE; > } > > + // > + // default device policy for device's link ASPM // if > + (mPciExpressPlatformPolicy.Aspm) { > + PciDevice->SetupAspm = EFI_PCI_EXPRESS_ASPM_AUTO; } else { > + PciDevice->SetupAspm = EFI_PCI_EXPRESS_NOT_APPLICABLE; } > + > + > } > > /** > @@ -517,6 +527,14 @@ GetPciExpressDevicePolicy ( > PciDevice->SetupExtTag = EFI_PCI_EXPRESS_NOT_APPLICABLE; > } > > + // > + // set the device-specific policy for the PCI Express feature ASPM > + // > + if (mPciExpressPlatformPolicy.Aspm) { > + PciDevice->SetupAspm = PciExpressDevicePolicy.LinkCtlASPMState; > + } else { > + PciDevice->SetupAspm = EFI_PCI_EXPRESS_NOT_APPLICABLE; > + } > > DEBUG (( > DEBUG_INFO, > @@ -697,6 +715,24 @@ GetPciExpressExtTag ( > } > } > > +EFI_PCI_EXPRESS_ASPM_SUPPORT > +GetPciExpressAspmState ( > + IN PCI_IO_DEVICE *PciDevice > + ) > +{ > + switch (PciDevice- > >PciExpressCapabilityStructure.LinkControl.Bits.AspmControl) { > + case 0: > + return EFI_PCI_EXPRESS_ASPM_DISABLE; > + case 1: > + return EFI_PCI_EXPRESS_ASPM_L0s_SUPPORT; > + case 2: > + return EFI_PCI_EXPRESS_ASPM_L1_SUPPORT; > + case 3: > + return EFI_PCI_EXPRESS_ASPM_L0S_L1_SUPPORT; > + } > + return EFI_PCI_EXPRESS_NOT_APPLICABLE; } > + > /** > Notifies the platform about the current PCI Express state of the device. > > @@ -805,6 +841,15 @@ PciExpressPlatformNotifyDeviceState ( > PciExDeviceConfiguration.DeviceCtlExtTag = > EFI_PCI_EXPRESS_NOT_APPLICABLE; > } > > + // > + // get the device-specific state for PCIe ASPM state // if > + (mPciExpressPlatformPolicy.Aspm) { > + PciExDeviceConfiguration.LinkCtlASPMState = GetPciExpressAspmState > + (PciDevice); } else { > + PciExDeviceConfiguration.LinkCtlASPMState = > + EFI_PCI_EXPRESS_NOT_APPLICABLE; } > + > if (mPciExPlatformProtocol != NULL) { > return mPciExPlatformProtocol->NotifyDeviceState ( > mPciExPlatformProtocol, > -- > 2.21.0.windows.1 > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#54087): https://edk2.groups.io/g/devel/message/54087 Mute This Topic: https://groups.io/mt/71063715/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-