This patch can also be viewed in the following repo:- https://github.com/ashrafj/edk2-staging/commit/b83f0f959ba7608bd802c19f9a022fad9e5d01cc
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 06/12] > PciBusDxe: New PCI Express feature No-Snoop > > BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2313 > > The code changes are made; as per the PCI Express Base Specification 4 > Revision > 1; to enable the configuration of PCI Express feature No-Snoop (NS), that > enables the PCI function to initiate requests if it does not require hardware > enforced cache-coherency for its transactions. > > The code changes are made to configure only those PCI devices which are > requested by platform for override through the new PCI Express Platform > protocol interface for device-specific policies. > > 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 | 70 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++ > MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h | 18 > ++++++++++++++++++ MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c > | 5 ++++- MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c | 62 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 155 insertions(+), 1 deletion(-) > > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > index d3d795d..e610b52 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > @@ -293,6 +293,7 @@ struct _PCI_IO_DEVICE { > UINT8 SetupMPS; > UINT8 SetupMRRS; > PCI_FEATURE_POLICY SetupRO; > + PCI_FEATURE_POLICY SetupNS; > }; > > #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 3262b76..df85366 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c > @@ -451,3 +451,73 @@ ProgramRelaxOrder ( > return Status; > } > > +/** > + Overrides the PCI Device Control register No-Snoop register 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 > +ProgramNoSnoop ( > + IN PCI_IO_DEVICE *PciDevice, > + IN VOID *PciExFeatureConfiguration > + ) > +{ > + PCI_REG_PCIE_DEVICE_CONTROL PcieDev; > + UINT32 Offset; > + EFI_STATUS Status; > + EFI_TPL OldTpl; > + > + PcieDev.Uint16 = 0; > + Offset = PciDevice->PciExpressCapabilityOffset + > + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl); > + Status = PciDevice->PciIo.Pci.Read ( > + &PciDevice->PciIo, > + EfiPciIoWidthUint16, > + Offset, > + 1, > + &PcieDev.Uint16 > + ); > + ASSERT (Status == EFI_SUCCESS); > + > + if (PciDevice->SetupNS.Override > + && PcieDev.Bits.NoSnoop != PciDevice->SetupNS.Act > + ) { > + PcieDev.Bits.NoSnoop = PciDevice->SetupNS.Act; > + DEBUG (( DEBUG_INFO, "NS=%d", PciDevice->SetupNS.Act)); > + > + // > + // 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, > + &PcieDev.Uint16 > + ); > + // > + // Restore TPL to its original level > + // > + gBS->RestoreTPL (OldTpl); > + > + if (!EFI_ERROR(Status)) { > + PciDevice->PciExpressCapabilityStructure.DeviceControl.Uint16 = > PcieDev.Uint16; > + } else { > + ReportPciWriteError (PciDevice->BusNumber, PciDevice->DeviceNumber, > PciDevice->FunctionNumber, Offset); > + } > + } else { > + DEBUG (( DEBUG_INFO, "No NS,", PciDevice->SetupRO.Act)); } > + > + return Status; > +} > + > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h > index 0d17801..ee636ce 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h > @@ -115,4 +115,22 @@ ProgramRelaxOrder ( > IN VOID *PciExFeatureConfiguration > ); > > +/** > + Overrides the PCI Device Control register No-Snoop register 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 > +ProgramNoSnoop ( > + 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 267f570..d264d13 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c > @@ -46,7 +46,7 @@ EFI_PCI_EXPRESS_PLATFORM_POLICY > mPciExpressPlatformPolicy = { > // > // support for PCI Express feature - No-Snoop > // > - FALSE, > + TRUE, > // > // support for PCI Express feature - ASPM state > // > @@ -116,6 +116,9 @@ PCI_EXPRESS_FEATURE_INITIALIZATION_POINT > mPciExpressFeatureInitializationList[] > }, > { > PciExpressFeatureProgramPhase, PciExpressRelaxOrder, > ProgramRelaxOrder > + }, > + { > + PciExpressFeatureProgramPhase, PciExpressNoSnoop, > ProgramNoSnoop > } > }; > > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c > index 40eb8a3..954ce16 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c > @@ -188,6 +188,46 @@ SetDevicePolicyPciExpressRo ( > } > } > > +/** > + Routine to set the device-specific policy for the PCI feature > +No-Snoop enable > + or disable > + > + @param NoSnoop value corresponding to data type > EFI_PCI_EXPRESS_NO_SNOOP > + @param PciDevice A pointer to PCI_IO_DEVICE > +**/ > +VOID > +SetDevicePolicyPciExpressNs ( > + IN EFI_PCI_EXPRESS_NO_SNOOP NoSnoop, > + OUT PCI_IO_DEVICE *PciDevice > + ) > +{ > + // > + // implementation specific rules for the usage of PCI_FEATURE_POLICY > +members > + // exclusively for the PCI Feature No-Snoop > + // > + // .Override = 0 to skip this PCI feature No-Snoop for the PCI device > + // .Override = 1 to program this No-Snoop PCI feature > + // .Act = 1 to enable the No-Snoop in the PCI device > + // .Act = 0 to disable the No-Snoop in the PCI device > + // > + switch (NoSnoop) { > + case EFI_PCI_EXPRESS_NS_AUTO: > + PciDevice->SetupNS.Override = 0; > + break; > + case EFI_PCI_EXPRESS_NS_DISABLE: > + PciDevice->SetupNS.Override = 1; > + PciDevice->SetupNS.Act = 0; > + break; > + case EFI_PCI_EXPRESS_NS_ENABLE: > + PciDevice->SetupNS.Override = 1; > + PciDevice->SetupNS.Act = 1; > + break; > + default: > + PciDevice->SetupNS.Override = 0; > + break; > + } > +} > + > /** > Generic routine to setup the PCI features as per its predetermined > defaults. > **/ > @@ -211,6 +251,8 @@ SetupDefaultPciExpressDevicePolicy ( > > PciDevice->SetupRO.Override = 0; > > + PciDevice->SetupNS.Override = 0; > + > } > > /** > @@ -309,6 +351,15 @@ GetPciExpressDevicePolicy ( > PciDevice->SetupRO.Override = 0; > } > > + // > + // set the device specific policy for No-Snoop > + // > + if (mPciExpressPlatformPolicy.NoSnoop) { > + SetDevicePolicyPciExpressNs (PciExpressDevicePolicy.DeviceCtlNoSnoop, > PciDevice); > + } else { > + PciDevice->SetupNS.Override = 0; > + } > + > > DEBUG (( > DEBUG_INFO, > @@ -499,6 +550,17 @@ PciExpressPlatformNotifyDeviceState ( > PciExDeviceConfiguration.DeviceCtlRelaxOrder = > EFI_PCI_EXPRESS_NOT_APPLICABLE; > } > > + // > + // get the device-specific state for the PCIe NoSnoop feature // if > + (mPciExpressPlatformPolicy.NoSnoop) { > + PciExDeviceConfiguration.DeviceCtlNoSnoop = PciDevice- > >PciExpressCapabilityStructure.DeviceControl.Bits.NoSnoop > + ? > EFI_PCI_EXPRESS_NS_ENABLE > + : > + EFI_PCI_EXPRESS_NS_DISABLE; } else { > + PciExDeviceConfiguration.DeviceCtlNoSnoop = > + EFI_PCI_EXPRESS_NOT_APPLICABLE; } > + > > if (mPciExPlatformProtocol != NULL) { > return mPciExPlatformProtocol->NotifyDeviceState ( > -- > 2.21.0.windows.1 > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#54081): https://edk2.groups.io/g/devel/message/54081 Mute This Topic: https://groups.io/mt/71063523/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-