From nobody Tue Nov 26 14:32:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+54071+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+54071+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1581105987823210.7614134506017; Fri, 7 Feb 2020 12:06:27 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id yeBtYY1788612xp8o5v0Yjwv; Fri, 07 Feb 2020 12:06:27 -0800 X-Received: from mga18.intel.com (mga18.intel.com []) by mx.groups.io with SMTP id smtpd.web09.10529.1581105978095314348 for ; Fri, 07 Feb 2020 12:06:26 -0800 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Feb 2020 12:06:26 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,414,1574150400"; d="scan'208";a="225644307" X-Received: from unknown (HELO PIDSBABIOS005.gar.corp.intel.com) ([10.223.9.183]) by fmsmga007.fm.intel.com with ESMTP; 07 Feb 2020 12:06:24 -0800 From: "Javeed, Ashraf" To: devel@edk2.groups.io Cc: Jian J Wang , Hao A Wu , Ray Ni Subject: [edk2-devel] [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 08/12] PciBusDxe: New PCI Express feature AtomicOp Date: Sat, 8 Feb 2020 01:34:43 +0530 Message-Id: <20200207200447.10536-9-ashraf.javeed@intel.com> In-Reply-To: <20200207200447.10536-1-ashraf.javeed@intel.com> References: <20200207200447.10536-1-ashraf.javeed@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,ashraf.javeed@intel.com X-Gm-Message-State: 4LwDK6CiGSpMN3Quph8Qx86cx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1581105987; bh=8o6Xh+yxDjrWhO9vK0+K40dcOY+vTR51BvRFE3Jravg=; h=Cc:Date:From:Reply-To:Subject:To; b=GFMjpDYBFDLIn7t84o/QdQzoU4bBfEodb2M7vLgP8X11KoX8Of1cg2dVSIn2r8ZavPr GtoI6TFHiJv5s5jyM5tK9r7H6QICjf+IuSZDrxupqlE45bcc2spp2U62kAVWSNloOZygl JDaJwir44Wiel2ZLbQ4quuRgRu9T4G+aPw4= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2499 This code change handles two PCI Express features related to AtomicOp, in compliance with the PCI Express Base SPecification 5: (1) configuring PCI function as an AtomicOp Requester (2) Enabling of Port Egress blocking depending on AtomicOp Routing Capability These is programmed based on the following criteria:- For a PCI Bridge device: - enables as AtomicOp Requester solely based on platform provided device policy - enabling of Port Egress blocking is based on platform device policy; only if its device capability register's AtomicOp Routing bit is 1 For an PCI EndPoint (EP) device: - if the platform's device policy wants to enable the AtomicOp Requester function for this device, than this device is enabled if all its bridge devices have the AtomicOp Routing capability bit set - Enabling of Port Egress disable is not applicable to PCI EP device For an PCI RCiEP device: - the AtomicOp Requester functionality is enabled solely based on the device policy provided by platform - similar to PCI EP device, the enabling of port Egress blocking is not applicable 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/PciExpressFeatures.c | 161 ++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h | 35 ++++++++++++++++= +++++++++++++++++++ MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c | 23 ++++++++++++++++= ++++++- MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h | 5 +++++ MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c | 23 ++++++++++++++++= +++++++ 6 files changed, 247 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci= /PciBusDxe/PciBus.h index 9b03c12..57ef1b2 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h @@ -295,6 +295,7 @@ struct _PCI_IO_DEVICE { PCI_FEATURE_POLICY SetupRO; PCI_FEATURE_POLICY SetupNS; PCI_FEATURE_POLICY SetupCTO; + EFI_PCI_EXPRESS_ATOMIC_OP SetupAtomicOp; }; =20 #define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \ diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c b/MdeModul= ePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c index f3f4d39..5c76ba4 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c @@ -908,3 +908,164 @@ ProgramCompletionTimeout ( return Status; } =20 +/** + Routine to setup the AtomicOp Requester in the PCI device, verifies the = routing + support in the bridge devices, to be complaint as per the PCI Base speci= fication. + + @param PciDevice A pointer to the PCI_IO_DEVICE. + @param PciExFeatureConfiguration pointer to common configuration ta= ble to + initialize the PCI Express feature + + @retval EFI_SUCCESS bridge device routing capability i= s successful. + EFI_INVALID_PARAMETER input parameter is NULL +**/ +EFI_STATUS +SetupAtomicOpRoutingSupport ( + IN PCI_IO_DEVICE *PciDevice, + IN PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE *PciExFeatureConfiguration + ) +{ + // + // to enable the AtomicOp Requester in the PCI EP device; its Root Port = (bridge), + // and its PCIe switch upstream & downstream ports (if present) needs to= support + // the AtomicOp Routing capability. + // + if (IS_PCI_BRIDGE (&PciDevice->Pci)) { + if (!PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Bits.A= tomicOpRouting) { + // + // since the AtomicOp Routing support flag is initialized as TRUE, n= egate + // in case if any of the PCI Bridge device in the PCI tree does not = support + // the AtomicOp Routing capability + // + if (PciExFeatureConfiguration =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + PciExFeatureConfiguration->AtomicOpRoutingSupported =3D FALSE; + } + } + + return EFI_SUCCESS; +} + +/** + Overrides the PCI Device Control 2 register AtomicOp Requester enable fi= eld; 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 P= CI device. + @retval EFI_UNSUPPORTED The address range specified by Offset, Wid= th, 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 +ProgramAtomicOp ( + IN PCI_IO_DEVICE *PciDevice, + IN PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE *PciExFeatureConfiguration + ) +{ + PCI_REG_PCIE_DEVICE_CONTROL2 PcieDev; + UINT32 Offset; + EFI_STATUS Status; + EFI_TPL OldTpl; + + PcieDev.Uint16 =3D 0; + Offset =3D PciDevice->PciExpressCapabilityOffset + + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2); + Status =3D PciDevice->PciIo.Pci.Read ( + &PciDevice->PciIo, + EfiPciIoWidthUint16, + Offset, + 1, + &PcieDev.Uint16 + ); + ASSERT (Status =3D=3D EFI_SUCCESS); + + if (PciDevice->SetupAtomicOp.Override) { + // + // override AtomicOp requester device control bit of the device based = on the + // platform request + // + if (IS_PCI_BRIDGE (&PciDevice->Pci)) { + // + // for a bridge device as AtomicOp Requester function; only platform= override + // request is used to set the device control register + // + if (PcieDev.Bits.AtomicOpRequester !=3D PciDevice->SetupAtomicOp.Ena= ble_AtomicOpRequester) { + PcieDev.Bits.AtomicOpRequester =3D PciDevice->SetupAtomicOp.Enable= _AtomicOpRequester; + } + // + // if platform also request its AtomicOp Egress blocking to be enabl= ed; set + // only if its device capability's AtomicOpRouting bit is 1. + // applicable to only the bridge devices + // + if (PciDevice->SetupAtomicOp.Enable_AtomicOpEgressBlocking) { + if (PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Bit= s.AtomicOpRouting) { + PcieDev.Bits.AtomicOpEgressBlocking =3D 1; + } + } + } else { + // + // in the case of non-bridge device + // + if (PciExFeatureConfiguration) { + // + // for a device as AtomicOp Requester function; its bridge devices= should + // support the AtomicOp Routing capability to enable the device's = as a + // requester function + // + if (PciExFeatureConfiguration->AtomicOpRoutingSupported) { + if (PcieDev.Bits.AtomicOpRequester !=3D PciDevice->SetupAtomicOp= .Enable_AtomicOpRequester) { + PcieDev.Bits.AtomicOpRequester =3D PciDevice->SetupAtomicOp.En= able_AtomicOpRequester; + } + } + } else { + // + // for the RCiEP device or the bridge device without any child, se= tup AtomicOp + // Requester as per platform's device policy + // + if (PcieDev.Bits.AtomicOpRequester !=3D PciDevice->SetupAtomicOp.E= nable_AtomicOpRequester) { + PcieDev.Bits.AtomicOpRequester =3D PciDevice->SetupAtomicOp.Enab= le_AtomicOpRequester; + } + } + // + // the enabling of AtomicOp Egress Blocking is not applicable to a n= on-bridge + // device + // + } + DEBUG (( + DEBUG_INFO, + "AtomicOp=3D%d,", + PcieDev.Bits.AtomicOpRequester + )); + + // + // Raise TPL to high level to disable timer interrupt while the write = operation completes + // + OldTpl =3D gBS->RaiseTPL (TPL_HIGH_LEVEL); + + Status =3D 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.DeviceControl2.Uint16 =3D P= cieDev.Uint16; + } else { + ReportPciWriteError (PciDevice->BusNumber, PciDevice->DeviceNumber, = PciDevice->FunctionNumber, Offset); + } + } else { + DEBUG (( DEBUG_INFO, "No AtomicOp,")); + } + + return Status; +} + diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h b/MdeModul= ePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h index 2ee7d4d..1e287fc 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h @@ -168,4 +168,39 @@ ProgramCompletionTimeout ( IN VOID *PciExFeatureConfiguration ); =20 +/** + Routine to setup the AtomicOp Requester in the PCI device, verifies the = routing + support in the bridge devices, to be complaint as per the PCI Base speci= fication. + + @param PciDevice A pointer to the PCI_IO_DEVICE. + @param PciExFeatureConfiguration pointer to common configuration ta= ble to + initialize the PCI Express feature + + @retval EFI_SUCCESS bridge device routing capability i= s successful. + EFI_INVALID_PARAMETER input parameter is NULL +**/ +EFI_STATUS +SetupAtomicOpRoutingSupport ( + IN PCI_IO_DEVICE *PciDevice, + IN PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE *PciExFeatureConfiguration + ); + +/** + Overrides the PCI Device Control 2 register AtomicOp Requester enable fi= eld; 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 P= CI device. + @retval EFI_UNSUPPORTED The address range specified by Offset, Wid= th, 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 +ProgramAtomicOp ( + IN PCI_IO_DEVICE *PciDevice, + IN VOID *PciExFeatureConfiguration + ); + #endif diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c b/MdeModule= Pkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c index d4459f3..9d624a0 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c @@ -62,7 +62,7 @@ EFI_PCI_EXPRESS_PLATFORM_POLICY mPciExpressPl= atformPolicy =3D { // // support for PCI Express feature - Atomic Op // - FALSE, + TRUE, // // support for PCI Express feature - LTR // @@ -125,6 +125,12 @@ PCI_EXPRESS_FEATURE_INITIALIZATION_POINT mPciExpressF= eatureInitializationList[] }, { PciExpressFeatureProgramPhase, PciExpressCto, ProgramCom= pletionTimeout + }, + { + PciExpressFeatureSetupPhase, PciExpressAtomicOp, SetupAtomi= cOpRoutingSupport + }, + { + PciExpressFeatureProgramPhase, PciExpressAtomicOp, ProgramAto= micOp } }; =20 @@ -297,6 +303,16 @@ IsPciExpressFeatureExtendedSetupRequired ( && PciExpressPolicy[mPciExpressFeatureInitializationList[idx].PciE= xpressFeatureId] =3D=3D TRUE ) { return TRUE; + } else if ( + // + // the PCI Express feature does not require extended setup phase b= ut it + // does require global flag to track the AtomicOpRouting caoabilit= y to + // be tracked for all its bridge devices + // + idx =3D=3D PciExpressAtomicOp + && PciExpressPolicy[idx] =3D=3D TRUE + ) { + return TRUE; } } =20 @@ -637,6 +653,11 @@ CreatePciRootBridgeDeviceNode ( // the devices in the PCI tree // PciConfigTable->Lock_Max_Read_Request_Size =3D FALSE; + // + // start by assuming the AtomicOp Routing capability is supported in t= he PCI + // tree + // + PciConfigTable->AtomicOpRoutingSupported =3D TRUE; } =20 RootBridgeNode->PciExFeaturesConfigurationTable =3D PciConfigTable; diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h b/MdeModule= Pkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h index a1fc39c..2bd565e 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h @@ -80,6 +80,11 @@ struct _PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE { // lock the Max_Read_Request_Size for the entire PCI tree of a root port // BOOLEAN Lock_Max_Read_Request_Size; + // + // to record the AtomicOp Routing capability of the PCI Heirarchy to ena= ble + // the AtomicOp of the EP device + // + BOOLEAN AtomicOpRoutingSupported; }; =20 // diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c b/MdeModul= ePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c index 1afea19..2707976 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c @@ -334,6 +334,8 @@ SetupDefaultPciExpressDevicePolicy ( =20 PciDevice->SetupCTO.Override =3D 0; =20 + PciDevice->SetupAtomicOp.Override =3D 0; + } =20 /** @@ -450,6 +452,14 @@ GetPciExpressDevicePolicy ( PciDevice->SetupCTO.Override =3D 0; } =20 + // + // set the device-specific policy for AtomicOp + // + if (mPciExpressPlatformPolicy.AtomicOp) { + PciDevice->SetupAtomicOp =3D PciExpressDevicePolicy.DeviceCtl2Atomic= Op; + } else { + PciDevice->SetupAtomicOp.Override =3D 0; + } =20 DEBUG (( DEBUG_INFO, @@ -692,6 +702,19 @@ PciExpressPlatformNotifyDeviceState ( PciExDeviceConfiguration.CTOsupport =3D EFI_PCI_EXPRESS_NOT_APPLICABLE; } =20 + // + // get the device-specific state for the PCIe AtomicOp feature + // + if (mPciExpressPlatformPolicy.AtomicOp) { + PciExDeviceConfiguration.DeviceCtl2AtomicOp.Enable_AtomicOpRequester + =3D (UINT8)PciDevice->PciExpressCapabilityStructure.DeviceControl2.Bit= s.AtomicOpRequester; + PciExDeviceConfiguration.DeviceCtl2AtomicOp.Enable_AtomicOpEgressBlock= ing + =3D (UINT8)PciDevice->PciExpressCapabilityStructure.DeviceControl2.Bit= s.AtomicOpEgressBlocking; + } else { + PciExDeviceConfiguration.DeviceCtl2AtomicOp.Override =3D 0; + PciExDeviceConfiguration.DeviceCtl2AtomicOp.Enable_AtomicOpRequester = =3D 0; + PciExDeviceConfiguration.DeviceCtl2AtomicOp.Enable_AtomicOpEgressBlock= ing =3D 0; + } =20 if (mPciExPlatformProtocol !=3D NULL) { return mPciExPlatformProtocol->NotifyDeviceState ( --=20 2.21.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#54071): https://edk2.groups.io/g/devel/message/54071 Mute This Topic: https://groups.io/mt/71063085/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-