From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga18.intel.com (mga18.intel.com []) by mx.groups.io with SMTP id smtpd.web12.5162.1572621016444543116 for ; Fri, 01 Nov 2019 08:10:30 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: ashraf.javeed@intel.com) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Nov 2019 08:10:29 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,256,1569308400"; d="scan'208";a="194687281" Received: from pidsbabios005.gar.corp.intel.com ([10.223.9.183]) by orsmga008.jf.intel.com with ESMTP; 01 Nov 2019 08:10:27 -0700 From: "Javeed, Ashraf" To: devel@edk2.groups.io Cc: Jian J Wang , Hao A Wu , Ray Ni Subject: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 11/12] PciBusDxe: New PCI feature No-Snoop Date: Fri, 1 Nov 2019 20:39:51 +0530 Message-Id: <20191101150952.3340-12-ashraf.javeed@intel.com> X-Mailer: git-send-email 2.21.0.windows.1 In-Reply-To: <20191101150952.3340-1-ashraf.javeed@intel.com> References: <20191101150952.3340-1-ashraf.javeed@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2313 The code changes are made; as per the PCI Base Specification 4 Revision 1; to enable the configuration of new PCI feature No-Snoop (NS), which enables the PCI function to initiate requests if it does not require har- dware enforced cache-coherency for its transactions. The code changes are made to configure only those PCI devices which are requested to override by platform through the new PCI Platform protocol interface for device-specific policies. Signed-off-by: Ashraf Javeed Cc: Jian J Wang Cc: Hao A Wu Cc: Ray Ni --- MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 1 + MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h index 9f017b7..be1c341 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/PciFeatureSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c index a60cb42..a7f0a2f 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c @@ -986,6 +986,81 @@ OverrideRelaxOrder ( 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 +OverrideNoSnoop ( + IN PCI_IO_DEVICE *PciDevice + ) +{ + 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 + ); + if (EFI_ERROR(Status)){ + DEBUG (( DEBUG_ERROR, "Unexpected DeviceControl register (0x%x) read error!", + Offset + )); + return Status; + } + if (PciDevice->SetupRO.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->PciExpStruct.DeviceControl.Uint16 = PcieDev.Uint16; + } else { + DEBUG (( DEBUG_ERROR, "Unexpected DeviceControl register (0x%x) write error!", + Offset + )); + } + } else { + DEBUG (( DEBUG_INFO, "No write of NS,", PciDevice->SetupRO.Act)); + } + + return Status; +} + /** helper routine to dump the PCIe Device Port Type **/ @@ -1200,6 +1275,9 @@ ProgramDevicePciFeatures ( if (SetupRelaxOrder ()) { Status = OverrideRelaxOrder (PciDevice); } + if (SetupNoSnoop ()) { + Status = OverrideNoSnoop (PciDevice); + } DEBUG (( DEBUG_INFO, "\n")); return Status; } diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c index f1e7039..47295cd 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c @@ -509,6 +509,46 @@ SetDevicePolicyRelaxOrder ( } } +/** + 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_CONF_NO_SNOOP + @param PciDevice A pointer to PCI_IO_DEVICE +**/ +VOID +SetDevicePolicyNoSnoop ( + IN EFI_PCI_CONF_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_CONF_NS_AUTO: + PciDevice->SetupNS.Override = 0; + break; + case EFI_PCI_CONF_NS_DISABLE: + PciDevice->SetupNS.Override = 1; + PciDevice->SetupNS.Act = 0; + break; + case EFI_PCI_CONF_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. **/ @@ -520,6 +560,7 @@ SetupDefaultsDevicePlatformPolicy ( PciDevice->SetupMPS = EFI_PCI_CONF_MAX_PAYLOAD_SIZE_AUTO; PciDevice->SetupMRRS = EFI_PCI_CONF_MAX_READ_REQ_SIZE_AUTO; PciDevice->SetupRO.Override = 0; + PciDevice->SetupNS.Override = 0; } /** @@ -561,6 +602,10 @@ GetPciDevicePlatformPolicyEx ( // set device specific policy for Relax Ordering // SetDevicePolicyRelaxOrder (PciPlatformExtendedPolicy.DeviceCtlRelaxOrder, PciIoDevice); + // + // set the device specific policy for No-Snoop + // + SetDevicePolicyNoSnoop (PciPlatformExtendedPolicy.DeviceCtlNoSnoop, PciIoDevice); DEBUG (( DEBUG_INFO, "[device policy: platform]" -- 2.21.0.windows.1