public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 01/15] MdePkg/Protocols: Deprecated the EFI encoded macros
       [not found] <20200510161412.13832-1-ashraf.javeed@intel.com>
@ 2020-05-10 16:13 ` 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
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-10 16:13 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Michael D Kinney, Liming Gao

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=1954

Deprecated the EFI encoded macros for the following PCIe features and
renamed its policy variables in EFI_PCI_EXPRESS_DEVICE_POLICY as
shown below:
1. Maximum Payload Size (MPS)       -> MaxPayloadSize
2. Maximum Read Request Size (MRRS) -> MaxReadRequestSize
3. Extended Tag                     -> ExtendedTag
4. Relax Order Enable               -> RelaxedOrdering
5. No Snoop Enable                  -> NoSnoop
6. ASPM support                     -> AspmControl
7. Common Clock Configuration       -> CommonClockConfiguration
8. Atomic Op                        -> AtomicOp
9. LTR Enable                       -> Ltr
10. PTM support                     -> Ptm
11. CTO support                     -> CompletionTimeout
12. CPM                             -> ClockPowerManagement
13. L1 PM Substates                 -> L1PmSubstates

Deprecated the PCIe feature Extended Synch from the PCI Express Platform
Protocol.
Introduced the global AUTO (0xFF) and NOT_APPLICABLE (0xFE) as device
policy for all PCIe features.

Signed-off-by: Ashraf Javeed <ashraf.javeed@intel.com>
Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
---
 MdePkg/Include/Protocol/PciExpressPlatform.h | 630 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 1 file changed, 241 insertions(+), 389 deletions(-)

diff --git a/MdePkg/Include/Protocol/PciExpressPlatform.h b/MdePkg/Include/Protocol/PciExpressPlatform.h
index bb2c8c8..4ca157a 100644
--- a/MdePkg/Include/Protocol/PciExpressPlatform.h
+++ b/MdePkg/Include/Protocol/PciExpressPlatform.h
@@ -4,7 +4,7 @@
   driver to describe the unique features of a platform.
   This protocol is optional.
 
-Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 
@@ -27,16 +27,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
     0x787b0367, 0xa945, 0x4d60, {0x8d, 0x34, 0xb9, 0xd1, 0x88, 0xd2, 0xd0, 0xb6} \
   }
 
-///
-/// As per the present definition and specification of this protocol, the major
-/// version is 1, and minor version is 1. Any driver utilizing this protocol
-/// shall use these versions number to maintain the backward compatibility as
-/// per its specification changes in future.
-///
-enum EfiPciExpressPlatformProtocolVersion {
-   EFI_PCI_EXPRESS_PLATFORM_PROTOCOL_MAJOR_VERSION = 1,
-   EFI_PCI_EXPRESS_PLATFORM_PROTOCOL_MINOR_VERSION = 1
-};
 
 ///
 /// Forward declaration for EFI_PCI_EXPRESS_PLATFORM_PROTOCOL.
@@ -46,385 +36,249 @@ typedef struct _EFI_PCI_EXPRESS_PLATFORM_PROTOCOL  EFI_PCI_EXPRESS_PLATFORM_PROT
 ///
 /// Related Definitions for EFI_PCI_EXPRESS_DEVICE_POLICY
 ///
+// Glossary of PCIe terminologies used:-
+//  RC = Root Complex
+//  RP = Root Port
+//  EP = Endpoint
+//  RCiEP = Root Complex integrated Endpoint
 
 ///
 /// EFI encoding used in notification to the platform, for any of the PCI Express
 /// capabilities feature state, to indicate that it is not a supported feature,
 /// or its present state is unknown
 ///
-#define EFI_PCI_EXPRESS_NOT_APPLICABLE  0xFF
-
-///
-/// Following are the data types for EFI_PCI_EXPRESS_DEVICE_POLICY
-/// each for the PCI standard feature and its corresponding bitmask
-/// representing the valid combinations of PCI attributes
-///
-
-///
-/// This data type is to retrieve the PCI device platform policy for the PCI
-/// Express feature PCIe device Maximum Payload Size (MPS). Refer to PCI Express
-/// Base Specification 4 (chapter 7.5.3.4), on how to translate the below EFI
-/// encodings as per the PCI hardware terminology. If this data member value is 0
-/// than there is no platform policy to override, this feature would be enabled as
-/// per its PCI specification based on the device capabilities. Below is it
-/// data type and the macro definitions which the driver uses for interpreting
-/// the platform policy.
-///
-typedef UINT8 EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE;
-
-#define EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_AUTO   0x00  //No request for override
-#define EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_128B   0x01  //set to default 128B
-#define EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_256B   0x02  //set to 256B if applicable
-#define EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_512B   0x03  //set to 512B if applicable
-#define EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_1024B  0x04  //set to 1024B if applicable
-#define EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_2048B  0x05  //set to 2048B if applicable
-#define EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_4096B  0x06  //set to 4096B if applicable
-
-///
-/// This data type is to retrieve the PCI device platform policy for the PCI
-/// Express feature Maximum Read Request Size (MRRS). Refer to PCI Express Base
-/// Specification 4 (chapter 7.5.3.4), on how to translate the below EFI
-/// encodings as per the PCI hardware terminology. If this data member value
-/// is returned as 0 than there is no platform policy to override, this feature
-/// would be enabled as per its PCI specification based on the device capabilities.
-/// Below is it data type and the macro definitions which the driver uses for
-/// interpreting the platform policy.
-///
-typedef UINT8 EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE;
-
-#define EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_AUTO  0x00  //No request for override
-#define EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_128B  0x01  //set to default 128B
-#define EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_256B  0x02  //set to 256B if applicable
-#define EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_512B  0x03  //set to 512B if applicable
-#define EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_1024B 0x04  //set to 1024B if applicable
-#define EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_2048B 0x05  //set to 2048B if applicable
-#define EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_4096B 0x06  //set to 4096B if applicable
+#define EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO            0xFF
+#define EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE  0xFE
 
 ///
-/// This data type is to retrieve the PCI device platform policy for the PCI
-/// Express feature Extended Tags. Refer to PCI Express Base Specification
-/// 4 (chapter 7.5.3.4), on how to translate the below EFI encodings as per the
-/// PCI hardware terminology. If this data member value is returned as 0 than
-/// there is no platform policy to override, this feature would be enabled as
-/// per its PCI specification based on the device capabilities. Below is it
-/// data type and the macro definitions which the driver uses for interpreting
-/// the platform policy.
-///
-typedef UINT8 EFI_PCI_EXPRESS_EXTENDED_TAG;
-
-#define EFI_PCI_EXPRESS_EXTENDED_TAG_AUTO   0x00  //No request for override
-#define EFI_PCI_EXPRESS_EXTENDED_TAG_5BIT   0x01  //set to default 5-bit
-#define EFI_PCI_EXPRESS_EXTENDED_TAG_8BIT   0x02  //set to 8-bit if applicable
-#define EFI_PCI_EXPRESS_EXTENDED_TAG_10BIT  0x03  //set to 10-bit if applicable
-
-///
-/// This data type is to retrieve the PCI device platform policy for the PCI
-/// Express feature PCIe link's Active State Power Mgmt (ASPM).
-/// Refer to PCI Express Base Specification 4 (chapter 7.5.3.7), on how to
-/// translate the below EFI encodings as per the PCI hardware terminology.
-/// If this data member value is returned as 0 than there is no platform policy
-/// to override, this feature would be enabled as per its PCI specification based
-/// on the device capabilities.
-/// Below is it data type and the macro definitions which the driver uses for
-/// interpreting the platform policy.
-///
-typedef UINT8 EFI_PCI_EXPRESS_ASPM_SUPPORT;
-
-#define EFI_PCI_EXPRESS_ASPM_AUTO           0x00  //No request for override
-#define EFI_PCI_EXPRESS_ASPM_DISABLE        0x01  //set to default disable state
-#define EFI_PCI_EXPRESS_ASPM_L0s_SUPPORT    0x02  //set to L0s state
-#define EFI_PCI_EXPRESS_ASPM_L1_SUPPORT     0x03  //set to L1 state
-#define EFI_PCI_EXPRESS_ASPM_L0S_L1_SUPPORT 0x04  //set to L0s and L1 state
-
-///
-/// This data type is to retrieve the PCI device platform policy for the PCI
-/// Express feature PCIe Device's Relax Ordering enable/disable.
-/// Refer to PCI Express Base Specification 4 (chapter 7.5.3.4), on how to
-/// translate the below EFI encodings as per the PCI hardware terminology.
-/// If this data member value is returned as 0 than there is no platform policy
-/// to override, this feature would be enabled as per its PCI specification based
-/// on the device capabilities.
-/// Below is it data type and the macro definitions which the driver uses for
-/// interpreting the platform policy.
-///
-typedef UINT8 EFI_PCI_EXPRESS_RELAX_ORDER;
-
-#define EFI_PCI_EXPRESS_RO_AUTO     0x00  //No request for override
-#define EFI_PCI_EXPRESS_RO_DISABLE  0x01  //set to default disable state
-#define EFI_PCI_EXPRESS_RO_ENABLE   0x02  //set to enable state
-
-///
-/// This data type is to retrieve the PCI device platform policy for the PCI
-/// Express feature PCIe Device's No-Snoop enable/disable.
-/// Refer to PCI Express Base Specification 4 (chapter 7.5.3.4), on how to
-/// translate the below EFI encodings as per the PCI hardware terminology.
-/// If this data member value is returned as 0 than there is no platform policy
-/// to override, this feature would be enabled as per its PCI specification based
-/// on the device capabilities.
-/// Below is it data type and the macro definitions which the driver uses for
-/// interpreting the platform policy.
-///
-typedef UINT8 EFI_PCI_EXPRESS_NO_SNOOP;
-
-#define EFI_PCI_EXPRESS_NS_AUTO     0x00  //No request for override
-#define EFI_PCI_EXPRESS_NS_DISABLE  0x01  //set to default disable state
-#define EFI_PCI_EXPRESS_NS_ENABLE   0x02  //set to enable state
-
-///
-/// This data type is to retrieve the PCI device platform policy for the PCI
-/// Express feature PCIe link's Clock configuration is common or discrete.
-/// Refer to PCI Express Base Specification 4 (chapter 7.5.3.7), on how to translate
-/// the below EFI encodings as per the PCI hardware terminology. If this data member
-/// value is returned as 0 than there is no platform policy to override, this
-/// feature would be enabled as per its PCI specification based on the device
-/// capabilities. Below is its data type and the macro definitions which the
-/// driver uses for interpreting the platform policy.
-///
-typedef UINT8 EFI_PCI_EXPRESS_COMMON_CLOCK_CFG;
-
-#define EFI_PCI_EXPRESS_CLK_CFG_AUTO    0x00   //No request for override
-#define EFI_PCI_EXPRESS_CLK_CFG_ASYNCH  0x01   //set to default asynchronous clock
-#define EFI_PCI_EXPRESS_CLK_CFG_COMMON  0x02   //set to common clock
-
-///
-/// This data type is to retrieve the PCI device platform policy for the PCI
-/// Express feature PCIe link's Extended Synch enable or disable.
-/// Refer to PCI Express Base Specification 4 (chapter 7.5.3.7), on how to translate
-/// the below EFI encodings as per the PCI hardware terminology. If this data member
-/// value is returned as 0 than there is no platform policy to override, this
-/// feature would be enabled as per its PCI specification based on the device
-/// capabilities. Below is its data type and the macro definitions which the
-/// driver uses for interpreting the platform policy.
-///
-typedef UINT8 EFI_PCI_EXPRESS_EXTENDED_SYNCH;
-
-#define EFI_PCI_EXPRESS_EXT_SYNCH_AUTO    0x00  //No request for override
-#define EFI_PCI_EXPRESS_EXT_SYNCH_DISABLE 0x01  //set to default disable state
-#define EFI_PCI_EXPRESS_EXT_SYNCH_ENABLE  0x02  //set to enable state
-
-///
-/// This data type is to retrieve the PCI device platform policy for the PCI
-/// Express feature PCIe Device's AtomicOp Requester enable or disable, as well
-/// as its Egress blocking based on the port's routing capability.
-/// Refer to PCI Express Base Specification 4 (chapter 7.5.3.16), on how to translate
-/// the given data structure as per the PCI hardware terminology.
-/// If the data member "Override" value is 0 than there is no platform policy to
-/// override, other data members value must be ignored. If 1 than other data
-/// members will be used as per the device capabilities. Below is its data type
-/// definitions which the driver uses for interpreting the platform policy.
+/// The EFI_PCI_EXPRESS_DEVICE_POLICY size is fixed as per its definition corresponding
+/// to its version, with each byte field represents one PCI Express feature and
+/// its bitmask define the legal combinations to represent all the valid combinations
+/// of its attributes, defined in the PCI Express Base Specification.
 ///
-typedef struct _EFI_PCI_EXPRESS_ATOMIC_OP EFI_PCI_EXPRESS_ATOMIC_OP;
+typedef struct {
 
-struct _EFI_PCI_EXPRESS_ATOMIC_OP {
   //
-  // set to indicate the platform request to override based on below data member
-  // bit fields; clear bit indicates no platform request to override and the other
-  // data member bit fields are not applicable.
-  // Ignored when passed as input parameters.
+  // For PCI Express feature - Maximum Payload Size
   //
-  UINT8   Override:1;
+  // Bit 0 - 2 should match with the definition of the "Max_Payload_Size" register
+  // field of the Device Control Register (Offset 08h) in the PCI Express Base
+  // Specification Revision 5, section 7.5.3.4 , for a valid device policy.
+  // The device policy AUTO shall be used to set the payload size as per the Device
+  // Capability register "Max_Payload_Size Supported" field, and by aligning to a
+  // common value supported among all the devices in the tree.
+  // The device policy NOT_APPLICABLE shall be used to skip programming of the
+  // maximum payload size of a device.
   //
-  // set to enable the device as the requester for AtomicOp; clear bit to force
-  // default disable state
+  UINT8                          MaxPayloadSize;
+
   //
-  UINT8   Enable_AtomicOpRequester:1;
+  // For PCI Express feature - Maximum Read Request Size
   //
-  // set to enable the AtomicOp Egress blocking on this port based on its routing
-  // capability; clear bit to force default disable state
+  // Bit 0 - 2 should match with the definition of the "Max_Read_Request_Size"
+  // register field of the Device Control Register (Offset 08h) in the PCI Express
+  // Base Specification Revision 5, section 7.5.3.4, for a valid device policy.
+  // The device policy AUTO shall be used to set the Memory read request size as
+  // per the device "Max_Payload_Size" value.
+  // The device policy NOT_APPLICABLE shall be used to skip programming of the
+  // Maximum Read Request Size in the Device Control register
   //
-  UINT8   Enable_AtomicOpEgressBlocking:1;
+  UINT8                          MaxReadRequestSize;
+
   //
-  // the remaining bits are unused for this feature
+  // For PCI Express feature - Extended Tag
   //
-  UINT8   Reserved:5;
-};
-
-///
-/// This data type is to retrieve the PCI device platform policy for the PCI
-/// Express feature PCIe Device's LTR Mechanism enable/disable.
-/// Refer to PCI Express Base Specification 4 (chapter 7.5.3.16), on how to translate
-/// the below EFI encodings as per the PCI hardware terminology. If this data member
-/// value is returned as 0 than there is no platform policy to override, this
-/// feature would be enabled as per its PCI specification based on the device
-/// capabilities. Below is its data type and the macro definitions which the
-/// driver uses for interpreting the platform policy.
-///
-typedef UINT8 EFI_PCI_EXPRESS_LTR;
-
-#define EFI_PCI_EXPRESS_LTR_AUTO    0x00  //No request for override
-#define EFI_PCI_EXPRESS_LTR_DISABLE 0x01  //set to default disable state
-#define EFI_PCI_EXPRESS_LTR_ENABLE  0x02  //set to enable state
+  // Bit 0 = 1 enables the 8b Extended Tag, else 5b Extended Tag.
+  // Bit 1 = 1 enables the 10b Extended Tag as a requester, else Bit 0 value gets
+  // applied.
+  // Bit 0 should match with the definition of the Device Control register Extended
+  // Tag Field Enable (bit 8) of the PCI Express Base Specification Revision 5,
+  // section 7.5.3.4.
+  // Bit 1 should match with the definition of the Device Control2 register 10-Bit
+  // Tag Requester Enable (bit 12) of the PCI Express Base Specification Revision 5,
+  // section 7.5.3.16.
+  // The device policy AUTO or NOT_APPLICABLE shall be treated as "do not touch".
+  // The device policy from platform can be different for the RP and its EP device;
+  // however if the device capability does not match with the policy than it shall
+  // be ignored. For example; if the policy for EP is to set the 10b Extended Tag
+  // than EP device capability as a requester and its RP completer capability is
+  // checked. If platform ask policy change only for RP than its device capability
+  // is checked to enable the 10b Extended Tag.
+  //
+  UINT8                          ExtendedTag;
 
-///
-/// This data type is to retrieve the PCI device platform policy for the PCI
-/// Express feature PCIe Device's Precision Time Measurement (PTM) enable/disable.
-/// Refer to PCI Express Base Specification 4 (chapter 7.5.3.16), on how to translate the
-/// below EFI encodings as per the PCI hardware terminology. If this data member
-/// value is returned as 0 than there is no platform policy to override, this
-/// feature would be enabled as per its PCI specification based on the device
-/// capabilities. Below is its data type and the macro definitions which the
-/// driver uses for interpreting the platform policy.
-///
-typedef UINT8 EFI_PCI_EXPRESS_PTM;
+  //
+  // For PCI Express feature - Relaxed Ordering
+  //
+  // Bit 0 = 1 Enable Relaxed Ordering, else disable.
+  // Bit 0 should match with the definition of the Device Control register Enable
+  // Relaxed Ordering (bit 4) of the PCI Express Base Specification Revision 5,
+  // section 7.5.3.4.
+  // The device policy AUTO or NOT_APPLICABLE shall be treated as "do not touch".
+  //
+  UINT8                          RelaxedOrdering;
 
-#define EFI_PCI_EXPRESS_PTM_AUTO      0x00  //No request for override
-#define EFI_PCI_EXPRESS_PTM_DISABLE   0x01  //set to default disable state
-#define EFI_PCI_EXPRESS_PTM_ENABLE    0x02  //set to enable state only
-#define EFI_PCI_EXPRESS_PTM_ROOT_SEL  0x02  //set to root select & enable
+  //
+  // For PCI Express feature - No-Snoop
+  //
+  // Bit 0 = 1 Enable No Snoop, else disable.
+  // Bit 0 should match with the definition of the Device Control register Enable
+  // No Snoop (bit 11) of the PCI Express Base Specification Revision 5, section
+  // 7.5.3.4.
+  // The device policy AUTO or NOT_APPLICABLE shall be treated as "do not touch".
+  //
+  UINT8                          NoSnoop;
 
-///
-/// This data type is to retrieve the PCI device platform policy for the PCI
-/// Express feature PCIe Device's Completion Timeout (CTO) set to supported ranges
-/// or disable. Refer to PCI Express Base Specification 4 (chapter 7.5.3.16), on how to
-/// translate the below EFI encodings as per the PCI hardware terminology. If this
-/// data member value is returned as 0 than there is no platform policy to override,
-/// this feature would be enabled as per its PCI specification based on the device
-/// capabilities. Below is its data type and the macro definitions which the
-/// driver uses for interpreting the platform policy.
-///
-typedef UINT8 EFI_PCI_EXPRESS_CTO_SUPPORT;
-
-#define EFI_PCI_EXPRESS_CTO_AUTO        0x00  //No request for override
-#define EFI_PCI_EXPRESS_CTO_DEFAULT     0x01  //set to default range of 5us to 50ms if applicable
-#define EFI_PCI_EXPRESS_CTO_RANGE_A1    0x02  //set to range of 50us to 100us if applicable
-#define EFI_PCI_EXPRESS_CTO_RANGE_A2    0x03  //set to range of 1ms to 10ms if applicable
-#define EFI_PCI_EXPRESS_CTO_RANGE_B1    0x04  //set to range of 16ms to 55ms if applicable
-#define EFI_PCI_EXPRESS_CTO_RANGE_B2    0x05  //set to range of 65ms to 210ms if applicable
-#define EFI_PCI_EXPRESS_CTO_RANGE_C1    0x06  //set to range of 260ms to 900ms if applicable
-#define EFI_PCI_EXPRESS_CTO_RANGE_C2    0x07  //set to range of 1s to 3.5s if applicable
-#define EFI_PCI_EXPRESS_CTO_RANGE_D1    0x08  //set to range of 4s to 13s if applicable
-#define EFI_PCI_EXPRESS_CTO_RANGE_D2    0x09  //set to range of 17s to 64s if applicable
-#define EFI_PCI_EXPRESS_CTO_DET_DISABLE 0x10  //set to CTO detection disable if applicable
+  //
+  // For PCI Express feature - ASPM state
+  //
+  // Bit 0 - 1 should match with the definition of the "ASPM Control" register field
+  // of the Link Control Register (Offset 10h) in the PCI Express Base Specification
+  // Revision 5, section 7.5.3.7.
+  // The device policy AUTO or NOT_APPLICABLE shall be treated as "do not touch".
+  // The device policy of the PCIe Root Port only shall be consider for the entire
+  // device tree; ignored for all other devices (EP and RCiEP).
+  //
+  UINT8                          AspmControl;
 
-///
-/// This data type is to retrieve the PCI device platform policy for the PCI
-/// Express feature PCIe link's Clock Power Management (CPM) enable or disable.
-/// Refer to PCI Express Base Specification 5 (chapter 7.5.3.7), on how to translate
-/// the below EFI encodings as per the PCI hardware terminology. If this data member
-/// value is returned as 0 than there is no platform policy to override, this
-/// feature would be ignored or disabled/enabled, as per its relation with other
-/// components and its capabilities, as defined in its PCI specification. Below
-/// is its data type and the macro definitions which the driver uses for interpreting
-/// the platform policy.
-///
-typedef UINT8 EFI_PCI_EXPRESS_CPM;
+  //
+  // For PCI Express feature - Common Clock Configuration
+  //
+  // The device policy AUTO shall be used to set the Common Clock Configuration
+  // (bit 6) of the Link Control register as per the device's Link Status register
+  // Slot Clock Configuration (bit 12) value.
+  // The device policy NOT_APPLICABLE shall be used to skip programming of the Common
+  // Clock Configuration of the device.
+  //
+  UINT8                          CommonClockConfiguration;
 
-#define EFI_PCI_EXPRESS_CPM_AUTO    0x00  //No request for override
-#define EFI_PCI_EXPRESS_CPM_DISABLE 0x01  //set to default disable state
-#define EFI_PCI_EXPRESS_CPM_ENABLE  0x02  //set to enable state
+  //
+  // For PCI Express feature - Atomic Op
+  //
+  // Bit 0 = 1 to enable the device as the AtomicOp Requester, else disable
+  // Bit 1 = 1 to block the incoming AtomicOp Requests going out of its Egress
+  // Port (enable Egress blocking for Switch upstream/downstream ports and RP).
+  // Bit 0,1 should match with the definition of the of the Device Control2 Register
+  // (offset 28h) bit 6,7 named "AtomicOp Requester Enable" and "AtomicOp Egress
+  // Blocking" respectively, as in the PCI Express Base Specification Revision
+  // 5, section 7.5.3.16.
+  // The device policy AUTO or NOT_APPLICABLE shall be treated as "do not touch".
+  // The Bit 1 device policy shall be applied only based on the Device Capability2
+  // register field "AtomicOp Routing Supported" (bit 6).
+  //
+  UINT8                          AtomicOp;
 
-///
-/// This data type is to retrieve the PCI device platform policy for the PCI
-/// Express feature PCIe link's L1 PM Substates.
-/// Refer to PCI Express Base Specification 5 (chapter 7.8.3.3), on how to translate
-/// the given data structure as per the PCI hardware terminology. If the data member
-/// "Override" value is 0 than there is no platform policy to override, other data
-/// members will be ignored; if 1 than other data members are used for this feature,
-/// to align the states based on its capabilities as well as its relationship with
-/// other components in the PCI hierarchy. The platform is expected to return any
-/// combination from the four L1 PM Substates.
-/// Below is its data type definitions which the driver uses for interpreting
-/// the platform policy.
-///
-typedef struct _EFI_PCI_EXPRESS_L1PM_SUBSTATES EFI_PCI_EXPRESS_L1PM_SUBSTATES;
+  //
+  // For PCI Express feature - LTR
+  //
+  // Bit 0 = 1 enables the LTR mechanism, else disables.
+  // Bit 0 should match with the definition of "LTR Mechanism Enable" (bit 10)
+  // of the Device Control 2 Register (Offset 28h) in the PCI Express Base Specification
+  // Revision 5, section 7.5.3.16.
+  // As per its specification, LTR can be enabled on a EP device if all the devices
+  // along the path to RC supports the LTR capability and are enabled.
+  // The platform is responsible to provide consist device policy for all the
+  // devices in an hierarchy; if RP policy is enable and EP policy is disable,
+  // they are permissible but no usage of feature as EP will not send LTR message
+  // to RP. Platform should not provide policy for RP as disable and EP as enable,
+  // as it shall result in Unsupported Request error. To avoid erroneous scenario
+  // even the EP shall be disabled, along with its RP.
+  // The device policy AUTO or NOT_APPLICABLE provided to EP shall be treated as
+  // mo LTR programming from the path of EP to parent RP. If same is provided for
+  // RP than its policy is replaced with the policy of its child device.
+  // The device policy is applicable if that is supported by LTR capability.
+  //
+  UINT8                          Ltr;
 
-struct _EFI_PCI_EXPRESS_L1PM_SUBSTATES {
   //
-  // set to indicate the platform request to override the L1 PM Substates using
-  // the other data member bit fields; bit clear means no request from platform
-  // to override the L1 PM Substates for the device. Ignored when passed as input
-  // parameters.
+  // For PCI Express feature - PTM
   //
-  UINT8 Override:1;
+  // Bit 0 = PTM Enable, if 1 enables the PTM mechanism as per device role's
+  // capability, else disables the PTM mechanism of the device.
+  // Bit 0 should match with the definition of the PCI Express Base Specification
+  // Revision 5, section 7.9.16.3 of the PTM Control Register (offset 08h).
+  // The device policy AUTO shall be used to set the PTM feature as per the device
+  // PTM Capability structure.
+  // The device policy NOT_APPLICABLE shall be used to prevent the PTM feature
+  // enabling for certain device, or for entire PCIe hierarchy.
+  // It is platform responsibility to maintain valid policies for all the PCIe
+  // devices in the device tree. Invalid combination of device policies in the
+  // device tree shall be ignored (for example port is provided wtih NOT_APPLICABLE
+  // while the EP device is provided with the AUTO policy).
   //
-  // set to enable the PCI-PM L1.2 state; bit clear to force default disable state
+  UINT8                          Ptm;
+
   //
-  UINT8 Enable_Pci_Pm_L1_2:1;
+  // For PCI Express feature - Completion Timeout
   //
-  // set to enable the PCI-PM L1.1 state; bit clear to force default disable state
+  // Bit 0 - 4 should match with the definition of the register fields "Completion
+  // Timeout Value" (bit 0 - 3), and "Completion Timeout Disable" (bit 4) of the
+  // PCI Express Base Specification Revision 5, section 7.5.3.16 Device Control
+  // 2 Register (Offset 28h), for a valid device policy.
+  // The device policy AUTO or NOT_APPLICABLE shall be treated as "do not touch".
+  // The device policy is applicable if that is supported in the device capability.
   //
-  UINT8 Enable_Pci_Pm_L1_1:1;
+  UINT8                          CompletionTimeout;
+
   //
-  // set to enable the ASPM L1.2 state; bit clear to force default disable state
+  // For PCI Express feature - Clock Power Management
   //
-  UINT8 Enable_Aspm_L1_2:1;
+  // Bit 0 = Enable Clock Power Management (value 1), else disable.
+  // Bit 0 should match with the definition of the PCI Express Base Specification
+  // Revision 5, section 7.5.3.7 of the Link Control Register (offset 10h) bit 8.
+  // This device policy shall be applied based on device Link Capability register
+  // value of bit 18 of offset 0Ch.
+  // The device policy AUTO or NOT_APPLICABLE shall be treated as "do not touch".
   //
-  // set to enable the ASPM L1.1 state; bit clear to force default disable state
+  UINT8                          ClockPowerManagement;
+
   //
-  UINT8 Enable_Aspm_L1_1:1;
+  // For PCI Express feature - L1 PM Substates
   //
-  // rest of the remaining bits are reserved, not utilized; can be reused in
-  // future to define additional conditions as per PCIe capabilities
+  // Bit 0 = PCI-PM L1.2 Enable, Bit 1 = PCI-PM L1.1 Enable, Bit 2 = ASPM L1.2 Enable,
+  // Bit 3 = ASPM L1.1 Enable; if set enables L1 substates else disables.
+  // Bit 0 - 3 should match with the definition of the PCI Express Base Specification
+  // Revision 5, section 7.8.3.3 of L1 PM Substates Control 1 Register (Offset 08h).
+  // The device policy AUTO or NOT_APPLICABLE shall be treated as "do not touch".
+  // The device policy of only the PCIe Root Port should be consider for the entire
+  // device tree; ignored for all other devices (EP and RCiEP).
   //
-  UINT8 Reserved:3;
-};
-
-///
-/// The EFI_PCI_EXPRESS_DEVICE_POLICY size is fixed as per its definition corresponding
-/// to its version, with each byte field represents one PCI Express feature and
-/// its bitmask define the legal combinations to represent all the valid combinations
-/// of its attributes, defined in the PCI Express Base Specification.
-///
-typedef struct {
-  EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE  DeviceCtlMPS;
-  EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE DeviceCtlMRRS;
-  EFI_PCI_EXPRESS_EXTENDED_TAG      DeviceCtlExtTag;
-  EFI_PCI_EXPRESS_RELAX_ORDER       DeviceCtlRelaxOrder;
-  EFI_PCI_EXPRESS_NO_SNOOP          DeviceCtlNoSnoop;
-  EFI_PCI_EXPRESS_ASPM_SUPPORT      LinkCtlASPMState;
-  EFI_PCI_EXPRESS_COMMON_CLOCK_CFG  LinkCtlCommonClkCfg;
-  EFI_PCI_EXPRESS_EXTENDED_SYNCH    LinkCtlExtSynch;
-  EFI_PCI_EXPRESS_ATOMIC_OP         DeviceCtl2AtomicOp;
-  EFI_PCI_EXPRESS_LTR               DeviceCtl2LTR;
-  EFI_PCI_EXPRESS_PTM               PTMControl;
-  EFI_PCI_EXPRESS_CTO_SUPPORT       CTOsupport;
-  EFI_PCI_EXPRESS_CPM               LinkCtlCPM;
-  EFI_PCI_EXPRESS_L1PM_SUBSTATES    L1PMSubstates;
+  UINT8                           L1PmSubstates;
 } EFI_PCI_EXPRESS_DEVICE_POLICY;
 
 ///
-/// The EFI_PCI_EXPRESS_DEVICE_CONFIGURATION is an alias of the data type of
-/// EFI_PCI_EXPRESS_DEVICE_POLICY, used in notifying the platform about the
-/// PCI Express features device configured states, through the NotifyDeviceState
-/// interface method.
-/// The EFI encoded macros like EFI_PCI_EXPRESS_*_AUTO, with the value 0 will not
-/// be used to report the PCI feature definite state; similarly for the data type
-/// of DeviceCtl2AtomicOp and L1PMSubstates, its data member "Override" will not
-/// be used. For any of the device's PCI features that are not supported, or its
-/// state is unknown, it will be returned as EFI_PCI_EXPRESS_NOT_APPLICABLE.
+/// The EFI_PCI_EXPRESS_DEVICE_STATE is an alias of EFI_PCI_EXPRESS_DEVICE_POLICY,
+/// used for notification to the platform about the device PCI Express features
+/// state, through the NotifyDeviceState interface method.
+/// For any of the device's PCIe features that are not supported, or its
+/// state is unknown, it will be returned as EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE.
 ///
-typedef EFI_PCI_EXPRESS_DEVICE_POLICY EFI_PCI_EXPRESS_DEVICE_CONFIGURATION;
+typedef EFI_PCI_EXPRESS_DEVICE_POLICY EFI_PCI_EXPRESS_DEVICE_STATE;
 
 /**
-  Interface to retrieve the PCI device-specific platform policies to override
-  the PCI Express feature capabilities, of an PCI device.
+  Interface to receive the PCIe features device policy from platform.
 
   The consumer driver(s), like PCI Bus driver and PCI Host Bridge Resource Allocation
   Protocol drivers; can call this member function to retrieve the platform policies
   specific to PCI device, related to its PCI Express capabilities. The producer of
-  this protocol is platform whom shall provide the device-specific pilicies to
-  override its PCIe features.
-
-  The GetDevicePolicy() member function is meant to return data about other PCI
-  Express features which would be supported by the PCI Bus driver in future;
-  like for example the MPS, MRRS, Extended Tag, ASPM, etc. The details about
-  this PCI features can be obtained from the PCI Express Base Specification (Rev.4
-  or 5). The EFI encodings for these features are defined in the EFI_PCI_EXPRESS
-  _PLATFORM_POLICY, see the Related Definition section for this. This member function
+  this protocol shall be the platform itself to provide the device-specific policies.
+
+  The GetDevicePolicy() member function is meant to return data about the PCIe
+  features like the MPS, MRRS, Extended Tag, ASPM, etc. The details about
+  these PCIe features can be obtained from the PCI Express Base Specification (Rev.4
+  or 5). The EFI encodings are defined in the EFI_PCI_EXPRESS_PLATFORM_POLICY,
+  see the Related Definition section for this. This member function
   will use the associated EFI handle of the root bridge instance and the PCI address
   of type EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS to determine the physical
-  PCI device within the chipset, to return its device-specific platform policies.
+  PCI device within the chipset.
   It is caller's responsibility to allocate the buffer and pass its pointer of
   type EFI_PCI_EXPRESS_DEVICE_POLICY to this member function, to get its device
   -specific policy data.
   The caller is required to initialize the input buffer with either of two values:-
-  1.  EFI_PCI_EXPRESS_NOT_APPLICABLE: for those PCI Express features which are not
-      supported by the calling driver
-  2.  EFI_PCI_EXPRESS_*_AUTO: for those PCI Express features which are supported
-      by the calling driver
-  In order to skip any PCI Express feature for any particular PCI device, this
-  interface is expected to return its hardware default state as defined by the
-  PCI Express Base Specification.
+  1.  EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE: for those PCI Express features
+      which are not supported by the calling driver
+  2.  EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO: for those PCI Express features which
+      are supported by the calling driver
 
   @param[in]      This          Pointer to the  EFI_PCI_EXPRESS_PLATFORM_PROTOCOL instance.
   @param[in]      RootBridge    EFI handle of associated root bridge to the PCI device
@@ -434,8 +288,8 @@ typedef EFI_PCI_EXPRESS_DEVICE_POLICY EFI_PCI_EXPRESS_DEVICE_CONFIGURATION;
                                 device. See UEFI 2.1 Specification for the definition
                                 of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
   @param[in]      Size          The size, in bytes, of the input buffer, in next parameter.
-  @param[in,out]  PciExPolicy   The pointer to platform policy with respect to other
-                                PCI features like, the MPS, MRRS, etc. Type
+  @param[in,out]  PciePolicy    The pointer to buffer containing the device policies for
+                                PCIe features like, the MPS, MRRS, etc. Type
                                 EFI_PCI_EXPRESS_DEVICE_POLICY is defined above.
 
 
@@ -454,15 +308,14 @@ EFI_STATUS
   IN        EFI_HANDLE                                    RootBridge,
   IN        EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS   PciAddress,
   IN        UINTN                                         Size,
-  IN OUT    EFI_PCI_EXPRESS_DEVICE_POLICY                 *PciExPolicy
+  IN OUT    EFI_PCI_EXPRESS_DEVICE_POLICY                 *PciePolicy
 );
 
 /**
-  Notifies the platform about the PCI device current configuration state w.r.t.
-  its PCIe capabilites.
+  Notifies the platform about the PCI device current state of its PCIe capabilites.
 
   The PCI Bus driver or PCI Host Bridge Resource Allocation Protocol drivers
-  can call this member function to notfy the present PCIe configuration state
+  can call this member function to notify the present PCIe configuration state
   of the PCI device, to the platform. This is expected to be invoked after the
   completion of the PCI enumeration phase.
 
@@ -472,32 +325,29 @@ EFI_STATUS
   etc. The details about this PCI features can be obtained from the PCI Express
   Base Specification.
 
-  The EFI encodings and data types used to report out the present configuration
-  state, are same as those that were used by the platform to return the device-specific
+  The EFI encodings and data types used to report out the current state, are
+  same as those that were used by the platform to return the device-specific
   platform policies, in the EFI_PCI_EXPRESS_DEVICE_POLICY (see the "Related
   Definition" section for this). The difference is that it should return the actual
-  state in the EFI_PCI_EXPRESS_DEVICE_CONFIGURATION; without any macros corresponding
-  to EFI_PCI_EXPRESS_*_AUTO, and for the data types of DeviceCtl2AtomicOp and
-  L1PMSubstates, its corresponding data member "Override" bit field value shall be
-  ignored, will not be applicable. Note that, if the notifying driver does not
+  state in the EFI_PCI_EXPRESS_DEVICE_STATE; without any macros corresponding
+  to EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO. Note that, if the notifying driver does not
   support any PCIe feature than it shall return its corresponding value as
-  EFI_PCI_EXPRESS_NOT_APPLICABLE.
+  EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE.
 
   This member function will use the associated EFI handle of the PCI IO Protocol
   to address the physical PCI device within the chipset. It is caller's
   responsibility to allocate the buffer and pass its pointer to this member
   function.
 
-  @param[in]  This                      Pointer to the  EFI_PCI_EXPRESS_PLATFORM_PROTOCOL instance.
-  @param[in]  PciDevice                 The associated PCI IO Protocol handle of the PCI
-                                        device. Type EFI_HANDLE is defined in
-                                        InstallProtocolInterface() in the UEFI 2.1
-                                        Specification
-  @param[in] Size                       The size, in bytes, of the input buffer in next parameter.
-  @param[in] PciExDeviceConfiguration   The pointer to device configuration state with respect
-                                        to other PCI features like, the MPS, MRRS, etc. Type
-                                        EFI_PCI_EXPRESS_DEVICE_CONFIGURATION is an alias to
-                                        EFI_PCI_EXPRESS_DEVICE_POLICY, as defined above.
+  @param[in]  This          Pointer to the  EFI_PCI_EXPRESS_PLATFORM_PROTOCOL instance.
+  @param[in]  PciDevice     The associated PCI IO Protocol handle of the PCI
+                            device. Type EFI_HANDLE is defined in
+                            InstallProtocolInterface() in the UEFI 2.1 Specification
+  @param[in] Size           The size, in bytes, of the input buffer in next parameter.
+  @param[in] PcieState      The pointer to device configuration state with respect
+                            to other PCI features like, the MPS, MRRS, etc. Type
+                            EFI_PCI_EXPRESS_DEVICE_STATE is an alias to
+                            EFI_PCI_EXPRESS_DEVICE_POLICY, as defined above.
 
 
   @retval EFI_SUCCESS             This function completed successfully, the platform
@@ -513,7 +363,7 @@ EFI_STATUS
   IN CONST  EFI_PCI_EXPRESS_PLATFORM_PROTOCOL     *This,
   IN        EFI_HANDLE                            PciDevice,
   IN        UINTN                                 Size,
-  IN        EFI_PCI_EXPRESS_DEVICE_CONFIGURATION  *PciExDeviceConfiguration
+  IN        EFI_PCI_EXPRESS_DEVICE_STATE          *PcieState
   );
 
 ///
@@ -527,21 +377,21 @@ EFI_STATUS
 ///
 typedef struct {
   //
-  // For PCI Express feature - Max. Payload Size
+  // For PCI Express feature - Maximum Payload Size
   //
-  BOOLEAN  Mps;
+  BOOLEAN  MaxPayloadSize;
   //
-  // For PCI Express feature - Max. Read Request Size
+  // For PCI Express feature - Maximum Read Request Size
   //
-  BOOLEAN  Mrrs;
+  BOOLEAN  MaxReadRequestSize;
   //
   // For PCI Express feature - Extended Tag
   //
-  BOOLEAN  ExtTag;
+  BOOLEAN  ExtendedTag;
   //
-  // For PCI Express feature - Relax Order
+  // For PCI Express feature - Relaxed Ordering
   //
-  BOOLEAN  RelaxOrder;
+  BOOLEAN  RelaxedOrdering;
   //
   // For PCI Express feature - No-Snoop
   //
@@ -553,11 +403,7 @@ typedef struct {
   //
   // For PCI Express feature - Common Clock Configuration
   //
-  BOOLEAN  Ccc;
-  //
-  // For PCI Express feature - Extended Sync
-  //
-  BOOLEAN  ExtSync;
+  BOOLEAN  CommonClockConfiguration;
   //
   // For PCI Express feature - Atomic Op
   //
@@ -573,11 +419,11 @@ typedef struct {
   //
   // For PCI Express feature - Completion Timeout
   //
-  BOOLEAN  Cto;
+  BOOLEAN  CompletionTimeout;
   //
   // For PCI Express feature - Clock Power Management
   //
-  BOOLEAN  Cpm;
+  BOOLEAN  ClockPowerManagement;
   //
   // For PCI Express feature - L1 PM Substates
   //
@@ -587,14 +433,14 @@ typedef struct {
 
 /**
   Informs the platform about its PCI Express features support capability and it
-  accepts request from platform to initialize only those features.
+  accepts request from platform to initialize those features.
 
   The caller shall first invoke this interface to inform platform about the list
-  of PCI Express feature supported, in the buffer of type EFI_PCI_EXPRESS_PLATFORM_POLICY.
-  On return, it expects the list of supported PCI Express features that are required
-  to be configured; in the same form with the value of TRUE. The caller shall
-  ignore the feature request if its value is TRUE if that feature was initialized
-  as FALSE when it was passed as the input parameter.
+  of PCI Express feature that are supported by passing its value as TRUE, and value
+  FALSE for unsupported features, in the buffer of type EFI_PCI_EXPRESS_PLATFORM_POLICY.
+  On return, it expects the list of supported PCI Express features as a requirement
+  from platform; if its return value is TRUE. The caller shall ignore invalid TRUE
+  values.
 
   The caller shall treat this list of PCI Express features as the global platform
   requirement; and corresponding to that feature list it expects device-specific
@@ -609,8 +455,8 @@ typedef struct {
   The protocol producing driver shall use the size input parameter to determine
   the length of the buffer of type EFI_PCI_EXPRESS_PLATFORM_POLICY, and to also
   determine version of the caller. If the size of the input buffer is more than
-  what its supporting version (indicated through the MajorVersion and MinorVersion
-  data members of the protocol) than it shall return EFI_INVALID_PARAMETER.
+  what its supporting version (indicated through the Revision data member of the
+  protocol) than it shall return EFI_INVALID_PARAMETER.
 
   The error code in returned status essential means that the caller cannot initialize
   any PCI Express features. Thus, this interface would be primary interface for the
@@ -644,6 +490,16 @@ EFI_STATUS
   IN OUT    EFI_PCI_EXPRESS_PLATFORM_POLICY       *PlatformPolicy
 );
 
+///
+/// The revision of the PCI Express Protocol is represented as 32-bit value
+/// with the lower WORD representing the Minor value and upper WORD
+/// representing the Major value.
+/// As per the specification of this protocol, the revision is 1.1.
+/// Any driver utilizing this protocol shall use the revision number to
+/// maintain the backward compatibility.
+///
+#define EFI_PCI_EXPRESS_PLATFORM_PROTOCOL_REVISION 0x00010001
+
 ///
 /// This protocol provides the interface between the PCI bus driver/PCI Host
 /// Bridge Resource Allocation driver and a platform-specific driver to describe
@@ -651,13 +507,9 @@ EFI_STATUS
 ///
 struct _EFI_PCI_EXPRESS_PLATFORM_PROTOCOL {
   ///
-  /// The major version of this PCIe Platform Protocol
-  ///
-  UINT8                                  MajorVersion;
-  ///
-  /// The minor version of this PCIe Platform Protocol
+  /// The revision of this PCIe Platform Protocol
   ///
-  UINT8                                  MinorVersion;
+  UINT32                                 Revision;
   ///
   /// Retrieves the PCIe device-specific platform policy regarding enumeration.
   ///
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 02/15] MdeModulePkg/PciBusDxe: PciBusDxe Code refactor
       [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-10 16:13 ` 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
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-10 16:13 UTC (permalink / raw)
  To: devel; +Cc: Jian J Wang, Hao A Wu, Ray Ni

References:-
  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

This code change represents the code refactoring by expelling the
previous changes of the PCIe features.

Signed-off-by: Ashraf Javeed <ashraf.javeed@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>
---
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c             |    4 --
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h             |   20 ++-------
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf        |   10 +----
 MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c   |   11 +----
 MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c | 2178 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h |  399 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c  | 1019 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h  |  304 -----------------------------------------------------------------------------------------------------------------------------------
 MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c |  902 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.h |  119 ----------------------------------------------------
 10 files changed, 6 insertions(+), 4960 deletions(-)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
index 714101c..53e6dfa 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
@@ -284,10 +284,6 @@ PciBusDriverBindingStart (
           (VOID **) &gPciOverrideProtocol
           );
   }
-  //
-  // get the PCI Express Protocol or the PCI Express Override Protocol
-  //
-  GetPciExpressProtocol ();
 
   if (mIoMmuProtocol == NULL) {
     gBS->LocateProtocol (
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
index 34f482d..5a7c1c2 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
@@ -27,6 +27,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Protocol/PciOverride.h>
 #include <Protocol/PciEnumerationComplete.h>
 #include <Protocol/IoMmu.h>
+#include <Protocol/PciExpressOverride.h>
+#include <Protocol/PciExpressPlatform.h>
 
 #include <Library/DebugLib.h>
 #include <Library/UefiDriverEntryPoint.h>
@@ -42,8 +44,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <IndustryStandard/Pci.h>
 #include <IndustryStandard/PeImage.h>
 #include <IndustryStandard/Acpi.h>
-#include <Protocol/PciExpressOverride.h>
-#include <Protocol/PciExpressPlatform.h>
+
 
 typedef struct _PCI_IO_DEVICE              PCI_IO_DEVICE;
 typedef struct _PCI_BAR                    PCI_BAR;
@@ -81,8 +82,6 @@ typedef enum {
 #include "PciPowerManagement.h"
 #include "PciHotPlugSupport.h"
 #include "PciLib.h"
-#include "PciPlatformSupport.h"
-#include "PciFeatureSupport.h"
 
 #define VGABASE1  0x3B0
 #define VGALIMIT1 0x3BB
@@ -287,19 +286,6 @@ struct _PCI_IO_DEVICE {
   // This field is used to support this case.
   //
   UINT16                                    BridgeIoAlignment;
-  //
-  // PCI Express features setup flags
-  //
-  UINT8                                     SetupMPS;
-  UINT8                                     SetupMRRS;
-  PCI_FEATURE_POLICY                        SetupRO;
-  PCI_FEATURE_POLICY                        SetupNS;
-  PCI_FEATURE_POLICY                        SetupCTO;
-  EFI_PCI_EXPRESS_ATOMIC_OP                 SetupAtomicOp;
-  BOOLEAN                                   SetupLtr;
-  UINT8                                     SetupExtTag;
-  UINT8                                     SetupAspm;
-  EFI_PCI_EXPRESS_COMMON_CLOCK_CFG          SetupCcc;
 };
 
 #define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
index e3ad105..3b1559e 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
@@ -57,12 +57,6 @@
   PciCommand.h
   PciIo.h
   PciBus.h
-  PciFeatureSupport.c
-  PciFeatureSupport.h
-  PciPlatformSupport.c
-  PciPlatformSupport.h
-  PciExpressFeatures.c
-  PciExpressFeatures.h
 
 [Packages]
   MdePkg/MdePkg.dec
@@ -97,8 +91,8 @@
   gEfiLoadFile2ProtocolGuid                       ## SOMETIMES_PRODUCES
   gEdkiiIoMmuProtocolGuid                         ## SOMETIMES_CONSUMES
   gEfiLoadedImageDevicePathProtocolGuid           ## CONSUMES
-  gEfiPciExpressPlatformProtocolGuid                     ## SOMETIMES_CONSUMES
-  gEfiPciExpressOverrideProtocolGuid                     ## SOMETIMES_CONSUMES
+  gEfiPciExpressPlatformProtocolGuid              ## SOMETIMES_CONSUMES
+  gEfiPciExpressOverrideProtocolGuid              ## SOMETIMES_CONSUMES
 
 
 [FeaturePcd]
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
index 07ee9ba..5724fd6 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
@@ -859,16 +859,7 @@ StartPciDevicesOnBridge (
     // the platform is required to indicate its requirement for the initialization
     // of PCI Express features by publishing its protocol
     //
-    if (
-        gFullEnumeration
-        && IsPciExpressProtocolPresent ()
-    ) {
-
-      Status = EnumeratePciExpressFeatures (
-                Controller,
-                RootBridge
-                );
-    }
+
     //
     // finally start those PCI bridge port devices only
     //
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c
deleted file mode 100644
index 1e2f4a4..0000000
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c
+++ /dev/null
@@ -1,2178 +0,0 @@
-/** @file
-  PCI standard feature support functions implementation for PCI Bus module..
-
-Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "PciBus.h"
-#include "PciFeatureSupport.h"
-
-VOID
-ReportPciWriteError (
-  IN UINT8  Bus,
-  IN UINT8  Device,
-  IN UINT8  Function,
-  IN UINT32 Offset
-  )
-{
-  DEBUG ((
-    DEBUG_ERROR,
-    "Unexpected PCI register (%d,%d,%d,0x%x) write error!",
-    Bus,
-    Device,
-    Function,
-    Offset
-    ));
-}
-
-/**
-  Compare and Swap the payload value - between the global variable to maaintain
-  common value among all the devices in the PCIe heirarchy from the root bridge
-  device and all its child devices; with the device-sepcific setup value.
-
-  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
-  @param PciExpressConfigurationTable  pointer to PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE
-
-  @retval EFI_SUCCESS                   processing of PCI feature Max_Payload_Size
-                                        is successful.
-**/
-EFI_STATUS
-CasMaxPayloadSize (
-    IN  PCI_IO_DEVICE                             *PciDevice,
-    IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
-  )
-{
-  UINT8                                   MpsValue;
-
-  //
-  // align the MPS of the tree to the HCF with this device
-  //
-  if (PciExpressConfigurationTable) {
-    MpsValue = PciExpressConfigurationTable->Max_Payload_Size;
-
-    MpsValue = MIN (PciDevice->SetupMPS, MpsValue);
-    PciDevice->SetupMPS = MIN (PciDevice->SetupMPS, MpsValue);
-
-    if (MpsValue != PciExpressConfigurationTable->Max_Payload_Size) {
-      PciExpressConfigurationTable->Max_Payload_Size = MpsValue;
-    }
-  }
-
-  DEBUG ((
-    DEBUG_INFO,
-    "MPS: %d [DevCap:%d],",
-    PciDevice->SetupMPS, PciDevice->PciExpressCapabilityStructure.DeviceCapability.Bits.MaxPayloadSize
-  ));
-
-  return EFI_SUCCESS;
-}
-
-/**
-  The main routine which process the PCI feature Max_Payload_Size as per the
-  device-specific platform policy, as well as in complaince with the PCI Base
-  specification Revision 4, that aligns the value for the entire PCI heirarchy
-  starting from its physical PCI Root port / Bridge device.
-
-  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
-  @param PciExpressConfigurationTable  pointer to PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE
-
-  @retval EFI_SUCCESS                   processing of PCI feature Max_Payload_Size
-                                        is successful.
-**/
-EFI_STATUS
-SetupMaxPayloadSize (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
-  )
-{
-  PCI_REG_PCIE_DEVICE_CAPABILITY          PciDeviceCap;
-  UINT8                                   MpsValue;
-
-
-  PciDeviceCap.Uint32 = PciDevice->PciExpressCapabilityStructure.DeviceCapability.Uint32;
-
-  if (PciDevice->SetupMPS == EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_AUTO) {
-    //
-    // configure this feature as per its PCIe device capabilities
-    //
-    MpsValue = (UINT8)PciDeviceCap.Bits.MaxPayloadSize;
-    //
-    // no change to PCI Root ports without any endpoint device
-    //
-    if (IS_PCI_BRIDGE (&PciDevice->Pci) && PciDeviceCap.Bits.MaxPayloadSize) {
-      if (IsListEmpty  (&PciDevice->ChildList)) {
-        //
-        // No device on root bridge
-        //
-        MpsValue = PCIE_MAX_PAYLOAD_SIZE_128B;
-      }
-    }
-  } else {
-    MpsValue = SetDevicePolicyPciExpressMps (PciDevice->SetupMPS);
-  }
-  //
-  // discard device policy override request if greater than PCI device capability
-  //
-  PciDevice->SetupMPS = MIN ((UINT8)PciDeviceCap.Bits.MaxPayloadSize, MpsValue);
-
-  return CasMaxPayloadSize (
-          PciDevice,
-          PciExpressConfigurationTable
-          );
-}
-
-/**
-  Overrides the PCI Device Control register MaxPayloadSize 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
-ProgramMaxPayloadSize (
-  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 (PcieDev.Bits.MaxPayloadSize != PciDevice->SetupMPS) {
-    PcieDev.Bits.MaxPayloadSize = PciDevice->SetupMPS;
-    DEBUG (( DEBUG_INFO, "MPS=%d,", PciDevice->SetupMPS));
-
-    //
-    // 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 MPS=%d,", PciDevice->SetupMPS));
-  }
-
-  return Status;
-}
-
-EFI_STATUS
-ConditionalCasMaxReadReqSize (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
-  )
-{
-  //
-  // align the Max_Read_Request_Size of the PCI tree based on 3 conditions:
-  // first, if user defines MRRS for any one PCI device in the tree than align
-  // all the devices in the PCI tree.
-  // second, if user override is not define for this PCI tree than setup the MRRS
-  // based on MPS value of the tree to meet the criteria for the isochronous
-  // traffic.
-  // third, if no user override, or platform firmware policy has not selected
-  // this PCI bus driver to configure the MPS; than configure the MRRS to a
-  // highest common value of PCI device capability for the MPS found among all
-  // the PCI devices in this tree
-  //
-  if (PciExpressConfigurationTable) {
-    if (PciExpressConfigurationTable->Lock_Max_Read_Request_Size) {
-      PciDevice->SetupMRRS = PciExpressConfigurationTable->Max_Read_Request_Size;
-    } else {
-      if (mPciExpressPlatformPolicy.Mps) {
-        PciDevice->SetupMRRS = PciDevice->SetupMPS;
-      } else {
-        PciDevice->SetupMRRS = MIN (
-                                PciDevice->SetupMRRS,
-                                PciExpressConfigurationTable->Max_Read_Request_Size
-                                );
-      }
-      PciExpressConfigurationTable->Max_Read_Request_Size = PciDevice->SetupMRRS;
-    }
-  }
-  DEBUG (( DEBUG_INFO, "MRRS: %d,", PciDevice->SetupMRRS));
-
-  return EFI_SUCCESS;
-}
-
-/**
-  The main routine which process the PCI feature Max_Read_Req_Size as per the
-  device-specific platform policy, as well as in complaince with the PCI Base
-  specification Revision 4, that aligns the value for the entire PCI heirarchy
-  starting from its physical PCI Root port / Bridge device.
-
-  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
-  @param PciExpressConfigurationTable  pointer to PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE
-
-  @retval EFI_SUCCESS                   processing of PCI feature Max_Read_Req_Size
-                                        is successful.
-**/
-EFI_STATUS
-SetupMaxReadReqSize (
-  IN  PCI_IO_DEVICE                           *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
-  )
-{
-  PCI_REG_PCIE_DEVICE_CAPABILITY  PciDeviceCap;
-  UINT8                           MrrsValue;
-
-  PciDeviceCap.Uint32 = PciDevice->PciExpressCapabilityStructure.DeviceCapability.Uint32;
-
-  if (PciDevice->SetupMRRS == EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_AUTO) {
-    //
-    // The maximum read request size is not the data packet size of the TLP,
-    // but the memory read request size, and set to the function as a requestor
-    // to not exceed this limit.
-    // However, for the PCI device capable of isochronous traffic; this memory read
-    // request size should not extend beyond the Max_Payload_Size. Thus, in case if
-    // device policy return by platform indicates to set as per device capability
-    // than set as per Max_Payload_Size configuration value
-    //
-    if (mPciExpressPlatformPolicy.Mps) {
-      MrrsValue = PciDevice->SetupMPS;
-    } else {
-      //
-      // in case this driver is not required to configure the Max_Payload_Size
-      // than consider programming HCF of the device capability's Max_Payload_Size
-      // in this PCI hierarchy; thus making this an implementation specific feature
-      // which the platform should avoid. For better results, the platform should
-      // make both the Max_Payload_Size & Max_Read_Request_Size to be configured
-      // by this driver
-      //
-      MrrsValue = (UINT8)PciDeviceCap.Bits.MaxPayloadSize;
-    }
-  } else {
-    //
-    // override as per platform based device policy
-    //
-    MrrsValue = SetDevicePolicyPciExpressMrrs (PciDevice->SetupMRRS);
-    //
-    // align this device's Max_Read_Request_Size value to the entire PCI tree
-    //
-    if (PciExpressConfigurationTable) {
-      if (!PciExpressConfigurationTable->Lock_Max_Read_Request_Size) {
-        PciExpressConfigurationTable->Lock_Max_Read_Request_Size = TRUE;
-        PciExpressConfigurationTable->Max_Read_Request_Size = MrrsValue;
-      } else {
-        //
-        // in case of another user enforced value of MRRS within the same tree,
-        // pick the smallest between the locked value and this value; to set
-        // across entire PCI tree nodes
-        //
-        MrrsValue = MIN (
-                      MrrsValue,
-                      PciExpressConfigurationTable->Max_Read_Request_Size
-                      );
-        PciExpressConfigurationTable->Max_Read_Request_Size = MrrsValue;
-      }
-    }
-  }
-  //
-  // align this device's Max_Read_Request_Size to derived configuration value
-  //
-  PciDevice->SetupMRRS = MrrsValue;
-
-  return ConditionalCasMaxReadReqSize (
-          PciDevice,
-          PciExpressConfigurationTable
-          );
-}
-
-
-/**
-  Overrides the PCI Device Control register Max_Read_Req_Size 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 controller.
-  @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
-ProgramMaxReadReqSize (
-  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 (PcieDev.Bits.MaxReadRequestSize != PciDevice->SetupMRRS) {
-    PcieDev.Bits.MaxReadRequestSize = PciDevice->SetupMRRS;
-    DEBUG (( DEBUG_INFO, "MRRS: %d,", PciDevice->SetupMRRS));
-
-    //
-    // 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 MRRS=%d,", PciDevice->SetupMRRS));
-  }
-
-  return Status;
-}
-
-/**
-  Overrides the PCI Device Control register Relax Order 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
-ProgramRelaxOrder (
-  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->SetupRO.Override
-      &&  PcieDev.Bits.RelaxedOrdering != PciDevice->SetupRO.Act
-      ) {
-    PcieDev.Bits.RelaxedOrdering = PciDevice->SetupRO.Act;
-    DEBUG (( DEBUG_INFO, "RO=%d,", PciDevice->SetupRO.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 RO,", PciDevice->SetupRO.Act));
-  }
-
-  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;
-}
-
-/**
-  To determine the CTO Range A values
-
-  @param  CtoValue    input CTO range value from 0 to 14
-  @retval TRUE        the given CTO value belongs to Range A
-          FALSE       the given value does not belong to Range A
-**/
-BOOLEAN
-IsCtoRangeA (
-  IN  UINT8   CtoValue
-  )
-{
-  switch (CtoValue) {
-    case  PCIE_COMPLETION_TIMEOUT_50US_100US:
-    case  PCIE_COMPLETION_TIMEOUT_1MS_10MS:
-      return TRUE;
-  }
-  return FALSE;
-}
-
-/**
-  To determine the CTO Range B values
-
-  @param  CtoValue    input CTO range value from 0 to 14
-  @retval TRUE        the given CTO value belongs to Range B
-          FALSE       the given value does not belong to Range B
-**/
-BOOLEAN
-IsCtoRangeB (
-  IN  UINT8   CtoValue
-  )
-{
-  switch (CtoValue) {
-    case  PCIE_COMPLETION_TIMEOUT_16MS_55MS:
-    case  PCIE_COMPLETION_TIMEOUT_65MS_210MS:
-      return TRUE;
-  }
-  return FALSE;
-}
-
-/**
-  To determine the CTO Range C values
-
-  @param  CtoValue    input CTO range value from 0 to 14
-  @retval TRUE        the given CTO value belongs to Range C
-          FALSE       the given value does not belong to Range C
-**/
-BOOLEAN
-IsCtoRangeC (
-  IN  UINT8   CtoValue
-  )
-{
-  switch (CtoValue) {
-    case  PCIE_COMPLETION_TIMEOUT_260MS_900MS:
-    case  PCIE_COMPLETION_TIMEOUT_1S_3_5S:
-      return TRUE;
-  }
-  return FALSE;
-}
-
-/**
-  To determine the CTO Range D values
-
-  @param  CtoValue    input CTO range value from 0 to 14
-  @retval TRUE        the given CTO value belongs to Range D
-          FALSE       the given value does not belong to Range D
-**/
-BOOLEAN
-IsCtoRangeD (
-  IN  UINT8   CtoValue
-  )
-{
-  switch (CtoValue) {
-    case  PCIE_COMPLETION_TIMEOUT_4S_13S:
-    case  PCIE_COMPLETION_TIMEOUT_17S_64S:
-      return TRUE;
-  }
-  return FALSE;
-}
-
-/**
-  The main routine which setup the PCI feature Completion Timeout as per the
-  device-specific platform policy, as well as in complaince with the PCI Base
-  specification Revision 4.
-
-  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
-
-  @retval EFI_SUCCESS                   processing of PCI feature CTO is successful.
-**/
-EFI_STATUS
-SetupCompletionTimeout (
-  IN PCI_IO_DEVICE          *PciDevice,
-  IN VOID                   *PciExFeatureConfiguration
-  )
-{
-  PCI_REG_PCIE_DEVICE_CAPABILITY2 DeviceCap2;
-  UINT8                           CtoRangeValue;
-
-  if (!PciDevice->SetupCTO.Override) {
-    //
-    // No override of CTO is required for this device
-    //
-    return  EFI_SUCCESS;
-  }
-
-  //
-  // determine the CTO range values as per its device capability register
-  //
-  DeviceCap2.Uint32 = PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Uint32;
-  if (!DeviceCap2.Bits.CompletionTimeoutRanges
-      && !DeviceCap2.Bits.CompletionTimeoutDisable
-  ) {
-    //
-    // device does not support the CTO mechanism, hence no override is applicable
-    //
-    return EFI_SUCCESS;
-  }
-
-  //
-  // override the device CTO values if applicable
-  //
-  if (PciDevice->SetupCTO.Act) {
-    //
-    // program the CTO range values
-    //
-    if (DeviceCap2.Bits.CompletionTimeoutRanges) {
-      CtoRangeValue = PCIE_COMPLETION_TIMEOUT_50US_50MS;
-      //
-      // in case if the supported CTO range and the requirement from platform
-      // policy does not match, than the CTO range setting would be based on
-      // this driver's implementation specific, and its rules are as follows:-
-      //
-      // if device is capable of Range A only and if platform ask for any of
-      // ranges B, C, D; than this implementation will only program the default
-      // range value for the duration of 50us to 50ms.
-      //
-      // if device is capable of Range B, or range B & C, or Ranges B, C & D only
-      // and if the platform ask for the Range A; than this implementation will
-      // only program the default range value for the duration of 50us to 50ms.
-      //
-      // if the device is capable of Range B only, or the ranges A & B; and the
-      // platform ask for Range C, or Range D values, than this implementation
-      // will only program the Range B value for the duration of 65ms to 210ms.
-      //
-      // if the device is capable of Ranges B & C, or Ranges A, B, and C; and
-      // if the platform ask for Range D values; than this implementation will
-      // only program the Range C for the duration of 1s to 3.5s.
-      //
-
-      switch (DeviceCap2.Bits.CompletionTimeoutRanges) {
-        case  PCIE_COMPLETION_TIMEOUT_RANGE_A_SUPPORTED:
-          if (IsCtoRangeA (PciDevice->SetupCTO.Support)) {
-            CtoRangeValue = PciDevice->SetupCTO.Support;
-          }
-          //
-          // if device is capable of Range A only and if platform ask for any of
-          // ranges B, C, D; than this implementation will only program the default
-          // range value for the duration of 50us to 50ms.
-          //
-          if (IsCtoRangeB (PciDevice->SetupCTO.Support)
-              || IsCtoRangeC (PciDevice->SetupCTO.Support)
-              || IsCtoRangeD (PciDevice->SetupCTO.Support)
-          ) {
-            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_50US_50MS;
-          }
-          break;
-
-        case  PCIE_COMPLETION_TIMEOUT_RANGE_B_SUPPORTED:
-          //
-          // if device is capable of Range B, or range B & C, or Ranges B, C & D only
-          // and if the platform ask for the Range A; than this implementation will
-          // only program the default range value for the duration of 50us to 50ms.
-          //
-          if (IsCtoRangeA (PciDevice->SetupCTO.Support)) {
-            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_50US_50MS;
-          }
-
-          if (IsCtoRangeB (PciDevice->SetupCTO.Support)) {
-            CtoRangeValue = PciDevice->SetupCTO.Support;
-          }
-          //
-          // if the device is capable of Range B only, or the ranges A & B; and the
-          // platform ask for Range C, or Range D values, than this implementation
-          // will only program the Range B value for the duration of 65ms to 210ms.
-          //
-          if (IsCtoRangeC (PciDevice->SetupCTO.Support)
-              || IsCtoRangeD (PciDevice->SetupCTO.Support)
-          ) {
-            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_65MS_210MS;
-          }
-          break;
-
-        case  PCIE_COMPLETION_TIMEOUT_RANGE_B_C_SUPPORTED:
-          if (IsCtoRangeA (PciDevice->SetupCTO.Support)) {
-            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_50US_50MS;
-          }
-
-          if (IsCtoRangeB (PciDevice->SetupCTO.Support)
-              || IsCtoRangeC (PciDevice->SetupCTO.Support)
-              ) {
-            CtoRangeValue = PciDevice->SetupCTO.Support;
-          }
-          //
-          // if the device is capable of Ranges B & C, or Ranges A, B, and C; and
-          // if the platform ask for Range D values; than this implementation will
-          // only program the Range C for the duration of 1s to 3.5s.
-          //
-          if (IsCtoRangeD (PciDevice->SetupCTO.Support)) {
-            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_1S_3_5S;
-          }
-          break;
-
-        case  PCIE_COMPLETION_TIMEOUT_RANGE_B_C_D_SUPPORTED:
-          if (IsCtoRangeA (PciDevice->SetupCTO.Support)) {
-            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_50US_50MS;
-          }
-          if (IsCtoRangeB (PciDevice->SetupCTO.Support)
-              || IsCtoRangeC (PciDevice->SetupCTO.Support)
-              || IsCtoRangeD (PciDevice->SetupCTO.Support)
-          ) {
-            CtoRangeValue = PciDevice->SetupCTO.Support;
-          }
-          break;
-
-        case  PCIE_COMPLETION_TIMEOUT_RANGE_A_B_SUPPORTED:
-          if (IsCtoRangeA (PciDevice->SetupCTO.Support)
-              || IsCtoRangeB (PciDevice->SetupCTO.Support)
-              ) {
-            CtoRangeValue = PciDevice->SetupCTO.Support;
-          }
-          if (IsCtoRangeC (PciDevice->SetupCTO.Support)
-              || IsCtoRangeD (PciDevice->SetupCTO.Support)
-          ) {
-            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_65MS_210MS;
-          }
-          break;
-
-        case  PCIE_COMPLETION_TIMEOUT_RANGE_A_B_C_SUPPORTED:
-          if (IsCtoRangeA (PciDevice->SetupCTO.Support)
-              || IsCtoRangeB (PciDevice->SetupCTO.Support)
-              || IsCtoRangeC (PciDevice->SetupCTO.Support)
-          ) {
-            CtoRangeValue = PciDevice->SetupCTO.Support;
-          }
-          if (IsCtoRangeD (PciDevice->SetupCTO.Support)) {
-            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_1S_3_5S;
-          }
-          break;
-
-        case  PCIE_COMPLETION_TIMEOUT_RANGE_A_B_C_D_SUPPORTED:
-          if (IsCtoRangeA (PciDevice->SetupCTO.Support)
-              || IsCtoRangeB (PciDevice->SetupCTO.Support)
-              || IsCtoRangeC (PciDevice->SetupCTO.Support)
-              || IsCtoRangeD (PciDevice->SetupCTO.Support)
-          ) {
-            CtoRangeValue = PciDevice->SetupCTO.Support;
-          }
-          break;
-
-        default:
-          DEBUG ((
-            DEBUG_ERROR,
-            "Invalid CTO range: %d\n",
-            DeviceCap2.Bits.CompletionTimeoutRanges
-            ));
-          return EFI_INVALID_PARAMETER;
-      }
-
-      if (PciDevice->SetupCTO.Support != CtoRangeValue) {
-        PciDevice->SetupCTO.Support = CtoRangeValue;
-      }
-    }
-    DEBUG (( DEBUG_INFO, "CTO enable: %d, CTO range: 0x%x,",
-        PciDevice->SetupCTO.Act,
-        PciDevice->SetupCTO.Support
-    ));
-  }
-  return EFI_SUCCESS;
-}
-
-/**
-  Overrides the PCI Device Control2 register Completion Timeout range; 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
-ProgramCompletionTimeout (
-  IN PCI_IO_DEVICE          *PciDevice,
-  IN VOID                   *PciExFeatureConfiguration
-  )
-{
-  PCI_REG_PCIE_DEVICE_CONTROL2    DeviceCtl2;
-  PCI_REG_PCIE_DEVICE_CAPABILITY2 DeviceCap2;
-  UINT32                          Offset;
-  EFI_STATUS                      Status;
-  EFI_TPL                         OldTpl;
-
-  if (!PciDevice->SetupCTO.Override) {
-    //
-    // No override of CTO is required for this device
-    //
-    DEBUG (( DEBUG_INFO, "CTO skipped,"));
-    return  EFI_SUCCESS;
-  }
-
-  //
-  // to program the CTO range values, determine in its device capability register
-  //
-  DeviceCap2.Uint32 = PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Uint32;
-  if (DeviceCap2.Bits.CompletionTimeoutRanges
-      || DeviceCap2.Bits.CompletionTimeoutDisable) {
-    //
-    // device supports the CTO mechanism
-    //
-    DeviceCtl2.Uint16 = 0;
-    Offset = PciDevice->PciExpressCapabilityOffset +
-              OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2);
-    Status = PciDevice->PciIo.Pci.Read (
-                                  &PciDevice->PciIo,
-                                  EfiPciIoWidthUint16,
-                                  Offset,
-                                  1,
-                                  &DeviceCtl2.Uint16
-                                  );
-    ASSERT (Status == EFI_SUCCESS);
-  } else {
-    //
-    // device does not support the CTO mechanism, hence no override performed
-    //
-    DEBUG (( DEBUG_INFO, "CTO n/a,"));
-    return EFI_SUCCESS;
-  }
-
-  //
-  // override the device CTO values if applicable
-  //
-  if (PciDevice->SetupCTO.Act) {
-    //
-    // program the CTO range values
-    //
-    if (PciDevice->SetupCTO.Support != DeviceCtl2.Bits.CompletionTimeoutValue) {
-      DeviceCtl2.Bits.CompletionTimeoutValue = PciDevice->SetupCTO.Support;
-    }
-  } else {
-    //
-    // disable the CTO mechanism in device
-    //
-    DeviceCtl2.Bits.CompletionTimeoutValue = 0;
-    DeviceCtl2.Bits.CompletionTimeoutDisable = 1;
-  }
-  DEBUG (( DEBUG_INFO, "CTO disable: %d, CTO range: 0x%x,",
-      DeviceCtl2.Bits.CompletionTimeoutDisable,
-      DeviceCtl2.Bits.CompletionTimeoutValue
-  ));
-
-  //
-  // 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,
-                                &DeviceCtl2.Uint16
-                                );
-  //
-  // Restore TPL to its original level
-  //
-  gBS->RestoreTPL (OldTpl);
-
-  if (!EFI_ERROR(Status)) {
-    PciDevice->PciExpressCapabilityStructure.DeviceControl2.Uint16 = DeviceCtl2.Uint16;
-  } else {
-    ReportPciWriteError (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, Offset);
-  }
-  return Status;
-}
-
-/**
-  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 specification.
-
-  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
-  @param PciExFeatureConfiguration      pointer to common configuration table to
-                                        initialize the PCI Express feature
-
-  @retval EFI_SUCCESS                   bridge device routing capability is 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.AtomicOpRouting) {
-      //
-      // since the AtomicOp Routing support flag is initialized as TRUE, negate
-      // in case if any of the PCI Bridge device in the PCI tree does not support
-      // the AtomicOp Routing capability
-      //
-      if (PciExFeatureConfiguration == NULL) {
-        return EFI_INVALID_PARAMETER;
-      }
-      PciExFeatureConfiguration->AtomicOpRoutingSupported = FALSE;
-    }
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Overrides the PCI Device Control 2 register AtomicOp Requester enable 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
-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 = 0;
-  Offset = PciDevice->PciExpressCapabilityOffset +
-               OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2);
-  Status = PciDevice->PciIo.Pci.Read (
-                                  &PciDevice->PciIo,
-                                  EfiPciIoWidthUint16,
-                                  Offset,
-                                  1,
-                                  &PcieDev.Uint16
-                                  );
-  ASSERT (Status == 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 != PciDevice->SetupAtomicOp.Enable_AtomicOpRequester) {
-        PcieDev.Bits.AtomicOpRequester = PciDevice->SetupAtomicOp.Enable_AtomicOpRequester;
-      }
-      //
-      // if platform also request its AtomicOp Egress blocking to be enabled; 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.Bits.AtomicOpRouting) {
-          PcieDev.Bits.AtomicOpEgressBlocking = 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 != PciDevice->SetupAtomicOp.Enable_AtomicOpRequester) {
-            PcieDev.Bits.AtomicOpRequester = PciDevice->SetupAtomicOp.Enable_AtomicOpRequester;
-          }
-        }
-      } else {
-        //
-        // for the RCiEP device or the bridge device without any child, setup AtomicOp
-        // Requester as per platform's device policy
-        //
-        if (PcieDev.Bits.AtomicOpRequester != PciDevice->SetupAtomicOp.Enable_AtomicOpRequester) {
-          PcieDev.Bits.AtomicOpRequester = PciDevice->SetupAtomicOp.Enable_AtomicOpRequester;
-        }
-      }
-      //
-      // the enabling of AtomicOp Egress Blocking is not applicable to a non-bridge
-      // device
-      //
-    }
-    DEBUG ((
-      DEBUG_INFO,
-      "AtomicOp=%d,",
-      PcieDev.Bits.AtomicOpRequester
-      ));
-
-    //
-    // 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.DeviceControl2.Uint16 = PcieDev.Uint16;
-    } else {
-      ReportPciWriteError (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, Offset);
-    }
-  } else {
-    DEBUG (( DEBUG_INFO, "No AtomicOp,"));
-  }
-
-  return Status;
-}
-
-/**
-  The main routine which process the PCI feature LTR enable/disable 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
-SetupLtr (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
-  )
-{
-  PCI_REG_PCIE_DEVICE_CAPABILITY2 DeviceCap2;
-  //
-  // as per the PCI-Express Base Specification, in order to enable LTR mechanism
-  // in the upstream ports, all the upstream ports and its downstream ports has
-  // to support the LTR mechanism reported in its Device Capability 2 register
-  //
-  DeviceCap2.Uint32 = PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Uint32;
-
-  if (PciExpressConfigurationTable) {
-    //
-    // in this phase establish 2 requirements:
-    // (1) all the PCI devices in the hierarchy supports the LTR mechanism
-    // (2) check and record any device-specific platform policy that wants to
-    //     enable the LTR mechanism
-    //
-    if (!PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Bits.LtrMechanism) {
-
-      //
-      // it starts with the assumption that all the PCI devices support LTR mechanism
-      // and negates the flag if any PCI device Device Capability 2 register advertizes
-      // as not supported
-      //
-      PciExpressConfigurationTable->LtrSupported = FALSE;
-    }
-
-    if (PciDevice->SetupLtr == TRUE) {
-      //
-      // it starts with the assumption that device-specific platform policy would
-      // be set to LTR disable, and negates the flag if any PCI device platform
-      // policy wants to override to enable the LTR mechanism
-      //
-      PciExpressConfigurationTable->LtrEnable = TRUE;
-    }
-  } else {
-    //
-    // in case of RCiEP device or the bridge device with out any child device,
-    // overrule the device policy if the device in not capable
-    //
-    if (!PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Bits.LtrMechanism
-        && PciDevice->SetupLtr == TRUE) {
-      PciDevice->SetupLtr = FALSE;
-    }
-    //
-    // for any bridge device which is Hot-Plug capable, it is expected that platform
-    // will not enforce the enabling of LTR mechanism only for the bridge device
-    //
-  }
-
-  DEBUG (( DEBUG_INFO, "LTR En: %d (LTR Cap: %d),",
-    PciDevice->SetupLtr ? 1 : 0,
-    PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Bits.LtrMechanism
-    ));
-  return EFI_SUCCESS;
-}
-
-EFI_STATUS
-ReSetupLtr (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
-  )
-{
-  //
-  // not applicable to RCiEP device...
-  // for the bridge device without any child device, the policy is already overruled
-  // based on capability in the above routine
-  //
-  if (PciExpressConfigurationTable) {
-    //
-    // in this phase align the device policy to enable LTR policy of any PCI device
-    // in the tree if all the devices are capable to support the LTR mechanism
-    //
-    if (PciExpressConfigurationTable->LtrSupported == TRUE
-        && PciExpressConfigurationTable->LtrEnable == TRUE
-    ) {
-      PciDevice->SetupLtr = TRUE;
-    } else {
-      PciDevice->SetupLtr = FALSE;
-    }
-  }
-
-  DEBUG (( DEBUG_INFO, "LTR En: %d (LTR Cap: %d),",
-    PciDevice->SetupLtr ? 1 : 0,
-    PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Bits.LtrMechanism
-    ));
-  return EFI_SUCCESS;
-}
-
-/**
-  Program the PCI Device Control 2 register LTR mechanism 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
-ProgramLtr (
-  IN PCI_IO_DEVICE          *PciDevice,
-  IN VOID                   *PciExFeatureConfiguration
-  )
-{
-  PCI_REG_PCIE_DEVICE_CONTROL2  PcieDev;
-  UINT32                        Offset;
-  EFI_STATUS                    Status;
-  EFI_TPL                       OldTpl;
-
-  PcieDev.Uint16 = 0;
-  Offset = PciDevice->PciExpressCapabilityOffset +
-               OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2);
-  Status = PciDevice->PciIo.Pci.Read (
-                                  &PciDevice->PciIo,
-                                  EfiPciIoWidthUint16,
-                                  Offset,
-                                  1,
-                                  &PcieDev.Uint16
-                                  );
-  ASSERT (Status == EFI_SUCCESS);
-
-  if (PciDevice->SetupLtr != (BOOLEAN) PcieDev.Bits.LtrMechanism) {
-    PcieDev.Bits.LtrMechanism = PciDevice->SetupLtr ? 1 : 0;
-    DEBUG (( DEBUG_INFO, "LTR=%d,", PcieDev.Bits.LtrMechanism));
-
-    //
-    // 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.DeviceControl2.Uint16 = PcieDev.Uint16;
-    } else {
-      ReportPciWriteError (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, Offset);
-    }
-  } else {
-    DEBUG (( DEBUG_INFO, "no LTR,"));
-  }
-
-  return Status;
-}
-
-/**
-  The main routine to setup the PCI Express feature Extended Tag 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
-SetupExtTag (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
-  )
-{
-  PCI_REG_PCIE_DEVICE_CAPABILITY2 DeviceCap2;
-  PCI_REG_PCIE_DEVICE_CAPABILITY  DeviceCap;
-  EFI_PCI_EXPRESS_EXTENDED_TAG    PciExpressExtendedTag;
-
-  DeviceCap.Uint32 = PciDevice->PciExpressCapabilityStructure.DeviceCapability.Uint32;
-  DeviceCap2.Uint32 = PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Uint32;
-  //
-  // The PCI Express feature Extended Tag has to be maintained common from a
-  // root bridge device to all its child devices.
-  // The Device Capability 2 register is used to determine the 10b Extended Tag
-  // capability of a device. The device capability register is used to determine
-  // 5b/8b Extended Tag capability of a device
-  //
-  if (DeviceCap2.Bits.TenBitTagCompleterSupported & DeviceCap2.Bits.TenBitTagRequesterSupported) {
-    //
-    // device supports the 10b Extended Tag capability
-    //
-    PciExpressExtendedTag = EFI_PCI_EXPRESS_EXTENDED_TAG_10BIT;
-  } else {
-    if (DeviceCap.Bits.ExtendedTagField) {
-      PciExpressExtendedTag = EFI_PCI_EXPRESS_EXTENDED_TAG_8BIT;
-    } else {
-      PciExpressExtendedTag = EFI_PCI_EXPRESS_EXTENDED_TAG_5BIT;
-    }
-  }
-  if (PciDevice->SetupExtTag == EFI_PCI_EXPRESS_EXTENDED_TAG_AUTO) {
-    PciDevice->SetupExtTag = PciExpressExtendedTag;
-  }
-  //
-  // in case of PCI Bridge and its child devices
-  //
-  if (PciExpressConfigurationTable) {
-    //
-    // align the Extended Tag value as per the device supported value
-    //
-    PciExpressConfigurationTable->ExtendedTag = MIN (
-                                                  PciExpressExtendedTag,
-                                                  PciExpressConfigurationTable->ExtendedTag
-                                                  );
-    //
-    // check for any invalid platform policy request for the device; if true than
-    // align with the device capability value. Else align as per platform request
-    //
-    if (PciDevice->SetupExtTag > PciExpressConfigurationTable->ExtendedTag) {
-      //
-      // setup the device Extended Tag to common value supported by all the devices
-      //
-      PciDevice->SetupExtTag = PciExpressConfigurationTable->ExtendedTag;
-    }
-    //
-    // if the platform policy is to downgrade the device's Extended Tag value than
-    // all the other devices in the PCI tree including the root bridge will be align
-    // with this device override value
-    //
-    if (PciDevice->SetupExtTag < PciExpressConfigurationTable->ExtendedTag) {
-      PciExpressConfigurationTable->ExtendedTag = PciDevice->SetupExtTag;
-    }
-  } else {
-    //
-    // in case of RCiEP devices or the bridge device without any child, overrule
-    // the Extended Tag device policy if it does not match with its capability
-    //
-    PciDevice->SetupExtTag = MIN (
-                              PciDevice->SetupExtTag,
-                              PciExpressExtendedTag
-                              );
-  }
-
-  DEBUG ((
-    DEBUG_INFO,
-    "ExtTag: %d [cap:%d],",
-    PciDevice->SetupExtTag,
-    PciExpressExtendedTag
-    ));
-  return EFI_SUCCESS;
-}
-
-/**
-  Additional routine to setup the PCI Express feature Extended Tag in complaince
-  with the PCI Express Base specification Revision, a common value for all the
-  devices in the PCI hierarchy.
-
-  @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
-AlignExtTag (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
-  )
-{
-  if (PciExpressConfigurationTable) {
-    //
-    // align the Extended Tag value to a common value among all the devices
-    //
-    PciDevice->SetupExtTag = MIN (
-                              PciDevice->SetupExtTag,
-                              PciExpressConfigurationTable->ExtendedTag
-                              );
-  }
-
-  DEBUG ((
-    DEBUG_INFO,
-    "ExtTag: %d,",
-    PciDevice->SetupExtTag
-    ));
-  return EFI_SUCCESS;
-}
-
-/**
-  Program the PCI Device Control 2 register for 10b Extended Tag value, or the
-  Device Control register for 5b/8b Extended Tag 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
-ProgramExtTag (
-  IN PCI_IO_DEVICE          *PciDevice,
-  IN VOID                   *PciExFeatureConfiguration
-  )
-{
-  PCI_REG_PCIE_DEVICE_CONTROL   DevCtl;
-  PCI_REG_PCIE_DEVICE_CONTROL2  DevCtl2;
-  UINT32                        Offset;
-  UINT32                        Offset2;
-  BOOLEAN                       OverrideDevCtl;
-  BOOLEAN                       OverrideDevCtl2;
-  EFI_STATUS                    Status;
-  EFI_TPL                       OldTpl;
-
-  //
-  // read the Device Control register for the Extended Tag Field Enable
-  //
-  DevCtl.Uint16 = 0;
-  Offset = PciDevice->PciExpressCapabilityOffset +
-              OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl);
-  Status = PciDevice->PciIo.Pci.Read (
-                                  &PciDevice->PciIo,
-                                  EfiPciIoWidthUint16,
-                                  Offset,
-                                  1,
-                                  &DevCtl.Uint16
-                                  );
-  ASSERT (Status == EFI_SUCCESS);
-
-  OverrideDevCtl = FALSE;
-  //
-  // read the Device COntrol 2 register for the 10-Bit Tag Requester Enable
-  //
-  DevCtl2.Uint16 = 0;
-  Offset2 = PciDevice->PciExpressCapabilityOffset +
-              OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2);
-  Status = PciDevice->PciIo.Pci.Read (
-                                  &PciDevice->PciIo,
-                                  EfiPciIoWidthUint16,
-                                  Offset2,
-                                  1,
-                                  &DevCtl2.Uint16
-                                  );
-  ASSERT (Status == EFI_SUCCESS);
-
-  OverrideDevCtl2 = FALSE;
-
-  if (PciDevice->SetupExtTag == EFI_PCI_EXPRESS_EXTENDED_TAG_5BIT) {
-    if (DevCtl.Bits.ExtendedTagField) {
-      DevCtl.Bits.ExtendedTagField = 0;
-      OverrideDevCtl = TRUE;
-    }
-
-    if (DevCtl2.Bits.TenBitTagRequesterEnable) {
-      DevCtl2.Bits.TenBitTagRequesterEnable = 0;
-      OverrideDevCtl2 = TRUE;
-    }
-  }
-  if (PciDevice->SetupExtTag == EFI_PCI_EXPRESS_EXTENDED_TAG_8BIT) {
-    if (!DevCtl.Bits.ExtendedTagField) {
-      DevCtl.Bits.ExtendedTagField = 1;
-      OverrideDevCtl = TRUE;
-    }
-    if (DevCtl2.Bits.TenBitTagRequesterEnable) {
-      DevCtl2.Bits.TenBitTagRequesterEnable = 0;
-      OverrideDevCtl2 = TRUE;
-    }
-  }
-  if (PciDevice->SetupExtTag == EFI_PCI_EXPRESS_EXTENDED_TAG_10BIT) {
-    if (!DevCtl2.Bits.TenBitTagRequesterEnable) {
-      DevCtl2.Bits.TenBitTagRequesterEnable = 1;
-      OverrideDevCtl2 = TRUE;
-    }
-  }
-
-  if (OverrideDevCtl) {
-
-    DEBUG (( DEBUG_INFO, "ExtTag=%d,", DevCtl.Bits.ExtendedTagField));
-
-    //
-    // 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,
-                                    &DevCtl.Uint16
-                                    );
-    //
-    // Restore TPL to its original level
-    //
-    gBS->RestoreTPL (OldTpl);
-
-    if (!EFI_ERROR(Status)) {
-      PciDevice->PciExpressCapabilityStructure.DeviceControl.Uint16 = DevCtl.Uint16;
-    } else {
-      ReportPciWriteError (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, Offset);
-    }
-  } else {
-    DEBUG (( DEBUG_INFO, "no ExtTag (%d),", DevCtl.Bits.ExtendedTagField));
-  }
-
-  if (OverrideDevCtl2) {
-
-    DEBUG (( DEBUG_INFO, "10bExtTag=%d,", DevCtl2.Bits.TenBitTagRequesterEnable));
-
-    //
-    // 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,
-                                    Offset2,
-                                    1,
-                                    &DevCtl2.Uint16
-                                    );
-    //
-    // Restore TPL to its original level
-    //
-    gBS->RestoreTPL (OldTpl);
-
-    if (!EFI_ERROR(Status)) {
-      PciDevice->PciExpressCapabilityStructure.DeviceControl2.Uint16 = DevCtl2.Uint16;
-    } else {
-      ReportPciWriteError (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, Offset2);
-    }
-  } else {
-    DEBUG (( DEBUG_INFO, "no 10bExtTag (%d),", DevCtl2.Bits.TenBitTagRequesterEnable));
-  }
-
-  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;
-}
-
-/**
-  The main routine to setup the PCI Express feature Common Clock configuration
-  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
-SetupCommonClkCfg (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
-  )
-{
-  PCI_REG_PCIE_LINK_STATUS                      LinkSts;
-
-  LinkSts.Uint16 = PciDevice->PciExpressCapabilityStructure.LinkStatus.Uint16;
-
-  //
-  // Common Clock Configuration is only applicable to root bridge and its child
-  // devices. Not applicable to empty bridge devices or RCiEP devices
-  //
-  if (PciExpressConfigurationTable) {
-    if (PciDevice->SetupCcc == EFI_PCI_EXPRESS_CLK_CFG_AUTO) {
-      //
-      // as per the PCI Express Base Specification, the link status register
-      // slot clock configuration of the opposing side of link devices indicate
-      // the clock configuration properly; hence rely on this data to configure
-      // the link's clock configuration
-      //
-      if (LinkSts.Bits.SlotClockConfiguration) {
-        PciExpressConfigurationTable->CommonClockConfiguration = TRUE;
-      } else {
-        PciExpressConfigurationTable->CommonClockConfiguration = FALSE;
-      }
-    } else if (PciDevice->SetupCcc == EFI_PCI_EXPRESS_CLK_CFG_ASYNCH) {
-      //
-      // platform override to any device shall change for other device on the
-      // link, the clock configuration has to be maintained common across all
-      // the devices
-      //
-      PciExpressConfigurationTable->CommonClockConfiguration = FALSE;
-    } else {
-      PciExpressConfigurationTable->CommonClockConfiguration = TRUE;
-    }
-  }
-  return EFI_SUCCESS;
-}
-
-/**
-  Program the PCIe Link Control register Coomon Clock Configuration 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
-ProgramCcc (
-  IN PCI_IO_DEVICE                            *PciDevice,
-  IN PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE *PciExFeatureConfiguration
-  )
-{
-  PCI_REG_PCIE_LINK_CONTROL     LinkCtl;
-  UINT32                        Offset;
-  EFI_STATUS                    Status;
-  EFI_TPL                       OldTpl;
-
-  //
-  // Common Clock Configuration 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);
-
-  //
-  // in case Common Clock Configuration is required to be programmed in the
-  // downstream ports from the root bridge devices in the heirarchy
-  //
-  if (PciExFeatureConfiguration->CommonClockConfiguration == TRUE) {
-    if (LinkCtl.Bits.CommonClockConfiguration == 0) {
-      LinkCtl.Bits.CommonClockConfiguration = 1;
-      //
-      // current clock mode does not match hence retrain of the link at bridge device
-      // is required
-      //
-      PciExFeatureConfiguration->LinkReTrain = TRUE;
-    }
-  } else {
-    //
-    // in case the opposing devices of the PCI link have different reference clock
-    // set the link control register CCC field accordingly
-    //
-    if (LinkCtl.Bits.CommonClockConfiguration) {
-      LinkCtl.Bits.CommonClockConfiguration = 0;
-      //
-      // current clock mode does not match hence retrain of the link at bridge device
-      // is required
-      //
-      PciExFeatureConfiguration->LinkReTrain = TRUE;
-    }
-  }
-  //
-  // use the retrain flag as a sigm to also update the CCC of the link register
-  //
-  if (PciExFeatureConfiguration->LinkReTrain == TRUE) {
-    DEBUG ((
-      DEBUG_INFO,
-      "CCC: %d,",
-      LinkCtl.Bits.CommonClockConfiguration
-      ));
-    //
-    // 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 {
-    PciDevice->PciExpressCapabilityStructure.LinkControl.Uint16 = LinkCtl.Uint16;
-    DEBUG ((
-      DEBUG_INFO,
-      "No CCC (%d),",
-      LinkCtl.Bits.CommonClockConfiguration
-      ));
-  }
-  return EFI_SUCCESS;
-}
-
-/**
-  Second phase of programming for Common Clock COnfiguration, conditoonally done
-  only on the downstream ports (bridge devices only).
-
-  @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
-EnforceCcc (
-  IN PCI_IO_DEVICE                            *PciDevice,
-  IN PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE *PciExFeatureConfiguration
-  )
-{
-  PCI_REG_PCIE_LINK_CONTROL     LinkCtl;
-  PCI_REG_PCIE_LINK_STATUS      LinkSts;
-  PCI_REG_PCIE_CAPABILITY       PciExCap;
-  UINT32                        Offset;
-  EFI_STATUS                    Status;
-  EFI_TPL                       OldTpl;
-
-  //
-  // Common Clock Configuration is only applicable to root bridge and its child
-  // devices. Not applicable to empty bridge devices or RCiEP devices
-  //
-  if (!PciExFeatureConfiguration) {
-    return EFI_SUCCESS;
-  }
-  PciExCap.Uint16 = PciDevice->PciExpressCapabilityStructure.Capability.Uint16;
-  LinkCtl.Uint16 = PciDevice->PciExpressCapabilityStructure.LinkControl.Uint16;
-
-  //
-  // retrain the bridge device (downstream ports including the root port)
-  //
-  if (PciExFeatureConfiguration->LinkReTrain == TRUE) {
-    if (IS_PCI_BRIDGE (&PciDevice->Pci)) {
-      //
-      // retrain of the PCI link happens for CCC change only on the downstream
-      // ports
-      //
-      if (
-        PciExCap.Bits.DevicePortType == PCIE_DEVICE_PORT_TYPE_ROOT_PORT
-        || PciExCap.Bits.DevicePortType == PCIE_DEVICE_PORT_TYPE_DOWNSTREAM_PORT
-        ) {
-        LinkCtl.Bits.RetrainLink = 1;
-        Offset = PciDevice->PciExpressCapabilityOffset +
-                     OFFSET_OF (PCI_CAPABILITY_PCIEXP, LinkControl);
-        //
-        // 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)) {
-          //
-          // poll the link status register for the link retrain to be complete
-          //
-          Offset = PciDevice->PciExpressCapabilityOffset +
-                               OFFSET_OF (PCI_CAPABILITY_PCIEXP, LinkStatus);
-          do {
-            Status = PciDevice->PciIo.Pci.Read (
-                                            &PciDevice->PciIo,
-                                            EfiPciIoWidthUint16,
-                                            Offset,
-                                            1,
-                                            &LinkSts.Uint16
-                                            );
-            ASSERT (Status == EFI_SUCCESS);
-          } while (LinkSts.Bits.LinkTraining);
-        } else {
-          ReportPciWriteError (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, Offset);
-          return Status;
-        }
-      }
-      //
-      // ignore the upstream bridge devices
-      //
-    }
-    //
-    // not applicable to endpoint devices
-    //
-  }
-  return EFI_SUCCESS;
-}
-
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h
deleted file mode 100644
index 33df337..0000000
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h
+++ /dev/null
@@ -1,399 +0,0 @@
-/** @file
-  PCI standard feature support functions implementation for PCI Bus module..
-
-Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-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
-  device-specific platform policy, as well as in complaince with the PCI Base
-  specification Revision 4, that aligns the value for the entire PCI heirarchy
-  starting from its physical PCI Root port / Bridge device.
-
-  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
-  @param PciFeaturesConfigurationTable  pointer to PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE
-
-  @retval EFI_SUCCESS                   processing of PCI feature Max_Payload_Size
-                                        is successful.
-**/
-EFI_STATUS
-SetupMaxPayloadSize (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
-  );
-
-EFI_STATUS
-CasMaxPayloadSize (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
-  );
-
-/**
-  Overrides the PCI Device Control register Max_Read_Req_Size 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 controller.
-  @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
-ProgramMaxPayloadSize (
-  IN PCI_IO_DEVICE          *PciDevice,
-  IN VOID                   *PciExFeatureConfiguration
-  );
-
-
-EFI_STATUS
-ConditionalCasMaxReadReqSize (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
-  );
-
-/**
-  The main routine which process the PCI feature Max_Read_Req_Size as per the
-  device-specific platform policy, as well as in complaince with the PCI Base
-  specification Revision 4, that aligns the value for the entire PCI heirarchy
-  starting from its physical PCI Root port / Bridge device.
-
-  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
-  @param PciConfigPhase                 for the PCI feature configuration phases:
-                                        PciExpressFeatureSetupPhase & PciExpressFeatureEntendedSetupPhase
-  @param PciFeaturesConfigurationTable  pointer to PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE
-
-  @retval EFI_SUCCESS                   processing of PCI feature Max_Read_Req_Size
-                                        is successful.
-**/
-EFI_STATUS
-SetupMaxReadReqSize (
-  IN  PCI_IO_DEVICE                           *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
-  );
-
-/**
-  Overrides the PCI Device Control register Max_Read_Req_Size 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 controller.
-  @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
-ProgramMaxReadReqSize (
-  IN PCI_IO_DEVICE          *PciDevice,
-  IN VOID                   *PciExFeatureConfiguration
-  );
-
-/**
-  Overrides the PCI Device Control register Relax Order 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
-ProgramRelaxOrder (
-  IN PCI_IO_DEVICE          *PciDevice,
-  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
-  );
-
-/**
-  The main routine which process the PCI feature Completion Timeout as per the
-  device-specific platform policy, as well as in complaince with the PCI Base
-  specification Revision 4.
-
-  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
-  @param PciConfigPhase                 for the PCI feature configuration phases:
-                                        PciExpressFeatureSetupPhase & PciExpressFeatureEntendedSetupPhase
-
-  @retval EFI_SUCCESS                   processing of PCI feature CTO is successful.
-**/
-EFI_STATUS
-SetupCompletionTimeout (
-  IN PCI_IO_DEVICE          *PciDevice,
-  IN VOID                   *PciExFeatureConfiguration
-  );
-
-/**
-  Overrides the PCI Device Control2 register Completion Timeout range; 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
-ProgramCompletionTimeout (
-  IN PCI_IO_DEVICE          *PciDevice,
-  IN VOID                   *PciExFeatureConfiguration
-  );
-
-/**
-  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 specification.
-
-  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
-  @param PciExFeatureConfiguration      pointer to common configuration table to
-                                        initialize the PCI Express feature
-
-  @retval EFI_SUCCESS                   bridge device routing capability is 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 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
-ProgramAtomicOp (
-  IN PCI_IO_DEVICE          *PciDevice,
-  IN VOID                   *PciExFeatureConfiguration
-  );
-
-/**
-  The main routine which process the PCI feature LTR enable/disable 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
-SetupLtr (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
-  );
-
-EFI_STATUS
-ReSetupLtr (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
-  );
-
-/**
-  Program the PCI Device Control 2 register LTR mechanism 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
-ProgramLtr (
-  IN PCI_IO_DEVICE          *PciDevice,
-  IN VOID                   *PciExFeatureConfiguration
-  );
-
-/**
-  The main routine to setup the PCI Express feature Extended Tag 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
-SetupExtTag (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
-  );
-
-/**
-  Additional routine to setup the PCI Express feature Extended Tag in complaince
-  with the PCI Express Base specification Revision, a common value for all the
-  devices in the PCI hierarchy.
-
-  @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
-AlignExtTag (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
-  );
-
-/**
-  Program the PCI Device Control 2 register for 10b Extended Tag value, or the
-  Device Control register for 5b/8b Extended Tag 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
-ProgramExtTag (
-  IN PCI_IO_DEVICE          *PciDevice,
-  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
-  );
-
-/**
-  The main routine to setup the PCI Express feature Common Clock configuration
-  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
-SetupCommonClkCfg (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
-  );
-
-/**
-  Program the PCIe Link Control register Coomon Clock Configuration 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
-ProgramCcc (
-  IN PCI_IO_DEVICE                            *PciDevice,
-  IN PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE *PciExFeatureConfiguration
-  );
-
-/**
-  Second phase of programming for Common Clock COnfiguration, conditoonally done
-  only on the downstream ports (bridge devices only).
-
-  @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
-EnforceCcc (
-  IN PCI_IO_DEVICE                            *PciDevice,
-  IN PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE *PciExFeatureConfiguration
-  );
-#endif
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c
deleted file mode 100644
index 4d3641c..0000000
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c
+++ /dev/null
@@ -1,1019 +0,0 @@
-/** @file
-  PCI standard feature support functions implementation for PCI Bus module..
-
-Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "PciBus.h"
-#include "PciFeatureSupport.h"
-#include "PciExpressFeatures.h"
-
-/**
-  Hold the current instance of Root Bridge IO protocol Handle
-**/
-EFI_HANDLE                                  mRootBridgeHandle;
-
-/**
-  A gobal pointer to BRIDGE_DEVICE_NODE buffer to track all the primary physical
-  PCI Root Ports (PCI Controllers) for a given PCI Root Bridge instance while
-  enumerating to configure the PCI features
-**/
-LIST_ENTRY                                  mRootBridgeDeviceList;
-
-/**
- global list to indicate the supported PCI Express features of this driver, it
- is expected to be overridden based on the platform request
-**/
-EFI_PCI_EXPRESS_PLATFORM_POLICY             mPciExpressPlatformPolicy = {
-    //
-    // support for PCI Express feature - Max. Payload Size
-    //
-    TRUE,
-    //
-    // support for PCI Express feature - Max. Read Request Size
-    //
-    TRUE,
-    //
-    // support for PCI Express feature - Extended Tag
-    //
-    TRUE,
-    //
-    // support for PCI Express feature - Relax Order
-    //
-    TRUE,
-    //
-    // support for PCI Express feature - No-Snoop
-    //
-    TRUE,
-    //
-    // support for PCI Express feature - ASPM state
-    //
-    TRUE,
-    //
-    // support for PCI Express feature - Common Clock Configuration
-    //
-    TRUE,
-    //
-    // support for PCI Express feature - Extended Sync
-    //
-    FALSE,
-    //
-    // support for PCI Express feature - Atomic Op
-    //
-    TRUE,
-    //
-    // support for PCI Express feature - LTR
-    //
-    TRUE,
-    //
-    // support for PCI Express feature - PTM
-    //
-    FALSE,
-    //
-    // support for PCI Express feature - Completion Timeout
-    //
-    TRUE,
-    //
-    // support for PCI Express feature - Clock Power Management
-    //
-    FALSE,
-    //
-    // support for PCI Express feature - L1 PM Substates
-    //
-    FALSE
-};
-
-//
-// indicates the driver has completed query to platform on the list of supported
-// PCI features to be configured
-//
-BOOLEAN   mPciExpressGetPlatformPolicyComplete = FALSE;
-
-//
-// PCI Express feature initialization phase handle routines
-//
-PCI_EXPRESS_FEATURE_INITIALIZATION_POINT  mPciExpressFeatureInitializationList[] = {
-  {
-    PciExpressFeatureSetupPhase,          PciExpressCcc,        SetupCommonClkCfg
-  },
-  {
-    PciExpressFeatureEntendedSetupPhase,  PciExpressCcc,        ProgramCcc
-  },
-  {
-    PciExpressFeatureProgramPhase,        PciExpressCcc,        EnforceCcc
-  },
-  {
-    PciExpressFeatureSetupPhase,          PciExpressAspm,       SetupAspm
-  },
-  {
-    PciExpressFeatureEntendedSetupPhase,  PciExpressAspm,       AlignAspm
-  },
-  {
-    PciExpressFeatureProgramPhase,        PciExpressAspm,       ProgramAspm
-  },
-  {
-    PciExpressFeatureSetupPhase,          PciExpressMps,        SetupMaxPayloadSize
-  },
-  {
-    PciExpressFeatureEntendedSetupPhase,  PciExpressMps,        CasMaxPayloadSize
-  },
-  {
-    PciExpressFeatureProgramPhase,        PciExpressMps,        ProgramMaxPayloadSize
-  },
-  {
-    PciExpressFeatureSetupPhase,          PciExpressMrrs,       SetupMaxReadReqSize
-  },
-  {
-    PciExpressFeatureEntendedSetupPhase,  PciExpressMrrs,       ConditionalCasMaxReadReqSize
-  },
-  {
-    PciExpressFeatureProgramPhase,        PciExpressMrrs,       ProgramMaxReadReqSize
-  },
-  {
-    PciExpressFeatureProgramPhase,        PciExpressRelaxOrder, ProgramRelaxOrder
-  },
-  {
-    PciExpressFeatureProgramPhase,        PciExpressNoSnoop,    ProgramNoSnoop
-  },
-  {
-    PciExpressFeatureSetupPhase,          PciExpressCto,        SetupCompletionTimeout
-  },
-  {
-    PciExpressFeatureProgramPhase,        PciExpressCto,        ProgramCompletionTimeout
-  },
-  {
-    PciExpressFeatureSetupPhase,          PciExpressAtomicOp,   SetupAtomicOpRoutingSupport
-  },
-  {
-    PciExpressFeatureProgramPhase,        PciExpressAtomicOp,   ProgramAtomicOp
-  },
-  {
-    PciExpressFeatureSetupPhase,          PciExpressLtr,        SetupLtr
-  },
-  {
-    PciExpressFeatureEntendedSetupPhase,  PciExpressLtr,        ReSetupLtr
-  },
-  {
-    PciExpressFeatureProgramPhase,        PciExpressLtr,        ProgramLtr
-  },
-  {
-    PciExpressFeatureSetupPhase,          PciExpressExtTag,     SetupExtTag
-  },
-  {
-    PciExpressFeatureEntendedSetupPhase,  PciExpressExtTag,     AlignExtTag
-  },
-  {
-    PciExpressFeatureProgramPhase,        PciExpressExtTag,     ProgramExtTag
-  }
-};
-
-/**
-  Routine to serially dispatch the designated the PCI Express feature specific
-  functions defined for each of the configuration phase. The order for each phase
-  would be based entirely on the table mPciExpressFeatureInitializationList.
-
-  @param  PciDevice                       pointer to PCI_IO_DEVICE to identify device
-  @param  PciExFeatureConfigPhase         input configuration phase
-  @param  PciExpressFeatureConfiguration  used pointer to void to accomodate any PCI
-                                          Express feature specific data type
-  @retval EFI_STATUS                      output only from feature specific function
-                                          defined in the table mPciExpressFeatureInitializationList
-**/
-EFI_STATUS
-DispatchPciExpressInitializationFunctions (
-  IN PCI_IO_DEVICE                            *PciDevice,
-  IN PCI_EXPRESS_FEATURE_CONFIGURATION_PHASE  PciExFeatureConfigPhase,
-  IN VOID                                     *PciExpressFeatureConfiguration
-  )
-{
-  UINTN       idx;
-  EFI_STATUS  Status;
-  UINT8       *PciExpressPolicy;
-
-  for (
-      idx = 0, PciExpressPolicy = (UINT8*)&mPciExpressPlatformPolicy
-      ; idx < sizeof (mPciExpressFeatureInitializationList) / sizeof (PCI_EXPRESS_FEATURE_INITIALIZATION_POINT)
-      ; idx++
-      ){
-    if (
-        //
-        // match the configuration phase
-        //
-        mPciExpressFeatureInitializationList[idx].PciExpressFeatureConfigurationPhase == PciExFeatureConfigPhase
-        //
-        // check whether the PCI Express features is enabled
-        //
-        && PciExpressPolicy[mPciExpressFeatureInitializationList[idx].PciExpressFeatureId] == TRUE
-        ) {
-      Status =  mPciExpressFeatureInitializationList[idx].PciExpressFeatureConfigurationRoutine (
-                                                            PciDevice,
-                                                            PciExpressFeatureConfiguration
-                                                            );
-    }
-  }
-  return Status;
-}
-
-/**
-  Main routine to indicate platform selection of any of the other PCI features
-  to be configured by this driver
-
-  @retval TRUE    platform has selected the other PCI features to be configured
-          FALSE   platform has not selected any of the other PCI features
-**/
-BOOLEAN
-CheckPciExpressFeatureList (
-  )
-{
-  UINTN     length;
-  UINT8     *list;
-
-  for (
-      length = 0, list = (UINT8*)&mPciExpressPlatformPolicy
-      ; length < sizeof (EFI_PCI_EXPRESS_PLATFORM_POLICY)
-      ; length++
-      ) {
-    if (list[length]) {
-      return TRUE;
-    }
-  }
-  return FALSE;
-}
-
-/**
-  helper routine to wipe out the global PCI Express feature list
-**/
-VOID
-NegatePciExpressFeatureList (
-  )
-{
-  UINTN     length;
-  UINT8      *list;
-
-  for (
-      length = 0, list = (UINT8*)&mPciExpressPlatformPolicy
-      ; length < sizeof (EFI_PCI_EXPRESS_PLATFORM_POLICY)
-      ; length++
-      ) {
-    if (list[length]) {
-      list[length] = FALSE;
-    }
-  }
-}
-
-/**
-  Main routine to indicate whether the PCI Express feature initialization is
-  required or not
-
-  @retval TRUE    PCI Express feature initialization required
-          FALSE   PCI Express feature not required
-**/
-BOOLEAN
-IsPciExpressFeatureConfigurationRequired (
-  )
-{
-  EFI_STATUS    Status;
-
-  if (mPciExpressGetPlatformPolicyComplete) {
-    return CheckPciExpressFeatureList ();
-  }
-  //
-  // initialize the PCI Express feature data members
-  //
-  InitializeListHead (&mRootBridgeDeviceList);
-  //
-  // check the platform to configure the PCI Express features
-  //
-  mPciExpressGetPlatformPolicyComplete = TRUE;
-
-  Status = PciExpressPlatformGetPolicy ();
-  if (EFI_ERROR (Status)) {
-    //
-    // fail to obtain the PCI Express feature configuration from platform,
-    // negate the list to avoid any unwanted configuration
-    //
-    NegatePciExpressFeatureList ();
-    return FALSE;
-  }
-  //
-  // PCI Express feature configuration list is ready from platform
-  //
-  return TRUE;
-}
-
-
-/**
-  Indicates whether the set of PCI Express features selected by platform requires
-  extended setup, that has additional resources that would be allocated to align
-  all the devices in the PCI tree, and free the resources later.
-
-  @retval TRUE    PCI Express feature requires extended setup
-          FALSE   PCI Express feature does not require extended setup
-**/
-BOOLEAN
-IsPciExpressFeatureExtendedSetupRequired (
-  )
-{
-  UINTN   idx;
-  UINT8   *PciExpressPolicy;
-  //
-  // return TRUE only for those features which are required to be aligned with
-  // common values among all the devices in the PCI tree
-  //
-  for (
-      idx = 0, PciExpressPolicy = (UINT8*)&mPciExpressPlatformPolicy
-      ; idx < sizeof (mPciExpressFeatureInitializationList) / sizeof (PCI_EXPRESS_FEATURE_INITIALIZATION_POINT)
-      ; idx++
-  ){
-    if (
-        //
-        // match the configuration phase to extended setup phase
-        //
-        mPciExpressFeatureInitializationList[idx].PciExpressFeatureConfigurationPhase == PciExpressFeatureEntendedSetupPhase
-        //
-        // check whether the PCI Express features is enabled
-        //
-        && PciExpressPolicy[mPciExpressFeatureInitializationList[idx].PciExpressFeatureId] == TRUE
-    ) {
-      return TRUE;
-    } else if (
-        //
-        // the PCI Express feature does not require extended setup phase but it
-        // does require global flag to track the AtomicOpRouting caoability to
-        // be tracked for all its bridge devices
-        //
-        idx == PciExpressAtomicOp
-        && PciExpressPolicy[idx] == TRUE
-        ) {
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-}
-
-/**
- Helper routine to determine the existence of previously enumerated PCI device
-
- @retval  TRUE  PCI device exist
-          FALSE does not exist
-**/
-BOOLEAN
-DeviceExist (
-  PCI_IO_DEVICE                   *PciDevice
-  )
-{
-  EFI_PCI_IO_PROTOCOL   *PciIoProtocol = &PciDevice->PciIo;
-  UINT16                VendorId = 0xFFFF;
-
-  PciIoProtocol->Pci.Read (
-                      PciIoProtocol,
-                      EfiPciIoWidthUint16,
-                      PCI_VENDOR_ID_OFFSET,
-                      1,
-                      &VendorId
-                      );
-  if (VendorId == 0 || VendorId == 0xFFFF) {
-    return FALSE;
-  } else {
-    return TRUE;
-  }
-}
-
-/**
-  Free up memory alloted for the primary physical PCI Root ports of the PCI Root
-  Bridge instance. Free up all the nodes of type BRIDGE_DEVICE_NODE.
-**/
-VOID
-DestroyRootBridgeDeviceNodes ()
-{
-  LIST_ENTRY                *Link;
-  BRIDGE_DEVICE_NODE        *Temp;
-
-  Link = mRootBridgeDeviceList.ForwardLink;
-  while (Link != NULL && Link != &mRootBridgeDeviceList) {
-    Temp = ROOT_BRIDGE_DEVICE_NODE_FROM_LINK (Link);
-    Link = RemoveEntryList (Link);
-    FreePool (Temp->PciExFeaturesConfigurationTable);
-    FreePool (Temp);
-  }
-}
-
-/**
-  Main routine to determine the child PCI devices of a PCI bridge device
-  and group them under a common internal PCI features Configuration table.
-
-  @param  PciDevice                       A pointer to the PCI_IO_DEVICE.
-  @param  PciFeaturesConfigTable          A pointer to a pointer to the
-                                          PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE.
-                                          Returns NULL in case of RCiEP or the PCI
-                                          device does match with any of the physical
-                                          Root ports, or it does not belong to any
-                                          Root port's PCI bus range (not a child)
-
-  @retval EFI_SUCCESS                     able to determine the PCI feature
-                                          configuration table. For RCiEP since
-                                          since it is not prepared.
-          EFI_DEVICE_ERROR                the PCI device has invalid EFI device
-                                          path
-**/
-EFI_STATUS
-GetPciExpressFeaturesConfigurationTable (
-  IN  PCI_IO_DEVICE                             *PciDevice,
-  OUT PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  **PciFeaturesConfigTable
-  )
-{
-  LIST_ENTRY                *Link;
-  BRIDGE_DEVICE_NODE        *Temp;
-  BOOLEAN                   NodeMatch;
-  EFI_DEVICE_PATH_PROTOCOL  *RootPortPath;
-  EFI_DEVICE_PATH_PROTOCOL  *PciDevicePath;
-
-  if (IsListEmpty (&mRootBridgeDeviceList)) {
-    //
-    // no populated PCI primary root ports to parse and match the PCI features
-    // configuration table
-    //
-    *PciFeaturesConfigTable = NULL;
-    return EFI_SUCCESS;
-  }
-
-  //
-  // The PCI features configuration table is not built for RCiEP, return NULL
-  //
-  if (PciDevice->PciExpressCapabilityStructure.Capability.Bits.DevicePortType == \
-      PCIE_DEVICE_PORT_TYPE_ROOT_COMPLEX_INTEGRATED_ENDPOINT) {
-    *PciFeaturesConfigTable = NULL;
-    return EFI_SUCCESS;
-  }
-
-  if (IsDevicePathEnd (PciDevice->DevicePath)){
-    //
-    // the given PCI device does not have a valid device path
-    //
-    *PciFeaturesConfigTable = NULL;
-    return EFI_DEVICE_ERROR;
-  }
-
-
-  Link = mRootBridgeDeviceList.ForwardLink;
-  do {
-    Temp = ROOT_BRIDGE_DEVICE_NODE_FROM_LINK (Link);
-    RootPortPath = Temp->RootBridgeDevicePath;
-    PciDevicePath = PciDevice->DevicePath;
-    NodeMatch = FALSE;
-    //
-    // match the device path from the list of primary Root Ports with the given
-    // device; the initial nodes matching in sequence indicate that the given PCI
-    // device belongs to that PCI tree from the root port
-    //
-    if (IsDevicePathEnd (RootPortPath)) {
-      //
-      // critical error as no device path available in root
-      //
-      *PciFeaturesConfigTable = NULL;
-      return EFI_DEVICE_ERROR;
-    }
-
-    if (EfiCompareDevicePath (RootPortPath, PciDevicePath)) {
-      //
-      // the given PCI device is the primary root port itself
-      //
-      *PciFeaturesConfigTable = Temp->PciExFeaturesConfigurationTable;
-      return EFI_SUCCESS;
-    }
-    //
-    // check this PCI device belongs to the primary root port of the root bridge
-    // any child PCI device will have the same initial device path nodes  as
-    // its parent root port
-    //
-    while (!IsDevicePathEnd (RootPortPath)){
-
-      if (DevicePathNodeLength (RootPortPath) != DevicePathNodeLength (PciDevicePath)) {
-        //
-        // break to check the next primary root port nodes as does not match
-        //
-        NodeMatch = FALSE;
-        break;
-      }
-      if (CompareMem (RootPortPath, PciDevicePath, DevicePathNodeLength (RootPortPath)) != 0) {
-        //
-        // node does not match, break to check next node
-        //
-        NodeMatch = FALSE;
-        break;
-      }
-      NodeMatch = TRUE;
-      //
-      // advance to next node
-      //
-      RootPortPath = NextDevicePathNode (RootPortPath);
-      PciDevicePath = NextDevicePathNode (PciDevicePath);
-    }
-
-    if (NodeMatch == TRUE) {
-      //
-      // device belongs to primary root port, return its PCI feature configuration
-      // table
-      //
-      *PciFeaturesConfigTable = Temp->PciExFeaturesConfigurationTable;
-      return EFI_SUCCESS;
-    }
-
-    //
-    // advance to next Root port node
-    //
-    Link = Link->ForwardLink;
-  } while (Link != &mRootBridgeDeviceList && Link != NULL);
-  //
-  // the PCI device must be RCiEP, does not belong to any primary root port
-  //
-  *PciFeaturesConfigTable = NULL;
-  return EFI_SUCCESS;
-}
-
-/**
-  helper routine to dump the PCIe Device Port Type
-**/
-VOID
-DumpDevicePortType (
-  IN  UINT8   DevicePortType
-  )
-{
-  switch (DevicePortType){
-    case PCIE_DEVICE_PORT_TYPE_PCIE_ENDPOINT:
-      DEBUG (( DEBUG_INFO, "PCIe endpoint found\n"));
-      break;
-    case PCIE_DEVICE_PORT_TYPE_LEGACY_PCIE_ENDPOINT:
-      DEBUG (( DEBUG_INFO, "legacy PCI endpoint found\n"));
-      break;
-    case PCIE_DEVICE_PORT_TYPE_ROOT_PORT:
-      DEBUG (( DEBUG_INFO, "PCIe Root Port found\n"));
-      break;
-    case PCIE_DEVICE_PORT_TYPE_UPSTREAM_PORT:
-      DEBUG (( DEBUG_INFO, "PCI switch upstream port found\n"));
-      break;
-    case PCIE_DEVICE_PORT_TYPE_DOWNSTREAM_PORT:
-      DEBUG (( DEBUG_INFO, "PCI switch downstream port found\n"));
-      break;
-    case PCIE_DEVICE_PORT_TYPE_PCIE_TO_PCI_BRIDGE:
-      DEBUG (( DEBUG_INFO, "PCIe-PCI bridge found\n"));
-      break;
-    case PCIE_DEVICE_PORT_TYPE_PCI_TO_PCIE_BRIDGE:
-      DEBUG (( DEBUG_INFO, "PCI-PCIe bridge found\n"));
-      break;
-    case PCIE_DEVICE_PORT_TYPE_ROOT_COMPLEX_INTEGRATED_ENDPOINT:
-      DEBUG (( DEBUG_INFO, "RCiEP found\n"));
-      break;
-    case PCIE_DEVICE_PORT_TYPE_ROOT_COMPLEX_EVENT_COLLECTOR:
-      DEBUG (( DEBUG_INFO, "RC Event Collector found\n"));
-      break;
-  }
-}
-
-/**
-   Setup each PCI device as per the pltaform's device-specific policy, in accordance
-   with PCI Express Base specification.
-
-  @param RootBridge             A pointer to the PCI_IO_DEVICE.
-
-  @retval EFI_SUCCESS           processing each PCI feature as per policy defined
-                                was successful.
- **/
-EFI_STATUS
-SetupDevicePciExpressFeatures (
-  IN  PCI_IO_DEVICE                           *PciDevice,
-  IN  PCI_EXPRESS_FEATURE_CONFIGURATION_PHASE PciConfigPhase
-  )
-{
-  EFI_STATUS                              Status;
-  PCI_REG_PCIE_CAPABILITY                 PcieCap;
-  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressFeaturesConfigTable;
-
-  PciExpressFeaturesConfigTable = NULL;
-  Status = GetPciExpressFeaturesConfigurationTable (PciDevice, &PciExpressFeaturesConfigTable);
-
-  if (PciConfigPhase == PciExpressFeatureSetupPhase) {
-    DEBUG_CODE (
-      if (EFI_ERROR( Status)) {
-        DEBUG ((
-          DEBUG_WARN,
-          "[Cfg group: 0 {error in dev path}]"
-          ));
-      } else if (PciExpressFeaturesConfigTable == NULL) {
-        DEBUG ((
-          DEBUG_INFO,
-          "[Cfg group: 0]"
-          ));
-      } else {
-        DEBUG ((
-          DEBUG_INFO,
-          "[Cfg group: %d]",
-          PciExpressFeaturesConfigTable->ID
-          ));
-      }
-      PcieCap.Uint16 = PciDevice->PciExpressCapabilityStructure.Capability.Uint16;
-      DumpDevicePortType ((UINT8)PcieCap.Bits.DevicePortType);
-    );
-
-    //
-    // get the device-specific platform policy for the PCI Express features
-    //
-    Status = PciExpressPlatformGetDevicePolicy (PciDevice);
-    if (EFI_ERROR(Status)) {
-      DEBUG ((
-        DEBUG_ERROR,
-        "Error in obtaining PCI device policy!!!\n"
-        ));
-    }
-  }
-
-  DEBUG ((DEBUG_INFO, "["));
-
-  Status = DispatchPciExpressInitializationFunctions (
-            PciDevice,
-            PciConfigPhase,
-            PciExpressFeaturesConfigTable
-            );
-
-  DEBUG ((DEBUG_INFO, "]\n"));
-  return Status;
-}
-
-/**
-  Create and append a node of type BRIDGE_DEVICE_NODE in the list for the primary
-  Root Port so that all its child PCI devices can be identified against the PCI
-  features configuration table group ID, of type PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE.
-
-  @param BridgePort    A pointer to the PCI_IO_DEVICE
-  @param PortNumber    A UINTN value to identify the PCI feature configuration
-                       table group
-
-  @retval EFI_SUCCESS           success in adding a node of BRIDGE_DEVICE_NODE
-                                to the list
-          EFI_OUT_OF_RESOURCES  unable to get memory for creating the node
-**/
-EFI_STATUS
-CreatePciRootBridgeDeviceNode (
-  IN  PCI_IO_DEVICE           *BridgePort,
-  IN  UINTN                   PortNumber
-  )
-{
-  BRIDGE_DEVICE_NODE                        *RootBridgeNode = NULL;
-  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciConfigTable = NULL;
-
-  RootBridgeNode = AllocateZeroPool (sizeof (BRIDGE_DEVICE_NODE));
-  if (RootBridgeNode == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-  RootBridgeNode->Signature                     = PCI_ROOT_BRIDGE_DEVICE_SIGNATURE;
-  RootBridgeNode->RootBridgeDevicePath          = BridgePort->DevicePath;
-  PciConfigTable = AllocateZeroPool (
-                     sizeof (PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE)
-                     );
-  if (PciConfigTable) {
-    PciConfigTable->ID                          = PortNumber;
-    //
-    // start by assuming 4096B as the default value for the Max. Payload Size
-    //
-    PciConfigTable->Max_Payload_Size            = PCIE_MAX_PAYLOAD_SIZE_4096B;
-    //
-    // start by assuming 4096B as the default value for the Max. Read Request Size
-    //
-    PciConfigTable->Max_Read_Request_Size       = PCIE_MAX_READ_REQ_SIZE_4096B;
-    //
-    // start by assuming the Max. Read Request Size need not be common for all
-    // the devices in the PCI tree
-    //
-    PciConfigTable->Lock_Max_Read_Request_Size  = FALSE;
-    //
-    // start by assuming the LTR mechanism is supported in a PCI tree
-    //
-    PciConfigTable->LtrSupported                = TRUE;
-    //
-    // the default LTR mechanism is disabled as per the PCI Base specification
-    //
-    PciConfigTable->LtrEnable                   = FALSE;
-    //
-    // start by assuming the AtomicOp Routing capability is supported in the PCI
-    // tree
-    //
-    PciConfigTable->AtomicOpRoutingSupported    = TRUE;
-    //
-    // 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;
-    //
-    // default link retrain is not required
-    //
-    PciConfigTable->LinkReTrain                 = FALSE;
-    //
-    // start by assuming no common clock configuration mode for the device's link
-    //
-    PciConfigTable->CommonClockConfiguration    = FALSE;
-  }
-
-  RootBridgeNode->PciExFeaturesConfigurationTable  = PciConfigTable;
-
-  InsertTailList (&mRootBridgeDeviceList, &RootBridgeNode->NextRootBridgeDevice);
-
-  if (PciConfigTable == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-  return EFI_SUCCESS;
-}
-
-/**
-  Scan all the nodes of the RootBridge to identify and create a separate list
-  of all primary physical PCI root ports and link each with its own instance of
-  the PCI Feature Configuration Table.
-
-  @param  RootBridge    A pointer to the PCI_IO_DEVICE of the PCI Root Bridge
-
-  @retval EFI_OUT_OF_RESOURCES  unable to allocate buffer to store PCI feature
-                                configuration table for all the physical PCI root
-                                ports given
-          EFI_NOT_FOUND         No PCI Bridge device found
-          EFI_SUCCESS           PCI Feature COnfiguration table created for all
-                                the PCI Rooot ports found
-          EFI_INVALID_PARAMETER invalid parameter passed to the routine which
-                                creates the PCI controller node for the primary
-                                Root post list
-**/
-EFI_STATUS
-CreatePciRootBridgeDeviceList (
-  IN  PCI_IO_DEVICE           *RootBridge
-  )
-{
-  EFI_STATUS              Status = EFI_NOT_FOUND;
-  LIST_ENTRY              *Link;
-  PCI_IO_DEVICE           *Device;
-  UINTN                   BridgeDeviceCount;
-
-  BridgeDeviceCount = 0;
-  for ( Link = RootBridge->ChildList.ForwardLink
-      ; Link != &RootBridge->ChildList
-      ; Link = Link->ForwardLink
-  ) {
-    Device = PCI_IO_DEVICE_FROM_LINK (Link);
-    if (!DeviceExist (Device)) {
-      continue;
-    }
-    if (IS_PCI_BRIDGE (&Device->Pci)) {
-      BridgeDeviceCount++;
-      DEBUG ((
-        DEBUG_INFO,
-        "#%d ::Bridge [%02x|%02x|%02x]",
-        BridgeDeviceCount, Device->BusNumber, Device->DeviceNumber, Device->FunctionNumber
-        ));
-      //
-      // create a list of bridge devices if that is connected to any other device
-      //
-      if (!IsListEmpty (&Device->ChildList)) {
-        DEBUG ((
-          DEBUG_INFO,
-          "- has downstream device!\n"
-          ));
-        Status = CreatePciRootBridgeDeviceNode (Device, BridgeDeviceCount);
-        if (EFI_ERROR (Status)) {
-          DEBUG ((
-            DEBUG_ERROR,
-            "PCI configuration table allocation failure for #%d ::Bridge [%02x|%02x|%02x]\n",
-            BridgeDeviceCount, Device->BusNumber, Device->DeviceNumber, Device->FunctionNumber
-            ));
-        }
-      } else {
-        DEBUG ((
-          DEBUG_INFO,
-          "- no downstream device!\n"
-          ));
-      }
-    }
-  }
-
-  return Status;
-}
-
-/**
-  Initialize the device's PCI Express features, in a staged manner
-  @param  PciDevice             A pointer to the PCI_IO_DEVICE.
-
-  @retval EFI_SUCCESS           initializing all the nodes of the root bridge
-                                instances were successfull.
-**/
-EFI_STATUS
-InitializeDevicePciExpressFeatures (
-  IN  PCI_IO_DEVICE                           *PciDevice,
-  IN  PCI_EXPRESS_FEATURE_CONFIGURATION_PHASE PciConfigPhase
-  )
-{
-  EFI_STATUS            Status;
-
-  switch (PciConfigPhase) {
-    case PciExpressFeatureSetupPhase:
-    case PciExpressFeatureEntendedSetupPhase:
-    case PciExpressFeatureProgramPhase:
-      Status = SetupDevicePciExpressFeatures (PciDevice, PciConfigPhase);
-      break;
-    case PciExpressFeatureEndPhase:
-      Status = PciExpressPlatformNotifyDeviceState (PciDevice);
-      break;
-  }
-  return Status;
-}
-
-/**
-  Traverse all the nodes from the root bridge or PCI-PCI bridge instance, to
-  configure the PCI Express features as per the PCI Express Base Secification
-  by considering its device-specific platform policy, and its device capability,
-  as applicable.
-
-  @param RootBridge             A pointer to the PCI_IO_DEVICE.
-
-  @retval EFI_SUCCESS           Traversing all the nodes of the root bridge
-                                instances were successfull.
-**/
-EFI_STATUS
-InitializePciExpressFeatures (
-  IN  PCI_IO_DEVICE                           *RootBridge,
-  IN  PCI_EXPRESS_FEATURE_CONFIGURATION_PHASE PciConfigPhase
-  )
-{
-  EFI_STATUS            Status;
-  LIST_ENTRY            *Link;
-  PCI_IO_DEVICE         *Device;
-
-  for ( Link = RootBridge->ChildList.ForwardLink
-      ; Link != &RootBridge->ChildList
-      ; Link = Link->ForwardLink
-  ) {
-    Device = PCI_IO_DEVICE_FROM_LINK (Link);
-    if (!DeviceExist (Device)) {
-      DEBUG ((
-        DEBUG_ERROR,
-        "::Device [%02x|%02x|%02x] - does not exist!!!\n",
-        Device->BusNumber, Device->DeviceNumber, Device->FunctionNumber
-        ));
-      continue;
-    }
-    if (IS_PCI_BRIDGE (&Device->Pci)) {
-      DEBUG ((
-        DEBUG_INFO,
-        "::Bridge [%02x|%02x|%02x] -",
-        Device->BusNumber, Device->DeviceNumber, Device->FunctionNumber
-        ));
-      if (Device->IsPciExp) {
-        Status = InitializeDevicePciExpressFeatures (
-                  Device,
-                  PciConfigPhase
-                  );
-      } else {
-        DEBUG ((
-          DEBUG_INFO,
-          "Not a PCIe capable device!\n"
-          ));
-        //
-        // PCI Bridge which does not have PCI Express Capability structure
-        // cannot process this kind of PCI Bridge device
-        //
-      }
-
-      InitializePciExpressFeatures (Device, PciConfigPhase);
-    } else {
-      DEBUG ((
-        DEBUG_INFO,
-        "::Device [%02x|%02x|%02x] -",
-        Device->BusNumber, Device->DeviceNumber, Device->FunctionNumber
-        ));
-      if (Device->IsPciExp) {
-        Status = InitializeDevicePciExpressFeatures (
-                  Device,
-                  PciConfigPhase
-                  );
-      } else {
-        DEBUG ((
-          DEBUG_INFO,
-          "Not a PCIe capable device!\n"
-          ));
-        //
-        // PCI Device which does not have PCI Express Capability structure
-        // cannot process this kind of PCI device
-        //
-      }
-    }
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  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
-EnumeratePciExpressFeatures (
-  IN EFI_HANDLE             Controller,
-  IN PCI_IO_DEVICE          *RootBridge
-  )
-{
-  EFI_STATUS            Status;
-  UINTN                 PciExpressFeatureConfigPhase;
-
-  if (!IsPciExpressFeatureConfigurationRequired ()) {
-    //
-    // exit as agreement is not reached with platform to configure the PCI
-    // Express features
-    //
-    return EFI_SUCCESS;
-  }
-  mRootBridgeHandle = Controller;
-
-  DEBUG_CODE (
-    CHAR16                *Str;
-    Str = ConvertDevicePathToText (
-            DevicePathFromHandle (RootBridge->Handle),
-            FALSE,
-            FALSE
-            );
-    DEBUG ((
-      DEBUG_INFO,
-      "Enumerating PCI features for Root Bridge %s\n",
-      Str != NULL ? Str : L""
-      ));
-
-    if (Str != NULL) {
-      FreePool (Str);
-    }
-  );
-
-  for ( PciExpressFeatureConfigPhase = PciExpressFeaturePreProcessPhase
-      ; PciExpressFeatureConfigPhase <= PciExpressFeatureEndPhase
-      ; PciExpressFeatureConfigPhase++
-      ) {
-    DEBUG ((
-      DEBUG_INFO,
-      "<<********** Phase [%d]**********>>\n",
-      PciExpressFeatureConfigPhase
-      ));
-    if (PciExpressFeatureConfigPhase == PciExpressFeaturePreProcessPhase) {
-      //
-      // create a list of root bridge devices (root ports) of the root complex
-      // if extra setup phase required
-      //
-      if (IsPciExpressFeatureExtendedSetupRequired ()) {
-        CreatePciRootBridgeDeviceList (RootBridge);
-      }
-      continue;
-    }
-    if (PciExpressFeatureConfigPhase == PciExpressFeatureEntendedSetupPhase) {
-      if (!IsPciExpressFeatureExtendedSetupRequired ()) {
-        //
-        // since the PCI Express features require no extra initialization steps
-        // skip this phase
-        //
-        continue;
-      }
-    }
-    //
-    // setup the PCI Express features
-    //
-    Status = InitializePciExpressFeatures (RootBridge, PciExpressFeatureConfigPhase);
-
-    if (PciExpressFeatureConfigPhase == PciExpressFeatureEndPhase) {
-      //
-      // clean up the temporary resource nodes created for this root bridge
-      //
-      if (IsPciExpressFeatureExtendedSetupRequired ()) {
-        DestroyRootBridgeDeviceNodes ();
-      }
-    }
-  }
-
-  return Status;
-}
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h
deleted file mode 100644
index 481bd90..0000000
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h
+++ /dev/null
@@ -1,304 +0,0 @@
-/** @file
-  PCI standard feature support functions implementation for PCI Bus module..
-
-Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _EFI_PCI_FEATURES_SUPPORT_H_
-#define _EFI_PCI_FEATURES_SUPPORT_H_
-
-extern  EFI_HANDLE                                  mRootBridgeHandle;
-extern  EFI_PCI_EXPRESS_PLATFORM_POLICY             mPciExpressPlatformPolicy;
-//
-// defines the data structure to hold the details of the PCI Root port devices
-//
-typedef struct _BRIDGE_DEVICE_NODE  BRIDGE_DEVICE_NODE;
-
-//
-// defines the data structure to hold the configuration data for the other PCI
-// features
-//
-typedef struct _PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE;
-
-//
-// define the data type for the PCI feature policy support
-//
-typedef struct _PCI_FEATURE_POLICY  PCI_FEATURE_POLICY;
-
-//
-// Signature value for the PCI Root Port node
-//
-#define PCI_ROOT_BRIDGE_DEVICE_SIGNATURE               SIGNATURE_32 ('p', 'c', 'i', 'p')
-
-//
-// Definitions of the PCI Root Port data structure members
-//
-struct _BRIDGE_DEVICE_NODE {
-  //
-  // Signature header
-  //
-  UINT32                                    Signature;
-  //
-  // linked list pointers to next node
-  //
-  LIST_ENTRY                                NextRootBridgeDevice;
-  //
-  // pointer to PCI_IO_DEVICE of the primary PCI Controller device
-  //
-  EFI_DEVICE_PATH_PROTOCOL                  *RootBridgeDevicePath;
-  //
-  // pointer to the corresponding PCI Express feature configuration Table node
-  // all the child PCI devices of the controller are aligned based on this table
-  //
-  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExFeaturesConfigurationTable;
-};
-
-#define ROOT_BRIDGE_DEVICE_NODE_FROM_LINK(a) \
-  CR (a, BRIDGE_DEVICE_NODE, NextRootBridgeDevice, PCI_ROOT_BRIDGE_DEVICE_SIGNATURE)
-
-//
-// Definition of the PCI Feature configuration Table members
-//
-struct _PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE {
-  //
-  // Configuration Table ID
-  //
-  UINTN                                     ID;
-  //
-  // to configure the PCI feature Maximum payload size to maintain the data packet
-  // size among all the PCI devices in the PCI hierarchy
-  //
-  UINT8                                     Max_Payload_Size;
-  //
-  // to configure the PCI feature maximum read request size to maintain the memory
-  // requester size among all the PCI devices in the PCI hierarchy
-  //
-  UINT8                                     Max_Read_Request_Size;
-  //
-  // lock the Max_Read_Request_Size for the entire PCI tree of a root port
-  //
-  BOOLEAN                                   Lock_Max_Read_Request_Size;
-  //
-  // to record the adversity in LTR mechanism support capability among the PCI
-  // device of an heirarchy
-  //
-  BOOLEAN                                   LtrSupported;
-  //
-  // to enable the LTR mechansim for the entire PCI tree from a root port
-  //
-  BOOLEAN                                   LtrEnable;
-  //
-  // to record the AtomicOp Routing capability of the PCI Heirarchy to enable
-  // the AtomicOp of the EP device
-  //
-  BOOLEAN                                   AtomicOpRoutingSupported;
-  //
-  // 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;
-  //
-  // flag to indicate the link training is required in the devices of downstream
-  // ports
-  //
-  BOOLEAN                                   LinkReTrain;
-  //
-  // link status slot clock configuration
-  //
-  BOOLEAN                                   CommonClockConfiguration;
-};
-
-//
-// Declaration of the internal sub-phases during enumeration to configure the PCI
-// Express features
-//
-typedef enum {
-  //
-  // preprocessing applicable only to few PCI Express features to bind all devices
-  // under the common root bridge device (root port), that would be useful to align
-  // all devices with a common value. This would be optional phase based on the
-  // type of the PCI Express feature to be programmed based on platform policy
-  //
-  PciExpressFeaturePreProcessPhase,
-
-  //
-  // mandatory phase to setup the PCI Express feature to its applicable attribute,
-  // based on its device-specific platform policies, matching with its device capabilities
-  //
-  PciExpressFeatureSetupPhase,
-
-  //
-  // optional phase primarily to align all devices, specially required when PCI
-  // switch is present in the hierarchy, applicable to certain few PCI Express
-  // features only
-  //
-  PciExpressFeatureEntendedSetupPhase,
-
-  //
-  // mandatory programming phase to complete the configuration of the PCI Express
-  // features
-  //
-  PciExpressFeatureProgramPhase,
-
-  //
-  // optional phase to clean up temporary buffers, like those that were prepared
-  // during the preprocessing phase above
-  //
-  PciExpressFeatureEndPhase
-
-}PCI_EXPRESS_FEATURE_CONFIGURATION_PHASE;
-
-//
-// declaration for the data type to harbor the PCI feature policies
-//
-struct  _PCI_FEATURE_POLICY {
-  //
-  // if set, it indicates the feature should be enabled
-  // if clear, it indicates the feature should be disabled
-  //
-  UINT8   Act : 1;
-  //
-  // this field will be specific to feature, it can be implementation specific
-  // or it can be reserved and remain unused
-  //
-  UINT8   Support : 6;
-  //
-  // if set indicates override the feature policy defined by the members above
-  // if clear it indicates that this feature policy should be ignored completely
-  // this means the above two members should not be used
-  //
-  UINT8   Override : 1;
-};
-
-//
-// Declaration of the PCI Express features unique Id
-//
-typedef enum {
-  //
-  // support for PCI Express feature - Max. Payload Size
-  //
-  PciExpressMps,
-  //
-  // support for PCI Express feature - Max. Read Request Size
-  //
-  PciExpressMrrs,
-  //
-  // support for PCI Express feature - Extended Tag
-  //
-  PciExpressExtTag,
-  //
-  // support for PCI Express feature - Relax Order
-  //
-  PciExpressRelaxOrder,
-  //
-  // support for PCI Express feature - No-Snoop
-  //
-  PciExpressNoSnoop,
-  //
-  // support for PCI Express feature - ASPM state
-  //
-  PciExpressAspm,
-  //
-  // support for PCI Express feature - Common Clock Configuration
-  //
-  PciExpressCcc,
-  //
-  // support for PCI Express feature - Extended Sync
-  //
-  PciExpressExtSync,
-  //
-  // support for PCI Express feature - Atomic Op
-  //
-  PciExpressAtomicOp,
-  //
-  // support for PCI Express feature - LTR
-  //
-  PciExpressLtr,
-  //
-  // support for PCI Express feature - PTM
-  //
-  PciExpressPtm,
-  //
-  // support for PCI Express feature - Completion Timeout
-  //
-  PciExpressCto,
-  //
-  // support for PCI Express feature - Clock Power Management
-  //
-  PciExpressCpm,
-  //
-  // support for PCI Express feature - L1 PM Substates
-  //
-  PciExpressL1PmSubstates
-
-} PCI_EXPRESS_FEATURE_ID;
-
-//
-// PCI Express feature configuration routine during initialization phases
-//
-typedef
-EFI_STATUS
-(*PCI_EXPRESS_FEATURE_CONFIGURATION_ROUTINE) (
-  IN PCI_IO_DEVICE                            *PciDevice,
-  IN VOID                                     *PciExpressFeatureConfiguration
-  );
-
-//
-// data type for the PCI Express feature initialization phases
-//
-typedef struct {
-  //
-  // Pci Express feature configuration phase
-  //
-  PCI_EXPRESS_FEATURE_CONFIGURATION_PHASE   PciExpressFeatureConfigurationPhase;
-  //
-  // PCI Express feature Id
-  //
-  PCI_EXPRESS_FEATURE_ID                    PciExpressFeatureId;
-  //
-  // PCI Express feature configuration routine
-  //
-  PCI_EXPRESS_FEATURE_CONFIGURATION_ROUTINE PciExpressFeatureConfigurationRoutine;
-
-}PCI_EXPRESS_FEATURE_INITIALIZATION_POINT;
-
-
-
-/**
-  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
-EnumeratePciExpressFeatures (
-  IN EFI_HANDLE             Controller,
-  IN PCI_IO_DEVICE          *RootBridge
-  );
-
-#endif
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c
deleted file mode 100644
index bf380ab..0000000
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c
+++ /dev/null
@@ -1,902 +0,0 @@
-/** @file
-  This file encapsulate the usage of PCI Platform Protocol
-
-  This file define the necessary hooks used to obtain the platform
-  level data and policies which could be used in the PCI Enumeration phases
-
-Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "PciBus.h"
-
-
-EFI_PCI_EXPRESS_PLATFORM_PROTOCOL             *mPciExPlatformProtocol;
-EFI_PCI_EXPRESS_OVERRIDE_PROTOCOL             *mPciExOverrideProtocol;
-
-
-/**
-  This function retrieves the PCI Express Platform Protocols published by platform
-  @retval EFI_STATUS          direct return status from the LocateProtocol ()
-                              boot service for the PCI Express Override Protocol
-          EFI_SUCCESS         The PCI Express Platform Protocol is found
-**/
-EFI_STATUS
-GetPciExpressProtocol (
-  )
-{
-  EFI_STATUS  Status;
-
-  if (mPciExPlatformProtocol) {
-    //
-    // the PCI Express Platform Protocol is already initialized
-    //
-    return EFI_SUCCESS;
-  }
-  if (mPciExOverrideProtocol) {
-    //
-    // the PCI Express Override Protocol is already initialized
-    //
-    return EFI_SUCCESS;
-  }
-  //
-  // locate the PCI Express Platform Protocol
-  //
-  Status = gBS->LocateProtocol (
-                  &gEfiPciExpressPlatformProtocolGuid,
-                  NULL,
-                  (VOID **) &mPciExPlatformProtocol
-                  );
-  if (!EFI_ERROR (Status)) {
-    return Status;
-  }
-  //
-  // If PCI Express Platform protocol doesn't exist, try to get the Pci Express
-  // Override Protocol.
-  //
-  return gBS->LocateProtocol (
-                &gEfiPciExpressOverrideProtocolGuid,
-                NULL,
-                (VOID **) &mPciExOverrideProtocol
-                );
-}
-
-/**
-  This function indicates that the platform has published the PCI Express Platform
-  Protocol (or PCI Express Override Protocol) to indicate that this driver can
-  initialize the PCI Express features.
-  @retval     TRUE or FALSE
-**/
-BOOLEAN
-IsPciExpressProtocolPresent (
-  )
-{
-  if (
-      mPciExPlatformProtocol == NULL
-      && mPciExOverrideProtocol == NULL
-      ) {
-    return FALSE;
-  }
-  return TRUE;
-}
-
-/**
-  Routine to translate the given device-specific platform policy from type
-  EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE to HW-specific value, as per PCI Base Specification
-  Revision 4.0; for the PCI feature Max_Payload_Size.
-
-  @param  MPS     Input device-specific policy should be in terms of type
-                  EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE
-
-  @retval         Range values for the Max_Payload_Size as defined in the PCI
-                  Base Specification 4.0
-**/
-UINT8
-SetDevicePolicyPciExpressMps (
-  IN  UINT8                   MPS
-)
-{
-  switch (MPS) {
-    case EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_128B:
-      return PCIE_MAX_PAYLOAD_SIZE_128B;
-    case EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_256B:
-      return PCIE_MAX_PAYLOAD_SIZE_256B;
-    case EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_512B:
-      return PCIE_MAX_PAYLOAD_SIZE_512B;
-    case EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_1024B:
-      return PCIE_MAX_PAYLOAD_SIZE_1024B;
-    case EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_2048B:
-      return PCIE_MAX_PAYLOAD_SIZE_2048B;
-    case EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_4096B:
-      return PCIE_MAX_PAYLOAD_SIZE_4096B;
-    default:
-      return PCIE_MAX_PAYLOAD_SIZE_128B;
-  }
-}
-
-/**
-  Routine to translate the given device-specific platform policy from type
-  EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE to HW-specific value, as per PCI Base Specification
-  Revision 4.0; for the PCI feature Max_Read_Req_Size.
-
-  @param  MRRS    Input device-specific policy should be in terms of type
-                  EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE
-
-  @retval         Range values for the Max_Read_Req_Size as defined in the PCI
-                  Base Specification 4.0
-**/
-UINT8
-SetDevicePolicyPciExpressMrrs (
-  IN  UINT8                   MRRS
-)
-{
-  switch (MRRS) {
-    case EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_128B:
-      return PCIE_MAX_READ_REQ_SIZE_128B;
-    case EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_256B:
-      return PCIE_MAX_READ_REQ_SIZE_256B;
-    case EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_512B:
-      return PCIE_MAX_READ_REQ_SIZE_512B;
-    case EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_1024B:
-      return PCIE_MAX_READ_REQ_SIZE_1024B;
-    case EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_2048B:
-      return PCIE_MAX_READ_REQ_SIZE_2048B;
-    case EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_4096B:
-      return PCIE_MAX_READ_REQ_SIZE_4096B;
-    default:
-      return PCIE_MAX_READ_REQ_SIZE_128B;
-  }
-}
-
-/**
-  Routine to set the device-specific policy for the PCI feature Relax Ordering
-
-  @param  RelaxOrder    value corresponding to data type EFI_PCI_EXPRESS_RELAX_ORDER
-  @param  PciDevice     A pointer to PCI_IO_DEVICE
-**/
-VOID
-SetDevicePolicyPciExpressRo (
-  IN  EFI_PCI_EXPRESS_RELAX_ORDER RelaxOrder,
-  OUT PCI_IO_DEVICE               *PciDevice
-  )
-{
-  //
-  // implementation specific rules for the usage of PCI_FEATURE_POLICY members
-  // exclusively for the PCI Feature Relax Ordering (RO)
-  //
-  // .Override = 0 to skip this PCI feature RO for the PCI device
-  // .Override = 1 to program this RO PCI feature
-  //      .Act = 1 to enable the RO in the PCI device
-  //      .Act = 0 to disable the RO in the PCI device
-  //
-  switch (RelaxOrder) {
-    case  EFI_PCI_EXPRESS_RO_AUTO:
-      PciDevice->SetupRO.Override = 0;
-      break;
-    case  EFI_PCI_EXPRESS_RO_DISABLE:
-      PciDevice->SetupRO.Override = 1;
-      PciDevice->SetupRO.Act = 0;
-      break;
-    case  EFI_PCI_EXPRESS_RO_ENABLE:
-      PciDevice->SetupRO.Override = 1;
-      PciDevice->SetupRO.Act = 1;
-      break;
-    default:
-      PciDevice->SetupRO.Override = 0;
-      break;
-  }
-}
-
-/**
-  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;
-  }
-}
-
-/**
-  Routine to set the device-specific policy for the PCI feature CTO value range
-  or disable
-
-  @param  CtoSupport    value corresponding to data type EFI_PCI_EXPRESS_CTO_SUPPORT
-  @param  PciDevice     A pointer to PCI_IO_DEVICE
-**/
-VOID
-SetDevicePolicyPciExpressCto (
-  IN  EFI_PCI_EXPRESS_CTO_SUPPORT    CtoSupport,
-  OUT PCI_IO_DEVICE               *PciDevice
-)
-{
-  //
-  // implementation specific rules for the usage of PCI_FEATURE_POLICY members
-  // exclusively for the PCI Feature CTO
-  //
-  // .Override = 0 to skip this PCI feature CTO for the PCI device
-  // .Override = 1 to program this CTO PCI feature
-  //      .Act = 1 to program the CTO range as per given device policy in .Support
-  //      .Act = 0 to disable the CTO mechanism in the PCI device, CTO set to default range
-  //
-  switch (CtoSupport) {
-    case  EFI_PCI_EXPRESS_CTO_AUTO:
-      PciDevice->SetupCTO.Override = 0;
-      break;
-    case  EFI_PCI_EXPRESS_CTO_DEFAULT:
-      PciDevice->SetupCTO.Override = 1;
-      PciDevice->SetupCTO.Act = 1;
-      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_50US_50MS;
-      break;
-    case  EFI_PCI_EXPRESS_CTO_RANGE_A1:
-      PciDevice->SetupCTO.Override = 1;
-      PciDevice->SetupCTO.Act = 1;
-      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_50US_100US;
-      break;
-    case  EFI_PCI_EXPRESS_CTO_RANGE_A2:
-      PciDevice->SetupCTO.Override = 1;
-      PciDevice->SetupCTO.Act = 1;
-      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_1MS_10MS;
-      break;
-    case  EFI_PCI_EXPRESS_CTO_RANGE_B1:
-      PciDevice->SetupCTO.Override = 1;
-      PciDevice->SetupCTO.Act = 1;
-      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_16MS_55MS;
-      break;
-    case  EFI_PCI_EXPRESS_CTO_RANGE_B2:
-      PciDevice->SetupCTO.Override = 1;
-      PciDevice->SetupCTO.Act = 1;
-      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_65MS_210MS;
-      break;
-    case  EFI_PCI_EXPRESS_CTO_RANGE_C1:
-      PciDevice->SetupCTO.Override = 1;
-      PciDevice->SetupCTO.Act = 1;
-      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_260MS_900MS;
-      break;
-    case  EFI_PCI_EXPRESS_CTO_RANGE_C2:
-      PciDevice->SetupCTO.Override = 1;
-      PciDevice->SetupCTO.Act = 1;
-      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_1S_3_5S;
-      break;
-    case  EFI_PCI_EXPRESS_CTO_RANGE_D1:
-      PciDevice->SetupCTO.Override = 1;
-      PciDevice->SetupCTO.Act = 1;
-      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_4S_13S;
-      break;
-    case  EFI_PCI_EXPRESS_CTO_RANGE_D2:
-      PciDevice->SetupCTO.Override = 1;
-      PciDevice->SetupCTO.Act = 1;
-      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_17S_64S;
-      break;
-    case  EFI_PCI_EXPRESS_CTO_DET_DISABLE:
-      PciDevice->SetupCTO.Override = 1;
-      PciDevice->SetupCTO.Act = 0;
-      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_50US_50MS;
-      break;
-  }
-}
-
-/**
-  Routine to set the device-specific policy for the PCI feature LTR enable/disable
-
-  @param  AtomicOp      value corresponding to data type EFI_PCI_EXPRESS_ATOMIC_OP
-  @param  PciDevice     A pointer to PCI_IO_DEVICE
-
-**/
-VOID
-SetDevicePolicyPciExpressLtr (
-  IN  EFI_PCI_EXPRESS_LTR            Ltr,
-  OUT PCI_IO_DEVICE               *PciDevice
-  )
-{
-  switch (Ltr){
-    case EFI_PCI_EXPRESS_LTR_AUTO:
-    case EFI_PCI_EXPRESS_LTR_DISABLE:
-      //
-      // leave the LTR mechanism disable or restore to its default state
-      //
-      PciDevice->SetupLtr = FALSE;
-      break;
-    case EFI_PCI_EXPRESS_LTR_ENABLE:
-      //
-      // LTR mechanism enable
-      //
-      PciDevice->SetupLtr = TRUE;
-      break;
-  }
-}
-
-/**
-  Generic routine to setup the PCI features as per its predetermined defaults.
-**/
-VOID
-SetupDefaultPciExpressDevicePolicy (
-  IN  PCI_IO_DEVICE               *PciDevice
-  )
-{
-
-  if (mPciExpressPlatformPolicy.Mps) {
-    PciDevice->SetupMPS = EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_AUTO;
-  } else {
-    PciDevice->SetupMPS = EFI_PCI_EXPRESS_NOT_APPLICABLE;
-  }
-
-  if (mPciExpressPlatformPolicy.Mrrs) {
-    PciDevice->SetupMRRS = EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_AUTO;
-  } else {
-    PciDevice->SetupMRRS = EFI_PCI_EXPRESS_NOT_APPLICABLE;
-  }
-
-  PciDevice->SetupRO.Override = 0;
-
-  PciDevice->SetupNS.Override = 0;
-
-  PciDevice->SetupCTO.Override = 0;
-
-  PciDevice->SetupAtomicOp.Override = 0;
-
-  PciDevice->SetupLtr = FALSE;
-
-  if (mPciExpressPlatformPolicy.ExtTag) {
-    PciDevice->SetupExtTag = EFI_PCI_EXPRESS_EXTENDED_TAG_AUTO;
-  } else {
-    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;
-  }
-
-  //
-  // default device policy for the device's link clock configuration
-  //
-  if (mPciExpressPlatformPolicy.Ccc) {
-    PciDevice->SetupCcc = EFI_PCI_EXPRESS_CLK_CFG_AUTO;
-  } else {
-    PciDevice->SetupCcc = EFI_PCI_EXPRESS_NOT_APPLICABLE;
-  }
-
-}
-
-/**
-  initialize the device policy data members
-**/
-VOID
-InitializeDevicePolicyData (
-  IN EFI_PCI_EXPRESS_DEVICE_POLICY  *PciExpressDevicePolicy
-  )
-{
-  UINTN     length;
-  UINT8     *PciExpressPolicy;
-  UINT8     *PciExDevicePolicy;
-
-
-  ZeroMem (PciExpressDevicePolicy, sizeof (EFI_PCI_EXPRESS_DEVICE_POLICY));
-
-  for (
-      length = 0
-      , PciExpressPolicy = (UINT8*)&mPciExpressPlatformPolicy
-      , PciExDevicePolicy = (UINT8*)PciExpressDevicePolicy
-      ; length < sizeof (EFI_PCI_EXPRESS_PLATFORM_POLICY)
-      ; length++
-      ) {
-    if (!PciExpressPolicy[length]) {
-      PciExDevicePolicy[length] = EFI_PCI_EXPRESS_NOT_APPLICABLE;
-    }
-  }
-}
-
-/**
-  Intermediate routine to either get the PCI device specific platform policies
-  through the PCI Platform Protocol, or its alias the PCI Override Protocol.
-
-  @param  PciDevice           A pointer to PCI_IO_DEVICE
-  @param  PciPlatformProtocol A pointer to EFI_PCI_EXPRESS_PLATFORM_PROTOCOL
-
-  @retval EFI_STATUS          The direct status from the PCI Platform Protocol
-  @retval EFI_SUCCESS         if on returning predetermined PCI features defaults,
-                              for the case when protocol returns as EFI_UNSUPPORTED
-                              to indicate PCI device exist and it has no platform
-                              policy defined.
-**/
-EFI_STATUS
-GetPciExpressDevicePolicy (
-  IN  PCI_IO_DEVICE                     *PciDevice,
-  IN  EFI_PCI_EXPRESS_PLATFORM_PROTOCOL *PciPlatformProtocol
-  )
-{
-  EFI_PCI_EXPRESS_DEVICE_POLICY               PciExpressDevicePolicy;
-  EFI_STATUS                                  Status;
-  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress;
-
-  PciAddress.Bus = PciDevice->BusNumber;
-  PciAddress.Device = PciDevice->DeviceNumber;
-  PciAddress.Function = PciDevice->FunctionNumber;
-  PciAddress.Register = 0;
-  PciAddress.ExtendedRegister = 0;
-
-  InitializeDevicePolicyData (&PciExpressDevicePolicy);
-  Status = PciPlatformProtocol->GetDevicePolicy (
-                                  PciPlatformProtocol,
-                                  mRootBridgeHandle,
-                                  PciAddress,
-                                  sizeof (EFI_PCI_EXPRESS_DEVICE_POLICY),
-                                  &PciExpressDevicePolicy
-                                  );
-  if (!EFI_ERROR(Status)) {
-    //
-    // platform chipset policies are returned for this PCI device
-    //
-
-    //
-    // set device specific policy for the Max_Payload_Size
-    //
-    if (mPciExpressPlatformPolicy.Mps) {
-      PciDevice->SetupMPS = PciExpressDevicePolicy.DeviceCtlMPS;
-    } else {
-      PciDevice->SetupMPS = EFI_PCI_EXPRESS_NOT_APPLICABLE;
-    }
-
-    //
-    // set device specific policy for Max_Read_Req_Size
-    //
-    if (mPciExpressPlatformPolicy.Mrrs) {
-      PciDevice->SetupMRRS = PciExpressDevicePolicy.DeviceCtlMRRS;
-    } else {
-      PciDevice->SetupMRRS = EFI_PCI_EXPRESS_NOT_APPLICABLE;
-    }
-    //
-    // set device specific policy for Relax Ordering
-    //
-    if (mPciExpressPlatformPolicy.RelaxOrder) {
-      SetDevicePolicyPciExpressRo (PciExpressDevicePolicy.DeviceCtlRelaxOrder, PciDevice);
-    } else {
-      PciDevice->SetupRO.Override = 0;
-    }
-
-    //
-    // set the device specific policy for No-Snoop
-    //
-    if (mPciExpressPlatformPolicy.NoSnoop) {
-      SetDevicePolicyPciExpressNs (PciExpressDevicePolicy.DeviceCtlNoSnoop, PciDevice);
-    } else {
-      PciDevice->SetupNS.Override = 0;
-    }
-
-    //
-    // set the device specific policy for Completion Timeout (CTO)
-    //
-    if (mPciExpressPlatformPolicy.Cto) {
-      SetDevicePolicyPciExpressCto (PciExpressDevicePolicy.CTOsupport, PciDevice);
-    } else {
-      PciDevice->SetupCTO.Override = 0;
-    }
-
-    //
-    // set the device-specific policy for AtomicOp
-    //
-    if (mPciExpressPlatformPolicy.AtomicOp) {
-      PciDevice->SetupAtomicOp = PciExpressDevicePolicy.DeviceCtl2AtomicOp;
-    } else {
-      PciDevice->SetupAtomicOp.Override = 0;
-    }
-
-    //
-    // set the device-specific policy for LTR mechanism in the function
-    //
-    if (mPciExpressPlatformPolicy.Ltr) {
-      SetDevicePolicyPciExpressLtr (PciExpressDevicePolicy.DeviceCtl2LTR, PciDevice);
-    } else {
-      PciDevice->SetupLtr = FALSE;
-    }
-
-    //
-    // set the device-specifci policy for the PCI Express feature Extended Tag
-    //
-    if (mPciExpressPlatformPolicy.ExtTag) {
-      PciDevice->SetupExtTag = PciExpressDevicePolicy.DeviceCtlExtTag;
-    } else {
-      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;
-    }
-
-    //
-    // set the device policy for the PCI Express feature Common Clock Configuration
-    //
-    if (mPciExpressPlatformPolicy.Ccc) {
-      PciDevice->SetupCcc = PciExpressDevicePolicy.LinkCtlCommonClkCfg;
-    } else {
-      PciDevice->SetupCcc = EFI_PCI_EXPRESS_NOT_APPLICABLE;
-    }
-
-    DEBUG ((
-      DEBUG_INFO,
-      "[device policy: platform]"
-      ));
-    return Status;
-  } else if (Status == EFI_UNSUPPORTED) {
-    //
-    // platform chipset policies are not provided for this PCI device
-    // let the enumeration happen as per the PCI standard way
-    //
-    SetupDefaultPciExpressDevicePolicy (PciDevice);
-    DEBUG ((
-      DEBUG_INFO,
-      "[device policy: default]"
-      ));
-    return EFI_SUCCESS;
-  }
-  DEBUG ((
-    DEBUG_ERROR,
-    "[device policy: none (error)]"
-    ));
-  return Status;
-}
-
-/**
-  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  PciDevice     A pointer to PCI_IO_DEVICE
-
-  @retval EFI_STATUS    The direct status from the PCI Platform Protocol
-  @retval EFI_SUCCESS   On return of predetermined PCI features defaults, for
-                        the case when protocol returns as EFI_UNSUPPORTED to
-                        indicate PCI device exist and it has no platform policy
-                        defined. Also, on returns when no PCI Platform Protocol
-                        exist.
-**/
-EFI_STATUS
-PciExpressPlatformGetDevicePolicy (
-  IN PCI_IO_DEVICE          *PciDevice
-  )
-{
-  if (mPciExPlatformProtocol != NULL) {
-    return GetPciExpressDevicePolicy (PciDevice, mPciExPlatformProtocol);
-  } else if (mPciExOverrideProtocol != NULL) {
-    return GetPciExpressDevicePolicy (PciDevice, mPciExOverrideProtocol);
-  } else {
-    //
-    // no protocol found, platform does not require the PCI Express initialization
-    //
-    return EFI_UNSUPPORTED;
-  }
-}
-
-/**
-  This function gets the platform requirement to initialize the list of PCI Express
-  features from the protocol definition supported.
-  This function should be called after the LocatePciPlatformProtocol.
-  @retval EFI_SUCCESS           return by platform to acknowledge the list of
-                                PCI Express feature to be configured
-                                (in mPciExpressPlatformPolicy)
-          EFI_INVALID_PARAMETER platform does not support the protocol arguements
-                                passed
-          EFI_UNSUPPORTED       platform did not published the protocol
-**/
-EFI_STATUS
-PciExpressPlatformGetPolicy (
-  )
-{
-  EFI_STATUS    Status;
-
-  if (mPciExPlatformProtocol) {
-    Status = mPciExPlatformProtocol->GetPolicy (
-                                      mPciExPlatformProtocol,
-                                      sizeof (EFI_PCI_EXPRESS_PLATFORM_POLICY),
-                                      &mPciExpressPlatformPolicy
-                                      );
-  } else if (mPciExOverrideProtocol) {
-    Status = mPciExOverrideProtocol->GetPolicy (
-                                      mPciExOverrideProtocol,
-                                      sizeof (EFI_PCI_EXPRESS_PLATFORM_POLICY),
-                                      &mPciExpressPlatformPolicy
-                                      );
-  } else {
-    //
-    // no protocol found, platform does not require the PCI Express initialization
-    //
-    return EFI_UNSUPPORTED;
-  }
-  return Status;
-}
-
-EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE
-GetPciExpressMps (
-  IN UINT8              Mps
-  )
-{
-  switch (Mps) {
-    case PCIE_MAX_PAYLOAD_SIZE_128B:
-      return EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_128B;
-    case PCIE_MAX_PAYLOAD_SIZE_256B:
-      return EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_256B;
-    case PCIE_MAX_PAYLOAD_SIZE_512B:
-      return EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_512B;
-    case PCIE_MAX_PAYLOAD_SIZE_1024B:
-      return EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_1024B;
-    case PCIE_MAX_PAYLOAD_SIZE_2048B:
-      return EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_2048B;
-    case PCIE_MAX_PAYLOAD_SIZE_4096B:
-      return EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_4096B;
-  }
-  return EFI_PCI_EXPRESS_NOT_APPLICABLE;
-}
-
-EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE
-GetPciExpressMrrs (
-  IN UINT8              Mrrs
-  )
-{
-  switch (Mrrs) {
-    case PCIE_MAX_READ_REQ_SIZE_128B:
-      return EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_128B;
-    case PCIE_MAX_READ_REQ_SIZE_256B:
-      return EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_256B;
-    case PCIE_MAX_READ_REQ_SIZE_512B:
-      return EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_512B;
-    case PCIE_MAX_READ_REQ_SIZE_1024B:
-      return EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_1024B;
-    case PCIE_MAX_READ_REQ_SIZE_2048B:
-      return EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_2048B;
-    case PCIE_MAX_READ_REQ_SIZE_4096B:
-      return EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_4096B;
-  }
-  return EFI_PCI_EXPRESS_NOT_APPLICABLE;
-}
-
-EFI_PCI_EXPRESS_CTO_SUPPORT
-GetPciExpressCto (
-  IN UINT8              Cto
-  )
-{
-  switch (Cto) {
-    case PCIE_COMPLETION_TIMEOUT_50US_50MS:
-      return EFI_PCI_EXPRESS_CTO_DEFAULT;
-    case PCIE_COMPLETION_TIMEOUT_50US_100US:
-      return EFI_PCI_EXPRESS_CTO_RANGE_A1;
-    case PCIE_COMPLETION_TIMEOUT_1MS_10MS:
-      return EFI_PCI_EXPRESS_CTO_RANGE_A2;
-    case PCIE_COMPLETION_TIMEOUT_16MS_55MS:
-      return EFI_PCI_EXPRESS_CTO_RANGE_B1;
-    case PCIE_COMPLETION_TIMEOUT_65MS_210MS:
-      return EFI_PCI_EXPRESS_CTO_RANGE_B2;
-    case PCIE_COMPLETION_TIMEOUT_260MS_900MS:
-      return EFI_PCI_EXPRESS_CTO_RANGE_C1;
-    case PCIE_COMPLETION_TIMEOUT_1S_3_5S:
-      return EFI_PCI_EXPRESS_CTO_RANGE_C2;
-    case PCIE_COMPLETION_TIMEOUT_4S_13S:
-      return EFI_PCI_EXPRESS_CTO_RANGE_D1;
-    case PCIE_COMPLETION_TIMEOUT_17S_64S:
-      return EFI_PCI_EXPRESS_CTO_RANGE_D2;
-  }
-  return EFI_PCI_EXPRESS_NOT_APPLICABLE;
-}
-
-EFI_PCI_EXPRESS_EXTENDED_TAG
-GetPciExpressExtTag (
-  IN PCI_IO_DEVICE                        *PciDevice
-  )
-{
-  if (PciDevice->PciExpressCapabilityStructure.DeviceControl2.Bits.TenBitTagRequesterEnable) {
-    return EFI_PCI_EXPRESS_EXTENDED_TAG_10BIT;
-  } else if (PciDevice->PciExpressCapabilityStructure.DeviceControl.Bits.ExtendedTagField) {
-    return EFI_PCI_EXPRESS_EXTENDED_TAG_8BIT;
-  } else {
-    return EFI_PCI_EXPRESS_EXTENDED_TAG_5BIT;
-  }
-}
-
-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.
-
-  @param  PciDevice                 A pointer to PCI_IO_DEVICE
-  @param  PciExDeviceConfiguration  Pointer to EFI_PCI_EXPRESS_DEVICE_CONFIGURATION.
-                                    Used to pass the current state of device to
-                                    platform.
-
-  @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
-PciExpressPlatformNotifyDeviceState (
-  IN PCI_IO_DEVICE                        *PciDevice
-  )
-{
-  EFI_PCI_EXPRESS_DEVICE_CONFIGURATION      PciExDeviceConfiguration;
-
-  //
-  // get the device-specific state for the PCIe Max_Payload_Size feature
-  //
-  if (mPciExpressPlatformPolicy.Mps) {
-    PciExDeviceConfiguration.DeviceCtlMPS = GetPciExpressMps (
-                                              (UINT8)PciDevice->PciExpressCapabilityStructure.DeviceControl.Bits.MaxPayloadSize
-                                              );
-  } else {
-    PciExDeviceConfiguration.DeviceCtlMPS = EFI_PCI_EXPRESS_NOT_APPLICABLE;
-  }
-
-  //
-  // get the device-specific state for the PCIe Max_Read_Req_Size feature
-  //
-  if (mPciExpressPlatformPolicy.Mrrs) {
-    PciExDeviceConfiguration.DeviceCtlMRRS = GetPciExpressMrrs (
-                                              (UINT8)PciDevice->PciExpressCapabilityStructure.DeviceControl.Bits.MaxReadRequestSize
-                                              );
-  } else {
-    PciExDeviceConfiguration.DeviceCtlMRRS = EFI_PCI_EXPRESS_NOT_APPLICABLE;
-  }
-  //
-  // get the device-specific state for the PCIe Relax Order feature
-  //
-  if (mPciExpressPlatformPolicy.RelaxOrder) {
-    PciExDeviceConfiguration.DeviceCtlRelaxOrder = PciDevice->PciExpressCapabilityStructure.DeviceControl.Bits.RelaxedOrdering
-                                                      ? EFI_PCI_EXPRESS_RO_ENABLE
-                                                      : EFI_PCI_EXPRESS_RO_DISABLE;
-  } else {
-    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;
-  }
-
-  //
-  // get the device-specific state for the PCIe CTO feature
-  //
-  if (mPciExpressPlatformPolicy.Cto) {
-    PciExDeviceConfiguration.CTOsupport = PciDevice->PciExpressCapabilityStructure.DeviceControl2.Bits.CompletionTimeoutDisable
-                                          ? EFI_PCI_EXPRESS_CTO_DET_DISABLE
-                                          : GetPciExpressCto (
-                                              (UINT8)PciDevice->PciExpressCapabilityStructure.DeviceControl2.Bits.CompletionTimeoutValue
-                                              );
-  } else {
-    PciExDeviceConfiguration.CTOsupport = EFI_PCI_EXPRESS_NOT_APPLICABLE;
-  }
-
-  //
-  // get the device-specific state for the PCIe AtomicOp feature
-  //
-  if (mPciExpressPlatformPolicy.AtomicOp) {
-    PciExDeviceConfiguration.DeviceCtl2AtomicOp.Enable_AtomicOpRequester
-    = (UINT8)PciDevice->PciExpressCapabilityStructure.DeviceControl2.Bits.AtomicOpRequester;
-    PciExDeviceConfiguration.DeviceCtl2AtomicOp.Enable_AtomicOpEgressBlocking
-    = (UINT8)PciDevice->PciExpressCapabilityStructure.DeviceControl2.Bits.AtomicOpEgressBlocking;
-  } else {
-    PciExDeviceConfiguration.DeviceCtl2AtomicOp.Override = 0;
-    PciExDeviceConfiguration.DeviceCtl2AtomicOp.Enable_AtomicOpRequester = 0;
-    PciExDeviceConfiguration.DeviceCtl2AtomicOp.Enable_AtomicOpEgressBlocking = 0;
-  }
-  //
-  // get the device-specific state for LTR mechanism in the function
-  //
-  if (mPciExpressPlatformPolicy.Ltr) {
-    PciExDeviceConfiguration.DeviceCtl2LTR = PciDevice->PciExpressCapabilityStructure.DeviceControl2.Bits.LtrMechanism
-                                                ? EFI_PCI_EXPRESS_LTR_ENABLE
-                                                : EFI_PCI_EXPRESS_LTR_DISABLE;
-  } else {
-    PciExDeviceConfiguration.DeviceCtl2LTR = EFI_PCI_EXPRESS_NOT_APPLICABLE;
-  }
-
-  //
-  // get the device-specific state for the PCie Extended Tag in the function
-  //
-  if (mPciExpressPlatformPolicy.ExtTag) {
-    PciExDeviceConfiguration.DeviceCtlExtTag = GetPciExpressExtTag (PciDevice);
-  } else {
-    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;
-  }
-
-  //
-  // get the device-specific Common CLock Configuration value
-  //
-  if (mPciExpressPlatformPolicy.Ccc) {
-    PciExDeviceConfiguration.LinkCtlCommonClkCfg =
-        PciDevice->PciExpressCapabilityStructure.LinkControl.Bits.CommonClockConfiguration ?
-            EFI_PCI_EXPRESS_CLK_CFG_COMMON : EFI_PCI_EXPRESS_CLK_CFG_ASYNCH;
-  } else {
-    PciExDeviceConfiguration.LinkCtlCommonClkCfg = EFI_PCI_EXPRESS_NOT_APPLICABLE;
-  }
-
-  if (mPciExPlatformProtocol != NULL) {
-    return mPciExPlatformProtocol->NotifyDeviceState (
-                                    mPciExPlatformProtocol,
-                                    PciDevice->Handle,
-                                    sizeof (EFI_PCI_EXPRESS_DEVICE_CONFIGURATION),
-                                    &PciExDeviceConfiguration
-                                    );
-  } else if (mPciExOverrideProtocol != NULL) {
-    return mPciExOverrideProtocol->NotifyDeviceState (
-                                    mPciExOverrideProtocol,
-                                    PciDevice->Handle,
-                                    sizeof (EFI_PCI_EXPRESS_DEVICE_CONFIGURATION),
-                                    &PciExDeviceConfiguration
-                                    );
-  } else {
-    //
-    // unexpected error
-    //
-    return EFI_UNSUPPORTED;
-  }
-}
-
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.h
deleted file mode 100644
index 4653c79..0000000
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/** @file
-  This file encapsulate the usage of PCI Platform Protocol
-
-  This file define the necessary hooks used to obtain the platform
-  level data and policies which could be used in the PCI Enumeration phases
-
-Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-
-#ifndef _EFI_PCI_PLATFORM_SUPPORT_H_
-#define _EFI_PCI_PLATFORM_SUPPORT_H_
-
-
-/**
-  This function retrieves the PCI Express Platform Protocols published by platform
-  @retval EFI_STATUS          direct return status from the LocateProtocol ()
-                              boot service for the PCI Express Override Protocol
-          EFI_SUCCESS         The PCI Express Platform Protocol is found
-**/
-EFI_STATUS
-GetPciExpressProtocol (
-  );
-
-/**
-  This function indicates that the platform has published the PCI Express Platform
-  Protocol (or PCI Express Override Protocol) to indicate that this driver can
-  initialize the PCI Express features.
-  @retval     TRUE or FALSE
-**/
-BOOLEAN
-IsPciExpressProtocolPresent (
-  );
-
-/**
-  This function gets the platform requirement to initialize the list of PCI Express
-  features from the protocol definition supported.
-  This function should be called after the LocatePciPlatformProtocol.
-  @retval EFI_SUCCESS           return by platform to acknowledge the list of
-                                PCI Express feature to be configured
-                                (in mPciExpressPlatformPolicy)
-          EFI_INVALID_PARAMETER platform does not support the protocol arguements
-                                passed
-          EFI_UNSUPPORTED       platform did not published the protocol
-**/
-EFI_STATUS
-PciExpressPlatformGetPolicy (
-  );
-
-/**
-  Gets the PCI device-specific platform policy from the PCI 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  PciDevice     A pointer to PCI_IO_DEVICE
-
-  @retval EFI_STATUS    The direct status from the PCI Platform Protocol
-  @retval EFI_SUCCESS   On return of predetermined PCI features defaults, for
-                        the case when protocol returns as EFI_UNSUPPORTED to
-                        indicate PCI device exist and it has no platform policy
-                        defined. Also, on returns when no PCI Platform Protocol
-                        exist.
-**/
-EFI_STATUS
-PciExpressPlatformGetDevicePolicy (
-  IN PCI_IO_DEVICE          *PciDevice
-  );
-
-/**
-  Notifies the platform about the current PCI Express state of the device.
-
-  @param  PciDevice                 A pointer to PCI_IO_DEVICE
-  @param  PciExDeviceConfiguration  Pointer to EFI_PCI_EXPRESS_DEVICE_CONFIGURATION.
-                                    Used to pass the current state of device to
-                                    platform.
-
-  @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
-PciExpressPlatformNotifyDeviceState (
-  IN PCI_IO_DEVICE                        *PciDevice
-  );
-
-/**
-  Routine to translate the given device-specific platform policy from type
-  EFI_PCI_CONF_MAX_PAYLOAD_SIZE to HW-specific value, as per PCI Base Specification
-  Revision 4.0; for the PCI feature Max_Payload_Size.
-
-  @param  MPS     Input device-specific policy should be in terms of type
-                  EFI_PCI_CONF_MAX_PAYLOAD_SIZE
-
-  @retval         Range values for the Max_Payload_Size as defined in the PCI
-                  Base Specification 4.0
-**/
-UINT8
-SetDevicePolicyPciExpressMps (
-  IN  UINT8                   MPS
-);
-
-/**
-  Routine to translate the given device-specific platform policy from type
-  EFI_PCI_CONF_MAX_READ_REQ_SIZE to HW-specific value, as per PCI Base Specification
-  Revision 4.0; for the PCI feature Max_Read_Req_Size.
-
-  @param  MRRS    Input device-specific policy should be in terms of type
-                  EFI_PCI_CONF_MAX_READ_REQ_SIZE
-
-  @retval         Range values for the Max_Read_Req_Size as defined in the PCI
-                  Base Specification 4.0
-**/
-UINT8
-SetDevicePolicyPciExpressMrrs (
-  IN  UINT8                   MRRS
-);
-#endif
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 03/15] MdeModulePkg/PciBus: Rename Cache PCIe Capability Structure
       [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-10 16:13 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 02/15] MdeModulePkg/PciBusDxe: PciBusDxe Code refactor Javeed, Ashraf
@ 2020-05-10 16:14 ` 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
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-10 16:14 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Jian J Wang, Hao A Wu

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

Rename the cache PCIe Capability Structure.

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>
---
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h               | 2 +-
 MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
index 5a7c1c2..9947203 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
@@ -269,7 +269,7 @@ struct _PCI_IO_DEVICE {
   // For PCI Express Capability List Structure
   //
   UINT8                                     PciExpressCapabilityOffset;
-  PCI_CAPABILITY_PCIEXP                     PciExpressCapabilityStructure;
+  PCI_CAPABILITY_PCIEXP                     PciExpressCapability;
   //
   // For SR-IOV
   //
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
index c9e52ea..0f43e43 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
@@ -2162,7 +2162,7 @@ CreatePciIoDevice (
                   EfiPciIoWidthUint8,
                   PciIoDevice->PciExpressCapabilityOffset,
                   sizeof (PCI_CAPABILITY_PCIEXP) / sizeof (UINT8),
-                  &PciIoDevice->PciExpressCapabilityStructure
+                  &PciIoDevice->PciExpressCapability
                   );
   }
 
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 04/15] MdeModulePkg/PciBusDxe: Refactor the PCIe Bridge enable
       [not found] <20200510161412.13832-1-ashraf.javeed@intel.com>
                   ` (2 preceding siblings ...)
  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-10 16:14 ` 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
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-10 16:14 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Jian J Wang, Hao A Wu

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

Refactor the PCIe Bridge enabling code.

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>
---
 MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c | 70 ++++++++++++++++++++--------------------------------------------------
 1 file changed, 20 insertions(+), 50 deletions(-)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
index 5724fd6..62ef184 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
@@ -597,52 +597,36 @@ DeRegisterPciDevice (
 }
 
 /**
-  Start the PCI root Ports or PCI-PCI Bridge only.
+  Enable all the PCI bridges under the specified root bridge or PCI-PCI Bridge.
 
-  @param Controller          The root bridge handle.
-  @param RootBridge          A pointer to the PCI_IO_DEVICE.
-  @param RemainingDevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL.
-  @param NumberOfChildren    Children number.
-  @param ChildHandleBuffer   A pointer to the child handle buffer.
-
-  @retval EFI_NOT_READY   Device is not allocated.
-  @retval EFI_UNSUPPORTED Device only support PCI-PCI bridge.
-  @retval EFI_NOT_FOUND   Can not find the specific device.
-  @retval EFI_SUCCESS     Success to start Pci devices on bridge.
+  @param Bridge          A pointer to the PCI_IO_DEVICE.
 
 **/
-EFI_STATUS
+VOID
 EnablePciBridges (
-  IN EFI_HANDLE                          Controller,
-  IN PCI_IO_DEVICE                       *RootBridge
+  IN PCI_IO_DEVICE          *Bridge
   )
 
 {
   PCI_IO_DEVICE             *PciIoDevice;
-  EFI_STATUS                Status;
-  LIST_ENTRY                *CurrentLink;
+  LIST_ENTRY                *Link;
   UINT64                    Supports;
 
-  PciIoDevice = NULL;
-  CurrentLink = RootBridge->ChildList.ForwardLink;
-
-  while (CurrentLink != NULL && CurrentLink != &RootBridge->ChildList) {
-
-    PciIoDevice = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
-
+  for ( Link = GetFirstNode (&Bridge->ChildList)
+      ; !IsNull (&Bridge->ChildList, Link)
+      ; Link = GetNextNode (&Bridge->ChildList, Link)
+      ) {
+    PciIoDevice = PCI_IO_DEVICE_FROM_LINK (Link);
     //
-    // check if the device has been assigned with required resource
-    // and registered
+    // Skip the device hasn't been assigned with required resource
+    // or registered.
     //
-    if (!PciIoDevice->Registered && !PciIoDevice->Allocated) {
-      return EFI_NOT_READY;
+    if (!PciIoDevice->Registered || !PciIoDevice->Allocated) {
+      continue;
     }
 
     if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {
-      Status = EnablePciBridges (
-                 Controller,
-                 PciIoDevice
-                 );
+      EnablePciBridges (PciIoDevice);
 
       PciIoDevice->PciIo.Attributes (
                            &(PciIoDevice->PciIo),
@@ -650,27 +634,17 @@ EnablePciBridges (
                            0,
                            &Supports
                          );
-      Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
+      Supports &= (UINT64) EFI_PCI_DEVICE_ENABLE;
       PciIoDevice->PciIo.Attributes (
                            &(PciIoDevice->PciIo),
                            EfiPciIoAttributeOperationEnable,
                            Supports,
                            NULL
                          );
-
     }
-
-    CurrentLink = CurrentLink->ForwardLink;
-  }
-
-  if (PciIoDevice == NULL) {
-    return EFI_NOT_FOUND;
-  } else {
-    return EFI_SUCCESS;
   }
 }
 
-
 /**
   Register to manage the PCI device on the specified root bridge or PCI-PCI Bridge.
 
@@ -851,9 +825,7 @@ StartPciDevicesOnBridge (
              ChildHandleBuffer
              );
 
-  if (EFI_ERROR (Status)) {
-    return Status;
-  } else {
+  if (!EFI_ERROR (Status)) {
     //
     // the late configuration of PCI Express features
     // the platform is required to indicate its requirement for the initialization
@@ -861,13 +833,11 @@ StartPciDevicesOnBridge (
     //
 
     //
-    // finally start those PCI bridge port devices only
+    // finally enable those PCI bridges
     //
-    return EnablePciBridges (
-             Controller,
-             RootBridge
-             );
+    EnablePciBridges (RootBridge);
   }
+  return Status;
 }
 
 /**
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 05/15] MdeModulePkg/PciBusDxe: Locate PciePlatform/PcieOverride protocol
       [not found] <20200510161412.13832-1-ashraf.javeed@intel.com>
                   ` (3 preceding siblings ...)
  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-10 16:14 ` Javeed, Ashraf
  2020-05-13  6:31   ` Ni, Ray
  2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 06/15] MdeModulePkg/PciBusDxe: Add the framework to init PCIe features Javeed, Ashraf
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-10 16:14 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Jian J Wang, Hao A Wu

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

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.c             |  5 +++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h             |  1 +
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf        |  2 ++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.h | 25 +++++++++++++++++++++++++
 5 files changed, 77 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
index 53e6dfa..a139bed 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
@@ -285,6 +285,11 @@ PciBusDriverBindingStart (
           );
   }
 
+  //
+  // get the PCI Express Protocol or the PCI Express Override Protocol
+  //
+  InitializePciExpressProtocols ();
+
   if (mIoMmuProtocol == NULL) {
     gBS->LocateProtocol (
           &gEdkiiIoMmuProtocolGuid,
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
index 9947203..ccf9ffa 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
@@ -82,6 +82,7 @@ typedef enum {
 #include "PciPowerManagement.h"
 #include "PciHotPlugSupport.h"
 #include "PciLib.h"
+#include "PcieFeatureSupport.h"
 
 #define VGABASE1  0x3B0
 #define VGALIMIT1 0x3BB
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
index 3b1559e..0818153 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
@@ -57,6 +57,8 @@
   PciCommand.h
   PciIo.h
   PciBus.h
+  PcieFeatureSupport.c
+  PcieFeatureSupport.h
 
 [Packages]
   MdePkg/MdePkg.dec
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
new file mode 100644
index 0000000..13d0e0b
--- /dev/null
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
@@ -0,0 +1,44 @@
+/** @file
+  PCI standard feature support functions implementation for PCI Bus module..
+
+Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PciBus.h"
+#include "PcieFeatureSupport.h"
+EFI_PCI_EXPRESS_PLATFORM_PROTOCOL    *mPciePlatformProtocol;
+
+/**
+  This function retrieves the PCI Express Platform Protocols published by platform
+  @retval EFI_STATUS          direct return status from the LocateProtocol ()
+                              boot service for the PCI Express Override Protocol.
+          EFI_SUCCESS         The PCI Express Platform Protocol is found.
+**/
+EFI_STATUS
+InitializePciExpressProtocols (
+  VOID
+  )
+{
+  EFI_STATUS                      Status;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiPciExpressPlatformProtocolGuid,
+                  NULL,
+                  (VOID **) &mPciePlatformProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    //
+    // If PCI Express Platform protocol doesn't exist, try to get the Pci Express
+    // Override Protocol and treat it as PCI Express Platform protocol.
+    //
+    Status = gBS->LocateProtocol (
+                    &gEfiPciExpressOverrideProtocolGuid,
+                    NULL,
+                    (VOID **) &mPciePlatformProtocol
+                    );
+  }
+  return Status;
+}
+
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.h
new file mode 100644
index 0000000..5d15e0a
--- /dev/null
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.h
@@ -0,0 +1,25 @@
+/** @file
+  PCI standard feature support functions implementation for PCI Bus module..
+
+Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PCIE_FEATURE_SUPPORT_H__
+#define __PCIE_FEATURE_SUPPORT_H__
+
+extern EFI_PCI_EXPRESS_PLATFORM_PROTOCOL *mPciePlatformProtocol;
+/**
+  This function retrieves the PCI Express Platform Protocols published by platform
+  @retval EFI_STATUS          direct return status from the LocateProtocol ()
+                              boot service for the PCI Express Override Protocol
+          EFI_SUCCESS         The PCI Express Platform Protocol is found
+**/
+EFI_STATUS
+InitializePciExpressProtocols (
+  VOID
+  );
+
+
+#endif
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 06/15] MdeModulePkg/PciBusDxe: Add the framework to init PCIe features
       [not found] <20200510161412.13832-1-ashraf.javeed@intel.com>
                   ` (4 preceding siblings ...)
  2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 05/15] MdeModulePkg/PciBusDxe: Locate PciePlatform/PcieOverride protocol Javeed, Ashraf
@ 2020-05-10 16:14 ` Javeed, Ashraf
  2020-05-13  6:39   ` Ni, Ray
  2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 07/15] MdeModulePkg/PciBusDxe: Enable MaxPayloadSize feature Javeed, Ashraf
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-10 16:14 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Jian J Wang, Hao A Wu

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


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 07/15] MdeModulePkg/PciBusDxe: Enable MaxPayloadSize feature
       [not found] <20200510161412.13832-1-ashraf.javeed@intel.com>
                   ` (5 preceding siblings ...)
  2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 06/15] MdeModulePkg/PciBusDxe: Add the framework to init PCIe features Javeed, Ashraf
@ 2020-05-10 16:14 ` Javeed, Ashraf
  2020-05-13  6:45   ` Ni, Ray
  2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 08/15] MdeModulePkg/PciBusDxe: Enable MaxReadRequestSize feature Javeed, Ashraf
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-10 16:14 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Jian J Wang, Hao A Wu

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

Add the Scan and Program phase feature init routines for MaxPayloadSize
PCIe feature.

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/PciBusDxe.inf        |   2 ++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c |   9 ++++++++-
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c       | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h       |  28 ++++++++++++++++++++++++++++
 4 files changed, 157 insertions(+), 1 deletion(-)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
index 0818153..e4b0ed6 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
@@ -59,6 +59,8 @@
   PciBus.h
   PcieFeatureSupport.c
   PcieFeatureSupport.h
+  PcieFeatures.c
+  PcieFeatures.h
 
 [Packages]
   MdePkg/MdePkg.dec
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
index 20ef0e8..634e26b 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
@@ -8,6 +8,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 
 #include "PciBus.h"
 #include "PcieFeatureSupport.h"
+#include "PcieFeatures.h"
+
 EFI_PCI_EXPRESS_PLATFORM_PROTOCOL    *mPciePlatformProtocol;
 GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mPcieFeatureConfigurePhaseStr[] = { L"Scan", L"Program" };
 
@@ -47,7 +49,11 @@ STATIC_ASSERT (
   );
 
 PCIE_FEATURE_ENTRY  mPcieFeatures[] = {
-  { 0, FALSE } // a dummy feature to pass build.
+  //
+  // Individual PCIE features
+  //
+  { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, MaxPayloadSize),
+              TRUE, { TRUE,  TRUE }, { MaxPayloadSizeScan,      MaxPayloadSizeProgram } },
 };
 
 /**
@@ -220,6 +226,7 @@ PcieNotifyDeviceState (
 
   CopyMem (&PcieDeviceState, &PciIoDevice->DeviceState, sizeof (PciIoDevice->DeviceState));
 
+  PcieDeviceState.MaxPayloadSize      = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.MaxPayloadSize;
   return mPciePlatformProtocol->NotifyDeviceState (
                                   mPciePlatformProtocol,
                                   PciIoDevice->Handle,
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
new file mode 100644
index 0000000..d1a78f7
--- /dev/null
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
@@ -0,0 +1,119 @@
+/** @file
+  PCI standard feature support functions implementation for PCI Bus module..
+
+Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PciBus.h"
+#include "PcieFeatureSupport.h"
+
+
+/**
+  Scan the devices to finalize the MaxPayloadSize settings of each device.
+
+  @param PciDevice              A pointer to the PCI_IO_DEVICE.
+  @param Level                  The level of the PCI device in the heirarchy.
+                                Level of root ports is 0.
+  @param Context                Pointer to feature specific context.
+
+  @retval EFI_SUCCESS           setup of PCI feature MaxPayloadSize is successful.
+**/
+EFI_STATUS
+MaxPayloadSizeScan (
+  IN PCI_IO_DEVICE *PciDevice,
+  IN UINTN         Level,
+  IN VOID          **Context
+  )
+{
+  UINT8                           *MaxPayloadSize;
+  PCI_REG_PCIE_DEVICE_CAPABILITY  DeviceCapability;
+
+  DEBUG ((
+    DEBUG_INFO, "  %a [%02d|%02d|%02d]: Capability = %x\n",
+    __FUNCTION__, PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber,
+    PciDevice->PciExpressCapability.DeviceCapability.Bits.MaxPayloadSize
+    ));
+  DeviceCapability.Uint32 = PciDevice->PciExpressCapability.DeviceCapability.Uint32;
+
+  if ((PciDevice->DeviceState.MaxPayloadSize != EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) &&
+      (PciDevice->DeviceState.MaxPayloadSize != EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE)) {
+    DeviceCapability.Bits.MaxPayloadSize =
+      MIN (PciDevice->DeviceState.MaxPayloadSize, DeviceCapability.Bits.MaxPayloadSize);
+  }
+
+  MaxPayloadSize = *Context;
+  if (MaxPayloadSize == NULL) {
+    //
+    // Initialize the Context
+    //
+    MaxPayloadSize  = AllocatePool (sizeof (*MaxPayloadSize));
+    *MaxPayloadSize = (UINT8) DeviceCapability.Bits.MaxPayloadSize;
+    *Context        = MaxPayloadSize;
+  } else {
+    //
+    // Set the Context to the minimum Max Payload Size in the heirarchy.
+    //
+    *MaxPayloadSize = MIN (*MaxPayloadSize, (UINT8) DeviceCapability.Bits.MaxPayloadSize);
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Program the PCIe Device Control register Max. Payload Size field per platform policy.
+
+  @param PciDevice              A pointer to the PCI_IO_DEVICE instance.
+  @param Level                  The level of the PCI device in the heirarchy.
+                                Level of root ports is 0.
+  @param Context                Pointer to feature specific context.
+
+  @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
+MaxPayloadSizeProgram (
+  IN PCI_IO_DEVICE *PciDevice,
+  IN UINTN         Level,
+  IN VOID          **Context
+  )
+{
+  UINT8 *MaxPayloadSize;
+
+  ASSERT (Context != NULL);
+  ASSERT (*Context != NULL);
+
+  if (PciDevice->DeviceState.MaxPayloadSize == EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE) {
+    //
+    // NOT_APPLICABLE means platform requests PciBus doesn't change the setting.
+    // But the capability of this device is still honored when calculating the aligned value.
+    //
+    return EFI_SUCCESS;
+  }
+
+  MaxPayloadSize                        = (UINT8 *) *Context;
+  PciDevice->DeviceState.MaxPayloadSize = *MaxPayloadSize;
+
+  if (PciDevice->PciExpressCapability.DeviceControl.Bits.MaxPayloadSize != PciDevice->DeviceState.MaxPayloadSize) {
+    DEBUG ((
+      DEBUG_INFO, "  %a [%02d|%02d|%02d]: %x -> %x\n",
+      __FUNCTION__, PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber,
+      PciDevice->PciExpressCapability.DeviceControl.Bits.MaxPayloadSize,
+      PciDevice->DeviceState.MaxPayloadSize
+      ));
+    PciDevice->PciExpressCapability.DeviceControl.Bits.MaxPayloadSize = PciDevice->DeviceState.MaxPayloadSize;
+
+    return PciDevice->PciIo.Pci.Write (
+                                  &PciDevice->PciIo,
+                                  EfiPciIoWidthUint16,
+                                  PciDevice->PciExpressCapabilityOffset
+                                  + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl),
+                                  1,
+                                  &PciDevice->PciExpressCapability.DeviceControl.Uint16
+                                  );
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
new file mode 100644
index 0000000..7b820e8
--- /dev/null
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
@@ -0,0 +1,28 @@
+/** @file
+  PCI standard feature support functions implementation for PCI Bus module..
+
+Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_PCI_EXPRESS_FEATURES_H_
+#define _EFI_PCI_EXPRESS_FEATURES_H_
+
+
+EFI_STATUS
+MaxPayloadSizeScan (
+  IN PCI_IO_DEVICE *PciDevice,
+  IN UINTN         Level,
+  IN VOID          **Context
+  );
+
+EFI_STATUS
+MaxPayloadSizeProgram (
+  IN PCI_IO_DEVICE *PciDevice,
+  IN UINTN         Level,
+  IN VOID          **Context
+  );
+
+
+#endif
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 08/15] MdeModulePkg/PciBusDxe: Enable MaxReadRequestSize feature
       [not found] <20200510161412.13832-1-ashraf.javeed@intel.com>
                   ` (6 preceding siblings ...)
  2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 07/15] MdeModulePkg/PciBusDxe: Enable MaxPayloadSize feature Javeed, Ashraf
@ 2020-05-10 16:14 ` 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
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-10 16:14 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Jian J Wang, Hao A Wu

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

Add the Program phase feature init routine for MaxReadRequestSize
PCIe feature.

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/PcieFeatureSupport.c |  3 +++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c       | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h       |  6 ++++++
 3 files changed, 59 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
index 634e26b..e1f739e 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
@@ -54,6 +54,8 @@ PCIE_FEATURE_ENTRY  mPcieFeatures[] = {
   //
   { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, MaxPayloadSize),
               TRUE, { TRUE,  TRUE }, { MaxPayloadSizeScan,      MaxPayloadSizeProgram } },
+  { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, MaxReadRequestSize),
+              TRUE, { TRUE,  TRUE }, { NULL,                    MaxReadRequestSizeProgram } },
 };
 
 /**
@@ -227,6 +229,7 @@ PcieNotifyDeviceState (
   CopyMem (&PcieDeviceState, &PciIoDevice->DeviceState, sizeof (PciIoDevice->DeviceState));
 
   PcieDeviceState.MaxPayloadSize      = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.MaxPayloadSize;
+  PcieDeviceState.MaxReadRequestSize  = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.MaxReadRequestSize;
   return mPciePlatformProtocol->NotifyDeviceState (
                                   mPciePlatformProtocol,
                                   PciIoDevice->Handle,
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
index d1a78f7..a7591e6 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
@@ -117,3 +117,53 @@ MaxPayloadSizeProgram (
   return EFI_SUCCESS;
 }
 
+/**
+  Program the PCIe Device Control register Max. Read Request Size field per platform policy.
+
+  @param PciDevice              A pointer to the PCI_IO_DEVICE instance.
+  @param Level                  The level of the PCI device in the heirarchy.
+                                Level of root ports is 0.
+  @param Context                Pointer to feature specific context.
+
+  @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
+MaxReadRequestSizeProgram (
+  IN PCI_IO_DEVICE *PciDevice,
+  IN UINTN         Level,
+  IN VOID          **Context
+  )
+{
+  ASSERT (*Context == NULL);
+
+  if (PciDevice->DeviceState.MaxReadRequestSize == EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE) {
+    return EFI_SUCCESS;
+  }
+  if (PciDevice->DeviceState.MaxReadRequestSize == EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) {
+    PciDevice->DeviceState.MaxReadRequestSize = (UINT8) PciDevice->PciExpressCapability.DeviceControl.Bits.MaxPayloadSize;
+  }
+
+  if (PciDevice->PciExpressCapability.DeviceControl.Bits.MaxReadRequestSize != PciDevice->DeviceState.MaxReadRequestSize) {
+    DEBUG ((
+      DEBUG_INFO, "  %a [%02d|%02d|%02d]: %x -> %x\n",
+      __FUNCTION__, PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber,
+      PciDevice->PciExpressCapability.DeviceControl.Bits.MaxReadRequestSize,
+      PciDevice->DeviceState.MaxReadRequestSize
+      ));
+    PciDevice->PciExpressCapability.DeviceControl.Bits.MaxReadRequestSize = PciDevice->DeviceState.MaxReadRequestSize;
+
+    return PciDevice->PciIo.Pci.Write (
+                                  &PciDevice->PciIo,
+                                  EfiPciIoWidthUint16,
+                                  PciDevice->PciExpressCapabilityOffset
+                                  + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl),
+                                  1,
+                                  &PciDevice->PciExpressCapability.DeviceControl.Uint16
+                                  );
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
index 7b820e8..40e28b8 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
@@ -24,5 +24,11 @@ MaxPayloadSizeProgram (
   IN VOID          **Context
   );
 
+EFI_STATUS
+MaxReadRequestSizeProgram (
+  IN PCI_IO_DEVICE *PciDevice,
+  IN UINTN         Level,
+  IN VOID          **Context
+  );
 
 #endif
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 09/15] MdeModulePkg/PciBusDxe: Enable RelaxedOrdering feature
       [not found] <20200510161412.13832-1-ashraf.javeed@intel.com>
                   ` (7 preceding siblings ...)
  2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 08/15] MdeModulePkg/PciBusDxe: Enable MaxReadRequestSize feature Javeed, Ashraf
@ 2020-05-10 16:14 ` 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
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-10 16:14 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Jian J Wang, Hao A Wu

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

Add the Program phase feature init routine for RelaxedOrdering
PCIe feature.

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/PcieFeatureSupport.c |  3 +++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c       | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h       |  7 +++++++
 3 files changed, 59 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
index e1f739e..9948e17 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
@@ -56,6 +56,8 @@ PCIE_FEATURE_ENTRY  mPcieFeatures[] = {
               TRUE, { TRUE,  TRUE }, { MaxPayloadSizeScan,      MaxPayloadSizeProgram } },
   { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, MaxReadRequestSize),
               TRUE, { TRUE,  TRUE }, { NULL,                    MaxReadRequestSizeProgram } },
+  { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, RelaxedOrdering),
+              TRUE, { TRUE,  TRUE }, { NULL,                    RelaxedOrderingProgram } },
 };
 
 /**
@@ -230,6 +232,7 @@ PcieNotifyDeviceState (
 
   PcieDeviceState.MaxPayloadSize      = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.MaxPayloadSize;
   PcieDeviceState.MaxReadRequestSize  = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.MaxReadRequestSize;
+  PcieDeviceState.RelaxedOrdering     = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.RelaxedOrdering;
   return mPciePlatformProtocol->NotifyDeviceState (
                                   mPciePlatformProtocol,
                                   PciIoDevice->Handle,
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
index a7591e6..5216dac 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
@@ -167,3 +167,52 @@ MaxReadRequestSizeProgram (
   return EFI_SUCCESS;
 }
 
+
+/**
+  Program the PCIe Device Control register Relaxed Ordering field per platform policy.
+
+  @param PciDevice              A pointer to the PCI_IO_DEVICE instance.
+  @param Level                  The level of the PCI device in the heirarchy.
+                                Level of root ports is 0.
+  @param Context                Pointer to feature specific context.
+
+  @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
+RelaxedOrderingProgram (
+  IN PCI_IO_DEVICE *PciDevice,
+  IN UINTN         Level,
+  IN VOID          **Context
+  )
+{
+  ASSERT (*Context == NULL);
+
+  if (PciDevice->DeviceState.RelaxedOrdering == EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE ||
+      PciDevice->DeviceState.RelaxedOrdering == EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) {
+    return EFI_SUCCESS;
+  }
+
+  if (PciDevice->PciExpressCapability.DeviceControl.Bits.RelaxedOrdering != PciDevice->DeviceState.RelaxedOrdering) {
+    DEBUG ((
+      DEBUG_INFO, "  %a [%02d|%02d|%02d]: %x -> %x\n",
+      __FUNCTION__, PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber,
+      PciDevice->PciExpressCapability.DeviceControl.Bits.RelaxedOrdering,
+      PciDevice->DeviceState.RelaxedOrdering
+      ));
+    PciDevice->PciExpressCapability.DeviceControl.Bits.RelaxedOrdering = PciDevice->DeviceState.RelaxedOrdering;
+
+    return PciDevice->PciIo.Pci.Write (
+                                  &PciDevice->PciIo,
+                                  EfiPciIoWidthUint16,
+                                  PciDevice->PciExpressCapabilityOffset
+                                  + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl),
+                                  1,
+                                  &PciDevice->PciExpressCapability.DeviceControl.Uint16
+                                  );
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
index 40e28b8..7d70f06 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
@@ -31,4 +31,11 @@ MaxReadRequestSizeProgram (
   IN VOID          **Context
   );
 
+EFI_STATUS
+RelaxedOrderingProgram (
+  IN PCI_IO_DEVICE *PciDevice,
+  IN UINTN         Level,
+  IN VOID          **Context
+  );
+
 #endif
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 10/15] MdeModulePkg/PciBusDxe: Enable NoSnoop feature
       [not found] <20200510161412.13832-1-ashraf.javeed@intel.com>
                   ` (8 preceding siblings ...)
  2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 09/15] MdeModulePkg/PciBusDxe: Enable RelaxedOrdering feature Javeed, Ashraf
@ 2020-05-10 16:14 ` 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
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-10 16:14 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Jian J Wang, Hao A Wu

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

Add the Program phase feature init routine for NoSnoop
PCIe feature.

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/PcieFeatureSupport.c |  4 ++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c       | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h       |  7 +++++++
 3 files changed, 62 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
index 9948e17..6bf06b0 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
@@ -58,6 +58,8 @@ PCIE_FEATURE_ENTRY  mPcieFeatures[] = {
               TRUE, { TRUE,  TRUE }, { NULL,                    MaxReadRequestSizeProgram } },
   { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, RelaxedOrdering),
               TRUE, { TRUE,  TRUE }, { NULL,                    RelaxedOrderingProgram } },
+  { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, NoSnoop),
+              TRUE, { TRUE,  TRUE }, { NULL,                    NoSnoopProgram } },
 };
 
 /**
@@ -233,6 +235,8 @@ PcieNotifyDeviceState (
   PcieDeviceState.MaxPayloadSize      = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.MaxPayloadSize;
   PcieDeviceState.MaxReadRequestSize  = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.MaxReadRequestSize;
   PcieDeviceState.RelaxedOrdering     = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.RelaxedOrdering;
+  PcieDeviceState.NoSnoop             = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.NoSnoop;
+
   return mPciePlatformProtocol->NotifyDeviceState (
                                   mPciePlatformProtocol,
                                   PciIoDevice->Handle,
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
index 5216dac..6c22feb 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
@@ -216,3 +216,54 @@ RelaxedOrderingProgram (
   return EFI_SUCCESS;
 }
 
+/**
+  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.
+  @param Level                  The level of the PCI device in the heirarchy.
+                                Level of root ports is 0.
+  @param Context                Pointer to feature specific context.
+
+  @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
+NoSnoopProgram (
+  IN PCI_IO_DEVICE *PciDevice,
+  IN UINTN         Level,
+  IN VOID          **Context
+  )
+{
+  ASSERT (*Context == NULL);
+
+  if (PciDevice->DeviceState.NoSnoop == EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE ||
+      PciDevice->DeviceState.NoSnoop == EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) {
+    return EFI_SUCCESS;
+  }
+
+
+  if (PciDevice->PciExpressCapability.DeviceControl.Bits.NoSnoop != PciDevice->DeviceState.NoSnoop) {
+    DEBUG ((
+      DEBUG_INFO, "  %a [%02d|%02d|%02d]: %x -> %x\n",
+      __FUNCTION__, PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber,
+      PciDevice->PciExpressCapability.DeviceControl.Bits.NoSnoop,
+      PciDevice->DeviceState.NoSnoop
+      ));
+    PciDevice->PciExpressCapability.DeviceControl.Bits.NoSnoop = PciDevice->DeviceState.NoSnoop;
+
+    return PciDevice->PciIo.Pci.Write (
+                                  &PciDevice->PciIo,
+                                  EfiPciIoWidthUint16,
+                                  PciDevice->PciExpressCapabilityOffset
+                                  + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl),
+                                  1,
+                                  &PciDevice->PciExpressCapability.DeviceControl.Uint16
+                                  );
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
index 7d70f06..60b8742 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
@@ -38,4 +38,11 @@ RelaxedOrderingProgram (
   IN VOID          **Context
   );
 
+EFI_STATUS
+NoSnoopProgram (
+  IN PCI_IO_DEVICE *PciDevice,
+  IN UINTN         Level,
+  IN VOID          **Context
+  );
+
 #endif
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 11/15] MdeModulePkg/PciBusDxe: Enable CompletionTimeout feature
       [not found] <20200510161412.13832-1-ashraf.javeed@intel.com>
                   ` (9 preceding siblings ...)
  2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 10/15] MdeModulePkg/PciBusDxe: Enable NoSnoop feature Javeed, Ashraf
@ 2020-05-10 16:14 ` 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
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-10 16:14 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Jian J Wang, Hao A Wu

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

Add the Program phase feature init routine for CompletionTimeout
PCIe feature.

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/PcieFeatureSupport.c |  3 +++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c       | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h       | 15 +++++++++++++++
 3 files changed, 109 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
index 6bf06b0..e6d3363 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
@@ -60,6 +60,8 @@ PCIE_FEATURE_ENTRY  mPcieFeatures[] = {
               TRUE, { TRUE,  TRUE }, { NULL,                    RelaxedOrderingProgram } },
   { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, NoSnoop),
               TRUE, { TRUE,  TRUE }, { NULL,                    NoSnoopProgram } },
+  { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, CompletionTimeout),
+              TRUE, { TRUE,  TRUE }, { NULL,                    CompletionTimeoutProgram}},
 };
 
 /**
@@ -236,6 +238,7 @@ PcieNotifyDeviceState (
   PcieDeviceState.MaxReadRequestSize  = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.MaxReadRequestSize;
   PcieDeviceState.RelaxedOrdering     = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.RelaxedOrdering;
   PcieDeviceState.NoSnoop             = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.NoSnoop;
+  PcieDeviceState.CompletionTimeout   = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl2.Uint16 & 0x1F;
 
   return mPciePlatformProtocol->NotifyDeviceState (
                                   mPciePlatformProtocol,
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
index 6c22feb..ca4052f 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
@@ -267,3 +267,94 @@ NoSnoopProgram (
   return EFI_SUCCESS;
 }
 
+/**
+  Program PCIe feature Completion Timeout per the device-specific platform policy.
+
+  @param PciIoDevice            A pointer to the PCI_IO_DEVICE.
+  @param Level                  The level of the PCI device in the heirarchy.
+                                Level of root ports is 0.
+  @param Context                Pointer to feature specific context.
+
+  @retval EFI_SUCCESS           The feature is initialized successfully.
+  @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
+CompletionTimeoutProgram (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  IN UINTN         Level,
+  IN VOID          **Context
+  )
+{
+  PCI_REG_PCIE_DEVICE_CONTROL2    DevicePolicy;
+  UINTN                           RangeIndex;
+  UINT8                           SubRanges;
+
+  if (PciIoDevice->DeviceState.CompletionTimeout == EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE ||
+      PciIoDevice->DeviceState.CompletionTimeout == EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Interpret the policy value as BIT[0:4] in Device Control 2 Register
+  //
+  DevicePolicy.Uint16 = (UINT16) PciIoDevice->DeviceState.CompletionTimeout;
+
+  //
+  // Ignore when device doesn't support to disable Completion Timeout while the policy requests.
+  //
+  if (PciIoDevice->PciExpressCapability.DeviceCapability2.Bits.CompletionTimeoutDisable == 0 &&
+      DevicePolicy.Bits.CompletionTimeoutDisable == 1) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (DevicePolicy.Bits.CompletionTimeoutValue != 0) {
+    //
+    // Ignore when the policy requests to use a range that's not supported by the device.
+    // RangeIndex is 0 ~ 3 for Range A ~ D.
+    //
+    RangeIndex = DevicePolicy.Bits.CompletionTimeoutValue >> 2;
+    if ((PciIoDevice->PciExpressCapability.DeviceCapability2.Bits.CompletionTimeoutRanges & (1 < RangeIndex)) == 0) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    //
+    // Ignore when the policy doesn't request one and only one sub-range for a certain range.
+    //
+    SubRanges = (UINT8) (DevicePolicy.Bits.CompletionTimeoutValue & (BIT0 | BIT1));
+    if (SubRanges != BIT0 && SubRanges != BIT1) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  if ((PciIoDevice->PciExpressCapability.DeviceControl2.Bits.CompletionTimeoutDisable
+       != DevicePolicy.Bits.CompletionTimeoutDisable) ||
+      (PciIoDevice->PciExpressCapability.DeviceControl2.Bits.CompletionTimeoutValue
+       != DevicePolicy.Bits.CompletionTimeoutValue)) {
+    DEBUG ((
+      DEBUG_INFO, "  %a [%02d|%02d|%02d]: Disable = %x -> %x, Timeout = %x -> %x.\n",
+      __FUNCTION__, PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber,
+      PciIoDevice->PciExpressCapability.DeviceControl2.Bits.CompletionTimeoutDisable,
+      DevicePolicy.Bits.CompletionTimeoutDisable,
+      PciIoDevice->PciExpressCapability.DeviceControl2.Bits.CompletionTimeoutValue,
+      DevicePolicy.Bits.CompletionTimeoutValue
+      ));
+    PciIoDevice->PciExpressCapability.DeviceControl2.Bits.CompletionTimeoutDisable
+                      = DevicePolicy.Bits.CompletionTimeoutDisable;
+    PciIoDevice->PciExpressCapability.DeviceControl2.Bits.CompletionTimeoutValue
+                      = DevicePolicy.Bits.CompletionTimeoutValue;
+
+    return PciIoDevice->PciIo.Pci.Write (
+                                  &PciIoDevice->PciIo,
+                                  EfiPciIoWidthUint16,
+                                  PciIoDevice->PciExpressCapabilityOffset
+                                  + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2),
+                                  1,
+                                  &PciIoDevice->PciExpressCapability.DeviceControl2.Uint16
+                                  );
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
index 60b8742..bdb7004 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
@@ -45,4 +45,19 @@ NoSnoopProgram (
   IN VOID          **Context
   );
 
+/**
+  Program PCIE feature Completion Timeout per the device-specific platform policy.
+
+  @param PciIoDevice      A pointer to the PCI_IO_DEVICE.
+
+  @retval EFI_SUCCESS           The feature is initialized successfully.
+  @retval EFI_INVALID_PARAMETER The policy is not supported by the device.
+**/
+EFI_STATUS
+CompletionTimeoutProgram (
+  IN PCI_IO_DEVICE *PciIoDevice,
+  IN UINTN         Level,
+  IN VOID          **Context
+  );
+
 #endif
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 12/15] MdeModulePkg/PciBusDxe: Enable LTR feature
       [not found] <20200510161412.13832-1-ashraf.javeed@intel.com>
                   ` (10 preceding siblings ...)
  2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 11/15] MdeModulePkg/PciBusDxe: Enable CompletionTimeout feature Javeed, Ashraf
@ 2020-05-10 16:14 ` Javeed, Ashraf
  2020-05-13  6:49   ` Ni, Ray
  2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 13/15] MdeModulePkg/PciBusDxe: Enable AtomicOp feature Javeed, Ashraf
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-10 16:14 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Jian J Wang, Hao A Wu

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

Add the Scan and Program phase feature init routines for LTR
PCIe feature.

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/PcieFeatureSupport.c |   3 +++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c       | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h       |  34 ++++++++++++++++++++++++++++++++++
 3 files changed, 231 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
index e6d3363..35aaffa 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
@@ -62,6 +62,8 @@ PCIE_FEATURE_ENTRY  mPcieFeatures[] = {
               TRUE, { TRUE,  TRUE }, { NULL,                    NoSnoopProgram } },
   { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, CompletionTimeout),
               TRUE, { TRUE,  TRUE }, { NULL,                    CompletionTimeoutProgram}},
+  { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, Ltr),
+              TRUE, { FALSE, TRUE }, { LtrScan,                 LtrProgram}},
 };
 
 /**
@@ -239,6 +241,7 @@ PcieNotifyDeviceState (
   PcieDeviceState.RelaxedOrdering     = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.RelaxedOrdering;
   PcieDeviceState.NoSnoop             = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.NoSnoop;
   PcieDeviceState.CompletionTimeout   = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl2.Uint16 & 0x1F;
+  PcieDeviceState.Ltr                 = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl2.Bits.LtrMechanism;
 
   return mPciePlatformProtocol->NotifyDeviceState (
                                   mPciePlatformProtocol,
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
index ca4052f..8c7fae0 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
@@ -358,3 +358,197 @@ CompletionTimeoutProgram (
   return EFI_SUCCESS;
 }
 
+/**
+  disable LTR policy of the device. If bridge device than disable LTR policy of
+  all its child devices.
+
+  @param Bridge     A pointer to the PCI_IO_DEVICE
+**/
+STATIC
+VOID
+DisableLtrPolicy (
+  IN  PCI_IO_DEVICE *Bridge
+  )
+{
+  LIST_ENTRY            *Link;
+  PCI_IO_DEVICE         *PciIoDevice;
+
+  Bridge->DeviceState.Ltr = FALSE;
+
+  for ( Link = GetFirstNode (&Bridge->ChildList)
+      ; !IsNull (&Bridge->ChildList, Link)
+      ; Link = GetNextNode (&Bridge->ChildList, Link)
+  ) {
+    PciIoDevice = PCI_IO_DEVICE_FROM_LINK (Link);
+    if (PciIoDevice->IsPciExp) {
+      DisableLtrPolicy (PciIoDevice);
+    }
+  }
+}
+
+/**
+  Update the LTR for each level of devices.
+
+  @param Result     A pointer to the BOOLEAN
+  @param Ltr        value TRUE or FALSE.
+**/
+STATIC
+VOID
+LtrOr (
+  IN OUT  BOOLEAN   *Result,
+  IN      BOOLEAN   Ltr
+)
+{
+  ASSERT (Result != NULL);
+  ASSERT (*Result == 0xFF || *Result == TRUE || *Result == FALSE);
+  if (*Result == 0xFF) {
+    //
+    // Initialize Result when meeting the first device in the Level.
+    //
+    *Result = Ltr;
+  } else {
+    //
+    // Save the "OR" result of LTR of all devices in this Level.
+    //
+    *Result = (*Result || Ltr);
+  }
+}
+
+/**
+  Scan the devices to finalize the LTR settings of each device.
+
+  The scan needs to be done in post-order.
+
+  @param PciIoDevice            A pointer to the PCI_IO_DEVICE.
+  @param Level                  The level of the PCI device in the heirarchy.
+                                Level of root ports is 0.
+  @param Context                Pointer to feature specific context.
+
+
+  @retval EFI_SUCCESS           setup of PCI feature LTR is successful.
+**/
+EFI_STATUS
+LtrScan (
+  IN  PCI_IO_DEVICE *PciIoDevice,
+  IN  UINTN         Level,
+  IN  VOID          **Context
+  )
+{
+  BOOLEAN           *Ltr;
+  ASSERT (Level <= PCI_MAX_BUS);
+  //ASSERT (Context != NULL);
+
+  // LTR of a parent (certain bridge) in level N is enabled when any child in
+  // level N + 1 enables LTR.
+  //
+  // Because the devices are enumerated in post-order (children-then-parent),
+  // we could allocate one BOOLEAN in Context to save the "OR" result of LTR
+  // enable status of all children in a certain level. LTR of parent is set
+  // when the "OR" result is TRUE.
+  //
+  // Because the max level cannot exceed the max PCI bus number 256, allocating
+  // a BOOLEAN array of 256 elements should be enough.
+  //
+  Ltr = (BOOLEAN *) (*Context);
+  if (Ltr == NULL) {
+    Ltr = AllocatePool (sizeof (BOOLEAN) * (PCI_MAX_BUS + 1));
+    SetMem (Ltr, sizeof (BOOLEAN) * (PCI_MAX_BUS + 1), 0xFF);
+    *Context = Ltr;
+  }
+
+  DEBUG ((
+    DEBUG_INFO, "  %a [%02d|%02d|%02d]: Capability = %x.\n",
+    __FUNCTION__, PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber,
+    PciIoDevice->PciExpressCapability.DeviceCapability2.Bits.LtrMechanism
+    ));
+  //
+  // Disable LTR if the device doesn't support. In case of bridge device disable
+  // all its child devices.
+  // Even if the platform forces the bridge device to disable the LTR, all its
+  // child devices has to be forced to disable LTR because the child cannot send
+  // the LTR messages to parent bridge whose LTR is disabled.
+  //
+  if (!PciIoDevice->PciExpressCapability.DeviceCapability2.Bits.LtrMechanism
+      || PciIoDevice->DeviceState.Ltr == FALSE) {
+    DisableLtrPolicy (PciIoDevice);
+  }
+
+  //
+  // If the policy is AUTO or NOT_APPLICABLE for a certain device, only enable LTR
+  // when any of its children's LTR is enabled.
+  // Note:
+  //  It's platform's responsibility to make sure consistent policy is returned.
+  //  Inconsistent policy means Bridge's LTR is set to FALSE while child device's LTR is
+  //  set to TRUE in platform policy.
+  //
+  if ((PciIoDevice->DeviceState.Ltr != TRUE) && (PciIoDevice->DeviceState.Ltr != FALSE)) {
+    ASSERT (PciIoDevice->DeviceState.Ltr == EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO ||
+            PciIoDevice->DeviceState.Ltr == EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE);
+
+    if ((Level < PCI_MAX_BUS) && (Ltr[Level + 1] != 0xFF)) {
+      //
+      // LTR of a parent is the "OR" result of LTR of all children.
+      //
+      PciIoDevice->DeviceState.Ltr = Ltr[Level + 1];
+    }
+  }
+
+  if ((PciIoDevice->DeviceState.Ltr == TRUE) || (PciIoDevice->DeviceState.Ltr == FALSE)) {
+    LtrOr (&Ltr[Level], PciIoDevice->DeviceState.Ltr);
+  }
+
+  //
+  // Reset the LTR status of Level + 1 because Ltr[Level + 1] will be used by another sub-tree.
+  //
+  Ltr[Level + 1] = 0xFF;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Program the LTR settings of each device.
+
+  The program needs to be done in pre-order per the PCIe spec requirement
+
+  @param PciIoDevice            A pointer to the PCI_IO_DEVICE.
+  @param Level                  The level of the PCI device in the heirarchy.
+                                Level of root ports is 0.
+  @param Context                Pointer to feature specific context.
+
+
+  @retval EFI_SUCCESS           setup of PCI feature LTR is successful.
+  @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
+LtrProgram (
+  IN  PCI_IO_DEVICE *PciIoDevice,
+  IN  UINTN         Level,
+  IN  VOID          **Context
+  )
+{
+  if ((PciIoDevice->DeviceState.Ltr == TRUE) || (PciIoDevice->DeviceState.Ltr == FALSE)) {
+    if (PciIoDevice->DeviceState.Ltr != PciIoDevice->PciExpressCapability.DeviceControl2.Bits.LtrMechanism) {
+
+      DEBUG ((
+        DEBUG_INFO, "  %a [%02d|%02d|%02d]: %x -> %x.\n",
+        __FUNCTION__, PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber,
+        PciIoDevice->PciExpressCapability.DeviceControl2.Bits.LtrMechanism,
+        PciIoDevice->DeviceState.Ltr
+        ));
+
+      return PciIoDevice->PciIo.Pci.Write (
+                                    &PciIoDevice->PciIo,
+                                    EfiPciIoWidthUint16,
+                                    PciIoDevice->PciExpressCapabilityOffset
+                                    + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2),
+                                    1,
+                                    &PciIoDevice->PciExpressCapability.DeviceControl2.Uint16
+                                    );
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
index bdb7004..a9dacf3 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
@@ -60,4 +60,38 @@ CompletionTimeoutProgram (
   IN VOID          **Context
   );
 
+/**
+  Scan the devices to finalize the LTR settings of each device.
+
+  The scan needs to be done in post-order.
+
+  @param PciIoDevice  A pointer to the PCI_IO_DEVICE.
+  @param Context      Pointer to feature specific context.
+
+  @retval EFI_SUCCESS setup of PCI feature LTR is successful.
+**/
+EFI_STATUS
+LtrScan (
+  IN  PCI_IO_DEVICE *PciIoDevice,
+  IN  UINTN         Level,
+  IN  VOID          **Context
+  );
+
+/**
+  Program the LTR settings of each device.
+
+  The program needs to be done in pre-order per the PCIE spec requirement
+
+  @param PciIoDevice  A pointer to the PCI_IO_DEVICE.
+  @param Context      Pointer to feature specific context.
+
+  @retval EFI_SUCCESS setup of PCI feature LTR is successful.
+**/
+EFI_STATUS
+LtrProgram (
+  IN  PCI_IO_DEVICE *PciIoDevice,
+  IN  UINTN         Level,
+  IN  VOID          **Context
+  );
+
 #endif
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 13/15] MdeModulePkg/PciBusDxe: Enable AtomicOp feature
       [not found] <20200510161412.13832-1-ashraf.javeed@intel.com>
                   ` (11 preceding siblings ...)
  2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 12/15] MdeModulePkg/PciBusDxe: Enable LTR feature Javeed, Ashraf
@ 2020-05-10 16:14 ` 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-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 15/15] MdeModulePkg/PciBusDxe: Enable CommonClockConfiguration feature Javeed, Ashraf
  14 siblings, 1 reply; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-10 16:14 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Jian J Wang, Hao A Wu

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

Add the Program phase feature init routine for AtomicOp
PCIe feature.

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/PcieFeatureSupport.c |  3 +++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c       | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h       | 16 ++++++++++++++++
 3 files changed, 81 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
index 35aaffa..401521b 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
@@ -64,6 +64,8 @@ PCIE_FEATURE_ENTRY  mPcieFeatures[] = {
               TRUE, { TRUE,  TRUE }, { NULL,                    CompletionTimeoutProgram}},
   { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, Ltr),
               TRUE, { FALSE, TRUE }, { LtrScan,                 LtrProgram}},
+  { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, AtomicOp),
+              TRUE, { TRUE,  TRUE }, { NULL,                    AtomicOpProgram}},
 };
 
 /**
@@ -241,6 +243,7 @@ PcieNotifyDeviceState (
   PcieDeviceState.RelaxedOrdering     = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.RelaxedOrdering;
   PcieDeviceState.NoSnoop             = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.NoSnoop;
   PcieDeviceState.CompletionTimeout   = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl2.Uint16 & 0x1F;
+  PcieDeviceState.AtomicOp            = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl2.Bits.AtomicOpRequester;
   PcieDeviceState.Ltr                 = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl2.Bits.LtrMechanism;
 
   return mPciePlatformProtocol->NotifyDeviceState (
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
index 8c7fae0..407c94a 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
@@ -552,3 +552,65 @@ LtrProgram (
   return EFI_SUCCESS;
 }
 
+/**
+  Program AtomicOp.
+
+  @param PciIoDevice            A pointer to the PCI_IO_DEVICE.
+  @param Level                  The level of the PCI device in the heirarchy.
+                                Level of root ports is 0.
+  @param Context                Pointer to feature specific context.
+
+  @retval EFI_SUCCESS           setup of PCI feature AtomicOp is successful.
+  @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
+AtomicOpProgram (
+  IN  PCI_IO_DEVICE *PciIoDevice,
+  IN  UINTN         Level,
+  IN  VOID          **Context
+  )
+{
+  if (PciIoDevice->DeviceState.AtomicOp == EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO ||
+      PciIoDevice->DeviceState.AtomicOp == EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // BIT0 of the policy value is for AtomicOp Requester Enable (BIT6)
+  // BIT1 of the policy value is for AtomicOp Egress Blocking (BIT7)
+  //
+  if ((PciIoDevice->DeviceState.AtomicOp >> 2) != 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!PciIoDevice->PciExpressCapability.DeviceCapability2.Bits.AtomicOpRouting) {
+    PciIoDevice->DeviceState.AtomicOp &= ~BIT1;
+  }
+  if (PciIoDevice->DeviceState.AtomicOp !=
+      BitFieldRead16 (PciIoDevice->PciExpressCapability.DeviceControl2.Uint16, 6, 7)) {
+
+      DEBUG ((
+        DEBUG_INFO, "  %a [%02d|%02d|%02d]: %x -> %x.\n",
+        __FUNCTION__, PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber,
+        BitFieldRead16 (PciIoDevice->PciExpressCapability.DeviceControl2.Uint16, 6, 7),
+        PciIoDevice->DeviceState.AtomicOp
+        ));
+      BitFieldWrite16 (
+        PciIoDevice->PciExpressCapability.DeviceControl2.Uint16, 6, 7,
+        PciIoDevice->DeviceState.AtomicOp
+        );
+      return PciIoDevice->PciIo.Pci.Write (
+                                    &PciIoDevice->PciIo,
+                                    EfiPciIoWidthUint16,
+                                    PciIoDevice->PciExpressCapabilityOffset
+                                    + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2),
+                                    1,
+                                    &PciIoDevice->PciExpressCapability.DeviceControl2.Uint16
+                                    );
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
index a9dacf3..5c70e41 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
@@ -94,4 +94,20 @@ LtrProgram (
   IN  VOID          **Context
   );
 
+/**
+  Program AtomicOp.
+
+  @param PciIoDevice  A pointer to the PCI_IO_DEVICE.
+  @param Level        The level of the PCI device in the heirarchy.
+                      Level of root ports is 0.
+  @param Context      Pointer to feature specific context.
+
+  @retval EFI_SUCCESS setup of PCI feature LTR is successful.
+**/
+EFI_STATUS
+AtomicOpProgram (
+  IN  PCI_IO_DEVICE *PciIoDevice,
+  IN  UINTN         Level,
+  IN  VOID          **Context
+  );
 #endif
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 14/15] MdeModulePkg/PciBusDxe: Enable ExtendedTag feature
       [not found] <20200510161412.13832-1-ashraf.javeed@intel.com>
                   ` (12 preceding siblings ...)
  2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 13/15] MdeModulePkg/PciBusDxe: Enable AtomicOp feature Javeed, Ashraf
@ 2020-05-10 16:14 ` 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
  14 siblings, 1 reply; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-10 16:14 UTC (permalink / raw)
  To: devel; +Cc: Jian J Wang, Hao A Wu, Ray Ni

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

Add the Program phase feature init routine for ExtendedTag
PCIe feature.

Signed-off-by: Ashraf Javeed <ashraf.javeed@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/PcieFeatureSupport.c |   5 +++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c       | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h       |  18 ++++++++++++++++++
 3 files changed, 202 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
index 401521b..acd60d5 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
@@ -66,6 +66,8 @@ PCIE_FEATURE_ENTRY  mPcieFeatures[] = {
               TRUE, { FALSE, TRUE }, { LtrScan,                 LtrProgram}},
   { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, AtomicOp),
               TRUE, { TRUE,  TRUE }, { NULL,                    AtomicOpProgram}},
+  { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, ExtendedTag),
+              TRUE, { TRUE,  TRUE }, { NULL,                    ExtendedTagProgram } }
 };
 
 /**
@@ -245,6 +247,9 @@ PcieNotifyDeviceState (
   PcieDeviceState.CompletionTimeout   = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl2.Uint16 & 0x1F;
   PcieDeviceState.AtomicOp            = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl2.Bits.AtomicOpRequester;
   PcieDeviceState.Ltr                 = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl2.Bits.LtrMechanism;
+  PcieDeviceState.ExtendedTag         =
+                  (UINT8)((PciIoDevice->PciExpressCapability.DeviceControl2.Bits.TenBitTagRequesterEnable << 1)
+                           | PciIoDevice->PciExpressCapability.DeviceControl.Bits.ExtendedTagField);
 
   return mPciePlatformProtocol->NotifyDeviceState (
                                   mPciePlatformProtocol,
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
index 407c94a..095f2ec 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
@@ -614,3 +614,182 @@ AtomicOpProgram (
   return EFI_SUCCESS;
 }
 
+/**
+  Record the parent Root Port 10b Extended Tag Completer capability.
+
+  @param PciDevice              A pointer to the PCI_IO_DEVICE.
+  @param Level                  The level of the PCI device in the heirarchy.
+                                Level of root ports is 0.
+  @param Context                Pointer to feature specific context.
+**/
+STATIC
+VOID
+ExtendedTagCheck (
+  IN PCI_IO_DEVICE *PciDevice,
+  IN UINTN         Level,
+  IN VOID          **Context
+  )
+{
+  BOOLEAN                          *TenBitCompleterCapable;
+
+  DEBUG ((
+    DEBUG_INFO, "  %a [%02d|%02d|%02d]: Capability = %x",
+    __FUNCTION__, PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber,
+    PciDevice->PciExpressCapability.DeviceCapability.Bits.ExtendedTagField
+    ));
+  DEBUG ((
+    DEBUG_INFO, "  Capability2 = [%x, %x]\n",
+    PciDevice->PciExpressCapability.DeviceCapability2.Bits.TenBitTagRequesterSupported,
+    PciDevice->PciExpressCapability.DeviceCapability2.Bits.TenBitTagCompleterSupported
+    ));
+
+  TenBitCompleterCapable = *Context;
+  if (TenBitCompleterCapable == NULL) {
+    TenBitCompleterCapable = AllocatePool (sizeof (*TenBitCompleterCapable));
+    *Context = TenBitCompleterCapable;
+  }
+  if (Level == 1) {
+    *TenBitCompleterCapable = (BOOLEAN)
+        (PciDevice->PciExpressCapability.DeviceCapability2.Bits.TenBitTagCompleterSupported);
+  }
+}
+
+/**
+  Program PCIe feature ExtendedTag.
+
+  @param PciIoDevice            A pointer to the PCI_IO_DEVICE.
+  @param Level                  The level of the PCI device in the heirarchy.
+                                Level of root ports is 0.
+  @param Context                Pointer to feature specific context.
+
+  @retval EFI_SUCCESS           setup of PCI feature ExtendedTag is successful.
+  @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
+ExtendedTagProgram (
+  IN  PCI_IO_DEVICE *PciIoDevice,
+  IN  UINTN         Level,
+  IN  VOID          **Context
+  )
+{
+  BOOLEAN                       *TenBitCompleterCapable;
+  PCI_REG_PCIE_DEVICE_CONTROL2  DeviceCtl2;
+  PCI_REG_PCIE_DEVICE_CONTROL   DeviceCtl;
+  EFI_STATUS                    Status;
+
+  if (PciIoDevice->DeviceState.ExtendedTag == EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO ||
+      PciIoDevice->DeviceState.ExtendedTag == EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // BIT0 of the policy value is for 5b or 8b Extended Tag (DeviceControl BIT8)
+  // BIT1 of the policy value is for 10b Extended Tag (DeviceControl2 BIT12)
+  //
+  if ((PciIoDevice->DeviceState.ExtendedTag >> 2) != 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // check and prepare the context for the Extended Tag Completer capability
+  //
+  ExtendedTagCheck (PciIoDevice, Level, Context);
+
+  //
+  // start with no change to device 10b Requester Enable state
+  //
+  DeviceCtl2.Bits.TenBitTagRequesterEnable = 0;
+
+  //
+  // the device should be capable of 10b Extended Tag Requester
+  //
+  if ((PciIoDevice->DeviceState.ExtendedTag & BIT1) &&
+      (PciIoDevice->PciExpressCapability.DeviceCapability2.Bits.TenBitTagRequesterSupported)) {
+    //
+    // for the Endpoint device 10b Extended Tag Requester Enable, the RC should be
+    // 10b Completer capable
+    //
+    if (PciIoDevice->PciExpressCapability.Capability.Bits.DevicePortType == PCIE_DEVICE_PORT_TYPE_PCIE_ENDPOINT ||
+        PciIoDevice->PciExpressCapability.Capability.Bits.DevicePortType == PCIE_DEVICE_PORT_TYPE_LEGACY_PCIE_ENDPOINT) {
+      //
+      // check the parent Root Port 10b Extended Tag Completer Capability
+      //
+      TenBitCompleterCapable = *Context;
+      if (*TenBitCompleterCapable == TRUE) {
+        //
+        // since the RC is 10b COmpleter capable, enable the EP as 10b Requester
+        //
+        DeviceCtl2.Bits.TenBitTagRequesterEnable = 1;
+      }
+    } else {
+      //
+      // enable the device as 10b Requester if it is capable and per platform ask
+      //
+      DeviceCtl2.Bits.TenBitTagRequesterEnable = 1;
+    }
+    //
+    // write DeviceControl2 register for 10b Extended Tag Requester state
+    //
+    if (DeviceCtl2.Bits.TenBitTagRequesterEnable !=
+        PciIoDevice->PciExpressCapability.DeviceControl2.Bits.TenBitTagRequesterEnable) {
+
+        DEBUG ((
+          DEBUG_INFO, "  %a [%02d|%02d|%02d]: %x -> %x.\n",
+          __FUNCTION__, PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber,
+          PciIoDevice->PciExpressCapability.DeviceControl2.Bits.TenBitTagRequesterEnable,
+          DeviceCtl2.Bits.TenBitTagRequesterEnable
+          ));
+        PciIoDevice->PciExpressCapability.DeviceControl2.Bits.TenBitTagRequesterEnable =
+          DeviceCtl2.Bits.TenBitTagRequesterEnable;
+
+        Status = PciIoDevice->PciIo.Pci.Write (
+                                        &PciIoDevice->PciIo,
+                                        EfiPciIoWidthUint16,
+                                        PciIoDevice->PciExpressCapabilityOffset
+                                        + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2),
+                                        1,
+                                        &PciIoDevice->PciExpressCapability.DeviceControl2.Uint16
+                                        );
+        if (EFI_ERROR(Status)) {
+          return Status;
+        }
+    }
+  }
+
+  //
+  // if no 10b Extended Tag Requester for this device than consider 8b or 5b Extended Requester
+  //
+  if (!DeviceCtl2.Bits.TenBitTagRequesterEnable) {
+    //
+    // the device should be capable of 8b Extended Tag Requester
+    //
+    DeviceCtl.Bits.ExtendedTagField = (UINT16)
+              ((PciIoDevice->DeviceState.ExtendedTag & BIT0) &&
+               (PciIoDevice->PciExpressCapability.DeviceCapability.Bits.ExtendedTagField));
+
+    if (DeviceCtl.Bits.ExtendedTagField !=
+        PciIoDevice->PciExpressCapability.DeviceControl.Bits.ExtendedTagField) {
+      DEBUG ((
+          DEBUG_INFO, "  %a [%02d|%02d|%02d]: %x -> %x.\n",
+          __FUNCTION__, PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber,
+          PciIoDevice->PciExpressCapability.DeviceControl.Bits.ExtendedTagField,
+          DeviceCtl.Bits.ExtendedTagField
+          ));
+      PciIoDevice->PciExpressCapability.DeviceControl.Bits.ExtendedTagField = DeviceCtl.Bits.ExtendedTagField;
+
+      return PciIoDevice->PciIo.Pci.Write (
+                                    &PciIoDevice->PciIo,
+                                    EfiPciIoWidthUint16,
+                                    PciIoDevice->PciExpressCapabilityOffset
+                                    + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl),
+                                    1,
+                                    &PciIoDevice->PciExpressCapability.DeviceControl.Uint16
+                                    );
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
index 5c70e41..2699f70 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
@@ -110,4 +110,22 @@ AtomicOpProgram (
   IN  UINTN         Level,
   IN  VOID          **Context
   );
+
+/**
+  Program ExtendedTag.
+
+  @param PciIoDevice  A pointer to the PCI_IO_DEVICE.
+  @param Level        The level of the PCI device in the heirarchy.
+                      Level of root ports is 0.
+  @param Context      Pointer to feature specific context.
+
+  @retval EFI_SUCCESS setup of PCI feature ExtendedTag is successful.
+**/
+EFI_STATUS
+ExtendedTagProgram (
+  IN  PCI_IO_DEVICE *PciIoDevice,
+  IN  UINTN         Level,
+  IN  VOID          **Context
+  );
+
 #endif
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 15/15] MdeModulePkg/PciBusDxe: Enable CommonClockConfiguration feature
       [not found] <20200510161412.13832-1-ashraf.javeed@intel.com>
                   ` (13 preceding siblings ...)
  2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 14/15] MdeModulePkg/PciBusDxe: Enable ExtendedTag feature Javeed, Ashraf
@ 2020-05-10 16:14 ` Javeed, Ashraf
  2020-05-13  8:19   ` Ni, Ray
  14 siblings, 1 reply; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-10 16:14 UTC (permalink / raw)
  To: devel; +Cc: Jian J Wang, Hao A Wu, Ray Ni

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

Add the Program phase feature init routine for CommonClockConfiguration
PCIe feature.

Signed-off-by: Ashraf Javeed <ashraf.javeed@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/PcieFeatureSupport.c |  4 ++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c       | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h       | 17 +++++++++++++++++
 3 files changed, 119 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
index acd60d5..c4bba0e 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
@@ -52,6 +52,8 @@ PCIE_FEATURE_ENTRY  mPcieFeatures[] = {
   //
   // Individual PCIE features
   //
+  { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, CommonClockConfiguration),
+              TRUE, { TRUE,  FALSE },{ NULL,                    CommonClockConfigurationProgram } },
   { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, MaxPayloadSize),
               TRUE, { TRUE,  TRUE }, { MaxPayloadSizeScan,      MaxPayloadSizeProgram } },
   { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, MaxReadRequestSize),
@@ -250,6 +252,8 @@ PcieNotifyDeviceState (
   PcieDeviceState.ExtendedTag         =
                   (UINT8)((PciIoDevice->PciExpressCapability.DeviceControl2.Bits.TenBitTagRequesterEnable << 1)
                            | PciIoDevice->PciExpressCapability.DeviceControl.Bits.ExtendedTagField);
+  PcieDeviceState.CommonClockConfiguration = (UINT8)
+                                        PciIoDevice->PciExpressCapability.LinkControl.Bits.CommonClockConfiguration;
 
   return mPciePlatformProtocol->NotifyDeviceState (
                                   mPciePlatformProtocol,
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
index 095f2ec..063a6be 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
@@ -793,3 +793,101 @@ ExtendedTagProgram (
   return EFI_SUCCESS;
 }
 
+/**
+  Program PCIe feature CommonClockConfiguration.
+
+  @param PciIoDevice            A pointer to the PCI_IO_DEVICE.
+  @param Level                  The level of the PCI device in the heirarchy.
+                                Level of root ports is 0.
+  @param Context                Pointer to feature specific context.
+
+  @retval EFI_SUCCESS           setup of PCI feature CommonClockConfiguration is successful.
+  @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
+CommonClockConfigurationProgram (
+  IN  PCI_IO_DEVICE *PciIoDevice,
+  IN  UINTN         Level,
+  IN  VOID          **Context
+  )
+{
+  EFI_STATUS                    Status;
+
+  //
+  // no other options about the Common Clock Configuraton shall be accepted besides
+  // AUTO and NOT_APPLICABLE
+  //
+  if (PciIoDevice->DeviceState.CommonClockConfiguration != EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO &&
+      PciIoDevice->DeviceState.CommonClockConfiguration != EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // skip programming of the Common Clock COnfiguration in the Link Cnntrol register
+  //
+  if (PciIoDevice->DeviceState.CommonClockConfiguration == EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE) {
+    return EFI_SUCCESS;
+  }
+
+  DEBUG ((
+    DEBUG_INFO, "  %a [%02d|%02d|%02d]: Status = %x\n",
+    __FUNCTION__, PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber,
+    PciIoDevice->PciExpressCapability.LinkStatus.Bits.SlotClockConfiguration
+    ));
+
+  //
+  // the Common Clock Configuration of the device needs to be aligned with its
+  // Link Status register SlotClockConfiguration value
+  //
+  if (PciIoDevice->PciExpressCapability.LinkStatus.Bits.SlotClockConfiguration !=
+      PciIoDevice->PciExpressCapability.LinkControl.Bits.CommonClockConfiguration) {
+    DEBUG ((
+      DEBUG_INFO, "  %a [%02d|%02d|%02d]: %x -> %x.\n",
+      __FUNCTION__, PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber,
+      PciIoDevice->PciExpressCapability.LinkControl.Bits.CommonClockConfiguration,
+      PciIoDevice->PciExpressCapability.LinkStatus.Bits.SlotClockConfiguration
+      ));
+    PciIoDevice->PciExpressCapability.LinkControl.Bits.CommonClockConfiguration =
+        PciIoDevice->PciExpressCapability.LinkStatus.Bits.SlotClockConfiguration;
+    //
+    // retrain the link at Root Port level, if its link is active
+    //
+    if (Level == 1 && PciIoDevice->PciExpressCapability.LinkStatus.Bits.DataLinkLayerLinkActive) {
+      PciIoDevice->PciExpressCapability.LinkControl.Bits.RetrainLink = 1;
+    }
+
+    Status = PciIoDevice->PciIo.Pci.Write (
+                                    &PciIoDevice->PciIo,
+                                    EfiPciIoWidthUint16,
+                                    PciIoDevice->PciExpressCapabilityOffset
+                                    + OFFSET_OF (PCI_CAPABILITY_PCIEXP, LinkControl),
+                                    1,
+                                    &PciIoDevice->PciExpressCapability.LinkControl.Uint16
+                                    );
+    if (EFI_ERROR(Status)) {
+      return Status;
+    }
+    //
+    // wait till link retrain is complete
+    //
+    if (Level == 1 && PciIoDevice->PciExpressCapability.LinkStatus.Bits.DataLinkLayerLinkActive) {
+      do {
+        Status = PciIoDevice->PciIo.Pci.Read (
+                                        &PciIoDevice->PciIo,
+                                        EfiPciIoWidthUint16,
+                                        PciIoDevice->PciExpressCapabilityOffset
+                                        + OFFSET_OF (PCI_CAPABILITY_PCIEXP, LinkStatus),
+                                        1,
+                                        &PciIoDevice->PciExpressCapability.LinkStatus.Uint16
+                                        );
+        if (EFI_ERROR(Status)) {
+          return Status;
+        }
+      } while (PciIoDevice->PciExpressCapability.LinkStatus.Bits.LinkTraining);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
index 2699f70..f1c4cb7 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
@@ -128,4 +128,21 @@ ExtendedTagProgram (
   IN  VOID          **Context
   );
 
+/**
+  Program CommonClockConfiguration.
+
+  @param PciIoDevice  A pointer to the PCI_IO_DEVICE.
+  @param Level        The level of the PCI device in the heirarchy.
+                      Level of root ports is 0.
+  @param Context      Pointer to feature specific context.
+
+  @retval EFI_SUCCESS setup of PCI feature ExtendedTag is successful.
+**/
+EFI_STATUS
+CommonClockConfigurationProgram (
+  IN  PCI_IO_DEVICE *PciIoDevice,
+  IN  UINTN         Level,
+  IN  VOID          **Context
+  );
+
 #endif
-- 
2.21.0.windows.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 04/15] MdeModulePkg/PciBusDxe: Refactor the PCIe Bridge enable
  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
  0 siblings, 0 replies; 33+ messages in thread
From: Ni, Ray @ 2020-05-13  6:31 UTC (permalink / raw)
  To: Javeed, Ashraf, devel@edk2.groups.io; +Cc: Wang, Jian J, Wu, Hao A

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Javeed, Ashraf <ashraf.javeed@intel.com>
> Sent: Monday, May 11, 2020 12:14 AM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> Subject: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 04/15] MdeModulePkg/PciBusDxe: Refactor the PCIe Bridge enable
> 
> 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
> 
> Refactor the PCIe Bridge enabling code.
> 
> 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>
> ---
>  MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c | 70 ++++++++++++++++++++--------------------------------------------------
>  1 file changed, 20 insertions(+), 50 deletions(-)
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
> index 5724fd6..62ef184 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
> @@ -597,52 +597,36 @@ DeRegisterPciDevice (
>  }
> 
>  /**
> -  Start the PCI root Ports or PCI-PCI Bridge only.
> +  Enable all the PCI bridges under the specified root bridge or PCI-PCI Bridge.
> 
> -  @param Controller          The root bridge handle.
> -  @param RootBridge          A pointer to the PCI_IO_DEVICE.
> -  @param RemainingDevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL.
> -  @param NumberOfChildren    Children number.
> -  @param ChildHandleBuffer   A pointer to the child handle buffer.
> -
> -  @retval EFI_NOT_READY   Device is not allocated.
> -  @retval EFI_UNSUPPORTED Device only support PCI-PCI bridge.
> -  @retval EFI_NOT_FOUND   Can not find the specific device.
> -  @retval EFI_SUCCESS     Success to start Pci devices on bridge.
> +  @param Bridge          A pointer to the PCI_IO_DEVICE.
> 
>  **/
> -EFI_STATUS
> +VOID
>  EnablePciBridges (
> -  IN EFI_HANDLE                          Controller,
> -  IN PCI_IO_DEVICE                       *RootBridge
> +  IN PCI_IO_DEVICE          *Bridge
>    )
> 
>  {
>    PCI_IO_DEVICE             *PciIoDevice;
> -  EFI_STATUS                Status;
> -  LIST_ENTRY                *CurrentLink;
> +  LIST_ENTRY                *Link;
>    UINT64                    Supports;
> 
> -  PciIoDevice = NULL;
> -  CurrentLink = RootBridge->ChildList.ForwardLink;
> -
> -  while (CurrentLink != NULL && CurrentLink != &RootBridge->ChildList) {
> -
> -    PciIoDevice = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
> -
> +  for ( Link = GetFirstNode (&Bridge->ChildList)
> +      ; !IsNull (&Bridge->ChildList, Link)
> +      ; Link = GetNextNode (&Bridge->ChildList, Link)
> +      ) {
> +    PciIoDevice = PCI_IO_DEVICE_FROM_LINK (Link);
>      //
> -    // check if the device has been assigned with required resource
> -    // and registered
> +    // Skip the device hasn't been assigned with required resource
> +    // or registered.
>      //
> -    if (!PciIoDevice->Registered && !PciIoDevice->Allocated) {
> -      return EFI_NOT_READY;
> +    if (!PciIoDevice->Registered || !PciIoDevice->Allocated) {
> +      continue;
>      }
> 
>      if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {
> -      Status = EnablePciBridges (
> -                 Controller,
> -                 PciIoDevice
> -                 );
> +      EnablePciBridges (PciIoDevice);
> 
>        PciIoDevice->PciIo.Attributes (
>                             &(PciIoDevice->PciIo),
> @@ -650,27 +634,17 @@ EnablePciBridges (
>                             0,
>                             &Supports
>                           );
> -      Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
> +      Supports &= (UINT64) EFI_PCI_DEVICE_ENABLE;
>        PciIoDevice->PciIo.Attributes (
>                             &(PciIoDevice->PciIo),
>                             EfiPciIoAttributeOperationEnable,
>                             Supports,
>                             NULL
>                           );
> -
>      }
> -
> -    CurrentLink = CurrentLink->ForwardLink;
> -  }
> -
> -  if (PciIoDevice == NULL) {
> -    return EFI_NOT_FOUND;
> -  } else {
> -    return EFI_SUCCESS;
>    }
>  }
> 
> -
>  /**
>    Register to manage the PCI device on the specified root bridge or PCI-PCI Bridge.
> 
> @@ -851,9 +825,7 @@ StartPciDevicesOnBridge (
>               ChildHandleBuffer
>               );
> 
> -  if (EFI_ERROR (Status)) {
> -    return Status;
> -  } else {
> +  if (!EFI_ERROR (Status)) {
>      //
>      // the late configuration of PCI Express features
>      // the platform is required to indicate its requirement for the initialization
> @@ -861,13 +833,11 @@ StartPciDevicesOnBridge (
>      //
> 
>      //
> -    // finally start those PCI bridge port devices only
> +    // finally enable those PCI bridges
>      //
> -    return EnablePciBridges (
> -             Controller,
> -             RootBridge
> -             );
> +    EnablePciBridges (RootBridge);
>    }
> +  return Status;
>  }
> 
>  /**
> --
> 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 05/15] MdeModulePkg/PciBusDxe: Locate PciePlatform/PcieOverride protocol
  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
  0 siblings, 0 replies; 33+ messages in thread
From: Ni, Ray @ 2020-05-13  6:31 UTC (permalink / raw)
  To: Javeed, Ashraf, devel@edk2.groups.io; +Cc: Wang, Jian J, Wu, Hao A

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Javeed, Ashraf <ashraf.javeed@intel.com>
> Sent: Monday, May 11, 2020 12:14 AM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> Subject: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 05/15] MdeModulePkg/PciBusDxe: Locate PciePlatform/PcieOverride
> protocol
> 
> 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
> 
> 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.c             |  5 +++++
>  MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h             |  1 +
>  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf        |  2 ++
>  MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
>  MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.h | 25 +++++++++++++++++++++++++
>  5 files changed, 77 insertions(+)
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
> index 53e6dfa..a139bed 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
> @@ -285,6 +285,11 @@ PciBusDriverBindingStart (
>            );
>    }
> 
> +  //
> +  // get the PCI Express Protocol or the PCI Express Override Protocol
> +  //
> +  InitializePciExpressProtocols ();
> +
>    if (mIoMmuProtocol == NULL) {
>      gBS->LocateProtocol (
>            &gEdkiiIoMmuProtocolGuid,
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
> index 9947203..ccf9ffa 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
> @@ -82,6 +82,7 @@ typedef enum {
>  #include "PciPowerManagement.h"
>  #include "PciHotPlugSupport.h"
>  #include "PciLib.h"
> +#include "PcieFeatureSupport.h"
> 
>  #define VGABASE1  0x3B0
>  #define VGALIMIT1 0x3BB
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> index 3b1559e..0818153 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> @@ -57,6 +57,8 @@
>    PciCommand.h
>    PciIo.h
>    PciBus.h
> +  PcieFeatureSupport.c
> +  PcieFeatureSupport.h
> 
>  [Packages]
>    MdePkg/MdePkg.dec
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> new file mode 100644
> index 0000000..13d0e0b
> --- /dev/null
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> @@ -0,0 +1,44 @@
> +/** @file
> +  PCI standard feature support functions implementation for PCI Bus module..
> +
> +Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "PciBus.h"
> +#include "PcieFeatureSupport.h"
> +EFI_PCI_EXPRESS_PLATFORM_PROTOCOL    *mPciePlatformProtocol;
> +
> +/**
> +  This function retrieves the PCI Express Platform Protocols published by platform
> +  @retval EFI_STATUS          direct return status from the LocateProtocol ()
> +                              boot service for the PCI Express Override Protocol.
> +          EFI_SUCCESS         The PCI Express Platform Protocol is found.
> +**/
> +EFI_STATUS
> +InitializePciExpressProtocols (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                      Status;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiPciExpressPlatformProtocolGuid,
> +                  NULL,
> +                  (VOID **) &mPciePlatformProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // If PCI Express Platform protocol doesn't exist, try to get the Pci Express
> +    // Override Protocol and treat it as PCI Express Platform protocol.
> +    //
> +    Status = gBS->LocateProtocol (
> +                    &gEfiPciExpressOverrideProtocolGuid,
> +                    NULL,
> +                    (VOID **) &mPciePlatformProtocol
> +                    );
> +  }
> +  return Status;
> +}
> +
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.h
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.h
> new file mode 100644
> index 0000000..5d15e0a
> --- /dev/null
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.h
> @@ -0,0 +1,25 @@
> +/** @file
> +  PCI standard feature support functions implementation for PCI Bus module..
> +
> +Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __PCIE_FEATURE_SUPPORT_H__
> +#define __PCIE_FEATURE_SUPPORT_H__
> +
> +extern EFI_PCI_EXPRESS_PLATFORM_PROTOCOL *mPciePlatformProtocol;
> +/**
> +  This function retrieves the PCI Express Platform Protocols published by platform
> +  @retval EFI_STATUS          direct return status from the LocateProtocol ()
> +                              boot service for the PCI Express Override Protocol
> +          EFI_SUCCESS         The PCI Express Platform Protocol is found
> +**/
> +EFI_STATUS
> +InitializePciExpressProtocols (
> +  VOID
> +  );
> +
> +
> +#endif
> --
> 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 02/15] MdeModulePkg/PciBusDxe: PciBusDxe Code refactor
  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
  0 siblings, 0 replies; 33+ messages in thread
From: Ni, Ray @ 2020-05-13  6:31 UTC (permalink / raw)
  To: Javeed, Ashraf, devel@edk2.groups.io; +Cc: Wang, Jian J, Wu, Hao A

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Javeed, Ashraf <ashraf.javeed@intel.com>
> Sent: Monday, May 11, 2020 12:14 AM
> To: devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 02/15] MdeModulePkg/PciBusDxe: PciBusDxe Code refactor
> 
> References:-
>   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
> 
> This code change represents the code refactoring by expelling the
> previous changes of the PCIe features.
> 
> Signed-off-by: Ashraf Javeed <ashraf.javeed@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>
> ---
>  MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c             |    4 --
>  MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h             |   20 ++-------
>  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf        |   10 +----
>  MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c   |   11 +----
>  MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c | 2178 ---------------------------------------------------------------------------------
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> ---
>  MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h |  399 ----------------------------------------------------------------------------------
> ------------------------------------------------------------------------------------------
>  MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c  | 1019 ---------------------------------------------------------------------------------
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> ----------------
>  MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h  |  304 ----------------------------------------------------------------------------------
> -------------------------------------------------
>  MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c |  902 ----------------------------------------------------------------------------------
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> ----------------------------------------------------------------------------------------------------------------------------------------
>  MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.h |  119 ----------------------------------------------------
>  10 files changed, 6 insertions(+), 4960 deletions(-)
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
> index 714101c..53e6dfa 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
> @@ -284,10 +284,6 @@ PciBusDriverBindingStart (
>            (VOID **) &gPciOverrideProtocol
> 
>            );
> 
>    }
> 
> -  //
> 
> -  // get the PCI Express Protocol or the PCI Express Override Protocol
> 
> -  //
> 
> -  GetPciExpressProtocol ();
> 
> 
> 
>    if (mIoMmuProtocol == NULL) {
> 
>      gBS->LocateProtocol (
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
> index 34f482d..5a7c1c2 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
> @@ -27,6 +27,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
>  #include <Protocol/PciOverride.h>
> 
>  #include <Protocol/PciEnumerationComplete.h>
> 
>  #include <Protocol/IoMmu.h>
> 
> +#include <Protocol/PciExpressOverride.h>
> 
> +#include <Protocol/PciExpressPlatform.h>
> 
> 
> 
>  #include <Library/DebugLib.h>
> 
>  #include <Library/UefiDriverEntryPoint.h>
> 
> @@ -42,8 +44,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
>  #include <IndustryStandard/Pci.h>
> 
>  #include <IndustryStandard/PeImage.h>
> 
>  #include <IndustryStandard/Acpi.h>
> 
> -#include <Protocol/PciExpressOverride.h>
> 
> -#include <Protocol/PciExpressPlatform.h>
> 
> +
> 
> 
> 
>  typedef struct _PCI_IO_DEVICE              PCI_IO_DEVICE;
> 
>  typedef struct _PCI_BAR                    PCI_BAR;
> 
> @@ -81,8 +82,6 @@ typedef enum {
>  #include "PciPowerManagement.h"
> 
>  #include "PciHotPlugSupport.h"
> 
>  #include "PciLib.h"
> 
> -#include "PciPlatformSupport.h"
> 
> -#include "PciFeatureSupport.h"
> 
> 
> 
>  #define VGABASE1  0x3B0
> 
>  #define VGALIMIT1 0x3BB
> 
> @@ -287,19 +286,6 @@ struct _PCI_IO_DEVICE {
>    // This field is used to support this case.
> 
>    //
> 
>    UINT16                                    BridgeIoAlignment;
> 
> -  //
> 
> -  // PCI Express features setup flags
> 
> -  //
> 
> -  UINT8                                     SetupMPS;
> 
> -  UINT8                                     SetupMRRS;
> 
> -  PCI_FEATURE_POLICY                        SetupRO;
> 
> -  PCI_FEATURE_POLICY                        SetupNS;
> 
> -  PCI_FEATURE_POLICY                        SetupCTO;
> 
> -  EFI_PCI_EXPRESS_ATOMIC_OP                 SetupAtomicOp;
> 
> -  BOOLEAN                                   SetupLtr;
> 
> -  UINT8                                     SetupExtTag;
> 
> -  UINT8                                     SetupAspm;
> 
> -  EFI_PCI_EXPRESS_COMMON_CLOCK_CFG          SetupCcc;
> 
>  };
> 
> 
> 
>  #define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> index e3ad105..3b1559e 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> @@ -57,12 +57,6 @@
>    PciCommand.h
> 
>    PciIo.h
> 
>    PciBus.h
> 
> -  PciFeatureSupport.c
> 
> -  PciFeatureSupport.h
> 
> -  PciPlatformSupport.c
> 
> -  PciPlatformSupport.h
> 
> -  PciExpressFeatures.c
> 
> -  PciExpressFeatures.h
> 
> 
> 
>  [Packages]
> 
>    MdePkg/MdePkg.dec
> 
> @@ -97,8 +91,8 @@
>    gEfiLoadFile2ProtocolGuid                       ## SOMETIMES_PRODUCES
> 
>    gEdkiiIoMmuProtocolGuid                         ## SOMETIMES_CONSUMES
> 
>    gEfiLoadedImageDevicePathProtocolGuid           ## CONSUMES
> 
> -  gEfiPciExpressPlatformProtocolGuid                     ## SOMETIMES_CONSUMES
> 
> -  gEfiPciExpressOverrideProtocolGuid                     ## SOMETIMES_CONSUMES
> 
> +  gEfiPciExpressPlatformProtocolGuid              ## SOMETIMES_CONSUMES
> 
> +  gEfiPciExpressOverrideProtocolGuid              ## SOMETIMES_CONSUMES
> 
> 
> 
> 
> 
>  [FeaturePcd]
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
> index 07ee9ba..5724fd6 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c
> @@ -859,16 +859,7 @@ StartPciDevicesOnBridge (
>      // the platform is required to indicate its requirement for the initialization
> 
>      // of PCI Express features by publishing its protocol
> 
>      //
> 
> -    if (
> 
> -        gFullEnumeration
> 
> -        && IsPciExpressProtocolPresent ()
> 
> -    ) {
> 
> -
> 
> -      Status = EnumeratePciExpressFeatures (
> 
> -                Controller,
> 
> -                RootBridge
> 
> -                );
> 
> -    }
> 
> +
> 
>      //
> 
>      // finally start those PCI bridge port devices only
> 
>      //
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c
> deleted file mode 100644
> index 1e2f4a4..0000000
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c
> +++ /dev/null
> @@ -1,2178 +0,0 @@
> -/** @file
> 
> -  PCI standard feature support functions implementation for PCI Bus module..
> 
> -
> 
> -Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> 
> -SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> -
> 
> -**/
> 
> -
> 
> -#include "PciBus.h"
> 
> -#include "PciFeatureSupport.h"
> 
> -
> 
> -VOID
> 
> -ReportPciWriteError (
> 
> -  IN UINT8  Bus,
> 
> -  IN UINT8  Device,
> 
> -  IN UINT8  Function,
> 
> -  IN UINT32 Offset
> 
> -  )
> 
> -{
> 
> -  DEBUG ((
> 
> -    DEBUG_ERROR,
> 
> -    "Unexpected PCI register (%d,%d,%d,0x%x) write error!",
> 
> -    Bus,
> 
> -    Device,
> 
> -    Function,
> 
> -    Offset
> 
> -    ));
> 
> -}
> 
> -
> 
> -/**
> 
> -  Compare and Swap the payload value - between the global variable to maaintain
> 
> -  common value among all the devices in the PCIe heirarchy from the root bridge
> 
> -  device and all its child devices; with the device-sepcific setup value.
> 
> -
> 
> -  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
> 
> -  @param PciExpressConfigurationTable  pointer to PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE
> 
> -
> 
> -  @retval EFI_SUCCESS                   processing of PCI feature Max_Payload_Size
> 
> -                                        is successful.
> 
> -**/
> 
> -EFI_STATUS
> 
> -CasMaxPayloadSize (
> 
> -    IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -    IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
> 
> -  )
> 
> -{
> 
> -  UINT8                                   MpsValue;
> 
> -
> 
> -  //
> 
> -  // align the MPS of the tree to the HCF with this device
> 
> -  //
> 
> -  if (PciExpressConfigurationTable) {
> 
> -    MpsValue = PciExpressConfigurationTable->Max_Payload_Size;
> 
> -
> 
> -    MpsValue = MIN (PciDevice->SetupMPS, MpsValue);
> 
> -    PciDevice->SetupMPS = MIN (PciDevice->SetupMPS, MpsValue);
> 
> -
> 
> -    if (MpsValue != PciExpressConfigurationTable->Max_Payload_Size) {
> 
> -      PciExpressConfigurationTable->Max_Payload_Size = MpsValue;
> 
> -    }
> 
> -  }
> 
> -
> 
> -  DEBUG ((
> 
> -    DEBUG_INFO,
> 
> -    "MPS: %d [DevCap:%d],",
> 
> -    PciDevice->SetupMPS, PciDevice->PciExpressCapabilityStructure.DeviceCapability.Bits.MaxPayloadSize
> 
> -  ));
> 
> -
> 
> -  return EFI_SUCCESS;
> 
> -}
> 
> -
> 
> -/**
> 
> -  The main routine which process the PCI feature Max_Payload_Size as per the
> 
> -  device-specific platform policy, as well as in complaince with the PCI Base
> 
> -  specification Revision 4, that aligns the value for the entire PCI heirarchy
> 
> -  starting from its physical PCI Root port / Bridge device.
> 
> -
> 
> -  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
> 
> -  @param PciExpressConfigurationTable  pointer to PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE
> 
> -
> 
> -  @retval EFI_SUCCESS                   processing of PCI feature Max_Payload_Size
> 
> -                                        is successful.
> 
> -**/
> 
> -EFI_STATUS
> 
> -SetupMaxPayloadSize (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
> 
> -  )
> 
> -{
> 
> -  PCI_REG_PCIE_DEVICE_CAPABILITY          PciDeviceCap;
> 
> -  UINT8                                   MpsValue;
> 
> -
> 
> -
> 
> -  PciDeviceCap.Uint32 = PciDevice->PciExpressCapabilityStructure.DeviceCapability.Uint32;
> 
> -
> 
> -  if (PciDevice->SetupMPS == EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_AUTO) {
> 
> -    //
> 
> -    // configure this feature as per its PCIe device capabilities
> 
> -    //
> 
> -    MpsValue = (UINT8)PciDeviceCap.Bits.MaxPayloadSize;
> 
> -    //
> 
> -    // no change to PCI Root ports without any endpoint device
> 
> -    //
> 
> -    if (IS_PCI_BRIDGE (&PciDevice->Pci) && PciDeviceCap.Bits.MaxPayloadSize) {
> 
> -      if (IsListEmpty  (&PciDevice->ChildList)) {
> 
> -        //
> 
> -        // No device on root bridge
> 
> -        //
> 
> -        MpsValue = PCIE_MAX_PAYLOAD_SIZE_128B;
> 
> -      }
> 
> -    }
> 
> -  } else {
> 
> -    MpsValue = SetDevicePolicyPciExpressMps (PciDevice->SetupMPS);
> 
> -  }
> 
> -  //
> 
> -  // discard device policy override request if greater than PCI device capability
> 
> -  //
> 
> -  PciDevice->SetupMPS = MIN ((UINT8)PciDeviceCap.Bits.MaxPayloadSize, MpsValue);
> 
> -
> 
> -  return CasMaxPayloadSize (
> 
> -          PciDevice,
> 
> -          PciExpressConfigurationTable
> 
> -          );
> 
> -}
> 
> -
> 
> -/**
> 
> -  Overrides the PCI Device Control register MaxPayloadSize 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
> 
> -ProgramMaxPayloadSize (
> 
> -  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 (PcieDev.Bits.MaxPayloadSize != PciDevice->SetupMPS) {
> 
> -    PcieDev.Bits.MaxPayloadSize = PciDevice->SetupMPS;
> 
> -    DEBUG (( DEBUG_INFO, "MPS=%d,", PciDevice->SetupMPS));
> 
> -
> 
> -    //
> 
> -    // 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 MPS=%d,", PciDevice->SetupMPS));
> 
> -  }
> 
> -
> 
> -  return Status;
> 
> -}
> 
> -
> 
> -EFI_STATUS
> 
> -ConditionalCasMaxReadReqSize (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
> 
> -  )
> 
> -{
> 
> -  //
> 
> -  // align the Max_Read_Request_Size of the PCI tree based on 3 conditions:
> 
> -  // first, if user defines MRRS for any one PCI device in the tree than align
> 
> -  // all the devices in the PCI tree.
> 
> -  // second, if user override is not define for this PCI tree than setup the MRRS
> 
> -  // based on MPS value of the tree to meet the criteria for the isochronous
> 
> -  // traffic.
> 
> -  // third, if no user override, or platform firmware policy has not selected
> 
> -  // this PCI bus driver to configure the MPS; than configure the MRRS to a
> 
> -  // highest common value of PCI device capability for the MPS found among all
> 
> -  // the PCI devices in this tree
> 
> -  //
> 
> -  if (PciExpressConfigurationTable) {
> 
> -    if (PciExpressConfigurationTable->Lock_Max_Read_Request_Size) {
> 
> -      PciDevice->SetupMRRS = PciExpressConfigurationTable->Max_Read_Request_Size;
> 
> -    } else {
> 
> -      if (mPciExpressPlatformPolicy.Mps) {
> 
> -        PciDevice->SetupMRRS = PciDevice->SetupMPS;
> 
> -      } else {
> 
> -        PciDevice->SetupMRRS = MIN (
> 
> -                                PciDevice->SetupMRRS,
> 
> -                                PciExpressConfigurationTable->Max_Read_Request_Size
> 
> -                                );
> 
> -      }
> 
> -      PciExpressConfigurationTable->Max_Read_Request_Size = PciDevice->SetupMRRS;
> 
> -    }
> 
> -  }
> 
> -  DEBUG (( DEBUG_INFO, "MRRS: %d,", PciDevice->SetupMRRS));
> 
> -
> 
> -  return EFI_SUCCESS;
> 
> -}
> 
> -
> 
> -/**
> 
> -  The main routine which process the PCI feature Max_Read_Req_Size as per the
> 
> -  device-specific platform policy, as well as in complaince with the PCI Base
> 
> -  specification Revision 4, that aligns the value for the entire PCI heirarchy
> 
> -  starting from its physical PCI Root port / Bridge device.
> 
> -
> 
> -  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
> 
> -  @param PciExpressConfigurationTable  pointer to PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE
> 
> -
> 
> -  @retval EFI_SUCCESS                   processing of PCI feature Max_Read_Req_Size
> 
> -                                        is successful.
> 
> -**/
> 
> -EFI_STATUS
> 
> -SetupMaxReadReqSize (
> 
> -  IN  PCI_IO_DEVICE                           *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
> 
> -  )
> 
> -{
> 
> -  PCI_REG_PCIE_DEVICE_CAPABILITY  PciDeviceCap;
> 
> -  UINT8                           MrrsValue;
> 
> -
> 
> -  PciDeviceCap.Uint32 = PciDevice->PciExpressCapabilityStructure.DeviceCapability.Uint32;
> 
> -
> 
> -  if (PciDevice->SetupMRRS == EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_AUTO) {
> 
> -    //
> 
> -    // The maximum read request size is not the data packet size of the TLP,
> 
> -    // but the memory read request size, and set to the function as a requestor
> 
> -    // to not exceed this limit.
> 
> -    // However, for the PCI device capable of isochronous traffic; this memory read
> 
> -    // request size should not extend beyond the Max_Payload_Size. Thus, in case if
> 
> -    // device policy return by platform indicates to set as per device capability
> 
> -    // than set as per Max_Payload_Size configuration value
> 
> -    //
> 
> -    if (mPciExpressPlatformPolicy.Mps) {
> 
> -      MrrsValue = PciDevice->SetupMPS;
> 
> -    } else {
> 
> -      //
> 
> -      // in case this driver is not required to configure the Max_Payload_Size
> 
> -      // than consider programming HCF of the device capability's Max_Payload_Size
> 
> -      // in this PCI hierarchy; thus making this an implementation specific feature
> 
> -      // which the platform should avoid. For better results, the platform should
> 
> -      // make both the Max_Payload_Size & Max_Read_Request_Size to be configured
> 
> -      // by this driver
> 
> -      //
> 
> -      MrrsValue = (UINT8)PciDeviceCap.Bits.MaxPayloadSize;
> 
> -    }
> 
> -  } else {
> 
> -    //
> 
> -    // override as per platform based device policy
> 
> -    //
> 
> -    MrrsValue = SetDevicePolicyPciExpressMrrs (PciDevice->SetupMRRS);
> 
> -    //
> 
> -    // align this device's Max_Read_Request_Size value to the entire PCI tree
> 
> -    //
> 
> -    if (PciExpressConfigurationTable) {
> 
> -      if (!PciExpressConfigurationTable->Lock_Max_Read_Request_Size) {
> 
> -        PciExpressConfigurationTable->Lock_Max_Read_Request_Size = TRUE;
> 
> -        PciExpressConfigurationTable->Max_Read_Request_Size = MrrsValue;
> 
> -      } else {
> 
> -        //
> 
> -        // in case of another user enforced value of MRRS within the same tree,
> 
> -        // pick the smallest between the locked value and this value; to set
> 
> -        // across entire PCI tree nodes
> 
> -        //
> 
> -        MrrsValue = MIN (
> 
> -                      MrrsValue,
> 
> -                      PciExpressConfigurationTable->Max_Read_Request_Size
> 
> -                      );
> 
> -        PciExpressConfigurationTable->Max_Read_Request_Size = MrrsValue;
> 
> -      }
> 
> -    }
> 
> -  }
> 
> -  //
> 
> -  // align this device's Max_Read_Request_Size to derived configuration value
> 
> -  //
> 
> -  PciDevice->SetupMRRS = MrrsValue;
> 
> -
> 
> -  return ConditionalCasMaxReadReqSize (
> 
> -          PciDevice,
> 
> -          PciExpressConfigurationTable
> 
> -          );
> 
> -}
> 
> -
> 
> -
> 
> -/**
> 
> -  Overrides the PCI Device Control register Max_Read_Req_Size 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 controller.
> 
> -  @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
> 
> -ProgramMaxReadReqSize (
> 
> -  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 (PcieDev.Bits.MaxReadRequestSize != PciDevice->SetupMRRS) {
> 
> -    PcieDev.Bits.MaxReadRequestSize = PciDevice->SetupMRRS;
> 
> -    DEBUG (( DEBUG_INFO, "MRRS: %d,", PciDevice->SetupMRRS));
> 
> -
> 
> -    //
> 
> -    // 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 MRRS=%d,", PciDevice->SetupMRRS));
> 
> -  }
> 
> -
> 
> -  return Status;
> 
> -}
> 
> -
> 
> -/**
> 
> -  Overrides the PCI Device Control register Relax Order 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
> 
> -ProgramRelaxOrder (
> 
> -  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->SetupRO.Override
> 
> -      &&  PcieDev.Bits.RelaxedOrdering != PciDevice->SetupRO.Act
> 
> -      ) {
> 
> -    PcieDev.Bits.RelaxedOrdering = PciDevice->SetupRO.Act;
> 
> -    DEBUG (( DEBUG_INFO, "RO=%d,", PciDevice->SetupRO.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 RO,", PciDevice->SetupRO.Act));
> 
> -  }
> 
> -
> 
> -  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;
> 
> -}
> 
> -
> 
> -/**
> 
> -  To determine the CTO Range A values
> 
> -
> 
> -  @param  CtoValue    input CTO range value from 0 to 14
> 
> -  @retval TRUE        the given CTO value belongs to Range A
> 
> -          FALSE       the given value does not belong to Range A
> 
> -**/
> 
> -BOOLEAN
> 
> -IsCtoRangeA (
> 
> -  IN  UINT8   CtoValue
> 
> -  )
> 
> -{
> 
> -  switch (CtoValue) {
> 
> -    case  PCIE_COMPLETION_TIMEOUT_50US_100US:
> 
> -    case  PCIE_COMPLETION_TIMEOUT_1MS_10MS:
> 
> -      return TRUE;
> 
> -  }
> 
> -  return FALSE;
> 
> -}
> 
> -
> 
> -/**
> 
> -  To determine the CTO Range B values
> 
> -
> 
> -  @param  CtoValue    input CTO range value from 0 to 14
> 
> -  @retval TRUE        the given CTO value belongs to Range B
> 
> -          FALSE       the given value does not belong to Range B
> 
> -**/
> 
> -BOOLEAN
> 
> -IsCtoRangeB (
> 
> -  IN  UINT8   CtoValue
> 
> -  )
> 
> -{
> 
> -  switch (CtoValue) {
> 
> -    case  PCIE_COMPLETION_TIMEOUT_16MS_55MS:
> 
> -    case  PCIE_COMPLETION_TIMEOUT_65MS_210MS:
> 
> -      return TRUE;
> 
> -  }
> 
> -  return FALSE;
> 
> -}
> 
> -
> 
> -/**
> 
> -  To determine the CTO Range C values
> 
> -
> 
> -  @param  CtoValue    input CTO range value from 0 to 14
> 
> -  @retval TRUE        the given CTO value belongs to Range C
> 
> -          FALSE       the given value does not belong to Range C
> 
> -**/
> 
> -BOOLEAN
> 
> -IsCtoRangeC (
> 
> -  IN  UINT8   CtoValue
> 
> -  )
> 
> -{
> 
> -  switch (CtoValue) {
> 
> -    case  PCIE_COMPLETION_TIMEOUT_260MS_900MS:
> 
> -    case  PCIE_COMPLETION_TIMEOUT_1S_3_5S:
> 
> -      return TRUE;
> 
> -  }
> 
> -  return FALSE;
> 
> -}
> 
> -
> 
> -/**
> 
> -  To determine the CTO Range D values
> 
> -
> 
> -  @param  CtoValue    input CTO range value from 0 to 14
> 
> -  @retval TRUE        the given CTO value belongs to Range D
> 
> -          FALSE       the given value does not belong to Range D
> 
> -**/
> 
> -BOOLEAN
> 
> -IsCtoRangeD (
> 
> -  IN  UINT8   CtoValue
> 
> -  )
> 
> -{
> 
> -  switch (CtoValue) {
> 
> -    case  PCIE_COMPLETION_TIMEOUT_4S_13S:
> 
> -    case  PCIE_COMPLETION_TIMEOUT_17S_64S:
> 
> -      return TRUE;
> 
> -  }
> 
> -  return FALSE;
> 
> -}
> 
> -
> 
> -/**
> 
> -  The main routine which setup the PCI feature Completion Timeout as per the
> 
> -  device-specific platform policy, as well as in complaince with the PCI Base
> 
> -  specification Revision 4.
> 
> -
> 
> -  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
> 
> -
> 
> -  @retval EFI_SUCCESS                   processing of PCI feature CTO is successful.
> 
> -**/
> 
> -EFI_STATUS
> 
> -SetupCompletionTimeout (
> 
> -  IN PCI_IO_DEVICE          *PciDevice,
> 
> -  IN VOID                   *PciExFeatureConfiguration
> 
> -  )
> 
> -{
> 
> -  PCI_REG_PCIE_DEVICE_CAPABILITY2 DeviceCap2;
> 
> -  UINT8                           CtoRangeValue;
> 
> -
> 
> -  if (!PciDevice->SetupCTO.Override) {
> 
> -    //
> 
> -    // No override of CTO is required for this device
> 
> -    //
> 
> -    return  EFI_SUCCESS;
> 
> -  }
> 
> -
> 
> -  //
> 
> -  // determine the CTO range values as per its device capability register
> 
> -  //
> 
> -  DeviceCap2.Uint32 = PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Uint32;
> 
> -  if (!DeviceCap2.Bits.CompletionTimeoutRanges
> 
> -      && !DeviceCap2.Bits.CompletionTimeoutDisable
> 
> -  ) {
> 
> -    //
> 
> -    // device does not support the CTO mechanism, hence no override is applicable
> 
> -    //
> 
> -    return EFI_SUCCESS;
> 
> -  }
> 
> -
> 
> -  //
> 
> -  // override the device CTO values if applicable
> 
> -  //
> 
> -  if (PciDevice->SetupCTO.Act) {
> 
> -    //
> 
> -    // program the CTO range values
> 
> -    //
> 
> -    if (DeviceCap2.Bits.CompletionTimeoutRanges) {
> 
> -      CtoRangeValue = PCIE_COMPLETION_TIMEOUT_50US_50MS;
> 
> -      //
> 
> -      // in case if the supported CTO range and the requirement from platform
> 
> -      // policy does not match, than the CTO range setting would be based on
> 
> -      // this driver's implementation specific, and its rules are as follows:-
> 
> -      //
> 
> -      // if device is capable of Range A only and if platform ask for any of
> 
> -      // ranges B, C, D; than this implementation will only program the default
> 
> -      // range value for the duration of 50us to 50ms.
> 
> -      //
> 
> -      // if device is capable of Range B, or range B & C, or Ranges B, C & D only
> 
> -      // and if the platform ask for the Range A; than this implementation will
> 
> -      // only program the default range value for the duration of 50us to 50ms.
> 
> -      //
> 
> -      // if the device is capable of Range B only, or the ranges A & B; and the
> 
> -      // platform ask for Range C, or Range D values, than this implementation
> 
> -      // will only program the Range B value for the duration of 65ms to 210ms.
> 
> -      //
> 
> -      // if the device is capable of Ranges B & C, or Ranges A, B, and C; and
> 
> -      // if the platform ask for Range D values; than this implementation will
> 
> -      // only program the Range C for the duration of 1s to 3.5s.
> 
> -      //
> 
> -
> 
> -      switch (DeviceCap2.Bits.CompletionTimeoutRanges) {
> 
> -        case  PCIE_COMPLETION_TIMEOUT_RANGE_A_SUPPORTED:
> 
> -          if (IsCtoRangeA (PciDevice->SetupCTO.Support)) {
> 
> -            CtoRangeValue = PciDevice->SetupCTO.Support;
> 
> -          }
> 
> -          //
> 
> -          // if device is capable of Range A only and if platform ask for any of
> 
> -          // ranges B, C, D; than this implementation will only program the default
> 
> -          // range value for the duration of 50us to 50ms.
> 
> -          //
> 
> -          if (IsCtoRangeB (PciDevice->SetupCTO.Support)
> 
> -              || IsCtoRangeC (PciDevice->SetupCTO.Support)
> 
> -              || IsCtoRangeD (PciDevice->SetupCTO.Support)
> 
> -          ) {
> 
> -            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_50US_50MS;
> 
> -          }
> 
> -          break;
> 
> -
> 
> -        case  PCIE_COMPLETION_TIMEOUT_RANGE_B_SUPPORTED:
> 
> -          //
> 
> -          // if device is capable of Range B, or range B & C, or Ranges B, C & D only
> 
> -          // and if the platform ask for the Range A; than this implementation will
> 
> -          // only program the default range value for the duration of 50us to 50ms.
> 
> -          //
> 
> -          if (IsCtoRangeA (PciDevice->SetupCTO.Support)) {
> 
> -            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_50US_50MS;
> 
> -          }
> 
> -
> 
> -          if (IsCtoRangeB (PciDevice->SetupCTO.Support)) {
> 
> -            CtoRangeValue = PciDevice->SetupCTO.Support;
> 
> -          }
> 
> -          //
> 
> -          // if the device is capable of Range B only, or the ranges A & B; and the
> 
> -          // platform ask for Range C, or Range D values, than this implementation
> 
> -          // will only program the Range B value for the duration of 65ms to 210ms.
> 
> -          //
> 
> -          if (IsCtoRangeC (PciDevice->SetupCTO.Support)
> 
> -              || IsCtoRangeD (PciDevice->SetupCTO.Support)
> 
> -          ) {
> 
> -            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_65MS_210MS;
> 
> -          }
> 
> -          break;
> 
> -
> 
> -        case  PCIE_COMPLETION_TIMEOUT_RANGE_B_C_SUPPORTED:
> 
> -          if (IsCtoRangeA (PciDevice->SetupCTO.Support)) {
> 
> -            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_50US_50MS;
> 
> -          }
> 
> -
> 
> -          if (IsCtoRangeB (PciDevice->SetupCTO.Support)
> 
> -              || IsCtoRangeC (PciDevice->SetupCTO.Support)
> 
> -              ) {
> 
> -            CtoRangeValue = PciDevice->SetupCTO.Support;
> 
> -          }
> 
> -          //
> 
> -          // if the device is capable of Ranges B & C, or Ranges A, B, and C; and
> 
> -          // if the platform ask for Range D values; than this implementation will
> 
> -          // only program the Range C for the duration of 1s to 3.5s.
> 
> -          //
> 
> -          if (IsCtoRangeD (PciDevice->SetupCTO.Support)) {
> 
> -            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_1S_3_5S;
> 
> -          }
> 
> -          break;
> 
> -
> 
> -        case  PCIE_COMPLETION_TIMEOUT_RANGE_B_C_D_SUPPORTED:
> 
> -          if (IsCtoRangeA (PciDevice->SetupCTO.Support)) {
> 
> -            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_50US_50MS;
> 
> -          }
> 
> -          if (IsCtoRangeB (PciDevice->SetupCTO.Support)
> 
> -              || IsCtoRangeC (PciDevice->SetupCTO.Support)
> 
> -              || IsCtoRangeD (PciDevice->SetupCTO.Support)
> 
> -          ) {
> 
> -            CtoRangeValue = PciDevice->SetupCTO.Support;
> 
> -          }
> 
> -          break;
> 
> -
> 
> -        case  PCIE_COMPLETION_TIMEOUT_RANGE_A_B_SUPPORTED:
> 
> -          if (IsCtoRangeA (PciDevice->SetupCTO.Support)
> 
> -              || IsCtoRangeB (PciDevice->SetupCTO.Support)
> 
> -              ) {
> 
> -            CtoRangeValue = PciDevice->SetupCTO.Support;
> 
> -          }
> 
> -          if (IsCtoRangeC (PciDevice->SetupCTO.Support)
> 
> -              || IsCtoRangeD (PciDevice->SetupCTO.Support)
> 
> -          ) {
> 
> -            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_65MS_210MS;
> 
> -          }
> 
> -          break;
> 
> -
> 
> -        case  PCIE_COMPLETION_TIMEOUT_RANGE_A_B_C_SUPPORTED:
> 
> -          if (IsCtoRangeA (PciDevice->SetupCTO.Support)
> 
> -              || IsCtoRangeB (PciDevice->SetupCTO.Support)
> 
> -              || IsCtoRangeC (PciDevice->SetupCTO.Support)
> 
> -          ) {
> 
> -            CtoRangeValue = PciDevice->SetupCTO.Support;
> 
> -          }
> 
> -          if (IsCtoRangeD (PciDevice->SetupCTO.Support)) {
> 
> -            CtoRangeValue = PCIE_COMPLETION_TIMEOUT_1S_3_5S;
> 
> -          }
> 
> -          break;
> 
> -
> 
> -        case  PCIE_COMPLETION_TIMEOUT_RANGE_A_B_C_D_SUPPORTED:
> 
> -          if (IsCtoRangeA (PciDevice->SetupCTO.Support)
> 
> -              || IsCtoRangeB (PciDevice->SetupCTO.Support)
> 
> -              || IsCtoRangeC (PciDevice->SetupCTO.Support)
> 
> -              || IsCtoRangeD (PciDevice->SetupCTO.Support)
> 
> -          ) {
> 
> -            CtoRangeValue = PciDevice->SetupCTO.Support;
> 
> -          }
> 
> -          break;
> 
> -
> 
> -        default:
> 
> -          DEBUG ((
> 
> -            DEBUG_ERROR,
> 
> -            "Invalid CTO range: %d\n",
> 
> -            DeviceCap2.Bits.CompletionTimeoutRanges
> 
> -            ));
> 
> -          return EFI_INVALID_PARAMETER;
> 
> -      }
> 
> -
> 
> -      if (PciDevice->SetupCTO.Support != CtoRangeValue) {
> 
> -        PciDevice->SetupCTO.Support = CtoRangeValue;
> 
> -      }
> 
> -    }
> 
> -    DEBUG (( DEBUG_INFO, "CTO enable: %d, CTO range: 0x%x,",
> 
> -        PciDevice->SetupCTO.Act,
> 
> -        PciDevice->SetupCTO.Support
> 
> -    ));
> 
> -  }
> 
> -  return EFI_SUCCESS;
> 
> -}
> 
> -
> 
> -/**
> 
> -  Overrides the PCI Device Control2 register Completion Timeout range; 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
> 
> -ProgramCompletionTimeout (
> 
> -  IN PCI_IO_DEVICE          *PciDevice,
> 
> -  IN VOID                   *PciExFeatureConfiguration
> 
> -  )
> 
> -{
> 
> -  PCI_REG_PCIE_DEVICE_CONTROL2    DeviceCtl2;
> 
> -  PCI_REG_PCIE_DEVICE_CAPABILITY2 DeviceCap2;
> 
> -  UINT32                          Offset;
> 
> -  EFI_STATUS                      Status;
> 
> -  EFI_TPL                         OldTpl;
> 
> -
> 
> -  if (!PciDevice->SetupCTO.Override) {
> 
> -    //
> 
> -    // No override of CTO is required for this device
> 
> -    //
> 
> -    DEBUG (( DEBUG_INFO, "CTO skipped,"));
> 
> -    return  EFI_SUCCESS;
> 
> -  }
> 
> -
> 
> -  //
> 
> -  // to program the CTO range values, determine in its device capability register
> 
> -  //
> 
> -  DeviceCap2.Uint32 = PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Uint32;
> 
> -  if (DeviceCap2.Bits.CompletionTimeoutRanges
> 
> -      || DeviceCap2.Bits.CompletionTimeoutDisable) {
> 
> -    //
> 
> -    // device supports the CTO mechanism
> 
> -    //
> 
> -    DeviceCtl2.Uint16 = 0;
> 
> -    Offset = PciDevice->PciExpressCapabilityOffset +
> 
> -              OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2);
> 
> -    Status = PciDevice->PciIo.Pci.Read (
> 
> -                                  &PciDevice->PciIo,
> 
> -                                  EfiPciIoWidthUint16,
> 
> -                                  Offset,
> 
> -                                  1,
> 
> -                                  &DeviceCtl2.Uint16
> 
> -                                  );
> 
> -    ASSERT (Status == EFI_SUCCESS);
> 
> -  } else {
> 
> -    //
> 
> -    // device does not support the CTO mechanism, hence no override performed
> 
> -    //
> 
> -    DEBUG (( DEBUG_INFO, "CTO n/a,"));
> 
> -    return EFI_SUCCESS;
> 
> -  }
> 
> -
> 
> -  //
> 
> -  // override the device CTO values if applicable
> 
> -  //
> 
> -  if (PciDevice->SetupCTO.Act) {
> 
> -    //
> 
> -    // program the CTO range values
> 
> -    //
> 
> -    if (PciDevice->SetupCTO.Support != DeviceCtl2.Bits.CompletionTimeoutValue) {
> 
> -      DeviceCtl2.Bits.CompletionTimeoutValue = PciDevice->SetupCTO.Support;
> 
> -    }
> 
> -  } else {
> 
> -    //
> 
> -    // disable the CTO mechanism in device
> 
> -    //
> 
> -    DeviceCtl2.Bits.CompletionTimeoutValue = 0;
> 
> -    DeviceCtl2.Bits.CompletionTimeoutDisable = 1;
> 
> -  }
> 
> -  DEBUG (( DEBUG_INFO, "CTO disable: %d, CTO range: 0x%x,",
> 
> -      DeviceCtl2.Bits.CompletionTimeoutDisable,
> 
> -      DeviceCtl2.Bits.CompletionTimeoutValue
> 
> -  ));
> 
> -
> 
> -  //
> 
> -  // 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,
> 
> -                                &DeviceCtl2.Uint16
> 
> -                                );
> 
> -  //
> 
> -  // Restore TPL to its original level
> 
> -  //
> 
> -  gBS->RestoreTPL (OldTpl);
> 
> -
> 
> -  if (!EFI_ERROR(Status)) {
> 
> -    PciDevice->PciExpressCapabilityStructure.DeviceControl2.Uint16 = DeviceCtl2.Uint16;
> 
> -  } else {
> 
> -    ReportPciWriteError (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, Offset);
> 
> -  }
> 
> -  return Status;
> 
> -}
> 
> -
> 
> -/**
> 
> -  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 specification.
> 
> -
> 
> -  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
> 
> -  @param PciExFeatureConfiguration      pointer to common configuration table to
> 
> -                                        initialize the PCI Express feature
> 
> -
> 
> -  @retval EFI_SUCCESS                   bridge device routing capability is 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.AtomicOpRouting) {
> 
> -      //
> 
> -      // since the AtomicOp Routing support flag is initialized as TRUE, negate
> 
> -      // in case if any of the PCI Bridge device in the PCI tree does not support
> 
> -      // the AtomicOp Routing capability
> 
> -      //
> 
> -      if (PciExFeatureConfiguration == NULL) {
> 
> -        return EFI_INVALID_PARAMETER;
> 
> -      }
> 
> -      PciExFeatureConfiguration->AtomicOpRoutingSupported = FALSE;
> 
> -    }
> 
> -  }
> 
> -
> 
> -  return EFI_SUCCESS;
> 
> -}
> 
> -
> 
> -/**
> 
> -  Overrides the PCI Device Control 2 register AtomicOp Requester enable 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
> 
> -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 = 0;
> 
> -  Offset = PciDevice->PciExpressCapabilityOffset +
> 
> -               OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2);
> 
> -  Status = PciDevice->PciIo.Pci.Read (
> 
> -                                  &PciDevice->PciIo,
> 
> -                                  EfiPciIoWidthUint16,
> 
> -                                  Offset,
> 
> -                                  1,
> 
> -                                  &PcieDev.Uint16
> 
> -                                  );
> 
> -  ASSERT (Status == 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 != PciDevice->SetupAtomicOp.Enable_AtomicOpRequester) {
> 
> -        PcieDev.Bits.AtomicOpRequester = PciDevice->SetupAtomicOp.Enable_AtomicOpRequester;
> 
> -      }
> 
> -      //
> 
> -      // if platform also request its AtomicOp Egress blocking to be enabled; 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.Bits.AtomicOpRouting) {
> 
> -          PcieDev.Bits.AtomicOpEgressBlocking = 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 != PciDevice->SetupAtomicOp.Enable_AtomicOpRequester) {
> 
> -            PcieDev.Bits.AtomicOpRequester = PciDevice->SetupAtomicOp.Enable_AtomicOpRequester;
> 
> -          }
> 
> -        }
> 
> -      } else {
> 
> -        //
> 
> -        // for the RCiEP device or the bridge device without any child, setup AtomicOp
> 
> -        // Requester as per platform's device policy
> 
> -        //
> 
> -        if (PcieDev.Bits.AtomicOpRequester != PciDevice->SetupAtomicOp.Enable_AtomicOpRequester) {
> 
> -          PcieDev.Bits.AtomicOpRequester = PciDevice->SetupAtomicOp.Enable_AtomicOpRequester;
> 
> -        }
> 
> -      }
> 
> -      //
> 
> -      // the enabling of AtomicOp Egress Blocking is not applicable to a non-bridge
> 
> -      // device
> 
> -      //
> 
> -    }
> 
> -    DEBUG ((
> 
> -      DEBUG_INFO,
> 
> -      "AtomicOp=%d,",
> 
> -      PcieDev.Bits.AtomicOpRequester
> 
> -      ));
> 
> -
> 
> -    //
> 
> -    // 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.DeviceControl2.Uint16 = PcieDev.Uint16;
> 
> -    } else {
> 
> -      ReportPciWriteError (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, Offset);
> 
> -    }
> 
> -  } else {
> 
> -    DEBUG (( DEBUG_INFO, "No AtomicOp,"));
> 
> -  }
> 
> -
> 
> -  return Status;
> 
> -}
> 
> -
> 
> -/**
> 
> -  The main routine which process the PCI feature LTR enable/disable 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
> 
> -SetupLtr (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
> 
> -  )
> 
> -{
> 
> -  PCI_REG_PCIE_DEVICE_CAPABILITY2 DeviceCap2;
> 
> -  //
> 
> -  // as per the PCI-Express Base Specification, in order to enable LTR mechanism
> 
> -  // in the upstream ports, all the upstream ports and its downstream ports has
> 
> -  // to support the LTR mechanism reported in its Device Capability 2 register
> 
> -  //
> 
> -  DeviceCap2.Uint32 = PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Uint32;
> 
> -
> 
> -  if (PciExpressConfigurationTable) {
> 
> -    //
> 
> -    // in this phase establish 2 requirements:
> 
> -    // (1) all the PCI devices in the hierarchy supports the LTR mechanism
> 
> -    // (2) check and record any device-specific platform policy that wants to
> 
> -    //     enable the LTR mechanism
> 
> -    //
> 
> -    if (!PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Bits.LtrMechanism) {
> 
> -
> 
> -      //
> 
> -      // it starts with the assumption that all the PCI devices support LTR mechanism
> 
> -      // and negates the flag if any PCI device Device Capability 2 register advertizes
> 
> -      // as not supported
> 
> -      //
> 
> -      PciExpressConfigurationTable->LtrSupported = FALSE;
> 
> -    }
> 
> -
> 
> -    if (PciDevice->SetupLtr == TRUE) {
> 
> -      //
> 
> -      // it starts with the assumption that device-specific platform policy would
> 
> -      // be set to LTR disable, and negates the flag if any PCI device platform
> 
> -      // policy wants to override to enable the LTR mechanism
> 
> -      //
> 
> -      PciExpressConfigurationTable->LtrEnable = TRUE;
> 
> -    }
> 
> -  } else {
> 
> -    //
> 
> -    // in case of RCiEP device or the bridge device with out any child device,
> 
> -    // overrule the device policy if the device in not capable
> 
> -    //
> 
> -    if (!PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Bits.LtrMechanism
> 
> -        && PciDevice->SetupLtr == TRUE) {
> 
> -      PciDevice->SetupLtr = FALSE;
> 
> -    }
> 
> -    //
> 
> -    // for any bridge device which is Hot-Plug capable, it is expected that platform
> 
> -    // will not enforce the enabling of LTR mechanism only for the bridge device
> 
> -    //
> 
> -  }
> 
> -
> 
> -  DEBUG (( DEBUG_INFO, "LTR En: %d (LTR Cap: %d),",
> 
> -    PciDevice->SetupLtr ? 1 : 0,
> 
> -    PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Bits.LtrMechanism
> 
> -    ));
> 
> -  return EFI_SUCCESS;
> 
> -}
> 
> -
> 
> -EFI_STATUS
> 
> -ReSetupLtr (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
> 
> -  )
> 
> -{
> 
> -  //
> 
> -  // not applicable to RCiEP device...
> 
> -  // for the bridge device without any child device, the policy is already overruled
> 
> -  // based on capability in the above routine
> 
> -  //
> 
> -  if (PciExpressConfigurationTable) {
> 
> -    //
> 
> -    // in this phase align the device policy to enable LTR policy of any PCI device
> 
> -    // in the tree if all the devices are capable to support the LTR mechanism
> 
> -    //
> 
> -    if (PciExpressConfigurationTable->LtrSupported == TRUE
> 
> -        && PciExpressConfigurationTable->LtrEnable == TRUE
> 
> -    ) {
> 
> -      PciDevice->SetupLtr = TRUE;
> 
> -    } else {
> 
> -      PciDevice->SetupLtr = FALSE;
> 
> -    }
> 
> -  }
> 
> -
> 
> -  DEBUG (( DEBUG_INFO, "LTR En: %d (LTR Cap: %d),",
> 
> -    PciDevice->SetupLtr ? 1 : 0,
> 
> -    PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Bits.LtrMechanism
> 
> -    ));
> 
> -  return EFI_SUCCESS;
> 
> -}
> 
> -
> 
> -/**
> 
> -  Program the PCI Device Control 2 register LTR mechanism 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
> 
> -ProgramLtr (
> 
> -  IN PCI_IO_DEVICE          *PciDevice,
> 
> -  IN VOID                   *PciExFeatureConfiguration
> 
> -  )
> 
> -{
> 
> -  PCI_REG_PCIE_DEVICE_CONTROL2  PcieDev;
> 
> -  UINT32                        Offset;
> 
> -  EFI_STATUS                    Status;
> 
> -  EFI_TPL                       OldTpl;
> 
> -
> 
> -  PcieDev.Uint16 = 0;
> 
> -  Offset = PciDevice->PciExpressCapabilityOffset +
> 
> -               OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2);
> 
> -  Status = PciDevice->PciIo.Pci.Read (
> 
> -                                  &PciDevice->PciIo,
> 
> -                                  EfiPciIoWidthUint16,
> 
> -                                  Offset,
> 
> -                                  1,
> 
> -                                  &PcieDev.Uint16
> 
> -                                  );
> 
> -  ASSERT (Status == EFI_SUCCESS);
> 
> -
> 
> -  if (PciDevice->SetupLtr != (BOOLEAN) PcieDev.Bits.LtrMechanism) {
> 
> -    PcieDev.Bits.LtrMechanism = PciDevice->SetupLtr ? 1 : 0;
> 
> -    DEBUG (( DEBUG_INFO, "LTR=%d,", PcieDev.Bits.LtrMechanism));
> 
> -
> 
> -    //
> 
> -    // 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.DeviceControl2.Uint16 = PcieDev.Uint16;
> 
> -    } else {
> 
> -      ReportPciWriteError (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, Offset);
> 
> -    }
> 
> -  } else {
> 
> -    DEBUG (( DEBUG_INFO, "no LTR,"));
> 
> -  }
> 
> -
> 
> -  return Status;
> 
> -}
> 
> -
> 
> -/**
> 
> -  The main routine to setup the PCI Express feature Extended Tag 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
> 
> -SetupExtTag (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
> 
> -  )
> 
> -{
> 
> -  PCI_REG_PCIE_DEVICE_CAPABILITY2 DeviceCap2;
> 
> -  PCI_REG_PCIE_DEVICE_CAPABILITY  DeviceCap;
> 
> -  EFI_PCI_EXPRESS_EXTENDED_TAG    PciExpressExtendedTag;
> 
> -
> 
> -  DeviceCap.Uint32 = PciDevice->PciExpressCapabilityStructure.DeviceCapability.Uint32;
> 
> -  DeviceCap2.Uint32 = PciDevice->PciExpressCapabilityStructure.DeviceCapability2.Uint32;
> 
> -  //
> 
> -  // The PCI Express feature Extended Tag has to be maintained common from a
> 
> -  // root bridge device to all its child devices.
> 
> -  // The Device Capability 2 register is used to determine the 10b Extended Tag
> 
> -  // capability of a device. The device capability register is used to determine
> 
> -  // 5b/8b Extended Tag capability of a device
> 
> -  //
> 
> -  if (DeviceCap2.Bits.TenBitTagCompleterSupported & DeviceCap2.Bits.TenBitTagRequesterSupported) {
> 
> -    //
> 
> -    // device supports the 10b Extended Tag capability
> 
> -    //
> 
> -    PciExpressExtendedTag = EFI_PCI_EXPRESS_EXTENDED_TAG_10BIT;
> 
> -  } else {
> 
> -    if (DeviceCap.Bits.ExtendedTagField) {
> 
> -      PciExpressExtendedTag = EFI_PCI_EXPRESS_EXTENDED_TAG_8BIT;
> 
> -    } else {
> 
> -      PciExpressExtendedTag = EFI_PCI_EXPRESS_EXTENDED_TAG_5BIT;
> 
> -    }
> 
> -  }
> 
> -  if (PciDevice->SetupExtTag == EFI_PCI_EXPRESS_EXTENDED_TAG_AUTO) {
> 
> -    PciDevice->SetupExtTag = PciExpressExtendedTag;
> 
> -  }
> 
> -  //
> 
> -  // in case of PCI Bridge and its child devices
> 
> -  //
> 
> -  if (PciExpressConfigurationTable) {
> 
> -    //
> 
> -    // align the Extended Tag value as per the device supported value
> 
> -    //
> 
> -    PciExpressConfigurationTable->ExtendedTag = MIN (
> 
> -                                                  PciExpressExtendedTag,
> 
> -                                                  PciExpressConfigurationTable->ExtendedTag
> 
> -                                                  );
> 
> -    //
> 
> -    // check for any invalid platform policy request for the device; if true than
> 
> -    // align with the device capability value. Else align as per platform request
> 
> -    //
> 
> -    if (PciDevice->SetupExtTag > PciExpressConfigurationTable->ExtendedTag) {
> 
> -      //
> 
> -      // setup the device Extended Tag to common value supported by all the devices
> 
> -      //
> 
> -      PciDevice->SetupExtTag = PciExpressConfigurationTable->ExtendedTag;
> 
> -    }
> 
> -    //
> 
> -    // if the platform policy is to downgrade the device's Extended Tag value than
> 
> -    // all the other devices in the PCI tree including the root bridge will be align
> 
> -    // with this device override value
> 
> -    //
> 
> -    if (PciDevice->SetupExtTag < PciExpressConfigurationTable->ExtendedTag) {
> 
> -      PciExpressConfigurationTable->ExtendedTag = PciDevice->SetupExtTag;
> 
> -    }
> 
> -  } else {
> 
> -    //
> 
> -    // in case of RCiEP devices or the bridge device without any child, overrule
> 
> -    // the Extended Tag device policy if it does not match with its capability
> 
> -    //
> 
> -    PciDevice->SetupExtTag = MIN (
> 
> -                              PciDevice->SetupExtTag,
> 
> -                              PciExpressExtendedTag
> 
> -                              );
> 
> -  }
> 
> -
> 
> -  DEBUG ((
> 
> -    DEBUG_INFO,
> 
> -    "ExtTag: %d [cap:%d],",
> 
> -    PciDevice->SetupExtTag,
> 
> -    PciExpressExtendedTag
> 
> -    ));
> 
> -  return EFI_SUCCESS;
> 
> -}
> 
> -
> 
> -/**
> 
> -  Additional routine to setup the PCI Express feature Extended Tag in complaince
> 
> -  with the PCI Express Base specification Revision, a common value for all the
> 
> -  devices in the PCI hierarchy.
> 
> -
> 
> -  @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
> 
> -AlignExtTag (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
> 
> -  )
> 
> -{
> 
> -  if (PciExpressConfigurationTable) {
> 
> -    //
> 
> -    // align the Extended Tag value to a common value among all the devices
> 
> -    //
> 
> -    PciDevice->SetupExtTag = MIN (
> 
> -                              PciDevice->SetupExtTag,
> 
> -                              PciExpressConfigurationTable->ExtendedTag
> 
> -                              );
> 
> -  }
> 
> -
> 
> -  DEBUG ((
> 
> -    DEBUG_INFO,
> 
> -    "ExtTag: %d,",
> 
> -    PciDevice->SetupExtTag
> 
> -    ));
> 
> -  return EFI_SUCCESS;
> 
> -}
> 
> -
> 
> -/**
> 
> -  Program the PCI Device Control 2 register for 10b Extended Tag value, or the
> 
> -  Device Control register for 5b/8b Extended Tag 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
> 
> -ProgramExtTag (
> 
> -  IN PCI_IO_DEVICE          *PciDevice,
> 
> -  IN VOID                   *PciExFeatureConfiguration
> 
> -  )
> 
> -{
> 
> -  PCI_REG_PCIE_DEVICE_CONTROL   DevCtl;
> 
> -  PCI_REG_PCIE_DEVICE_CONTROL2  DevCtl2;
> 
> -  UINT32                        Offset;
> 
> -  UINT32                        Offset2;
> 
> -  BOOLEAN                       OverrideDevCtl;
> 
> -  BOOLEAN                       OverrideDevCtl2;
> 
> -  EFI_STATUS                    Status;
> 
> -  EFI_TPL                       OldTpl;
> 
> -
> 
> -  //
> 
> -  // read the Device Control register for the Extended Tag Field Enable
> 
> -  //
> 
> -  DevCtl.Uint16 = 0;
> 
> -  Offset = PciDevice->PciExpressCapabilityOffset +
> 
> -              OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl);
> 
> -  Status = PciDevice->PciIo.Pci.Read (
> 
> -                                  &PciDevice->PciIo,
> 
> -                                  EfiPciIoWidthUint16,
> 
> -                                  Offset,
> 
> -                                  1,
> 
> -                                  &DevCtl.Uint16
> 
> -                                  );
> 
> -  ASSERT (Status == EFI_SUCCESS);
> 
> -
> 
> -  OverrideDevCtl = FALSE;
> 
> -  //
> 
> -  // read the Device COntrol 2 register for the 10-Bit Tag Requester Enable
> 
> -  //
> 
> -  DevCtl2.Uint16 = 0;
> 
> -  Offset2 = PciDevice->PciExpressCapabilityOffset +
> 
> -              OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2);
> 
> -  Status = PciDevice->PciIo.Pci.Read (
> 
> -                                  &PciDevice->PciIo,
> 
> -                                  EfiPciIoWidthUint16,
> 
> -                                  Offset2,
> 
> -                                  1,
> 
> -                                  &DevCtl2.Uint16
> 
> -                                  );
> 
> -  ASSERT (Status == EFI_SUCCESS);
> 
> -
> 
> -  OverrideDevCtl2 = FALSE;
> 
> -
> 
> -  if (PciDevice->SetupExtTag == EFI_PCI_EXPRESS_EXTENDED_TAG_5BIT) {
> 
> -    if (DevCtl.Bits.ExtendedTagField) {
> 
> -      DevCtl.Bits.ExtendedTagField = 0;
> 
> -      OverrideDevCtl = TRUE;
> 
> -    }
> 
> -
> 
> -    if (DevCtl2.Bits.TenBitTagRequesterEnable) {
> 
> -      DevCtl2.Bits.TenBitTagRequesterEnable = 0;
> 
> -      OverrideDevCtl2 = TRUE;
> 
> -    }
> 
> -  }
> 
> -  if (PciDevice->SetupExtTag == EFI_PCI_EXPRESS_EXTENDED_TAG_8BIT) {
> 
> -    if (!DevCtl.Bits.ExtendedTagField) {
> 
> -      DevCtl.Bits.ExtendedTagField = 1;
> 
> -      OverrideDevCtl = TRUE;
> 
> -    }
> 
> -    if (DevCtl2.Bits.TenBitTagRequesterEnable) {
> 
> -      DevCtl2.Bits.TenBitTagRequesterEnable = 0;
> 
> -      OverrideDevCtl2 = TRUE;
> 
> -    }
> 
> -  }
> 
> -  if (PciDevice->SetupExtTag == EFI_PCI_EXPRESS_EXTENDED_TAG_10BIT) {
> 
> -    if (!DevCtl2.Bits.TenBitTagRequesterEnable) {
> 
> -      DevCtl2.Bits.TenBitTagRequesterEnable = 1;
> 
> -      OverrideDevCtl2 = TRUE;
> 
> -    }
> 
> -  }
> 
> -
> 
> -  if (OverrideDevCtl) {
> 
> -
> 
> -    DEBUG (( DEBUG_INFO, "ExtTag=%d,", DevCtl.Bits.ExtendedTagField));
> 
> -
> 
> -    //
> 
> -    // 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,
> 
> -                                    &DevCtl.Uint16
> 
> -                                    );
> 
> -    //
> 
> -    // Restore TPL to its original level
> 
> -    //
> 
> -    gBS->RestoreTPL (OldTpl);
> 
> -
> 
> -    if (!EFI_ERROR(Status)) {
> 
> -      PciDevice->PciExpressCapabilityStructure.DeviceControl.Uint16 = DevCtl.Uint16;
> 
> -    } else {
> 
> -      ReportPciWriteError (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, Offset);
> 
> -    }
> 
> -  } else {
> 
> -    DEBUG (( DEBUG_INFO, "no ExtTag (%d),", DevCtl.Bits.ExtendedTagField));
> 
> -  }
> 
> -
> 
> -  if (OverrideDevCtl2) {
> 
> -
> 
> -    DEBUG (( DEBUG_INFO, "10bExtTag=%d,", DevCtl2.Bits.TenBitTagRequesterEnable));
> 
> -
> 
> -    //
> 
> -    // 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,
> 
> -                                    Offset2,
> 
> -                                    1,
> 
> -                                    &DevCtl2.Uint16
> 
> -                                    );
> 
> -    //
> 
> -    // Restore TPL to its original level
> 
> -    //
> 
> -    gBS->RestoreTPL (OldTpl);
> 
> -
> 
> -    if (!EFI_ERROR(Status)) {
> 
> -      PciDevice->PciExpressCapabilityStructure.DeviceControl2.Uint16 = DevCtl2.Uint16;
> 
> -    } else {
> 
> -      ReportPciWriteError (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, Offset2);
> 
> -    }
> 
> -  } else {
> 
> -    DEBUG (( DEBUG_INFO, "no 10bExtTag (%d),", DevCtl2.Bits.TenBitTagRequesterEnable));
> 
> -  }
> 
> -
> 
> -  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;
> 
> -}
> 
> -
> 
> -/**
> 
> -  The main routine to setup the PCI Express feature Common Clock configuration
> 
> -  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
> 
> -SetupCommonClkCfg (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
> 
> -  )
> 
> -{
> 
> -  PCI_REG_PCIE_LINK_STATUS                      LinkSts;
> 
> -
> 
> -  LinkSts.Uint16 = PciDevice->PciExpressCapabilityStructure.LinkStatus.Uint16;
> 
> -
> 
> -  //
> 
> -  // Common Clock Configuration is only applicable to root bridge and its child
> 
> -  // devices. Not applicable to empty bridge devices or RCiEP devices
> 
> -  //
> 
> -  if (PciExpressConfigurationTable) {
> 
> -    if (PciDevice->SetupCcc == EFI_PCI_EXPRESS_CLK_CFG_AUTO) {
> 
> -      //
> 
> -      // as per the PCI Express Base Specification, the link status register
> 
> -      // slot clock configuration of the opposing side of link devices indicate
> 
> -      // the clock configuration properly; hence rely on this data to configure
> 
> -      // the link's clock configuration
> 
> -      //
> 
> -      if (LinkSts.Bits.SlotClockConfiguration) {
> 
> -        PciExpressConfigurationTable->CommonClockConfiguration = TRUE;
> 
> -      } else {
> 
> -        PciExpressConfigurationTable->CommonClockConfiguration = FALSE;
> 
> -      }
> 
> -    } else if (PciDevice->SetupCcc == EFI_PCI_EXPRESS_CLK_CFG_ASYNCH) {
> 
> -      //
> 
> -      // platform override to any device shall change for other device on the
> 
> -      // link, the clock configuration has to be maintained common across all
> 
> -      // the devices
> 
> -      //
> 
> -      PciExpressConfigurationTable->CommonClockConfiguration = FALSE;
> 
> -    } else {
> 
> -      PciExpressConfigurationTable->CommonClockConfiguration = TRUE;
> 
> -    }
> 
> -  }
> 
> -  return EFI_SUCCESS;
> 
> -}
> 
> -
> 
> -/**
> 
> -  Program the PCIe Link Control register Coomon Clock Configuration 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
> 
> -ProgramCcc (
> 
> -  IN PCI_IO_DEVICE                            *PciDevice,
> 
> -  IN PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE *PciExFeatureConfiguration
> 
> -  )
> 
> -{
> 
> -  PCI_REG_PCIE_LINK_CONTROL     LinkCtl;
> 
> -  UINT32                        Offset;
> 
> -  EFI_STATUS                    Status;
> 
> -  EFI_TPL                       OldTpl;
> 
> -
> 
> -  //
> 
> -  // Common Clock Configuration 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);
> 
> -
> 
> -  //
> 
> -  // in case Common Clock Configuration is required to be programmed in the
> 
> -  // downstream ports from the root bridge devices in the heirarchy
> 
> -  //
> 
> -  if (PciExFeatureConfiguration->CommonClockConfiguration == TRUE) {
> 
> -    if (LinkCtl.Bits.CommonClockConfiguration == 0) {
> 
> -      LinkCtl.Bits.CommonClockConfiguration = 1;
> 
> -      //
> 
> -      // current clock mode does not match hence retrain of the link at bridge device
> 
> -      // is required
> 
> -      //
> 
> -      PciExFeatureConfiguration->LinkReTrain = TRUE;
> 
> -    }
> 
> -  } else {
> 
> -    //
> 
> -    // in case the opposing devices of the PCI link have different reference clock
> 
> -    // set the link control register CCC field accordingly
> 
> -    //
> 
> -    if (LinkCtl.Bits.CommonClockConfiguration) {
> 
> -      LinkCtl.Bits.CommonClockConfiguration = 0;
> 
> -      //
> 
> -      // current clock mode does not match hence retrain of the link at bridge device
> 
> -      // is required
> 
> -      //
> 
> -      PciExFeatureConfiguration->LinkReTrain = TRUE;
> 
> -    }
> 
> -  }
> 
> -  //
> 
> -  // use the retrain flag as a sigm to also update the CCC of the link register
> 
> -  //
> 
> -  if (PciExFeatureConfiguration->LinkReTrain == TRUE) {
> 
> -    DEBUG ((
> 
> -      DEBUG_INFO,
> 
> -      "CCC: %d,",
> 
> -      LinkCtl.Bits.CommonClockConfiguration
> 
> -      ));
> 
> -    //
> 
> -    // 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 {
> 
> -    PciDevice->PciExpressCapabilityStructure.LinkControl.Uint16 = LinkCtl.Uint16;
> 
> -    DEBUG ((
> 
> -      DEBUG_INFO,
> 
> -      "No CCC (%d),",
> 
> -      LinkCtl.Bits.CommonClockConfiguration
> 
> -      ));
> 
> -  }
> 
> -  return EFI_SUCCESS;
> 
> -}
> 
> -
> 
> -/**
> 
> -  Second phase of programming for Common Clock COnfiguration, conditoonally done
> 
> -  only on the downstream ports (bridge devices only).
> 
> -
> 
> -  @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
> 
> -EnforceCcc (
> 
> -  IN PCI_IO_DEVICE                            *PciDevice,
> 
> -  IN PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE *PciExFeatureConfiguration
> 
> -  )
> 
> -{
> 
> -  PCI_REG_PCIE_LINK_CONTROL     LinkCtl;
> 
> -  PCI_REG_PCIE_LINK_STATUS      LinkSts;
> 
> -  PCI_REG_PCIE_CAPABILITY       PciExCap;
> 
> -  UINT32                        Offset;
> 
> -  EFI_STATUS                    Status;
> 
> -  EFI_TPL                       OldTpl;
> 
> -
> 
> -  //
> 
> -  // Common Clock Configuration is only applicable to root bridge and its child
> 
> -  // devices. Not applicable to empty bridge devices or RCiEP devices
> 
> -  //
> 
> -  if (!PciExFeatureConfiguration) {
> 
> -    return EFI_SUCCESS;
> 
> -  }
> 
> -  PciExCap.Uint16 = PciDevice->PciExpressCapabilityStructure.Capability.Uint16;
> 
> -  LinkCtl.Uint16 = PciDevice->PciExpressCapabilityStructure.LinkControl.Uint16;
> 
> -
> 
> -  //
> 
> -  // retrain the bridge device (downstream ports including the root port)
> 
> -  //
> 
> -  if (PciExFeatureConfiguration->LinkReTrain == TRUE) {
> 
> -    if (IS_PCI_BRIDGE (&PciDevice->Pci)) {
> 
> -      //
> 
> -      // retrain of the PCI link happens for CCC change only on the downstream
> 
> -      // ports
> 
> -      //
> 
> -      if (
> 
> -        PciExCap.Bits.DevicePortType == PCIE_DEVICE_PORT_TYPE_ROOT_PORT
> 
> -        || PciExCap.Bits.DevicePortType == PCIE_DEVICE_PORT_TYPE_DOWNSTREAM_PORT
> 
> -        ) {
> 
> -        LinkCtl.Bits.RetrainLink = 1;
> 
> -        Offset = PciDevice->PciExpressCapabilityOffset +
> 
> -                     OFFSET_OF (PCI_CAPABILITY_PCIEXP, LinkControl);
> 
> -        //
> 
> -        // 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)) {
> 
> -          //
> 
> -          // poll the link status register for the link retrain to be complete
> 
> -          //
> 
> -          Offset = PciDevice->PciExpressCapabilityOffset +
> 
> -                               OFFSET_OF (PCI_CAPABILITY_PCIEXP, LinkStatus);
> 
> -          do {
> 
> -            Status = PciDevice->PciIo.Pci.Read (
> 
> -                                            &PciDevice->PciIo,
> 
> -                                            EfiPciIoWidthUint16,
> 
> -                                            Offset,
> 
> -                                            1,
> 
> -                                            &LinkSts.Uint16
> 
> -                                            );
> 
> -            ASSERT (Status == EFI_SUCCESS);
> 
> -          } while (LinkSts.Bits.LinkTraining);
> 
> -        } else {
> 
> -          ReportPciWriteError (PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber, Offset);
> 
> -          return Status;
> 
> -        }
> 
> -      }
> 
> -      //
> 
> -      // ignore the upstream bridge devices
> 
> -      //
> 
> -    }
> 
> -    //
> 
> -    // not applicable to endpoint devices
> 
> -    //
> 
> -  }
> 
> -  return EFI_SUCCESS;
> 
> -}
> 
> -
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h
> deleted file mode 100644
> index 33df337..0000000
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h
> +++ /dev/null
> @@ -1,399 +0,0 @@
> -/** @file
> 
> -  PCI standard feature support functions implementation for PCI Bus module..
> 
> -
> 
> -Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> 
> -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
> 
> -  device-specific platform policy, as well as in complaince with the PCI Base
> 
> -  specification Revision 4, that aligns the value for the entire PCI heirarchy
> 
> -  starting from its physical PCI Root port / Bridge device.
> 
> -
> 
> -  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
> 
> -  @param PciFeaturesConfigurationTable  pointer to PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE
> 
> -
> 
> -  @retval EFI_SUCCESS                   processing of PCI feature Max_Payload_Size
> 
> -                                        is successful.
> 
> -**/
> 
> -EFI_STATUS
> 
> -SetupMaxPayloadSize (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
> 
> -  );
> 
> -
> 
> -EFI_STATUS
> 
> -CasMaxPayloadSize (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
> 
> -  );
> 
> -
> 
> -/**
> 
> -  Overrides the PCI Device Control register Max_Read_Req_Size 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 controller.
> 
> -  @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
> 
> -ProgramMaxPayloadSize (
> 
> -  IN PCI_IO_DEVICE          *PciDevice,
> 
> -  IN VOID                   *PciExFeatureConfiguration
> 
> -  );
> 
> -
> 
> -
> 
> -EFI_STATUS
> 
> -ConditionalCasMaxReadReqSize (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
> 
> -  );
> 
> -
> 
> -/**
> 
> -  The main routine which process the PCI feature Max_Read_Req_Size as per the
> 
> -  device-specific platform policy, as well as in complaince with the PCI Base
> 
> -  specification Revision 4, that aligns the value for the entire PCI heirarchy
> 
> -  starting from its physical PCI Root port / Bridge device.
> 
> -
> 
> -  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
> 
> -  @param PciConfigPhase                 for the PCI feature configuration phases:
> 
> -                                        PciExpressFeatureSetupPhase & PciExpressFeatureEntendedSetupPhase
> 
> -  @param PciFeaturesConfigurationTable  pointer to PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE
> 
> -
> 
> -  @retval EFI_SUCCESS                   processing of PCI feature Max_Read_Req_Size
> 
> -                                        is successful.
> 
> -**/
> 
> -EFI_STATUS
> 
> -SetupMaxReadReqSize (
> 
> -  IN  PCI_IO_DEVICE                           *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
> 
> -  );
> 
> -
> 
> -/**
> 
> -  Overrides the PCI Device Control register Max_Read_Req_Size 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 controller.
> 
> -  @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
> 
> -ProgramMaxReadReqSize (
> 
> -  IN PCI_IO_DEVICE          *PciDevice,
> 
> -  IN VOID                   *PciExFeatureConfiguration
> 
> -  );
> 
> -
> 
> -/**
> 
> -  Overrides the PCI Device Control register Relax Order 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
> 
> -ProgramRelaxOrder (
> 
> -  IN PCI_IO_DEVICE          *PciDevice,
> 
> -  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
> 
> -  );
> 
> -
> 
> -/**
> 
> -  The main routine which process the PCI feature Completion Timeout as per the
> 
> -  device-specific platform policy, as well as in complaince with the PCI Base
> 
> -  specification Revision 4.
> 
> -
> 
> -  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
> 
> -  @param PciConfigPhase                 for the PCI feature configuration phases:
> 
> -                                        PciExpressFeatureSetupPhase & PciExpressFeatureEntendedSetupPhase
> 
> -
> 
> -  @retval EFI_SUCCESS                   processing of PCI feature CTO is successful.
> 
> -**/
> 
> -EFI_STATUS
> 
> -SetupCompletionTimeout (
> 
> -  IN PCI_IO_DEVICE          *PciDevice,
> 
> -  IN VOID                   *PciExFeatureConfiguration
> 
> -  );
> 
> -
> 
> -/**
> 
> -  Overrides the PCI Device Control2 register Completion Timeout range; 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
> 
> -ProgramCompletionTimeout (
> 
> -  IN PCI_IO_DEVICE          *PciDevice,
> 
> -  IN VOID                   *PciExFeatureConfiguration
> 
> -  );
> 
> -
> 
> -/**
> 
> -  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 specification.
> 
> -
> 
> -  @param PciDevice                      A pointer to the PCI_IO_DEVICE.
> 
> -  @param PciExFeatureConfiguration      pointer to common configuration table to
> 
> -                                        initialize the PCI Express feature
> 
> -
> 
> -  @retval EFI_SUCCESS                   bridge device routing capability is 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 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
> 
> -ProgramAtomicOp (
> 
> -  IN PCI_IO_DEVICE          *PciDevice,
> 
> -  IN VOID                   *PciExFeatureConfiguration
> 
> -  );
> 
> -
> 
> -/**
> 
> -  The main routine which process the PCI feature LTR enable/disable 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
> 
> -SetupLtr (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
> 
> -  );
> 
> -
> 
> -EFI_STATUS
> 
> -ReSetupLtr (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
> 
> -  );
> 
> -
> 
> -/**
> 
> -  Program the PCI Device Control 2 register LTR mechanism 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
> 
> -ProgramLtr (
> 
> -  IN PCI_IO_DEVICE          *PciDevice,
> 
> -  IN VOID                   *PciExFeatureConfiguration
> 
> -  );
> 
> -
> 
> -/**
> 
> -  The main routine to setup the PCI Express feature Extended Tag 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
> 
> -SetupExtTag (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
> 
> -  );
> 
> -
> 
> -/**
> 
> -  Additional routine to setup the PCI Express feature Extended Tag in complaince
> 
> -  with the PCI Express Base specification Revision, a common value for all the
> 
> -  devices in the PCI hierarchy.
> 
> -
> 
> -  @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
> 
> -AlignExtTag (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciFeaturesConfigurationTable
> 
> -  );
> 
> -
> 
> -/**
> 
> -  Program the PCI Device Control 2 register for 10b Extended Tag value, or the
> 
> -  Device Control register for 5b/8b Extended Tag 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
> 
> -ProgramExtTag (
> 
> -  IN PCI_IO_DEVICE          *PciDevice,
> 
> -  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
> 
> -  );
> 
> -
> 
> -/**
> 
> -  The main routine to setup the PCI Express feature Common Clock configuration
> 
> -  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
> 
> -SetupCommonClkCfg (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressConfigurationTable
> 
> -  );
> 
> -
> 
> -/**
> 
> -  Program the PCIe Link Control register Coomon Clock Configuration 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
> 
> -ProgramCcc (
> 
> -  IN PCI_IO_DEVICE                            *PciDevice,
> 
> -  IN PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE *PciExFeatureConfiguration
> 
> -  );
> 
> -
> 
> -/**
> 
> -  Second phase of programming for Common Clock COnfiguration, conditoonally done
> 
> -  only on the downstream ports (bridge devices only).
> 
> -
> 
> -  @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
> 
> -EnforceCcc (
> 
> -  IN PCI_IO_DEVICE                            *PciDevice,
> 
> -  IN PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE *PciExFeatureConfiguration
> 
> -  );
> 
> -#endif
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c
> deleted file mode 100644
> index 4d3641c..0000000
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c
> +++ /dev/null
> @@ -1,1019 +0,0 @@
> -/** @file
> 
> -  PCI standard feature support functions implementation for PCI Bus module..
> 
> -
> 
> -Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> 
> -SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> -
> 
> -**/
> 
> -
> 
> -#include "PciBus.h"
> 
> -#include "PciFeatureSupport.h"
> 
> -#include "PciExpressFeatures.h"
> 
> -
> 
> -/**
> 
> -  Hold the current instance of Root Bridge IO protocol Handle
> 
> -**/
> 
> -EFI_HANDLE                                  mRootBridgeHandle;
> 
> -
> 
> -/**
> 
> -  A gobal pointer to BRIDGE_DEVICE_NODE buffer to track all the primary physical
> 
> -  PCI Root Ports (PCI Controllers) for a given PCI Root Bridge instance while
> 
> -  enumerating to configure the PCI features
> 
> -**/
> 
> -LIST_ENTRY                                  mRootBridgeDeviceList;
> 
> -
> 
> -/**
> 
> - global list to indicate the supported PCI Express features of this driver, it
> 
> - is expected to be overridden based on the platform request
> 
> -**/
> 
> -EFI_PCI_EXPRESS_PLATFORM_POLICY             mPciExpressPlatformPolicy = {
> 
> -    //
> 
> -    // support for PCI Express feature - Max. Payload Size
> 
> -    //
> 
> -    TRUE,
> 
> -    //
> 
> -    // support for PCI Express feature - Max. Read Request Size
> 
> -    //
> 
> -    TRUE,
> 
> -    //
> 
> -    // support for PCI Express feature - Extended Tag
> 
> -    //
> 
> -    TRUE,
> 
> -    //
> 
> -    // support for PCI Express feature - Relax Order
> 
> -    //
> 
> -    TRUE,
> 
> -    //
> 
> -    // support for PCI Express feature - No-Snoop
> 
> -    //
> 
> -    TRUE,
> 
> -    //
> 
> -    // support for PCI Express feature - ASPM state
> 
> -    //
> 
> -    TRUE,
> 
> -    //
> 
> -    // support for PCI Express feature - Common Clock Configuration
> 
> -    //
> 
> -    TRUE,
> 
> -    //
> 
> -    // support for PCI Express feature - Extended Sync
> 
> -    //
> 
> -    FALSE,
> 
> -    //
> 
> -    // support for PCI Express feature - Atomic Op
> 
> -    //
> 
> -    TRUE,
> 
> -    //
> 
> -    // support for PCI Express feature - LTR
> 
> -    //
> 
> -    TRUE,
> 
> -    //
> 
> -    // support for PCI Express feature - PTM
> 
> -    //
> 
> -    FALSE,
> 
> -    //
> 
> -    // support for PCI Express feature - Completion Timeout
> 
> -    //
> 
> -    TRUE,
> 
> -    //
> 
> -    // support for PCI Express feature - Clock Power Management
> 
> -    //
> 
> -    FALSE,
> 
> -    //
> 
> -    // support for PCI Express feature - L1 PM Substates
> 
> -    //
> 
> -    FALSE
> 
> -};
> 
> -
> 
> -//
> 
> -// indicates the driver has completed query to platform on the list of supported
> 
> -// PCI features to be configured
> 
> -//
> 
> -BOOLEAN   mPciExpressGetPlatformPolicyComplete = FALSE;
> 
> -
> 
> -//
> 
> -// PCI Express feature initialization phase handle routines
> 
> -//
> 
> -PCI_EXPRESS_FEATURE_INITIALIZATION_POINT  mPciExpressFeatureInitializationList[] = {
> 
> -  {
> 
> -    PciExpressFeatureSetupPhase,          PciExpressCcc,        SetupCommonClkCfg
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureEntendedSetupPhase,  PciExpressCcc,        ProgramCcc
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureProgramPhase,        PciExpressCcc,        EnforceCcc
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureSetupPhase,          PciExpressAspm,       SetupAspm
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureEntendedSetupPhase,  PciExpressAspm,       AlignAspm
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureProgramPhase,        PciExpressAspm,       ProgramAspm
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureSetupPhase,          PciExpressMps,        SetupMaxPayloadSize
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureEntendedSetupPhase,  PciExpressMps,        CasMaxPayloadSize
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureProgramPhase,        PciExpressMps,        ProgramMaxPayloadSize
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureSetupPhase,          PciExpressMrrs,       SetupMaxReadReqSize
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureEntendedSetupPhase,  PciExpressMrrs,       ConditionalCasMaxReadReqSize
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureProgramPhase,        PciExpressMrrs,       ProgramMaxReadReqSize
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureProgramPhase,        PciExpressRelaxOrder, ProgramRelaxOrder
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureProgramPhase,        PciExpressNoSnoop,    ProgramNoSnoop
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureSetupPhase,          PciExpressCto,        SetupCompletionTimeout
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureProgramPhase,        PciExpressCto,        ProgramCompletionTimeout
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureSetupPhase,          PciExpressAtomicOp,   SetupAtomicOpRoutingSupport
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureProgramPhase,        PciExpressAtomicOp,   ProgramAtomicOp
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureSetupPhase,          PciExpressLtr,        SetupLtr
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureEntendedSetupPhase,  PciExpressLtr,        ReSetupLtr
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureProgramPhase,        PciExpressLtr,        ProgramLtr
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureSetupPhase,          PciExpressExtTag,     SetupExtTag
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureEntendedSetupPhase,  PciExpressExtTag,     AlignExtTag
> 
> -  },
> 
> -  {
> 
> -    PciExpressFeatureProgramPhase,        PciExpressExtTag,     ProgramExtTag
> 
> -  }
> 
> -};
> 
> -
> 
> -/**
> 
> -  Routine to serially dispatch the designated the PCI Express feature specific
> 
> -  functions defined for each of the configuration phase. The order for each phase
> 
> -  would be based entirely on the table mPciExpressFeatureInitializationList.
> 
> -
> 
> -  @param  PciDevice                       pointer to PCI_IO_DEVICE to identify device
> 
> -  @param  PciExFeatureConfigPhase         input configuration phase
> 
> -  @param  PciExpressFeatureConfiguration  used pointer to void to accomodate any PCI
> 
> -                                          Express feature specific data type
> 
> -  @retval EFI_STATUS                      output only from feature specific function
> 
> -                                          defined in the table mPciExpressFeatureInitializationList
> 
> -**/
> 
> -EFI_STATUS
> 
> -DispatchPciExpressInitializationFunctions (
> 
> -  IN PCI_IO_DEVICE                            *PciDevice,
> 
> -  IN PCI_EXPRESS_FEATURE_CONFIGURATION_PHASE  PciExFeatureConfigPhase,
> 
> -  IN VOID                                     *PciExpressFeatureConfiguration
> 
> -  )
> 
> -{
> 
> -  UINTN       idx;
> 
> -  EFI_STATUS  Status;
> 
> -  UINT8       *PciExpressPolicy;
> 
> -
> 
> -  for (
> 
> -      idx = 0, PciExpressPolicy = (UINT8*)&mPciExpressPlatformPolicy
> 
> -      ; idx < sizeof (mPciExpressFeatureInitializationList) / sizeof (PCI_EXPRESS_FEATURE_INITIALIZATION_POINT)
> 
> -      ; idx++
> 
> -      ){
> 
> -    if (
> 
> -        //
> 
> -        // match the configuration phase
> 
> -        //
> 
> -        mPciExpressFeatureInitializationList[idx].PciExpressFeatureConfigurationPhase == PciExFeatureConfigPhase
> 
> -        //
> 
> -        // check whether the PCI Express features is enabled
> 
> -        //
> 
> -        && PciExpressPolicy[mPciExpressFeatureInitializationList[idx].PciExpressFeatureId] == TRUE
> 
> -        ) {
> 
> -      Status =  mPciExpressFeatureInitializationList[idx].PciExpressFeatureConfigurationRoutine (
> 
> -                                                            PciDevice,
> 
> -                                                            PciExpressFeatureConfiguration
> 
> -                                                            );
> 
> -    }
> 
> -  }
> 
> -  return Status;
> 
> -}
> 
> -
> 
> -/**
> 
> -  Main routine to indicate platform selection of any of the other PCI features
> 
> -  to be configured by this driver
> 
> -
> 
> -  @retval TRUE    platform has selected the other PCI features to be configured
> 
> -          FALSE   platform has not selected any of the other PCI features
> 
> -**/
> 
> -BOOLEAN
> 
> -CheckPciExpressFeatureList (
> 
> -  )
> 
> -{
> 
> -  UINTN     length;
> 
> -  UINT8     *list;
> 
> -
> 
> -  for (
> 
> -      length = 0, list = (UINT8*)&mPciExpressPlatformPolicy
> 
> -      ; length < sizeof (EFI_PCI_EXPRESS_PLATFORM_POLICY)
> 
> -      ; length++
> 
> -      ) {
> 
> -    if (list[length]) {
> 
> -      return TRUE;
> 
> -    }
> 
> -  }
> 
> -  return FALSE;
> 
> -}
> 
> -
> 
> -/**
> 
> -  helper routine to wipe out the global PCI Express feature list
> 
> -**/
> 
> -VOID
> 
> -NegatePciExpressFeatureList (
> 
> -  )
> 
> -{
> 
> -  UINTN     length;
> 
> -  UINT8      *list;
> 
> -
> 
> -  for (
> 
> -      length = 0, list = (UINT8*)&mPciExpressPlatformPolicy
> 
> -      ; length < sizeof (EFI_PCI_EXPRESS_PLATFORM_POLICY)
> 
> -      ; length++
> 
> -      ) {
> 
> -    if (list[length]) {
> 
> -      list[length] = FALSE;
> 
> -    }
> 
> -  }
> 
> -}
> 
> -
> 
> -/**
> 
> -  Main routine to indicate whether the PCI Express feature initialization is
> 
> -  required or not
> 
> -
> 
> -  @retval TRUE    PCI Express feature initialization required
> 
> -          FALSE   PCI Express feature not required
> 
> -**/
> 
> -BOOLEAN
> 
> -IsPciExpressFeatureConfigurationRequired (
> 
> -  )
> 
> -{
> 
> -  EFI_STATUS    Status;
> 
> -
> 
> -  if (mPciExpressGetPlatformPolicyComplete) {
> 
> -    return CheckPciExpressFeatureList ();
> 
> -  }
> 
> -  //
> 
> -  // initialize the PCI Express feature data members
> 
> -  //
> 
> -  InitializeListHead (&mRootBridgeDeviceList);
> 
> -  //
> 
> -  // check the platform to configure the PCI Express features
> 
> -  //
> 
> -  mPciExpressGetPlatformPolicyComplete = TRUE;
> 
> -
> 
> -  Status = PciExpressPlatformGetPolicy ();
> 
> -  if (EFI_ERROR (Status)) {
> 
> -    //
> 
> -    // fail to obtain the PCI Express feature configuration from platform,
> 
> -    // negate the list to avoid any unwanted configuration
> 
> -    //
> 
> -    NegatePciExpressFeatureList ();
> 
> -    return FALSE;
> 
> -  }
> 
> -  //
> 
> -  // PCI Express feature configuration list is ready from platform
> 
> -  //
> 
> -  return TRUE;
> 
> -}
> 
> -
> 
> -
> 
> -/**
> 
> -  Indicates whether the set of PCI Express features selected by platform requires
> 
> -  extended setup, that has additional resources that would be allocated to align
> 
> -  all the devices in the PCI tree, and free the resources later.
> 
> -
> 
> -  @retval TRUE    PCI Express feature requires extended setup
> 
> -          FALSE   PCI Express feature does not require extended setup
> 
> -**/
> 
> -BOOLEAN
> 
> -IsPciExpressFeatureExtendedSetupRequired (
> 
> -  )
> 
> -{
> 
> -  UINTN   idx;
> 
> -  UINT8   *PciExpressPolicy;
> 
> -  //
> 
> -  // return TRUE only for those features which are required to be aligned with
> 
> -  // common values among all the devices in the PCI tree
> 
> -  //
> 
> -  for (
> 
> -      idx = 0, PciExpressPolicy = (UINT8*)&mPciExpressPlatformPolicy
> 
> -      ; idx < sizeof (mPciExpressFeatureInitializationList) / sizeof (PCI_EXPRESS_FEATURE_INITIALIZATION_POINT)
> 
> -      ; idx++
> 
> -  ){
> 
> -    if (
> 
> -        //
> 
> -        // match the configuration phase to extended setup phase
> 
> -        //
> 
> -        mPciExpressFeatureInitializationList[idx].PciExpressFeatureConfigurationPhase ==
> PciExpressFeatureEntendedSetupPhase
> 
> -        //
> 
> -        // check whether the PCI Express features is enabled
> 
> -        //
> 
> -        && PciExpressPolicy[mPciExpressFeatureInitializationList[idx].PciExpressFeatureId] == TRUE
> 
> -    ) {
> 
> -      return TRUE;
> 
> -    } else if (
> 
> -        //
> 
> -        // the PCI Express feature does not require extended setup phase but it
> 
> -        // does require global flag to track the AtomicOpRouting caoability to
> 
> -        // be tracked for all its bridge devices
> 
> -        //
> 
> -        idx == PciExpressAtomicOp
> 
> -        && PciExpressPolicy[idx] == TRUE
> 
> -        ) {
> 
> -      return TRUE;
> 
> -    }
> 
> -  }
> 
> -
> 
> -  return FALSE;
> 
> -}
> 
> -
> 
> -/**
> 
> - Helper routine to determine the existence of previously enumerated PCI device
> 
> -
> 
> - @retval  TRUE  PCI device exist
> 
> -          FALSE does not exist
> 
> -**/
> 
> -BOOLEAN
> 
> -DeviceExist (
> 
> -  PCI_IO_DEVICE                   *PciDevice
> 
> -  )
> 
> -{
> 
> -  EFI_PCI_IO_PROTOCOL   *PciIoProtocol = &PciDevice->PciIo;
> 
> -  UINT16                VendorId = 0xFFFF;
> 
> -
> 
> -  PciIoProtocol->Pci.Read (
> 
> -                      PciIoProtocol,
> 
> -                      EfiPciIoWidthUint16,
> 
> -                      PCI_VENDOR_ID_OFFSET,
> 
> -                      1,
> 
> -                      &VendorId
> 
> -                      );
> 
> -  if (VendorId == 0 || VendorId == 0xFFFF) {
> 
> -    return FALSE;
> 
> -  } else {
> 
> -    return TRUE;
> 
> -  }
> 
> -}
> 
> -
> 
> -/**
> 
> -  Free up memory alloted for the primary physical PCI Root ports of the PCI Root
> 
> -  Bridge instance. Free up all the nodes of type BRIDGE_DEVICE_NODE.
> 
> -**/
> 
> -VOID
> 
> -DestroyRootBridgeDeviceNodes ()
> 
> -{
> 
> -  LIST_ENTRY                *Link;
> 
> -  BRIDGE_DEVICE_NODE        *Temp;
> 
> -
> 
> -  Link = mRootBridgeDeviceList.ForwardLink;
> 
> -  while (Link != NULL && Link != &mRootBridgeDeviceList) {
> 
> -    Temp = ROOT_BRIDGE_DEVICE_NODE_FROM_LINK (Link);
> 
> -    Link = RemoveEntryList (Link);
> 
> -    FreePool (Temp->PciExFeaturesConfigurationTable);
> 
> -    FreePool (Temp);
> 
> -  }
> 
> -}
> 
> -
> 
> -/**
> 
> -  Main routine to determine the child PCI devices of a PCI bridge device
> 
> -  and group them under a common internal PCI features Configuration table.
> 
> -
> 
> -  @param  PciDevice                       A pointer to the PCI_IO_DEVICE.
> 
> -  @param  PciFeaturesConfigTable          A pointer to a pointer to the
> 
> -                                          PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE.
> 
> -                                          Returns NULL in case of RCiEP or the PCI
> 
> -                                          device does match with any of the physical
> 
> -                                          Root ports, or it does not belong to any
> 
> -                                          Root port's PCI bus range (not a child)
> 
> -
> 
> -  @retval EFI_SUCCESS                     able to determine the PCI feature
> 
> -                                          configuration table. For RCiEP since
> 
> -                                          since it is not prepared.
> 
> -          EFI_DEVICE_ERROR                the PCI device has invalid EFI device
> 
> -                                          path
> 
> -**/
> 
> -EFI_STATUS
> 
> -GetPciExpressFeaturesConfigurationTable (
> 
> -  IN  PCI_IO_DEVICE                             *PciDevice,
> 
> -  OUT PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  **PciFeaturesConfigTable
> 
> -  )
> 
> -{
> 
> -  LIST_ENTRY                *Link;
> 
> -  BRIDGE_DEVICE_NODE        *Temp;
> 
> -  BOOLEAN                   NodeMatch;
> 
> -  EFI_DEVICE_PATH_PROTOCOL  *RootPortPath;
> 
> -  EFI_DEVICE_PATH_PROTOCOL  *PciDevicePath;
> 
> -
> 
> -  if (IsListEmpty (&mRootBridgeDeviceList)) {
> 
> -    //
> 
> -    // no populated PCI primary root ports to parse and match the PCI features
> 
> -    // configuration table
> 
> -    //
> 
> -    *PciFeaturesConfigTable = NULL;
> 
> -    return EFI_SUCCESS;
> 
> -  }
> 
> -
> 
> -  //
> 
> -  // The PCI features configuration table is not built for RCiEP, return NULL
> 
> -  //
> 
> -  if (PciDevice->PciExpressCapabilityStructure.Capability.Bits.DevicePortType == \
> 
> -      PCIE_DEVICE_PORT_TYPE_ROOT_COMPLEX_INTEGRATED_ENDPOINT) {
> 
> -    *PciFeaturesConfigTable = NULL;
> 
> -    return EFI_SUCCESS;
> 
> -  }
> 
> -
> 
> -  if (IsDevicePathEnd (PciDevice->DevicePath)){
> 
> -    //
> 
> -    // the given PCI device does not have a valid device path
> 
> -    //
> 
> -    *PciFeaturesConfigTable = NULL;
> 
> -    return EFI_DEVICE_ERROR;
> 
> -  }
> 
> -
> 
> -
> 
> -  Link = mRootBridgeDeviceList.ForwardLink;
> 
> -  do {
> 
> -    Temp = ROOT_BRIDGE_DEVICE_NODE_FROM_LINK (Link);
> 
> -    RootPortPath = Temp->RootBridgeDevicePath;
> 
> -    PciDevicePath = PciDevice->DevicePath;
> 
> -    NodeMatch = FALSE;
> 
> -    //
> 
> -    // match the device path from the list of primary Root Ports with the given
> 
> -    // device; the initial nodes matching in sequence indicate that the given PCI
> 
> -    // device belongs to that PCI tree from the root port
> 
> -    //
> 
> -    if (IsDevicePathEnd (RootPortPath)) {
> 
> -      //
> 
> -      // critical error as no device path available in root
> 
> -      //
> 
> -      *PciFeaturesConfigTable = NULL;
> 
> -      return EFI_DEVICE_ERROR;
> 
> -    }
> 
> -
> 
> -    if (EfiCompareDevicePath (RootPortPath, PciDevicePath)) {
> 
> -      //
> 
> -      // the given PCI device is the primary root port itself
> 
> -      //
> 
> -      *PciFeaturesConfigTable = Temp->PciExFeaturesConfigurationTable;
> 
> -      return EFI_SUCCESS;
> 
> -    }
> 
> -    //
> 
> -    // check this PCI device belongs to the primary root port of the root bridge
> 
> -    // any child PCI device will have the same initial device path nodes  as
> 
> -    // its parent root port
> 
> -    //
> 
> -    while (!IsDevicePathEnd (RootPortPath)){
> 
> -
> 
> -      if (DevicePathNodeLength (RootPortPath) != DevicePathNodeLength (PciDevicePath)) {
> 
> -        //
> 
> -        // break to check the next primary root port nodes as does not match
> 
> -        //
> 
> -        NodeMatch = FALSE;
> 
> -        break;
> 
> -      }
> 
> -      if (CompareMem (RootPortPath, PciDevicePath, DevicePathNodeLength (RootPortPath)) != 0) {
> 
> -        //
> 
> -        // node does not match, break to check next node
> 
> -        //
> 
> -        NodeMatch = FALSE;
> 
> -        break;
> 
> -      }
> 
> -      NodeMatch = TRUE;
> 
> -      //
> 
> -      // advance to next node
> 
> -      //
> 
> -      RootPortPath = NextDevicePathNode (RootPortPath);
> 
> -      PciDevicePath = NextDevicePathNode (PciDevicePath);
> 
> -    }
> 
> -
> 
> -    if (NodeMatch == TRUE) {
> 
> -      //
> 
> -      // device belongs to primary root port, return its PCI feature configuration
> 
> -      // table
> 
> -      //
> 
> -      *PciFeaturesConfigTable = Temp->PciExFeaturesConfigurationTable;
> 
> -      return EFI_SUCCESS;
> 
> -    }
> 
> -
> 
> -    //
> 
> -    // advance to next Root port node
> 
> -    //
> 
> -    Link = Link->ForwardLink;
> 
> -  } while (Link != &mRootBridgeDeviceList && Link != NULL);
> 
> -  //
> 
> -  // the PCI device must be RCiEP, does not belong to any primary root port
> 
> -  //
> 
> -  *PciFeaturesConfigTable = NULL;
> 
> -  return EFI_SUCCESS;
> 
> -}
> 
> -
> 
> -/**
> 
> -  helper routine to dump the PCIe Device Port Type
> 
> -**/
> 
> -VOID
> 
> -DumpDevicePortType (
> 
> -  IN  UINT8   DevicePortType
> 
> -  )
> 
> -{
> 
> -  switch (DevicePortType){
> 
> -    case PCIE_DEVICE_PORT_TYPE_PCIE_ENDPOINT:
> 
> -      DEBUG (( DEBUG_INFO, "PCIe endpoint found\n"));
> 
> -      break;
> 
> -    case PCIE_DEVICE_PORT_TYPE_LEGACY_PCIE_ENDPOINT:
> 
> -      DEBUG (( DEBUG_INFO, "legacy PCI endpoint found\n"));
> 
> -      break;
> 
> -    case PCIE_DEVICE_PORT_TYPE_ROOT_PORT:
> 
> -      DEBUG (( DEBUG_INFO, "PCIe Root Port found\n"));
> 
> -      break;
> 
> -    case PCIE_DEVICE_PORT_TYPE_UPSTREAM_PORT:
> 
> -      DEBUG (( DEBUG_INFO, "PCI switch upstream port found\n"));
> 
> -      break;
> 
> -    case PCIE_DEVICE_PORT_TYPE_DOWNSTREAM_PORT:
> 
> -      DEBUG (( DEBUG_INFO, "PCI switch downstream port found\n"));
> 
> -      break;
> 
> -    case PCIE_DEVICE_PORT_TYPE_PCIE_TO_PCI_BRIDGE:
> 
> -      DEBUG (( DEBUG_INFO, "PCIe-PCI bridge found\n"));
> 
> -      break;
> 
> -    case PCIE_DEVICE_PORT_TYPE_PCI_TO_PCIE_BRIDGE:
> 
> -      DEBUG (( DEBUG_INFO, "PCI-PCIe bridge found\n"));
> 
> -      break;
> 
> -    case PCIE_DEVICE_PORT_TYPE_ROOT_COMPLEX_INTEGRATED_ENDPOINT:
> 
> -      DEBUG (( DEBUG_INFO, "RCiEP found\n"));
> 
> -      break;
> 
> -    case PCIE_DEVICE_PORT_TYPE_ROOT_COMPLEX_EVENT_COLLECTOR:
> 
> -      DEBUG (( DEBUG_INFO, "RC Event Collector found\n"));
> 
> -      break;
> 
> -  }
> 
> -}
> 
> -
> 
> -/**
> 
> -   Setup each PCI device as per the pltaform's device-specific policy, in accordance
> 
> -   with PCI Express Base specification.
> 
> -
> 
> -  @param RootBridge             A pointer to the PCI_IO_DEVICE.
> 
> -
> 
> -  @retval EFI_SUCCESS           processing each PCI feature as per policy defined
> 
> -                                was successful.
> 
> - **/
> 
> -EFI_STATUS
> 
> -SetupDevicePciExpressFeatures (
> 
> -  IN  PCI_IO_DEVICE                           *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURE_CONFIGURATION_PHASE PciConfigPhase
> 
> -  )
> 
> -{
> 
> -  EFI_STATUS                              Status;
> 
> -  PCI_REG_PCIE_CAPABILITY                 PcieCap;
> 
> -  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExpressFeaturesConfigTable;
> 
> -
> 
> -  PciExpressFeaturesConfigTable = NULL;
> 
> -  Status = GetPciExpressFeaturesConfigurationTable (PciDevice, &PciExpressFeaturesConfigTable);
> 
> -
> 
> -  if (PciConfigPhase == PciExpressFeatureSetupPhase) {
> 
> -    DEBUG_CODE (
> 
> -      if (EFI_ERROR( Status)) {
> 
> -        DEBUG ((
> 
> -          DEBUG_WARN,
> 
> -          "[Cfg group: 0 {error in dev path}]"
> 
> -          ));
> 
> -      } else if (PciExpressFeaturesConfigTable == NULL) {
> 
> -        DEBUG ((
> 
> -          DEBUG_INFO,
> 
> -          "[Cfg group: 0]"
> 
> -          ));
> 
> -      } else {
> 
> -        DEBUG ((
> 
> -          DEBUG_INFO,
> 
> -          "[Cfg group: %d]",
> 
> -          PciExpressFeaturesConfigTable->ID
> 
> -          ));
> 
> -      }
> 
> -      PcieCap.Uint16 = PciDevice->PciExpressCapabilityStructure.Capability.Uint16;
> 
> -      DumpDevicePortType ((UINT8)PcieCap.Bits.DevicePortType);
> 
> -    );
> 
> -
> 
> -    //
> 
> -    // get the device-specific platform policy for the PCI Express features
> 
> -    //
> 
> -    Status = PciExpressPlatformGetDevicePolicy (PciDevice);
> 
> -    if (EFI_ERROR(Status)) {
> 
> -      DEBUG ((
> 
> -        DEBUG_ERROR,
> 
> -        "Error in obtaining PCI device policy!!!\n"
> 
> -        ));
> 
> -    }
> 
> -  }
> 
> -
> 
> -  DEBUG ((DEBUG_INFO, "["));
> 
> -
> 
> -  Status = DispatchPciExpressInitializationFunctions (
> 
> -            PciDevice,
> 
> -            PciConfigPhase,
> 
> -            PciExpressFeaturesConfigTable
> 
> -            );
> 
> -
> 
> -  DEBUG ((DEBUG_INFO, "]\n"));
> 
> -  return Status;
> 
> -}
> 
> -
> 
> -/**
> 
> -  Create and append a node of type BRIDGE_DEVICE_NODE in the list for the primary
> 
> -  Root Port so that all its child PCI devices can be identified against the PCI
> 
> -  features configuration table group ID, of type PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE.
> 
> -
> 
> -  @param BridgePort    A pointer to the PCI_IO_DEVICE
> 
> -  @param PortNumber    A UINTN value to identify the PCI feature configuration
> 
> -                       table group
> 
> -
> 
> -  @retval EFI_SUCCESS           success in adding a node of BRIDGE_DEVICE_NODE
> 
> -                                to the list
> 
> -          EFI_OUT_OF_RESOURCES  unable to get memory for creating the node
> 
> -**/
> 
> -EFI_STATUS
> 
> -CreatePciRootBridgeDeviceNode (
> 
> -  IN  PCI_IO_DEVICE           *BridgePort,
> 
> -  IN  UINTN                   PortNumber
> 
> -  )
> 
> -{
> 
> -  BRIDGE_DEVICE_NODE                        *RootBridgeNode = NULL;
> 
> -  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciConfigTable = NULL;
> 
> -
> 
> -  RootBridgeNode = AllocateZeroPool (sizeof (BRIDGE_DEVICE_NODE));
> 
> -  if (RootBridgeNode == NULL) {
> 
> -    return EFI_OUT_OF_RESOURCES;
> 
> -  }
> 
> -  RootBridgeNode->Signature                     = PCI_ROOT_BRIDGE_DEVICE_SIGNATURE;
> 
> -  RootBridgeNode->RootBridgeDevicePath          = BridgePort->DevicePath;
> 
> -  PciConfigTable = AllocateZeroPool (
> 
> -                     sizeof (PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE)
> 
> -                     );
> 
> -  if (PciConfigTable) {
> 
> -    PciConfigTable->ID                          = PortNumber;
> 
> -    //
> 
> -    // start by assuming 4096B as the default value for the Max. Payload Size
> 
> -    //
> 
> -    PciConfigTable->Max_Payload_Size            = PCIE_MAX_PAYLOAD_SIZE_4096B;
> 
> -    //
> 
> -    // start by assuming 4096B as the default value for the Max. Read Request Size
> 
> -    //
> 
> -    PciConfigTable->Max_Read_Request_Size       = PCIE_MAX_READ_REQ_SIZE_4096B;
> 
> -    //
> 
> -    // start by assuming the Max. Read Request Size need not be common for all
> 
> -    // the devices in the PCI tree
> 
> -    //
> 
> -    PciConfigTable->Lock_Max_Read_Request_Size  = FALSE;
> 
> -    //
> 
> -    // start by assuming the LTR mechanism is supported in a PCI tree
> 
> -    //
> 
> -    PciConfigTable->LtrSupported                = TRUE;
> 
> -    //
> 
> -    // the default LTR mechanism is disabled as per the PCI Base specification
> 
> -    //
> 
> -    PciConfigTable->LtrEnable                   = FALSE;
> 
> -    //
> 
> -    // start by assuming the AtomicOp Routing capability is supported in the PCI
> 
> -    // tree
> 
> -    //
> 
> -    PciConfigTable->AtomicOpRoutingSupported    = TRUE;
> 
> -    //
> 
> -    // 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;
> 
> -    //
> 
> -    // default link retrain is not required
> 
> -    //
> 
> -    PciConfigTable->LinkReTrain                 = FALSE;
> 
> -    //
> 
> -    // start by assuming no common clock configuration mode for the device's link
> 
> -    //
> 
> -    PciConfigTable->CommonClockConfiguration    = FALSE;
> 
> -  }
> 
> -
> 
> -  RootBridgeNode->PciExFeaturesConfigurationTable  = PciConfigTable;
> 
> -
> 
> -  InsertTailList (&mRootBridgeDeviceList, &RootBridgeNode->NextRootBridgeDevice);
> 
> -
> 
> -  if (PciConfigTable == NULL) {
> 
> -    return EFI_OUT_OF_RESOURCES;
> 
> -  }
> 
> -  return EFI_SUCCESS;
> 
> -}
> 
> -
> 
> -/**
> 
> -  Scan all the nodes of the RootBridge to identify and create a separate list
> 
> -  of all primary physical PCI root ports and link each with its own instance of
> 
> -  the PCI Feature Configuration Table.
> 
> -
> 
> -  @param  RootBridge    A pointer to the PCI_IO_DEVICE of the PCI Root Bridge
> 
> -
> 
> -  @retval EFI_OUT_OF_RESOURCES  unable to allocate buffer to store PCI feature
> 
> -                                configuration table for all the physical PCI root
> 
> -                                ports given
> 
> -          EFI_NOT_FOUND         No PCI Bridge device found
> 
> -          EFI_SUCCESS           PCI Feature COnfiguration table created for all
> 
> -                                the PCI Rooot ports found
> 
> -          EFI_INVALID_PARAMETER invalid parameter passed to the routine which
> 
> -                                creates the PCI controller node for the primary
> 
> -                                Root post list
> 
> -**/
> 
> -EFI_STATUS
> 
> -CreatePciRootBridgeDeviceList (
> 
> -  IN  PCI_IO_DEVICE           *RootBridge
> 
> -  )
> 
> -{
> 
> -  EFI_STATUS              Status = EFI_NOT_FOUND;
> 
> -  LIST_ENTRY              *Link;
> 
> -  PCI_IO_DEVICE           *Device;
> 
> -  UINTN                   BridgeDeviceCount;
> 
> -
> 
> -  BridgeDeviceCount = 0;
> 
> -  for ( Link = RootBridge->ChildList.ForwardLink
> 
> -      ; Link != &RootBridge->ChildList
> 
> -      ; Link = Link->ForwardLink
> 
> -  ) {
> 
> -    Device = PCI_IO_DEVICE_FROM_LINK (Link);
> 
> -    if (!DeviceExist (Device)) {
> 
> -      continue;
> 
> -    }
> 
> -    if (IS_PCI_BRIDGE (&Device->Pci)) {
> 
> -      BridgeDeviceCount++;
> 
> -      DEBUG ((
> 
> -        DEBUG_INFO,
> 
> -        "#%d ::Bridge [%02x|%02x|%02x]",
> 
> -        BridgeDeviceCount, Device->BusNumber, Device->DeviceNumber, Device->FunctionNumber
> 
> -        ));
> 
> -      //
> 
> -      // create a list of bridge devices if that is connected to any other device
> 
> -      //
> 
> -      if (!IsListEmpty (&Device->ChildList)) {
> 
> -        DEBUG ((
> 
> -          DEBUG_INFO,
> 
> -          "- has downstream device!\n"
> 
> -          ));
> 
> -        Status = CreatePciRootBridgeDeviceNode (Device, BridgeDeviceCount);
> 
> -        if (EFI_ERROR (Status)) {
> 
> -          DEBUG ((
> 
> -            DEBUG_ERROR,
> 
> -            "PCI configuration table allocation failure for #%d ::Bridge [%02x|%02x|%02x]\n",
> 
> -            BridgeDeviceCount, Device->BusNumber, Device->DeviceNumber, Device->FunctionNumber
> 
> -            ));
> 
> -        }
> 
> -      } else {
> 
> -        DEBUG ((
> 
> -          DEBUG_INFO,
> 
> -          "- no downstream device!\n"
> 
> -          ));
> 
> -      }
> 
> -    }
> 
> -  }
> 
> -
> 
> -  return Status;
> 
> -}
> 
> -
> 
> -/**
> 
> -  Initialize the device's PCI Express features, in a staged manner
> 
> -  @param  PciDevice             A pointer to the PCI_IO_DEVICE.
> 
> -
> 
> -  @retval EFI_SUCCESS           initializing all the nodes of the root bridge
> 
> -                                instances were successfull.
> 
> -**/
> 
> -EFI_STATUS
> 
> -InitializeDevicePciExpressFeatures (
> 
> -  IN  PCI_IO_DEVICE                           *PciDevice,
> 
> -  IN  PCI_EXPRESS_FEATURE_CONFIGURATION_PHASE PciConfigPhase
> 
> -  )
> 
> -{
> 
> -  EFI_STATUS            Status;
> 
> -
> 
> -  switch (PciConfigPhase) {
> 
> -    case PciExpressFeatureSetupPhase:
> 
> -    case PciExpressFeatureEntendedSetupPhase:
> 
> -    case PciExpressFeatureProgramPhase:
> 
> -      Status = SetupDevicePciExpressFeatures (PciDevice, PciConfigPhase);
> 
> -      break;
> 
> -    case PciExpressFeatureEndPhase:
> 
> -      Status = PciExpressPlatformNotifyDeviceState (PciDevice);
> 
> -      break;
> 
> -  }
> 
> -  return Status;
> 
> -}
> 
> -
> 
> -/**
> 
> -  Traverse all the nodes from the root bridge or PCI-PCI bridge instance, to
> 
> -  configure the PCI Express features as per the PCI Express Base Secification
> 
> -  by considering its device-specific platform policy, and its device capability,
> 
> -  as applicable.
> 
> -
> 
> -  @param RootBridge             A pointer to the PCI_IO_DEVICE.
> 
> -
> 
> -  @retval EFI_SUCCESS           Traversing all the nodes of the root bridge
> 
> -                                instances were successfull.
> 
> -**/
> 
> -EFI_STATUS
> 
> -InitializePciExpressFeatures (
> 
> -  IN  PCI_IO_DEVICE                           *RootBridge,
> 
> -  IN  PCI_EXPRESS_FEATURE_CONFIGURATION_PHASE PciConfigPhase
> 
> -  )
> 
> -{
> 
> -  EFI_STATUS            Status;
> 
> -  LIST_ENTRY            *Link;
> 
> -  PCI_IO_DEVICE         *Device;
> 
> -
> 
> -  for ( Link = RootBridge->ChildList.ForwardLink
> 
> -      ; Link != &RootBridge->ChildList
> 
> -      ; Link = Link->ForwardLink
> 
> -  ) {
> 
> -    Device = PCI_IO_DEVICE_FROM_LINK (Link);
> 
> -    if (!DeviceExist (Device)) {
> 
> -      DEBUG ((
> 
> -        DEBUG_ERROR,
> 
> -        "::Device [%02x|%02x|%02x] - does not exist!!!\n",
> 
> -        Device->BusNumber, Device->DeviceNumber, Device->FunctionNumber
> 
> -        ));
> 
> -      continue;
> 
> -    }
> 
> -    if (IS_PCI_BRIDGE (&Device->Pci)) {
> 
> -      DEBUG ((
> 
> -        DEBUG_INFO,
> 
> -        "::Bridge [%02x|%02x|%02x] -",
> 
> -        Device->BusNumber, Device->DeviceNumber, Device->FunctionNumber
> 
> -        ));
> 
> -      if (Device->IsPciExp) {
> 
> -        Status = InitializeDevicePciExpressFeatures (
> 
> -                  Device,
> 
> -                  PciConfigPhase
> 
> -                  );
> 
> -      } else {
> 
> -        DEBUG ((
> 
> -          DEBUG_INFO,
> 
> -          "Not a PCIe capable device!\n"
> 
> -          ));
> 
> -        //
> 
> -        // PCI Bridge which does not have PCI Express Capability structure
> 
> -        // cannot process this kind of PCI Bridge device
> 
> -        //
> 
> -      }
> 
> -
> 
> -      InitializePciExpressFeatures (Device, PciConfigPhase);
> 
> -    } else {
> 
> -      DEBUG ((
> 
> -        DEBUG_INFO,
> 
> -        "::Device [%02x|%02x|%02x] -",
> 
> -        Device->BusNumber, Device->DeviceNumber, Device->FunctionNumber
> 
> -        ));
> 
> -      if (Device->IsPciExp) {
> 
> -        Status = InitializeDevicePciExpressFeatures (
> 
> -                  Device,
> 
> -                  PciConfigPhase
> 
> -                  );
> 
> -      } else {
> 
> -        DEBUG ((
> 
> -          DEBUG_INFO,
> 
> -          "Not a PCIe capable device!\n"
> 
> -          ));
> 
> -        //
> 
> -        // PCI Device which does not have PCI Express Capability structure
> 
> -        // cannot process this kind of PCI device
> 
> -        //
> 
> -      }
> 
> -    }
> 
> -  }
> 
> -
> 
> -  return EFI_SUCCESS;
> 
> -}
> 
> -
> 
> -/**
> 
> -  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
> 
> -EnumeratePciExpressFeatures (
> 
> -  IN EFI_HANDLE             Controller,
> 
> -  IN PCI_IO_DEVICE          *RootBridge
> 
> -  )
> 
> -{
> 
> -  EFI_STATUS            Status;
> 
> -  UINTN                 PciExpressFeatureConfigPhase;
> 
> -
> 
> -  if (!IsPciExpressFeatureConfigurationRequired ()) {
> 
> -    //
> 
> -    // exit as agreement is not reached with platform to configure the PCI
> 
> -    // Express features
> 
> -    //
> 
> -    return EFI_SUCCESS;
> 
> -  }
> 
> -  mRootBridgeHandle = Controller;
> 
> -
> 
> -  DEBUG_CODE (
> 
> -    CHAR16                *Str;
> 
> -    Str = ConvertDevicePathToText (
> 
> -            DevicePathFromHandle (RootBridge->Handle),
> 
> -            FALSE,
> 
> -            FALSE
> 
> -            );
> 
> -    DEBUG ((
> 
> -      DEBUG_INFO,
> 
> -      "Enumerating PCI features for Root Bridge %s\n",
> 
> -      Str != NULL ? Str : L""
> 
> -      ));
> 
> -
> 
> -    if (Str != NULL) {
> 
> -      FreePool (Str);
> 
> -    }
> 
> -  );
> 
> -
> 
> -  for ( PciExpressFeatureConfigPhase = PciExpressFeaturePreProcessPhase
> 
> -      ; PciExpressFeatureConfigPhase <= PciExpressFeatureEndPhase
> 
> -      ; PciExpressFeatureConfigPhase++
> 
> -      ) {
> 
> -    DEBUG ((
> 
> -      DEBUG_INFO,
> 
> -      "<<********** Phase [%d]**********>>\n",
> 
> -      PciExpressFeatureConfigPhase
> 
> -      ));
> 
> -    if (PciExpressFeatureConfigPhase == PciExpressFeaturePreProcessPhase) {
> 
> -      //
> 
> -      // create a list of root bridge devices (root ports) of the root complex
> 
> -      // if extra setup phase required
> 
> -      //
> 
> -      if (IsPciExpressFeatureExtendedSetupRequired ()) {
> 
> -        CreatePciRootBridgeDeviceList (RootBridge);
> 
> -      }
> 
> -      continue;
> 
> -    }
> 
> -    if (PciExpressFeatureConfigPhase == PciExpressFeatureEntendedSetupPhase) {
> 
> -      if (!IsPciExpressFeatureExtendedSetupRequired ()) {
> 
> -        //
> 
> -        // since the PCI Express features require no extra initialization steps
> 
> -        // skip this phase
> 
> -        //
> 
> -        continue;
> 
> -      }
> 
> -    }
> 
> -    //
> 
> -    // setup the PCI Express features
> 
> -    //
> 
> -    Status = InitializePciExpressFeatures (RootBridge, PciExpressFeatureConfigPhase);
> 
> -
> 
> -    if (PciExpressFeatureConfigPhase == PciExpressFeatureEndPhase) {
> 
> -      //
> 
> -      // clean up the temporary resource nodes created for this root bridge
> 
> -      //
> 
> -      if (IsPciExpressFeatureExtendedSetupRequired ()) {
> 
> -        DestroyRootBridgeDeviceNodes ();
> 
> -      }
> 
> -    }
> 
> -  }
> 
> -
> 
> -  return Status;
> 
> -}
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h
> deleted file mode 100644
> index 481bd90..0000000
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h
> +++ /dev/null
> @@ -1,304 +0,0 @@
> -/** @file
> 
> -  PCI standard feature support functions implementation for PCI Bus module..
> 
> -
> 
> -Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> 
> -SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> -
> 
> -**/
> 
> -
> 
> -#ifndef _EFI_PCI_FEATURES_SUPPORT_H_
> 
> -#define _EFI_PCI_FEATURES_SUPPORT_H_
> 
> -
> 
> -extern  EFI_HANDLE                                  mRootBridgeHandle;
> 
> -extern  EFI_PCI_EXPRESS_PLATFORM_POLICY             mPciExpressPlatformPolicy;
> 
> -//
> 
> -// defines the data structure to hold the details of the PCI Root port devices
> 
> -//
> 
> -typedef struct _BRIDGE_DEVICE_NODE  BRIDGE_DEVICE_NODE;
> 
> -
> 
> -//
> 
> -// defines the data structure to hold the configuration data for the other PCI
> 
> -// features
> 
> -//
> 
> -typedef struct _PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE;
> 
> -
> 
> -//
> 
> -// define the data type for the PCI feature policy support
> 
> -//
> 
> -typedef struct _PCI_FEATURE_POLICY  PCI_FEATURE_POLICY;
> 
> -
> 
> -//
> 
> -// Signature value for the PCI Root Port node
> 
> -//
> 
> -#define PCI_ROOT_BRIDGE_DEVICE_SIGNATURE               SIGNATURE_32 ('p', 'c', 'i', 'p')
> 
> -
> 
> -//
> 
> -// Definitions of the PCI Root Port data structure members
> 
> -//
> 
> -struct _BRIDGE_DEVICE_NODE {
> 
> -  //
> 
> -  // Signature header
> 
> -  //
> 
> -  UINT32                                    Signature;
> 
> -  //
> 
> -  // linked list pointers to next node
> 
> -  //
> 
> -  LIST_ENTRY                                NextRootBridgeDevice;
> 
> -  //
> 
> -  // pointer to PCI_IO_DEVICE of the primary PCI Controller device
> 
> -  //
> 
> -  EFI_DEVICE_PATH_PROTOCOL                  *RootBridgeDevicePath;
> 
> -  //
> 
> -  // pointer to the corresponding PCI Express feature configuration Table node
> 
> -  // all the child PCI devices of the controller are aligned based on this table
> 
> -  //
> 
> -  PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE  *PciExFeaturesConfigurationTable;
> 
> -};
> 
> -
> 
> -#define ROOT_BRIDGE_DEVICE_NODE_FROM_LINK(a) \
> 
> -  CR (a, BRIDGE_DEVICE_NODE, NextRootBridgeDevice, PCI_ROOT_BRIDGE_DEVICE_SIGNATURE)
> 
> -
> 
> -//
> 
> -// Definition of the PCI Feature configuration Table members
> 
> -//
> 
> -struct _PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE {
> 
> -  //
> 
> -  // Configuration Table ID
> 
> -  //
> 
> -  UINTN                                     ID;
> 
> -  //
> 
> -  // to configure the PCI feature Maximum payload size to maintain the data packet
> 
> -  // size among all the PCI devices in the PCI hierarchy
> 
> -  //
> 
> -  UINT8                                     Max_Payload_Size;
> 
> -  //
> 
> -  // to configure the PCI feature maximum read request size to maintain the memory
> 
> -  // requester size among all the PCI devices in the PCI hierarchy
> 
> -  //
> 
> -  UINT8                                     Max_Read_Request_Size;
> 
> -  //
> 
> -  // lock the Max_Read_Request_Size for the entire PCI tree of a root port
> 
> -  //
> 
> -  BOOLEAN                                   Lock_Max_Read_Request_Size;
> 
> -  //
> 
> -  // to record the adversity in LTR mechanism support capability among the PCI
> 
> -  // device of an heirarchy
> 
> -  //
> 
> -  BOOLEAN                                   LtrSupported;
> 
> -  //
> 
> -  // to enable the LTR mechansim for the entire PCI tree from a root port
> 
> -  //
> 
> -  BOOLEAN                                   LtrEnable;
> 
> -  //
> 
> -  // to record the AtomicOp Routing capability of the PCI Heirarchy to enable
> 
> -  // the AtomicOp of the EP device
> 
> -  //
> 
> -  BOOLEAN                                   AtomicOpRoutingSupported;
> 
> -  //
> 
> -  // 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;
> 
> -  //
> 
> -  // flag to indicate the link training is required in the devices of downstream
> 
> -  // ports
> 
> -  //
> 
> -  BOOLEAN                                   LinkReTrain;
> 
> -  //
> 
> -  // link status slot clock configuration
> 
> -  //
> 
> -  BOOLEAN                                   CommonClockConfiguration;
> 
> -};
> 
> -
> 
> -//
> 
> -// Declaration of the internal sub-phases during enumeration to configure the PCI
> 
> -// Express features
> 
> -//
> 
> -typedef enum {
> 
> -  //
> 
> -  // preprocessing applicable only to few PCI Express features to bind all devices
> 
> -  // under the common root bridge device (root port), that would be useful to align
> 
> -  // all devices with a common value. This would be optional phase based on the
> 
> -  // type of the PCI Express feature to be programmed based on platform policy
> 
> -  //
> 
> -  PciExpressFeaturePreProcessPhase,
> 
> -
> 
> -  //
> 
> -  // mandatory phase to setup the PCI Express feature to its applicable attribute,
> 
> -  // based on its device-specific platform policies, matching with its device capabilities
> 
> -  //
> 
> -  PciExpressFeatureSetupPhase,
> 
> -
> 
> -  //
> 
> -  // optional phase primarily to align all devices, specially required when PCI
> 
> -  // switch is present in the hierarchy, applicable to certain few PCI Express
> 
> -  // features only
> 
> -  //
> 
> -  PciExpressFeatureEntendedSetupPhase,
> 
> -
> 
> -  //
> 
> -  // mandatory programming phase to complete the configuration of the PCI Express
> 
> -  // features
> 
> -  //
> 
> -  PciExpressFeatureProgramPhase,
> 
> -
> 
> -  //
> 
> -  // optional phase to clean up temporary buffers, like those that were prepared
> 
> -  // during the preprocessing phase above
> 
> -  //
> 
> -  PciExpressFeatureEndPhase
> 
> -
> 
> -}PCI_EXPRESS_FEATURE_CONFIGURATION_PHASE;
> 
> -
> 
> -//
> 
> -// declaration for the data type to harbor the PCI feature policies
> 
> -//
> 
> -struct  _PCI_FEATURE_POLICY {
> 
> -  //
> 
> -  // if set, it indicates the feature should be enabled
> 
> -  // if clear, it indicates the feature should be disabled
> 
> -  //
> 
> -  UINT8   Act : 1;
> 
> -  //
> 
> -  // this field will be specific to feature, it can be implementation specific
> 
> -  // or it can be reserved and remain unused
> 
> -  //
> 
> -  UINT8   Support : 6;
> 
> -  //
> 
> -  // if set indicates override the feature policy defined by the members above
> 
> -  // if clear it indicates that this feature policy should be ignored completely
> 
> -  // this means the above two members should not be used
> 
> -  //
> 
> -  UINT8   Override : 1;
> 
> -};
> 
> -
> 
> -//
> 
> -// Declaration of the PCI Express features unique Id
> 
> -//
> 
> -typedef enum {
> 
> -  //
> 
> -  // support for PCI Express feature - Max. Payload Size
> 
> -  //
> 
> -  PciExpressMps,
> 
> -  //
> 
> -  // support for PCI Express feature - Max. Read Request Size
> 
> -  //
> 
> -  PciExpressMrrs,
> 
> -  //
> 
> -  // support for PCI Express feature - Extended Tag
> 
> -  //
> 
> -  PciExpressExtTag,
> 
> -  //
> 
> -  // support for PCI Express feature - Relax Order
> 
> -  //
> 
> -  PciExpressRelaxOrder,
> 
> -  //
> 
> -  // support for PCI Express feature - No-Snoop
> 
> -  //
> 
> -  PciExpressNoSnoop,
> 
> -  //
> 
> -  // support for PCI Express feature - ASPM state
> 
> -  //
> 
> -  PciExpressAspm,
> 
> -  //
> 
> -  // support for PCI Express feature - Common Clock Configuration
> 
> -  //
> 
> -  PciExpressCcc,
> 
> -  //
> 
> -  // support for PCI Express feature - Extended Sync
> 
> -  //
> 
> -  PciExpressExtSync,
> 
> -  //
> 
> -  // support for PCI Express feature - Atomic Op
> 
> -  //
> 
> -  PciExpressAtomicOp,
> 
> -  //
> 
> -  // support for PCI Express feature - LTR
> 
> -  //
> 
> -  PciExpressLtr,
> 
> -  //
> 
> -  // support for PCI Express feature - PTM
> 
> -  //
> 
> -  PciExpressPtm,
> 
> -  //
> 
> -  // support for PCI Express feature - Completion Timeout
> 
> -  //
> 
> -  PciExpressCto,
> 
> -  //
> 
> -  // support for PCI Express feature - Clock Power Management
> 
> -  //
> 
> -  PciExpressCpm,
> 
> -  //
> 
> -  // support for PCI Express feature - L1 PM Substates
> 
> -  //
> 
> -  PciExpressL1PmSubstates
> 
> -
> 
> -} PCI_EXPRESS_FEATURE_ID;
> 
> -
> 
> -//
> 
> -// PCI Express feature configuration routine during initialization phases
> 
> -//
> 
> -typedef
> 
> -EFI_STATUS
> 
> -(*PCI_EXPRESS_FEATURE_CONFIGURATION_ROUTINE) (
> 
> -  IN PCI_IO_DEVICE                            *PciDevice,
> 
> -  IN VOID                                     *PciExpressFeatureConfiguration
> 
> -  );
> 
> -
> 
> -//
> 
> -// data type for the PCI Express feature initialization phases
> 
> -//
> 
> -typedef struct {
> 
> -  //
> 
> -  // Pci Express feature configuration phase
> 
> -  //
> 
> -  PCI_EXPRESS_FEATURE_CONFIGURATION_PHASE   PciExpressFeatureConfigurationPhase;
> 
> -  //
> 
> -  // PCI Express feature Id
> 
> -  //
> 
> -  PCI_EXPRESS_FEATURE_ID                    PciExpressFeatureId;
> 
> -  //
> 
> -  // PCI Express feature configuration routine
> 
> -  //
> 
> -  PCI_EXPRESS_FEATURE_CONFIGURATION_ROUTINE PciExpressFeatureConfigurationRoutine;
> 
> -
> 
> -}PCI_EXPRESS_FEATURE_INITIALIZATION_POINT;
> 
> -
> 
> -
> 
> -
> 
> -/**
> 
> -  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
> 
> -EnumeratePciExpressFeatures (
> 
> -  IN EFI_HANDLE             Controller,
> 
> -  IN PCI_IO_DEVICE          *RootBridge
> 
> -  );
> 
> -
> 
> -#endif
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c
> deleted file mode 100644
> index bf380ab..0000000
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c
> +++ /dev/null
> @@ -1,902 +0,0 @@
> -/** @file
> 
> -  This file encapsulate the usage of PCI Platform Protocol
> 
> -
> 
> -  This file define the necessary hooks used to obtain the platform
> 
> -  level data and policies which could be used in the PCI Enumeration phases
> 
> -
> 
> -Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> 
> -SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> -
> 
> -**/
> 
> -
> 
> -#include "PciBus.h"
> 
> -
> 
> -
> 
> -EFI_PCI_EXPRESS_PLATFORM_PROTOCOL             *mPciExPlatformProtocol;
> 
> -EFI_PCI_EXPRESS_OVERRIDE_PROTOCOL             *mPciExOverrideProtocol;
> 
> -
> 
> -
> 
> -/**
> 
> -  This function retrieves the PCI Express Platform Protocols published by platform
> 
> -  @retval EFI_STATUS          direct return status from the LocateProtocol ()
> 
> -                              boot service for the PCI Express Override Protocol
> 
> -          EFI_SUCCESS         The PCI Express Platform Protocol is found
> 
> -**/
> 
> -EFI_STATUS
> 
> -GetPciExpressProtocol (
> 
> -  )
> 
> -{
> 
> -  EFI_STATUS  Status;
> 
> -
> 
> -  if (mPciExPlatformProtocol) {
> 
> -    //
> 
> -    // the PCI Express Platform Protocol is already initialized
> 
> -    //
> 
> -    return EFI_SUCCESS;
> 
> -  }
> 
> -  if (mPciExOverrideProtocol) {
> 
> -    //
> 
> -    // the PCI Express Override Protocol is already initialized
> 
> -    //
> 
> -    return EFI_SUCCESS;
> 
> -  }
> 
> -  //
> 
> -  // locate the PCI Express Platform Protocol
> 
> -  //
> 
> -  Status = gBS->LocateProtocol (
> 
> -                  &gEfiPciExpressPlatformProtocolGuid,
> 
> -                  NULL,
> 
> -                  (VOID **) &mPciExPlatformProtocol
> 
> -                  );
> 
> -  if (!EFI_ERROR (Status)) {
> 
> -    return Status;
> 
> -  }
> 
> -  //
> 
> -  // If PCI Express Platform protocol doesn't exist, try to get the Pci Express
> 
> -  // Override Protocol.
> 
> -  //
> 
> -  return gBS->LocateProtocol (
> 
> -                &gEfiPciExpressOverrideProtocolGuid,
> 
> -                NULL,
> 
> -                (VOID **) &mPciExOverrideProtocol
> 
> -                );
> 
> -}
> 
> -
> 
> -/**
> 
> -  This function indicates that the platform has published the PCI Express Platform
> 
> -  Protocol (or PCI Express Override Protocol) to indicate that this driver can
> 
> -  initialize the PCI Express features.
> 
> -  @retval     TRUE or FALSE
> 
> -**/
> 
> -BOOLEAN
> 
> -IsPciExpressProtocolPresent (
> 
> -  )
> 
> -{
> 
> -  if (
> 
> -      mPciExPlatformProtocol == NULL
> 
> -      && mPciExOverrideProtocol == NULL
> 
> -      ) {
> 
> -    return FALSE;
> 
> -  }
> 
> -  return TRUE;
> 
> -}
> 
> -
> 
> -/**
> 
> -  Routine to translate the given device-specific platform policy from type
> 
> -  EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE to HW-specific value, as per PCI Base Specification
> 
> -  Revision 4.0; for the PCI feature Max_Payload_Size.
> 
> -
> 
> -  @param  MPS     Input device-specific policy should be in terms of type
> 
> -                  EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE
> 
> -
> 
> -  @retval         Range values for the Max_Payload_Size as defined in the PCI
> 
> -                  Base Specification 4.0
> 
> -**/
> 
> -UINT8
> 
> -SetDevicePolicyPciExpressMps (
> 
> -  IN  UINT8                   MPS
> 
> -)
> 
> -{
> 
> -  switch (MPS) {
> 
> -    case EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_128B:
> 
> -      return PCIE_MAX_PAYLOAD_SIZE_128B;
> 
> -    case EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_256B:
> 
> -      return PCIE_MAX_PAYLOAD_SIZE_256B;
> 
> -    case EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_512B:
> 
> -      return PCIE_MAX_PAYLOAD_SIZE_512B;
> 
> -    case EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_1024B:
> 
> -      return PCIE_MAX_PAYLOAD_SIZE_1024B;
> 
> -    case EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_2048B:
> 
> -      return PCIE_MAX_PAYLOAD_SIZE_2048B;
> 
> -    case EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_4096B:
> 
> -      return PCIE_MAX_PAYLOAD_SIZE_4096B;
> 
> -    default:
> 
> -      return PCIE_MAX_PAYLOAD_SIZE_128B;
> 
> -  }
> 
> -}
> 
> -
> 
> -/**
> 
> -  Routine to translate the given device-specific platform policy from type
> 
> -  EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE to HW-specific value, as per PCI Base Specification
> 
> -  Revision 4.0; for the PCI feature Max_Read_Req_Size.
> 
> -
> 
> -  @param  MRRS    Input device-specific policy should be in terms of type
> 
> -                  EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE
> 
> -
> 
> -  @retval         Range values for the Max_Read_Req_Size as defined in the PCI
> 
> -                  Base Specification 4.0
> 
> -**/
> 
> -UINT8
> 
> -SetDevicePolicyPciExpressMrrs (
> 
> -  IN  UINT8                   MRRS
> 
> -)
> 
> -{
> 
> -  switch (MRRS) {
> 
> -    case EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_128B:
> 
> -      return PCIE_MAX_READ_REQ_SIZE_128B;
> 
> -    case EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_256B:
> 
> -      return PCIE_MAX_READ_REQ_SIZE_256B;
> 
> -    case EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_512B:
> 
> -      return PCIE_MAX_READ_REQ_SIZE_512B;
> 
> -    case EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_1024B:
> 
> -      return PCIE_MAX_READ_REQ_SIZE_1024B;
> 
> -    case EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_2048B:
> 
> -      return PCIE_MAX_READ_REQ_SIZE_2048B;
> 
> -    case EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_4096B:
> 
> -      return PCIE_MAX_READ_REQ_SIZE_4096B;
> 
> -    default:
> 
> -      return PCIE_MAX_READ_REQ_SIZE_128B;
> 
> -  }
> 
> -}
> 
> -
> 
> -/**
> 
> -  Routine to set the device-specific policy for the PCI feature Relax Ordering
> 
> -
> 
> -  @param  RelaxOrder    value corresponding to data type EFI_PCI_EXPRESS_RELAX_ORDER
> 
> -  @param  PciDevice     A pointer to PCI_IO_DEVICE
> 
> -**/
> 
> -VOID
> 
> -SetDevicePolicyPciExpressRo (
> 
> -  IN  EFI_PCI_EXPRESS_RELAX_ORDER RelaxOrder,
> 
> -  OUT PCI_IO_DEVICE               *PciDevice
> 
> -  )
> 
> -{
> 
> -  //
> 
> -  // implementation specific rules for the usage of PCI_FEATURE_POLICY members
> 
> -  // exclusively for the PCI Feature Relax Ordering (RO)
> 
> -  //
> 
> -  // .Override = 0 to skip this PCI feature RO for the PCI device
> 
> -  // .Override = 1 to program this RO PCI feature
> 
> -  //      .Act = 1 to enable the RO in the PCI device
> 
> -  //      .Act = 0 to disable the RO in the PCI device
> 
> -  //
> 
> -  switch (RelaxOrder) {
> 
> -    case  EFI_PCI_EXPRESS_RO_AUTO:
> 
> -      PciDevice->SetupRO.Override = 0;
> 
> -      break;
> 
> -    case  EFI_PCI_EXPRESS_RO_DISABLE:
> 
> -      PciDevice->SetupRO.Override = 1;
> 
> -      PciDevice->SetupRO.Act = 0;
> 
> -      break;
> 
> -    case  EFI_PCI_EXPRESS_RO_ENABLE:
> 
> -      PciDevice->SetupRO.Override = 1;
> 
> -      PciDevice->SetupRO.Act = 1;
> 
> -      break;
> 
> -    default:
> 
> -      PciDevice->SetupRO.Override = 0;
> 
> -      break;
> 
> -  }
> 
> -}
> 
> -
> 
> -/**
> 
> -  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;
> 
> -  }
> 
> -}
> 
> -
> 
> -/**
> 
> -  Routine to set the device-specific policy for the PCI feature CTO value range
> 
> -  or disable
> 
> -
> 
> -  @param  CtoSupport    value corresponding to data type EFI_PCI_EXPRESS_CTO_SUPPORT
> 
> -  @param  PciDevice     A pointer to PCI_IO_DEVICE
> 
> -**/
> 
> -VOID
> 
> -SetDevicePolicyPciExpressCto (
> 
> -  IN  EFI_PCI_EXPRESS_CTO_SUPPORT    CtoSupport,
> 
> -  OUT PCI_IO_DEVICE               *PciDevice
> 
> -)
> 
> -{
> 
> -  //
> 
> -  // implementation specific rules for the usage of PCI_FEATURE_POLICY members
> 
> -  // exclusively for the PCI Feature CTO
> 
> -  //
> 
> -  // .Override = 0 to skip this PCI feature CTO for the PCI device
> 
> -  // .Override = 1 to program this CTO PCI feature
> 
> -  //      .Act = 1 to program the CTO range as per given device policy in .Support
> 
> -  //      .Act = 0 to disable the CTO mechanism in the PCI device, CTO set to default range
> 
> -  //
> 
> -  switch (CtoSupport) {
> 
> -    case  EFI_PCI_EXPRESS_CTO_AUTO:
> 
> -      PciDevice->SetupCTO.Override = 0;
> 
> -      break;
> 
> -    case  EFI_PCI_EXPRESS_CTO_DEFAULT:
> 
> -      PciDevice->SetupCTO.Override = 1;
> 
> -      PciDevice->SetupCTO.Act = 1;
> 
> -      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_50US_50MS;
> 
> -      break;
> 
> -    case  EFI_PCI_EXPRESS_CTO_RANGE_A1:
> 
> -      PciDevice->SetupCTO.Override = 1;
> 
> -      PciDevice->SetupCTO.Act = 1;
> 
> -      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_50US_100US;
> 
> -      break;
> 
> -    case  EFI_PCI_EXPRESS_CTO_RANGE_A2:
> 
> -      PciDevice->SetupCTO.Override = 1;
> 
> -      PciDevice->SetupCTO.Act = 1;
> 
> -      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_1MS_10MS;
> 
> -      break;
> 
> -    case  EFI_PCI_EXPRESS_CTO_RANGE_B1:
> 
> -      PciDevice->SetupCTO.Override = 1;
> 
> -      PciDevice->SetupCTO.Act = 1;
> 
> -      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_16MS_55MS;
> 
> -      break;
> 
> -    case  EFI_PCI_EXPRESS_CTO_RANGE_B2:
> 
> -      PciDevice->SetupCTO.Override = 1;
> 
> -      PciDevice->SetupCTO.Act = 1;
> 
> -      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_65MS_210MS;
> 
> -      break;
> 
> -    case  EFI_PCI_EXPRESS_CTO_RANGE_C1:
> 
> -      PciDevice->SetupCTO.Override = 1;
> 
> -      PciDevice->SetupCTO.Act = 1;
> 
> -      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_260MS_900MS;
> 
> -      break;
> 
> -    case  EFI_PCI_EXPRESS_CTO_RANGE_C2:
> 
> -      PciDevice->SetupCTO.Override = 1;
> 
> -      PciDevice->SetupCTO.Act = 1;
> 
> -      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_1S_3_5S;
> 
> -      break;
> 
> -    case  EFI_PCI_EXPRESS_CTO_RANGE_D1:
> 
> -      PciDevice->SetupCTO.Override = 1;
> 
> -      PciDevice->SetupCTO.Act = 1;
> 
> -      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_4S_13S;
> 
> -      break;
> 
> -    case  EFI_PCI_EXPRESS_CTO_RANGE_D2:
> 
> -      PciDevice->SetupCTO.Override = 1;
> 
> -      PciDevice->SetupCTO.Act = 1;
> 
> -      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_17S_64S;
> 
> -      break;
> 
> -    case  EFI_PCI_EXPRESS_CTO_DET_DISABLE:
> 
> -      PciDevice->SetupCTO.Override = 1;
> 
> -      PciDevice->SetupCTO.Act = 0;
> 
> -      PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_50US_50MS;
> 
> -      break;
> 
> -  }
> 
> -}
> 
> -
> 
> -/**
> 
> -  Routine to set the device-specific policy for the PCI feature LTR enable/disable
> 
> -
> 
> -  @param  AtomicOp      value corresponding to data type EFI_PCI_EXPRESS_ATOMIC_OP
> 
> -  @param  PciDevice     A pointer to PCI_IO_DEVICE
> 
> -
> 
> -**/
> 
> -VOID
> 
> -SetDevicePolicyPciExpressLtr (
> 
> -  IN  EFI_PCI_EXPRESS_LTR            Ltr,
> 
> -  OUT PCI_IO_DEVICE               *PciDevice
> 
> -  )
> 
> -{
> 
> -  switch (Ltr){
> 
> -    case EFI_PCI_EXPRESS_LTR_AUTO:
> 
> -    case EFI_PCI_EXPRESS_LTR_DISABLE:
> 
> -      //
> 
> -      // leave the LTR mechanism disable or restore to its default state
> 
> -      //
> 
> -      PciDevice->SetupLtr = FALSE;
> 
> -      break;
> 
> -    case EFI_PCI_EXPRESS_LTR_ENABLE:
> 
> -      //
> 
> -      // LTR mechanism enable
> 
> -      //
> 
> -      PciDevice->SetupLtr = TRUE;
> 
> -      break;
> 
> -  }
> 
> -}
> 
> -
> 
> -/**
> 
> -  Generic routine to setup the PCI features as per its predetermined defaults.
> 
> -**/
> 
> -VOID
> 
> -SetupDefaultPciExpressDevicePolicy (
> 
> -  IN  PCI_IO_DEVICE               *PciDevice
> 
> -  )
> 
> -{
> 
> -
> 
> -  if (mPciExpressPlatformPolicy.Mps) {
> 
> -    PciDevice->SetupMPS = EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_AUTO;
> 
> -  } else {
> 
> -    PciDevice->SetupMPS = EFI_PCI_EXPRESS_NOT_APPLICABLE;
> 
> -  }
> 
> -
> 
> -  if (mPciExpressPlatformPolicy.Mrrs) {
> 
> -    PciDevice->SetupMRRS = EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_AUTO;
> 
> -  } else {
> 
> -    PciDevice->SetupMRRS = EFI_PCI_EXPRESS_NOT_APPLICABLE;
> 
> -  }
> 
> -
> 
> -  PciDevice->SetupRO.Override = 0;
> 
> -
> 
> -  PciDevice->SetupNS.Override = 0;
> 
> -
> 
> -  PciDevice->SetupCTO.Override = 0;
> 
> -
> 
> -  PciDevice->SetupAtomicOp.Override = 0;
> 
> -
> 
> -  PciDevice->SetupLtr = FALSE;
> 
> -
> 
> -  if (mPciExpressPlatformPolicy.ExtTag) {
> 
> -    PciDevice->SetupExtTag = EFI_PCI_EXPRESS_EXTENDED_TAG_AUTO;
> 
> -  } else {
> 
> -    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;
> 
> -  }
> 
> -
> 
> -  //
> 
> -  // default device policy for the device's link clock configuration
> 
> -  //
> 
> -  if (mPciExpressPlatformPolicy.Ccc) {
> 
> -    PciDevice->SetupCcc = EFI_PCI_EXPRESS_CLK_CFG_AUTO;
> 
> -  } else {
> 
> -    PciDevice->SetupCcc = EFI_PCI_EXPRESS_NOT_APPLICABLE;
> 
> -  }
> 
> -
> 
> -}
> 
> -
> 
> -/**
> 
> -  initialize the device policy data members
> 
> -**/
> 
> -VOID
> 
> -InitializeDevicePolicyData (
> 
> -  IN EFI_PCI_EXPRESS_DEVICE_POLICY  *PciExpressDevicePolicy
> 
> -  )
> 
> -{
> 
> -  UINTN     length;
> 
> -  UINT8     *PciExpressPolicy;
> 
> -  UINT8     *PciExDevicePolicy;
> 
> -
> 
> -
> 
> -  ZeroMem (PciExpressDevicePolicy, sizeof (EFI_PCI_EXPRESS_DEVICE_POLICY));
> 
> -
> 
> -  for (
> 
> -      length = 0
> 
> -      , PciExpressPolicy = (UINT8*)&mPciExpressPlatformPolicy
> 
> -      , PciExDevicePolicy = (UINT8*)PciExpressDevicePolicy
> 
> -      ; length < sizeof (EFI_PCI_EXPRESS_PLATFORM_POLICY)
> 
> -      ; length++
> 
> -      ) {
> 
> -    if (!PciExpressPolicy[length]) {
> 
> -      PciExDevicePolicy[length] = EFI_PCI_EXPRESS_NOT_APPLICABLE;
> 
> -    }
> 
> -  }
> 
> -}
> 
> -
> 
> -/**
> 
> -  Intermediate routine to either get the PCI device specific platform policies
> 
> -  through the PCI Platform Protocol, or its alias the PCI Override Protocol.
> 
> -
> 
> -  @param  PciDevice           A pointer to PCI_IO_DEVICE
> 
> -  @param  PciPlatformProtocol A pointer to EFI_PCI_EXPRESS_PLATFORM_PROTOCOL
> 
> -
> 
> -  @retval EFI_STATUS          The direct status from the PCI Platform Protocol
> 
> -  @retval EFI_SUCCESS         if on returning predetermined PCI features defaults,
> 
> -                              for the case when protocol returns as EFI_UNSUPPORTED
> 
> -                              to indicate PCI device exist and it has no platform
> 
> -                              policy defined.
> 
> -**/
> 
> -EFI_STATUS
> 
> -GetPciExpressDevicePolicy (
> 
> -  IN  PCI_IO_DEVICE                     *PciDevice,
> 
> -  IN  EFI_PCI_EXPRESS_PLATFORM_PROTOCOL *PciPlatformProtocol
> 
> -  )
> 
> -{
> 
> -  EFI_PCI_EXPRESS_DEVICE_POLICY               PciExpressDevicePolicy;
> 
> -  EFI_STATUS                                  Status;
> 
> -  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress;
> 
> -
> 
> -  PciAddress.Bus = PciDevice->BusNumber;
> 
> -  PciAddress.Device = PciDevice->DeviceNumber;
> 
> -  PciAddress.Function = PciDevice->FunctionNumber;
> 
> -  PciAddress.Register = 0;
> 
> -  PciAddress.ExtendedRegister = 0;
> 
> -
> 
> -  InitializeDevicePolicyData (&PciExpressDevicePolicy);
> 
> -  Status = PciPlatformProtocol->GetDevicePolicy (
> 
> -                                  PciPlatformProtocol,
> 
> -                                  mRootBridgeHandle,
> 
> -                                  PciAddress,
> 
> -                                  sizeof (EFI_PCI_EXPRESS_DEVICE_POLICY),
> 
> -                                  &PciExpressDevicePolicy
> 
> -                                  );
> 
> -  if (!EFI_ERROR(Status)) {
> 
> -    //
> 
> -    // platform chipset policies are returned for this PCI device
> 
> -    //
> 
> -
> 
> -    //
> 
> -    // set device specific policy for the Max_Payload_Size
> 
> -    //
> 
> -    if (mPciExpressPlatformPolicy.Mps) {
> 
> -      PciDevice->SetupMPS = PciExpressDevicePolicy.DeviceCtlMPS;
> 
> -    } else {
> 
> -      PciDevice->SetupMPS = EFI_PCI_EXPRESS_NOT_APPLICABLE;
> 
> -    }
> 
> -
> 
> -    //
> 
> -    // set device specific policy for Max_Read_Req_Size
> 
> -    //
> 
> -    if (mPciExpressPlatformPolicy.Mrrs) {
> 
> -      PciDevice->SetupMRRS = PciExpressDevicePolicy.DeviceCtlMRRS;
> 
> -    } else {
> 
> -      PciDevice->SetupMRRS = EFI_PCI_EXPRESS_NOT_APPLICABLE;
> 
> -    }
> 
> -    //
> 
> -    // set device specific policy for Relax Ordering
> 
> -    //
> 
> -    if (mPciExpressPlatformPolicy.RelaxOrder) {
> 
> -      SetDevicePolicyPciExpressRo (PciExpressDevicePolicy.DeviceCtlRelaxOrder, PciDevice);
> 
> -    } else {
> 
> -      PciDevice->SetupRO.Override = 0;
> 
> -    }
> 
> -
> 
> -    //
> 
> -    // set the device specific policy for No-Snoop
> 
> -    //
> 
> -    if (mPciExpressPlatformPolicy.NoSnoop) {
> 
> -      SetDevicePolicyPciExpressNs (PciExpressDevicePolicy.DeviceCtlNoSnoop, PciDevice);
> 
> -    } else {
> 
> -      PciDevice->SetupNS.Override = 0;
> 
> -    }
> 
> -
> 
> -    //
> 
> -    // set the device specific policy for Completion Timeout (CTO)
> 
> -    //
> 
> -    if (mPciExpressPlatformPolicy.Cto) {
> 
> -      SetDevicePolicyPciExpressCto (PciExpressDevicePolicy.CTOsupport, PciDevice);
> 
> -    } else {
> 
> -      PciDevice->SetupCTO.Override = 0;
> 
> -    }
> 
> -
> 
> -    //
> 
> -    // set the device-specific policy for AtomicOp
> 
> -    //
> 
> -    if (mPciExpressPlatformPolicy.AtomicOp) {
> 
> -      PciDevice->SetupAtomicOp = PciExpressDevicePolicy.DeviceCtl2AtomicOp;
> 
> -    } else {
> 
> -      PciDevice->SetupAtomicOp.Override = 0;
> 
> -    }
> 
> -
> 
> -    //
> 
> -    // set the device-specific policy for LTR mechanism in the function
> 
> -    //
> 
> -    if (mPciExpressPlatformPolicy.Ltr) {
> 
> -      SetDevicePolicyPciExpressLtr (PciExpressDevicePolicy.DeviceCtl2LTR, PciDevice);
> 
> -    } else {
> 
> -      PciDevice->SetupLtr = FALSE;
> 
> -    }
> 
> -
> 
> -    //
> 
> -    // set the device-specifci policy for the PCI Express feature Extended Tag
> 
> -    //
> 
> -    if (mPciExpressPlatformPolicy.ExtTag) {
> 
> -      PciDevice->SetupExtTag = PciExpressDevicePolicy.DeviceCtlExtTag;
> 
> -    } else {
> 
> -      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;
> 
> -    }
> 
> -
> 
> -    //
> 
> -    // set the device policy for the PCI Express feature Common Clock Configuration
> 
> -    //
> 
> -    if (mPciExpressPlatformPolicy.Ccc) {
> 
> -      PciDevice->SetupCcc = PciExpressDevicePolicy.LinkCtlCommonClkCfg;
> 
> -    } else {
> 
> -      PciDevice->SetupCcc = EFI_PCI_EXPRESS_NOT_APPLICABLE;
> 
> -    }
> 
> -
> 
> -    DEBUG ((
> 
> -      DEBUG_INFO,
> 
> -      "[device policy: platform]"
> 
> -      ));
> 
> -    return Status;
> 
> -  } else if (Status == EFI_UNSUPPORTED) {
> 
> -    //
> 
> -    // platform chipset policies are not provided for this PCI device
> 
> -    // let the enumeration happen as per the PCI standard way
> 
> -    //
> 
> -    SetupDefaultPciExpressDevicePolicy (PciDevice);
> 
> -    DEBUG ((
> 
> -      DEBUG_INFO,
> 
> -      "[device policy: default]"
> 
> -      ));
> 
> -    return EFI_SUCCESS;
> 
> -  }
> 
> -  DEBUG ((
> 
> -    DEBUG_ERROR,
> 
> -    "[device policy: none (error)]"
> 
> -    ));
> 
> -  return Status;
> 
> -}
> 
> -
> 
> -/**
> 
> -  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  PciDevice     A pointer to PCI_IO_DEVICE
> 
> -
> 
> -  @retval EFI_STATUS    The direct status from the PCI Platform Protocol
> 
> -  @retval EFI_SUCCESS   On return of predetermined PCI features defaults, for
> 
> -                        the case when protocol returns as EFI_UNSUPPORTED to
> 
> -                        indicate PCI device exist and it has no platform policy
> 
> -                        defined. Also, on returns when no PCI Platform Protocol
> 
> -                        exist.
> 
> -**/
> 
> -EFI_STATUS
> 
> -PciExpressPlatformGetDevicePolicy (
> 
> -  IN PCI_IO_DEVICE          *PciDevice
> 
> -  )
> 
> -{
> 
> -  if (mPciExPlatformProtocol != NULL) {
> 
> -    return GetPciExpressDevicePolicy (PciDevice, mPciExPlatformProtocol);
> 
> -  } else if (mPciExOverrideProtocol != NULL) {
> 
> -    return GetPciExpressDevicePolicy (PciDevice, mPciExOverrideProtocol);
> 
> -  } else {
> 
> -    //
> 
> -    // no protocol found, platform does not require the PCI Express initialization
> 
> -    //
> 
> -    return EFI_UNSUPPORTED;
> 
> -  }
> 
> -}
> 
> -
> 
> -/**
> 
> -  This function gets the platform requirement to initialize the list of PCI Express
> 
> -  features from the protocol definition supported.
> 
> -  This function should be called after the LocatePciPlatformProtocol.
> 
> -  @retval EFI_SUCCESS           return by platform to acknowledge the list of
> 
> -                                PCI Express feature to be configured
> 
> -                                (in mPciExpressPlatformPolicy)
> 
> -          EFI_INVALID_PARAMETER platform does not support the protocol arguements
> 
> -                                passed
> 
> -          EFI_UNSUPPORTED       platform did not published the protocol
> 
> -**/
> 
> -EFI_STATUS
> 
> -PciExpressPlatformGetPolicy (
> 
> -  )
> 
> -{
> 
> -  EFI_STATUS    Status;
> 
> -
> 
> -  if (mPciExPlatformProtocol) {
> 
> -    Status = mPciExPlatformProtocol->GetPolicy (
> 
> -                                      mPciExPlatformProtocol,
> 
> -                                      sizeof (EFI_PCI_EXPRESS_PLATFORM_POLICY),
> 
> -                                      &mPciExpressPlatformPolicy
> 
> -                                      );
> 
> -  } else if (mPciExOverrideProtocol) {
> 
> -    Status = mPciExOverrideProtocol->GetPolicy (
> 
> -                                      mPciExOverrideProtocol,
> 
> -                                      sizeof (EFI_PCI_EXPRESS_PLATFORM_POLICY),
> 
> -                                      &mPciExpressPlatformPolicy
> 
> -                                      );
> 
> -  } else {
> 
> -    //
> 
> -    // no protocol found, platform does not require the PCI Express initialization
> 
> -    //
> 
> -    return EFI_UNSUPPORTED;
> 
> -  }
> 
> -  return Status;
> 
> -}
> 
> -
> 
> -EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE
> 
> -GetPciExpressMps (
> 
> -  IN UINT8              Mps
> 
> -  )
> 
> -{
> 
> -  switch (Mps) {
> 
> -    case PCIE_MAX_PAYLOAD_SIZE_128B:
> 
> -      return EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_128B;
> 
> -    case PCIE_MAX_PAYLOAD_SIZE_256B:
> 
> -      return EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_256B;
> 
> -    case PCIE_MAX_PAYLOAD_SIZE_512B:
> 
> -      return EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_512B;
> 
> -    case PCIE_MAX_PAYLOAD_SIZE_1024B:
> 
> -      return EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_1024B;
> 
> -    case PCIE_MAX_PAYLOAD_SIZE_2048B:
> 
> -      return EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_2048B;
> 
> -    case PCIE_MAX_PAYLOAD_SIZE_4096B:
> 
> -      return EFI_PCI_EXPRESS_MAX_PAYLOAD_SIZE_4096B;
> 
> -  }
> 
> -  return EFI_PCI_EXPRESS_NOT_APPLICABLE;
> 
> -}
> 
> -
> 
> -EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE
> 
> -GetPciExpressMrrs (
> 
> -  IN UINT8              Mrrs
> 
> -  )
> 
> -{
> 
> -  switch (Mrrs) {
> 
> -    case PCIE_MAX_READ_REQ_SIZE_128B:
> 
> -      return EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_128B;
> 
> -    case PCIE_MAX_READ_REQ_SIZE_256B:
> 
> -      return EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_256B;
> 
> -    case PCIE_MAX_READ_REQ_SIZE_512B:
> 
> -      return EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_512B;
> 
> -    case PCIE_MAX_READ_REQ_SIZE_1024B:
> 
> -      return EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_1024B;
> 
> -    case PCIE_MAX_READ_REQ_SIZE_2048B:
> 
> -      return EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_2048B;
> 
> -    case PCIE_MAX_READ_REQ_SIZE_4096B:
> 
> -      return EFI_PCI_EXPRESS_MAX_READ_REQ_SIZE_4096B;
> 
> -  }
> 
> -  return EFI_PCI_EXPRESS_NOT_APPLICABLE;
> 
> -}
> 
> -
> 
> -EFI_PCI_EXPRESS_CTO_SUPPORT
> 
> -GetPciExpressCto (
> 
> -  IN UINT8              Cto
> 
> -  )
> 
> -{
> 
> -  switch (Cto) {
> 
> -    case PCIE_COMPLETION_TIMEOUT_50US_50MS:
> 
> -      return EFI_PCI_EXPRESS_CTO_DEFAULT;
> 
> -    case PCIE_COMPLETION_TIMEOUT_50US_100US:
> 
> -      return EFI_PCI_EXPRESS_CTO_RANGE_A1;
> 
> -    case PCIE_COMPLETION_TIMEOUT_1MS_10MS:
> 
> -      return EFI_PCI_EXPRESS_CTO_RANGE_A2;
> 
> -    case PCIE_COMPLETION_TIMEOUT_16MS_55MS:
> 
> -      return EFI_PCI_EXPRESS_CTO_RANGE_B1;
> 
> -    case PCIE_COMPLETION_TIMEOUT_65MS_210MS:
> 
> -      return EFI_PCI_EXPRESS_CTO_RANGE_B2;
> 
> -    case PCIE_COMPLETION_TIMEOUT_260MS_900MS:
> 
> -      return EFI_PCI_EXPRESS_CTO_RANGE_C1;
> 
> -    case PCIE_COMPLETION_TIMEOUT_1S_3_5S:
> 
> -      return EFI_PCI_EXPRESS_CTO_RANGE_C2;
> 
> -    case PCIE_COMPLETION_TIMEOUT_4S_13S:
> 
> -      return EFI_PCI_EXPRESS_CTO_RANGE_D1;
> 
> -    case PCIE_COMPLETION_TIMEOUT_17S_64S:
> 
> -      return EFI_PCI_EXPRESS_CTO_RANGE_D2;
> 
> -  }
> 
> -  return EFI_PCI_EXPRESS_NOT_APPLICABLE;
> 
> -}
> 
> -
> 
> -EFI_PCI_EXPRESS_EXTENDED_TAG
> 
> -GetPciExpressExtTag (
> 
> -  IN PCI_IO_DEVICE                        *PciDevice
> 
> -  )
> 
> -{
> 
> -  if (PciDevice->PciExpressCapabilityStructure.DeviceControl2.Bits.TenBitTagRequesterEnable) {
> 
> -    return EFI_PCI_EXPRESS_EXTENDED_TAG_10BIT;
> 
> -  } else if (PciDevice->PciExpressCapabilityStructure.DeviceControl.Bits.ExtendedTagField) {
> 
> -    return EFI_PCI_EXPRESS_EXTENDED_TAG_8BIT;
> 
> -  } else {
> 
> -    return EFI_PCI_EXPRESS_EXTENDED_TAG_5BIT;
> 
> -  }
> 
> -}
> 
> -
> 
> -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.
> 
> -
> 
> -  @param  PciDevice                 A pointer to PCI_IO_DEVICE
> 
> -  @param  PciExDeviceConfiguration  Pointer to EFI_PCI_EXPRESS_DEVICE_CONFIGURATION.
> 
> -                                    Used to pass the current state of device to
> 
> -                                    platform.
> 
> -
> 
> -  @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
> 
> -PciExpressPlatformNotifyDeviceState (
> 
> -  IN PCI_IO_DEVICE                        *PciDevice
> 
> -  )
> 
> -{
> 
> -  EFI_PCI_EXPRESS_DEVICE_CONFIGURATION      PciExDeviceConfiguration;
> 
> -
> 
> -  //
> 
> -  // get the device-specific state for the PCIe Max_Payload_Size feature
> 
> -  //
> 
> -  if (mPciExpressPlatformPolicy.Mps) {
> 
> -    PciExDeviceConfiguration.DeviceCtlMPS = GetPciExpressMps (
> 
> -                                              (UINT8)PciDevice->PciExpressCapabilityStructure.DeviceControl.Bits.MaxPayloadSize
> 
> -                                              );
> 
> -  } else {
> 
> -    PciExDeviceConfiguration.DeviceCtlMPS = EFI_PCI_EXPRESS_NOT_APPLICABLE;
> 
> -  }
> 
> -
> 
> -  //
> 
> -  // get the device-specific state for the PCIe Max_Read_Req_Size feature
> 
> -  //
> 
> -  if (mPciExpressPlatformPolicy.Mrrs) {
> 
> -    PciExDeviceConfiguration.DeviceCtlMRRS = GetPciExpressMrrs (
> 
> -                                              (UINT8)PciDevice->PciExpressCapabilityStructure.DeviceControl.Bits.MaxReadRequestSize
> 
> -                                              );
> 
> -  } else {
> 
> -    PciExDeviceConfiguration.DeviceCtlMRRS = EFI_PCI_EXPRESS_NOT_APPLICABLE;
> 
> -  }
> 
> -  //
> 
> -  // get the device-specific state for the PCIe Relax Order feature
> 
> -  //
> 
> -  if (mPciExpressPlatformPolicy.RelaxOrder) {
> 
> -    PciExDeviceConfiguration.DeviceCtlRelaxOrder = PciDevice-
> >PciExpressCapabilityStructure.DeviceControl.Bits.RelaxedOrdering
> 
> -                                                      ? EFI_PCI_EXPRESS_RO_ENABLE
> 
> -                                                      : EFI_PCI_EXPRESS_RO_DISABLE;
> 
> -  } else {
> 
> -    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;
> 
> -  }
> 
> -
> 
> -  //
> 
> -  // get the device-specific state for the PCIe CTO feature
> 
> -  //
> 
> -  if (mPciExpressPlatformPolicy.Cto) {
> 
> -    PciExDeviceConfiguration.CTOsupport = PciDevice-
> >PciExpressCapabilityStructure.DeviceControl2.Bits.CompletionTimeoutDisable
> 
> -                                          ? EFI_PCI_EXPRESS_CTO_DET_DISABLE
> 
> -                                          : GetPciExpressCto (
> 
> -                                              (UINT8)PciDevice->PciExpressCapabilityStructure.DeviceControl2.Bits.CompletionTimeoutValue
> 
> -                                              );
> 
> -  } else {
> 
> -    PciExDeviceConfiguration.CTOsupport = EFI_PCI_EXPRESS_NOT_APPLICABLE;
> 
> -  }
> 
> -
> 
> -  //
> 
> -  // get the device-specific state for the PCIe AtomicOp feature
> 
> -  //
> 
> -  if (mPciExpressPlatformPolicy.AtomicOp) {
> 
> -    PciExDeviceConfiguration.DeviceCtl2AtomicOp.Enable_AtomicOpRequester
> 
> -    = (UINT8)PciDevice->PciExpressCapabilityStructure.DeviceControl2.Bits.AtomicOpRequester;
> 
> -    PciExDeviceConfiguration.DeviceCtl2AtomicOp.Enable_AtomicOpEgressBlocking
> 
> -    = (UINT8)PciDevice->PciExpressCapabilityStructure.DeviceControl2.Bits.AtomicOpEgressBlocking;
> 
> -  } else {
> 
> -    PciExDeviceConfiguration.DeviceCtl2AtomicOp.Override = 0;
> 
> -    PciExDeviceConfiguration.DeviceCtl2AtomicOp.Enable_AtomicOpRequester = 0;
> 
> -    PciExDeviceConfiguration.DeviceCtl2AtomicOp.Enable_AtomicOpEgressBlocking = 0;
> 
> -  }
> 
> -  //
> 
> -  // get the device-specific state for LTR mechanism in the function
> 
> -  //
> 
> -  if (mPciExpressPlatformPolicy.Ltr) {
> 
> -    PciExDeviceConfiguration.DeviceCtl2LTR = PciDevice->PciExpressCapabilityStructure.DeviceControl2.Bits.LtrMechanism
> 
> -                                                ? EFI_PCI_EXPRESS_LTR_ENABLE
> 
> -                                                : EFI_PCI_EXPRESS_LTR_DISABLE;
> 
> -  } else {
> 
> -    PciExDeviceConfiguration.DeviceCtl2LTR = EFI_PCI_EXPRESS_NOT_APPLICABLE;
> 
> -  }
> 
> -
> 
> -  //
> 
> -  // get the device-specific state for the PCie Extended Tag in the function
> 
> -  //
> 
> -  if (mPciExpressPlatformPolicy.ExtTag) {
> 
> -    PciExDeviceConfiguration.DeviceCtlExtTag = GetPciExpressExtTag (PciDevice);
> 
> -  } else {
> 
> -    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;
> 
> -  }
> 
> -
> 
> -  //
> 
> -  // get the device-specific Common CLock Configuration value
> 
> -  //
> 
> -  if (mPciExpressPlatformPolicy.Ccc) {
> 
> -    PciExDeviceConfiguration.LinkCtlCommonClkCfg =
> 
> -        PciDevice->PciExpressCapabilityStructure.LinkControl.Bits.CommonClockConfiguration ?
> 
> -            EFI_PCI_EXPRESS_CLK_CFG_COMMON : EFI_PCI_EXPRESS_CLK_CFG_ASYNCH;
> 
> -  } else {
> 
> -    PciExDeviceConfiguration.LinkCtlCommonClkCfg = EFI_PCI_EXPRESS_NOT_APPLICABLE;
> 
> -  }
> 
> -
> 
> -  if (mPciExPlatformProtocol != NULL) {
> 
> -    return mPciExPlatformProtocol->NotifyDeviceState (
> 
> -                                    mPciExPlatformProtocol,
> 
> -                                    PciDevice->Handle,
> 
> -                                    sizeof (EFI_PCI_EXPRESS_DEVICE_CONFIGURATION),
> 
> -                                    &PciExDeviceConfiguration
> 
> -                                    );
> 
> -  } else if (mPciExOverrideProtocol != NULL) {
> 
> -    return mPciExOverrideProtocol->NotifyDeviceState (
> 
> -                                    mPciExOverrideProtocol,
> 
> -                                    PciDevice->Handle,
> 
> -                                    sizeof (EFI_PCI_EXPRESS_DEVICE_CONFIGURATION),
> 
> -                                    &PciExDeviceConfiguration
> 
> -                                    );
> 
> -  } else {
> 
> -    //
> 
> -    // unexpected error
> 
> -    //
> 
> -    return EFI_UNSUPPORTED;
> 
> -  }
> 
> -}
> 
> -
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.h
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.h
> deleted file mode 100644
> index 4653c79..0000000
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.h
> +++ /dev/null
> @@ -1,119 +0,0 @@
> -/** @file
> 
> -  This file encapsulate the usage of PCI Platform Protocol
> 
> -
> 
> -  This file define the necessary hooks used to obtain the platform
> 
> -  level data and policies which could be used in the PCI Enumeration phases
> 
> -
> 
> -Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> 
> -SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> -
> 
> -**/
> 
> -
> 
> -
> 
> -#ifndef _EFI_PCI_PLATFORM_SUPPORT_H_
> 
> -#define _EFI_PCI_PLATFORM_SUPPORT_H_
> 
> -
> 
> -
> 
> -/**
> 
> -  This function retrieves the PCI Express Platform Protocols published by platform
> 
> -  @retval EFI_STATUS          direct return status from the LocateProtocol ()
> 
> -                              boot service for the PCI Express Override Protocol
> 
> -          EFI_SUCCESS         The PCI Express Platform Protocol is found
> 
> -**/
> 
> -EFI_STATUS
> 
> -GetPciExpressProtocol (
> 
> -  );
> 
> -
> 
> -/**
> 
> -  This function indicates that the platform has published the PCI Express Platform
> 
> -  Protocol (or PCI Express Override Protocol) to indicate that this driver can
> 
> -  initialize the PCI Express features.
> 
> -  @retval     TRUE or FALSE
> 
> -**/
> 
> -BOOLEAN
> 
> -IsPciExpressProtocolPresent (
> 
> -  );
> 
> -
> 
> -/**
> 
> -  This function gets the platform requirement to initialize the list of PCI Express
> 
> -  features from the protocol definition supported.
> 
> -  This function should be called after the LocatePciPlatformProtocol.
> 
> -  @retval EFI_SUCCESS           return by platform to acknowledge the list of
> 
> -                                PCI Express feature to be configured
> 
> -                                (in mPciExpressPlatformPolicy)
> 
> -          EFI_INVALID_PARAMETER platform does not support the protocol arguements
> 
> -                                passed
> 
> -          EFI_UNSUPPORTED       platform did not published the protocol
> 
> -**/
> 
> -EFI_STATUS
> 
> -PciExpressPlatformGetPolicy (
> 
> -  );
> 
> -
> 
> -/**
> 
> -  Gets the PCI device-specific platform policy from the PCI 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  PciDevice     A pointer to PCI_IO_DEVICE
> 
> -
> 
> -  @retval EFI_STATUS    The direct status from the PCI Platform Protocol
> 
> -  @retval EFI_SUCCESS   On return of predetermined PCI features defaults, for
> 
> -                        the case when protocol returns as EFI_UNSUPPORTED to
> 
> -                        indicate PCI device exist and it has no platform policy
> 
> -                        defined. Also, on returns when no PCI Platform Protocol
> 
> -                        exist.
> 
> -**/
> 
> -EFI_STATUS
> 
> -PciExpressPlatformGetDevicePolicy (
> 
> -  IN PCI_IO_DEVICE          *PciDevice
> 
> -  );
> 
> -
> 
> -/**
> 
> -  Notifies the platform about the current PCI Express state of the device.
> 
> -
> 
> -  @param  PciDevice                 A pointer to PCI_IO_DEVICE
> 
> -  @param  PciExDeviceConfiguration  Pointer to EFI_PCI_EXPRESS_DEVICE_CONFIGURATION.
> 
> -                                    Used to pass the current state of device to
> 
> -                                    platform.
> 
> -
> 
> -  @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
> 
> -PciExpressPlatformNotifyDeviceState (
> 
> -  IN PCI_IO_DEVICE                        *PciDevice
> 
> -  );
> 
> -
> 
> -/**
> 
> -  Routine to translate the given device-specific platform policy from type
> 
> -  EFI_PCI_CONF_MAX_PAYLOAD_SIZE to HW-specific value, as per PCI Base Specification
> 
> -  Revision 4.0; for the PCI feature Max_Payload_Size.
> 
> -
> 
> -  @param  MPS     Input device-specific policy should be in terms of type
> 
> -                  EFI_PCI_CONF_MAX_PAYLOAD_SIZE
> 
> -
> 
> -  @retval         Range values for the Max_Payload_Size as defined in the PCI
> 
> -                  Base Specification 4.0
> 
> -**/
> 
> -UINT8
> 
> -SetDevicePolicyPciExpressMps (
> 
> -  IN  UINT8                   MPS
> 
> -);
> 
> -
> 
> -/**
> 
> -  Routine to translate the given device-specific platform policy from type
> 
> -  EFI_PCI_CONF_MAX_READ_REQ_SIZE to HW-specific value, as per PCI Base Specification
> 
> -  Revision 4.0; for the PCI feature Max_Read_Req_Size.
> 
> -
> 
> -  @param  MRRS    Input device-specific policy should be in terms of type
> 
> -                  EFI_PCI_CONF_MAX_READ_REQ_SIZE
> 
> -
> 
> -  @retval         Range values for the Max_Read_Req_Size as defined in the PCI
> 
> -                  Base Specification 4.0
> 
> -**/
> 
> -UINT8
> 
> -SetDevicePolicyPciExpressMrrs (
> 
> -  IN  UINT8                   MRRS
> 
> -);
> 
> -#endif
> 
> --
> 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 03/15] MdeModulePkg/PciBus: Rename Cache PCIe Capability Structure
  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
  0 siblings, 0 replies; 33+ messages in thread
From: Ni, Ray @ 2020-05-13  6:31 UTC (permalink / raw)
  To: Javeed, Ashraf, devel@edk2.groups.io; +Cc: Wang, Jian J, Wu, Hao A

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Javeed, Ashraf <ashraf.javeed@intel.com>
> Sent: Monday, May 11, 2020 12:14 AM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> Subject: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 03/15] MdeModulePkg/PciBus: Rename Cache PCIe Capability
> Structure
> 
> 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
> 
> Rename the cache PCIe Capability Structure.
> 
> 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>
> ---
>  MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h               | 2 +-
>  MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
> index 5a7c1c2..9947203 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
> @@ -269,7 +269,7 @@ struct _PCI_IO_DEVICE {
>    // For PCI Express Capability List Structure
>    //
>    UINT8                                     PciExpressCapabilityOffset;
> -  PCI_CAPABILITY_PCIEXP                     PciExpressCapabilityStructure;
> +  PCI_CAPABILITY_PCIEXP                     PciExpressCapability;
>    //
>    // For SR-IOV
>    //
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
> index c9e52ea..0f43e43 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
> @@ -2162,7 +2162,7 @@ CreatePciIoDevice (
>                    EfiPciIoWidthUint8,
>                    PciIoDevice->PciExpressCapabilityOffset,
>                    sizeof (PCI_CAPABILITY_PCIEXP) / sizeof (UINT8),
> -                  &PciIoDevice->PciExpressCapabilityStructure
> +                  &PciIoDevice->PciExpressCapability
>                    );
>    }
> 
> --
> 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 06/15] MdeModulePkg/PciBusDxe: Add the framework to init PCIe features
  2020-05-10 16:14 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 06/15] MdeModulePkg/PciBusDxe: Add the framework to init PCIe features Javeed, Ashraf
@ 2020-05-13  6:39   ` Ni, Ray
  2020-05-13  6:46     ` Javeed, Ashraf
  0 siblings, 1 reply; 33+ messages in thread
From: Ni, Ray @ 2020-05-13  6:39 UTC (permalink / raw)
  To: Javeed, Ashraf, devel@edk2.groups.io; +Cc: Wang, Jian J, Wu, Hao A

> +   //                 "  Device   MPS MRRS RO NS CTO LTR\n"
1. Can you update above comments to below?
        //                 "Device   MPS MRRS RO NS CTO LTR AtomicOp ExtTag CCC\n"
It explains why "%03x" or "%08x" is chosen in below DEBUG output.

> +  DEBUG ((
> +    DEBUG_INFO, "  %02x|%02x|%02x %03x %04x %02x %02x %03x %03x %08x %06x %03x\n",


> +}
> +        }
> +        //DEBUG ((DEBUG_INFO, "  PCIe %s feature...\n", mPcieFeatureStr[Index]));
2. Can you please remove the above commented debug message?

With the two comments addressed, Reviewed-by: Ray Ni <ray.ni@intel.com>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 07/15] MdeModulePkg/PciBusDxe: Enable MaxPayloadSize feature
  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
  0 siblings, 1 reply; 33+ messages in thread
From: Ni, Ray @ 2020-05-13  6:45 UTC (permalink / raw)
  To: Javeed, Ashraf, devel@edk2.groups.io; +Cc: Wang, Jian J, Wu, Hao A

>  /**
> @@ -220,6 +226,7 @@ PcieNotifyDeviceState (
> 
>    CopyMem (&PcieDeviceState, &PciIoDevice->DeviceState, sizeof (PciIoDevice->DeviceState));
> 
> +  PcieDeviceState.MaxPayloadSize      = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.MaxPayloadSize;

My original idea is to directly use the PciIoDevice->DeviceState.
Your patch is even better because if the policy value is AUTO, it's better to report the actual value in HW to platform instead of AUTO.

Can you remove the CopyMem() call?

Thanks,
Ray

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 06/15] MdeModulePkg/PciBusDxe: Add the framework to init PCIe features
  2020-05-13  6:39   ` Ni, Ray
@ 2020-05-13  6:46     ` Javeed, Ashraf
  0 siblings, 0 replies; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-13  6:46 UTC (permalink / raw)
  To: Ni, Ray, devel@edk2.groups.io; +Cc: Wang, Jian J, Wu, Hao A

Yes, both the comments shall be fixed.
Thanks
Ashraf

> -----Original Message-----
> From: Ni, Ray <ray.ni@intel.com>
> Sent: Wednesday, May 13, 2020 12:09 PM
> To: Javeed, Ashraf <ashraf.javeed@intel.com>; devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A
> <hao.a.wu@intel.com>
> Subject: RE: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 06/15]
> MdeModulePkg/PciBusDxe: Add the framework to init PCIe features
> 
> > +   //                 "  Device   MPS MRRS RO NS CTO LTR\n"
> 1. Can you update above comments to below?
>         //                 "Device   MPS MRRS RO NS CTO LTR AtomicOp ExtTag
> CCC\n"
> It explains why "%03x" or "%08x" is chosen in below DEBUG output.
> 
> > +  DEBUG ((
> > +    DEBUG_INFO, "  %02x|%02x|%02x %03x %04x %02x %02x %03x %03x
> %08x %06x %03x\n",
> 
> 
> > +}
> > +        }
> > +        //DEBUG ((DEBUG_INFO, "  PCIe %s feature...\n",
> mPcieFeatureStr[Index]));
> 2. Can you please remove the above commented debug message?
> 
> With the two comments addressed, Reviewed-by: Ray Ni
> <ray.ni@intel.com>


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 09/15] MdeModulePkg/PciBusDxe: Enable RelaxedOrdering feature
  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
  0 siblings, 0 replies; 33+ messages in thread
From: Ni, Ray @ 2020-05-13  6:49 UTC (permalink / raw)
  To: Javeed, Ashraf, devel@edk2.groups.io; +Cc: Wang, Jian J, Wu, Hao A

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Javeed, Ashraf <ashraf.javeed@intel.com>
> Sent: Monday, May 11, 2020 12:14 AM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> Subject: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 09/15] MdeModulePkg/PciBusDxe: Enable RelaxedOrdering feature
> 
> 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
> 
> Add the Program phase feature init routine for RelaxedOrdering
> PCIe feature.
> 
> 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/PcieFeatureSupport.c |  3 +++
>  MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c       | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
>  MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h       |  7 +++++++
>  3 files changed, 59 insertions(+)
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> index e1f739e..9948e17 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> @@ -56,6 +56,8 @@ PCIE_FEATURE_ENTRY  mPcieFeatures[] = {
>                TRUE, { TRUE,  TRUE }, { MaxPayloadSizeScan,      MaxPayloadSizeProgram } },
>    { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, MaxReadRequestSize),
>                TRUE, { TRUE,  TRUE }, { NULL,                    MaxReadRequestSizeProgram } },
> +  { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, RelaxedOrdering),
> +              TRUE, { TRUE,  TRUE }, { NULL,                    RelaxedOrderingProgram } },
>  };
> 
>  /**
> @@ -230,6 +232,7 @@ PcieNotifyDeviceState (
> 
>    PcieDeviceState.MaxPayloadSize      = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.MaxPayloadSize;
>    PcieDeviceState.MaxReadRequestSize  = (UINT8)PciIoDevice-
> >PciExpressCapability.DeviceControl.Bits.MaxReadRequestSize;
> +  PcieDeviceState.RelaxedOrdering     = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.RelaxedOrdering;
>    return mPciePlatformProtocol->NotifyDeviceState (
>                                    mPciePlatformProtocol,
>                                    PciIoDevice->Handle,
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
> index a7591e6..5216dac 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
> @@ -167,3 +167,52 @@ MaxReadRequestSizeProgram (
>    return EFI_SUCCESS;
>  }
> 
> +
> +/**
> +  Program the PCIe Device Control register Relaxed Ordering field per platform policy.
> +
> +  @param PciDevice              A pointer to the PCI_IO_DEVICE instance.
> +  @param Level                  The level of the PCI device in the heirarchy.
> +                                Level of root ports is 0.
> +  @param Context                Pointer to feature specific context.
> +
> +  @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
> +RelaxedOrderingProgram (
> +  IN PCI_IO_DEVICE *PciDevice,
> +  IN UINTN         Level,
> +  IN VOID          **Context
> +  )
> +{
> +  ASSERT (*Context == NULL);
> +
> +  if (PciDevice->DeviceState.RelaxedOrdering == EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE ||
> +      PciDevice->DeviceState.RelaxedOrdering == EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (PciDevice->PciExpressCapability.DeviceControl.Bits.RelaxedOrdering != PciDevice->DeviceState.RelaxedOrdering) {
> +    DEBUG ((
> +      DEBUG_INFO, "  %a [%02d|%02d|%02d]: %x -> %x\n",
> +      __FUNCTION__, PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber,
> +      PciDevice->PciExpressCapability.DeviceControl.Bits.RelaxedOrdering,
> +      PciDevice->DeviceState.RelaxedOrdering
> +      ));
> +    PciDevice->PciExpressCapability.DeviceControl.Bits.RelaxedOrdering = PciDevice->DeviceState.RelaxedOrdering;
> +
> +    return PciDevice->PciIo.Pci.Write (
> +                                  &PciDevice->PciIo,
> +                                  EfiPciIoWidthUint16,
> +                                  PciDevice->PciExpressCapabilityOffset
> +                                  + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl),
> +                                  1,
> +                                  &PciDevice->PciExpressCapability.DeviceControl.Uint16
> +                                  );
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
> index 40e28b8..7d70f06 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
> @@ -31,4 +31,11 @@ MaxReadRequestSizeProgram (
>    IN VOID          **Context
>    );
> 
> +EFI_STATUS
> +RelaxedOrderingProgram (
> +  IN PCI_IO_DEVICE *PciDevice,
> +  IN UINTN         Level,
> +  IN VOID          **Context
> +  );
> +
>  #endif
> --
> 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 08/15] MdeModulePkg/PciBusDxe: Enable MaxReadRequestSize feature
  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
  0 siblings, 0 replies; 33+ messages in thread
From: Ni, Ray @ 2020-05-13  6:49 UTC (permalink / raw)
  To: Javeed, Ashraf, devel@edk2.groups.io; +Cc: Wang, Jian J, Wu, Hao A

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Javeed, Ashraf <ashraf.javeed@intel.com>
> Sent: Monday, May 11, 2020 12:14 AM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> Subject: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 08/15] MdeModulePkg/PciBusDxe: Enable MaxReadRequestSize
> feature
> 
> 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
> 
> Add the Program phase feature init routine for MaxReadRequestSize
> PCIe feature.
> 
> 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/PcieFeatureSupport.c |  3 +++
>  MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c       | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h       |  6 ++++++
>  3 files changed, 59 insertions(+)
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> index 634e26b..e1f739e 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> @@ -54,6 +54,8 @@ PCIE_FEATURE_ENTRY  mPcieFeatures[] = {
>    //
>    { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, MaxPayloadSize),
>                TRUE, { TRUE,  TRUE }, { MaxPayloadSizeScan,      MaxPayloadSizeProgram } },
> +  { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, MaxReadRequestSize),
> +              TRUE, { TRUE,  TRUE }, { NULL,                    MaxReadRequestSizeProgram } },
>  };
> 
>  /**
> @@ -227,6 +229,7 @@ PcieNotifyDeviceState (
>    CopyMem (&PcieDeviceState, &PciIoDevice->DeviceState, sizeof (PciIoDevice->DeviceState));
> 
>    PcieDeviceState.MaxPayloadSize      = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.MaxPayloadSize;
> +  PcieDeviceState.MaxReadRequestSize  = (UINT8)PciIoDevice-
> >PciExpressCapability.DeviceControl.Bits.MaxReadRequestSize;
>    return mPciePlatformProtocol->NotifyDeviceState (
>                                    mPciePlatformProtocol,
>                                    PciIoDevice->Handle,
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
> index d1a78f7..a7591e6 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
> @@ -117,3 +117,53 @@ MaxPayloadSizeProgram (
>    return EFI_SUCCESS;
>  }
> 
> +/**
> +  Program the PCIe Device Control register Max. Read Request Size field per platform policy.
> +
> +  @param PciDevice              A pointer to the PCI_IO_DEVICE instance.
> +  @param Level                  The level of the PCI device in the heirarchy.
> +                                Level of root ports is 0.
> +  @param Context                Pointer to feature specific context.
> +
> +  @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
> +MaxReadRequestSizeProgram (
> +  IN PCI_IO_DEVICE *PciDevice,
> +  IN UINTN         Level,
> +  IN VOID          **Context
> +  )
> +{
> +  ASSERT (*Context == NULL);
> +
> +  if (PciDevice->DeviceState.MaxReadRequestSize == EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE) {
> +    return EFI_SUCCESS;
> +  }
> +  if (PciDevice->DeviceState.MaxReadRequestSize == EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) {
> +    PciDevice->DeviceState.MaxReadRequestSize = (UINT8) PciDevice-
> >PciExpressCapability.DeviceControl.Bits.MaxPayloadSize;
> +  }
> +
> +  if (PciDevice->PciExpressCapability.DeviceControl.Bits.MaxReadRequestSize != PciDevice-
> >DeviceState.MaxReadRequestSize) {
> +    DEBUG ((
> +      DEBUG_INFO, "  %a [%02d|%02d|%02d]: %x -> %x\n",
> +      __FUNCTION__, PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber,
> +      PciDevice->PciExpressCapability.DeviceControl.Bits.MaxReadRequestSize,
> +      PciDevice->DeviceState.MaxReadRequestSize
> +      ));
> +    PciDevice->PciExpressCapability.DeviceControl.Bits.MaxReadRequestSize = PciDevice->DeviceState.MaxReadRequestSize;
> +
> +    return PciDevice->PciIo.Pci.Write (
> +                                  &PciDevice->PciIo,
> +                                  EfiPciIoWidthUint16,
> +                                  PciDevice->PciExpressCapabilityOffset
> +                                  + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl),
> +                                  1,
> +                                  &PciDevice->PciExpressCapability.DeviceControl.Uint16
> +                                  );
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
> index 7b820e8..40e28b8 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
> @@ -24,5 +24,11 @@ MaxPayloadSizeProgram (
>    IN VOID          **Context
>    );
> 
> +EFI_STATUS
> +MaxReadRequestSizeProgram (
> +  IN PCI_IO_DEVICE *PciDevice,
> +  IN UINTN         Level,
> +  IN VOID          **Context
> +  );
> 
>  #endif
> --
> 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 11/15] MdeModulePkg/PciBusDxe: Enable CompletionTimeout feature
  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
  0 siblings, 0 replies; 33+ messages in thread
From: Ni, Ray @ 2020-05-13  6:49 UTC (permalink / raw)
  To: Javeed, Ashraf, devel@edk2.groups.io; +Cc: Wang, Jian J, Wu, Hao A

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Javeed, Ashraf <ashraf.javeed@intel.com>
> Sent: Monday, May 11, 2020 12:14 AM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> Subject: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 11/15] MdeModulePkg/PciBusDxe: Enable CompletionTimeout feature
> 
> 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
> 
> Add the Program phase feature init routine for CompletionTimeout
> PCIe feature.
> 
> 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/PcieFeatureSupport.c |  3 +++
>  MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c       | 91
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h       | 15 +++++++++++++++
>  3 files changed, 109 insertions(+)
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> index 6bf06b0..e6d3363 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> @@ -60,6 +60,8 @@ PCIE_FEATURE_ENTRY  mPcieFeatures[] = {
>                TRUE, { TRUE,  TRUE }, { NULL,                    RelaxedOrderingProgram } },
>    { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, NoSnoop),
>                TRUE, { TRUE,  TRUE }, { NULL,                    NoSnoopProgram } },
> +  { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, CompletionTimeout),
> +              TRUE, { TRUE,  TRUE }, { NULL,                    CompletionTimeoutProgram}},
>  };
> 
>  /**
> @@ -236,6 +238,7 @@ PcieNotifyDeviceState (
>    PcieDeviceState.MaxReadRequestSize  = (UINT8)PciIoDevice-
> >PciExpressCapability.DeviceControl.Bits.MaxReadRequestSize;
>    PcieDeviceState.RelaxedOrdering     = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.RelaxedOrdering;
>    PcieDeviceState.NoSnoop             = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.NoSnoop;
> +  PcieDeviceState.CompletionTimeout   = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl2.Uint16 & 0x1F;
> 
>    return mPciePlatformProtocol->NotifyDeviceState (
>                                    mPciePlatformProtocol,
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
> index 6c22feb..ca4052f 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
> @@ -267,3 +267,94 @@ NoSnoopProgram (
>    return EFI_SUCCESS;
>  }
> 
> +/**
> +  Program PCIe feature Completion Timeout per the device-specific platform policy.
> +
> +  @param PciIoDevice            A pointer to the PCI_IO_DEVICE.
> +  @param Level                  The level of the PCI device in the heirarchy.
> +                                Level of root ports is 0.
> +  @param Context                Pointer to feature specific context.
> +
> +  @retval EFI_SUCCESS           The feature is initialized successfully.
> +  @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
> +CompletionTimeoutProgram (
> +  IN PCI_IO_DEVICE *PciIoDevice,
> +  IN UINTN         Level,
> +  IN VOID          **Context
> +  )
> +{
> +  PCI_REG_PCIE_DEVICE_CONTROL2    DevicePolicy;
> +  UINTN                           RangeIndex;
> +  UINT8                           SubRanges;
> +
> +  if (PciIoDevice->DeviceState.CompletionTimeout == EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE ||
> +      PciIoDevice->DeviceState.CompletionTimeout == EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // Interpret the policy value as BIT[0:4] in Device Control 2 Register
> +  //
> +  DevicePolicy.Uint16 = (UINT16) PciIoDevice->DeviceState.CompletionTimeout;
> +
> +  //
> +  // Ignore when device doesn't support to disable Completion Timeout while the policy requests.
> +  //
> +  if (PciIoDevice->PciExpressCapability.DeviceCapability2.Bits.CompletionTimeoutDisable == 0 &&
> +      DevicePolicy.Bits.CompletionTimeoutDisable == 1) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (DevicePolicy.Bits.CompletionTimeoutValue != 0) {
> +    //
> +    // Ignore when the policy requests to use a range that's not supported by the device.
> +    // RangeIndex is 0 ~ 3 for Range A ~ D.
> +    //
> +    RangeIndex = DevicePolicy.Bits.CompletionTimeoutValue >> 2;
> +    if ((PciIoDevice->PciExpressCapability.DeviceCapability2.Bits.CompletionTimeoutRanges & (1 < RangeIndex)) == 0) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +
> +    //
> +    // Ignore when the policy doesn't request one and only one sub-range for a certain range.
> +    //
> +    SubRanges = (UINT8) (DevicePolicy.Bits.CompletionTimeoutValue & (BIT0 | BIT1));
> +    if (SubRanges != BIT0 && SubRanges != BIT1) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  }
> +
> +  if ((PciIoDevice->PciExpressCapability.DeviceControl2.Bits.CompletionTimeoutDisable
> +       != DevicePolicy.Bits.CompletionTimeoutDisable) ||
> +      (PciIoDevice->PciExpressCapability.DeviceControl2.Bits.CompletionTimeoutValue
> +       != DevicePolicy.Bits.CompletionTimeoutValue)) {
> +    DEBUG ((
> +      DEBUG_INFO, "  %a [%02d|%02d|%02d]: Disable = %x -> %x, Timeout = %x -> %x.\n",
> +      __FUNCTION__, PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber,
> +      PciIoDevice->PciExpressCapability.DeviceControl2.Bits.CompletionTimeoutDisable,
> +      DevicePolicy.Bits.CompletionTimeoutDisable,
> +      PciIoDevice->PciExpressCapability.DeviceControl2.Bits.CompletionTimeoutValue,
> +      DevicePolicy.Bits.CompletionTimeoutValue
> +      ));
> +    PciIoDevice->PciExpressCapability.DeviceControl2.Bits.CompletionTimeoutDisable
> +                      = DevicePolicy.Bits.CompletionTimeoutDisable;
> +    PciIoDevice->PciExpressCapability.DeviceControl2.Bits.CompletionTimeoutValue
> +                      = DevicePolicy.Bits.CompletionTimeoutValue;
> +
> +    return PciIoDevice->PciIo.Pci.Write (
> +                                  &PciIoDevice->PciIo,
> +                                  EfiPciIoWidthUint16,
> +                                  PciIoDevice->PciExpressCapabilityOffset
> +                                  + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2),
> +                                  1,
> +                                  &PciIoDevice->PciExpressCapability.DeviceControl2.Uint16
> +                                  );
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
> index 60b8742..bdb7004 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
> @@ -45,4 +45,19 @@ NoSnoopProgram (
>    IN VOID          **Context
>    );
> 
> +/**
> +  Program PCIE feature Completion Timeout per the device-specific platform policy.
> +
> +  @param PciIoDevice      A pointer to the PCI_IO_DEVICE.
> +
> +  @retval EFI_SUCCESS           The feature is initialized successfully.
> +  @retval EFI_INVALID_PARAMETER The policy is not supported by the device.
> +**/
> +EFI_STATUS
> +CompletionTimeoutProgram (
> +  IN PCI_IO_DEVICE *PciIoDevice,
> +  IN UINTN         Level,
> +  IN VOID          **Context
> +  );
> +
>  #endif
> --
> 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 10/15] MdeModulePkg/PciBusDxe: Enable NoSnoop feature
  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
  0 siblings, 0 replies; 33+ messages in thread
From: Ni, Ray @ 2020-05-13  6:49 UTC (permalink / raw)
  To: Javeed, Ashraf, devel@edk2.groups.io; +Cc: Wang, Jian J, Wu, Hao A

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Javeed, Ashraf <ashraf.javeed@intel.com>
> Sent: Monday, May 11, 2020 12:14 AM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> Subject: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 10/15] MdeModulePkg/PciBusDxe: Enable NoSnoop feature
> 
> 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
> 
> Add the Program phase feature init routine for NoSnoop
> PCIe feature.
> 
> 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/PcieFeatureSupport.c |  4 ++++
>  MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c       | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h       |  7 +++++++
>  3 files changed, 62 insertions(+)
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> index 9948e17..6bf06b0 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> @@ -58,6 +58,8 @@ PCIE_FEATURE_ENTRY  mPcieFeatures[] = {
>                TRUE, { TRUE,  TRUE }, { NULL,                    MaxReadRequestSizeProgram } },
>    { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, RelaxedOrdering),
>                TRUE, { TRUE,  TRUE }, { NULL,                    RelaxedOrderingProgram } },
> +  { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, NoSnoop),
> +              TRUE, { TRUE,  TRUE }, { NULL,                    NoSnoopProgram } },
>  };
> 
>  /**
> @@ -233,6 +235,8 @@ PcieNotifyDeviceState (
>    PcieDeviceState.MaxPayloadSize      = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.MaxPayloadSize;
>    PcieDeviceState.MaxReadRequestSize  = (UINT8)PciIoDevice-
> >PciExpressCapability.DeviceControl.Bits.MaxReadRequestSize;
>    PcieDeviceState.RelaxedOrdering     = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.RelaxedOrdering;
> +  PcieDeviceState.NoSnoop             = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.NoSnoop;
> +
>    return mPciePlatformProtocol->NotifyDeviceState (
>                                    mPciePlatformProtocol,
>                                    PciIoDevice->Handle,
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
> index 5216dac..6c22feb 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
> @@ -216,3 +216,54 @@ RelaxedOrderingProgram (
>    return EFI_SUCCESS;
>  }
> 
> +/**
> +  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.
> +  @param Level                  The level of the PCI device in the heirarchy.
> +                                Level of root ports is 0.
> +  @param Context                Pointer to feature specific context.
> +
> +  @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
> +NoSnoopProgram (
> +  IN PCI_IO_DEVICE *PciDevice,
> +  IN UINTN         Level,
> +  IN VOID          **Context
> +  )
> +{
> +  ASSERT (*Context == NULL);
> +
> +  if (PciDevice->DeviceState.NoSnoop == EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE ||
> +      PciDevice->DeviceState.NoSnoop == EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO) {
> +    return EFI_SUCCESS;
> +  }
> +
> +
> +  if (PciDevice->PciExpressCapability.DeviceControl.Bits.NoSnoop != PciDevice->DeviceState.NoSnoop) {
> +    DEBUG ((
> +      DEBUG_INFO, "  %a [%02d|%02d|%02d]: %x -> %x\n",
> +      __FUNCTION__, PciDevice->BusNumber, PciDevice->DeviceNumber, PciDevice->FunctionNumber,
> +      PciDevice->PciExpressCapability.DeviceControl.Bits.NoSnoop,
> +      PciDevice->DeviceState.NoSnoop
> +      ));
> +    PciDevice->PciExpressCapability.DeviceControl.Bits.NoSnoop = PciDevice->DeviceState.NoSnoop;
> +
> +    return PciDevice->PciIo.Pci.Write (
> +                                  &PciDevice->PciIo,
> +                                  EfiPciIoWidthUint16,
> +                                  PciDevice->PciExpressCapabilityOffset
> +                                  + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl),
> +                                  1,
> +                                  &PciDevice->PciExpressCapability.DeviceControl.Uint16
> +                                  );
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
> index 7d70f06..60b8742 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
> @@ -38,4 +38,11 @@ RelaxedOrderingProgram (
>    IN VOID          **Context
>    );
> 
> +EFI_STATUS
> +NoSnoopProgram (
> +  IN PCI_IO_DEVICE *PciDevice,
> +  IN UINTN         Level,
> +  IN VOID          **Context
> +  );
> +
>  #endif
> --
> 2.21.0.windows.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 12/15] MdeModulePkg/PciBusDxe: Enable LTR feature
  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
  0 siblings, 1 reply; 33+ messages in thread
From: Ni, Ray @ 2020-05-13  6:49 UTC (permalink / raw)
  To: Javeed, Ashraf, devel@edk2.groups.io; +Cc: Wang, Jian J, Wu, Hao A

> +EFI_STATUS
> +LtrScan (
> +  IN  PCI_IO_DEVICE *PciIoDevice,
> +  IN  UINTN         Level,
> +  IN  VOID          **Context
> +  )
> +{
> +  BOOLEAN           *Ltr;
> +  ASSERT (Level <= PCI_MAX_BUS);
> +  //ASSERT (Context != NULL);

Why the "ASSERT (Context != NULL)" is commented out?

Thanks,
Ray


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-devel] [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 13/15] MdeModulePkg/PciBusDxe: Enable AtomicOp feature
  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   ` Ni, Ray
  0 siblings, 0 replies; 33+ messages in thread
From: Ni, Ray @ 2020-05-13  6:51 UTC (permalink / raw)
  To: devel@edk2.groups.io, Javeed, Ashraf; +Cc: Wang, Jian J, Wu, Hao A

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Javeed, Ashraf
> Sent: Monday, May 11, 2020 12:14 AM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>
> Subject: [edk2-devel] [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 13/15] MdeModulePkg/PciBusDxe: Enable AtomicOp
> feature
> 
> 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
> 
> Add the Program phase feature init routine for AtomicOp
> PCIe feature.
> 
> 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/PcieFeatureSupport.c |  3 +++
>  MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c       | 62
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h       | 16 ++++++++++++++++
>  3 files changed, 81 insertions(+)
> 
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> index 35aaffa..401521b 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatureSupport.c
> @@ -64,6 +64,8 @@ PCIE_FEATURE_ENTRY  mPcieFeatures[] = {
>                TRUE, { TRUE,  TRUE }, { NULL,                    CompletionTimeoutProgram}},
>    { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, Ltr),
>                TRUE, { FALSE, TRUE }, { LtrScan,                 LtrProgram}},
> +  { OFFSET_OF (EFI_PCI_EXPRESS_PLATFORM_POLICY, AtomicOp),
> +              TRUE, { TRUE,  TRUE }, { NULL,                    AtomicOpProgram}},
>  };
> 
>  /**
> @@ -241,6 +243,7 @@ PcieNotifyDeviceState (
>    PcieDeviceState.RelaxedOrdering     = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.RelaxedOrdering;
>    PcieDeviceState.NoSnoop             = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl.Bits.NoSnoop;
>    PcieDeviceState.CompletionTimeout   = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl2.Uint16 & 0x1F;
> +  PcieDeviceState.AtomicOp            = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl2.Bits.AtomicOpRequester;
>    PcieDeviceState.Ltr                 = (UINT8)PciIoDevice->PciExpressCapability.DeviceControl2.Bits.LtrMechanism;
> 
>    return mPciePlatformProtocol->NotifyDeviceState (
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
> index 8c7fae0..407c94a 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.c
> @@ -552,3 +552,65 @@ LtrProgram (
>    return EFI_SUCCESS;
>  }
> 
> +/**
> +  Program AtomicOp.
> +
> +  @param PciIoDevice            A pointer to the PCI_IO_DEVICE.
> +  @param Level                  The level of the PCI device in the heirarchy.
> +                                Level of root ports is 0.
> +  @param Context                Pointer to feature specific context.
> +
> +  @retval EFI_SUCCESS           setup of PCI feature AtomicOp is successful.
> +  @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
> +AtomicOpProgram (
> +  IN  PCI_IO_DEVICE *PciIoDevice,
> +  IN  UINTN         Level,
> +  IN  VOID          **Context
> +  )
> +{
> +  if (PciIoDevice->DeviceState.AtomicOp == EFI_PCI_EXPRESS_DEVICE_POLICY_AUTO ||
> +      PciIoDevice->DeviceState.AtomicOp == EFI_PCI_EXPRESS_DEVICE_POLICY_NOT_APPLICABLE) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // BIT0 of the policy value is for AtomicOp Requester Enable (BIT6)
> +  // BIT1 of the policy value is for AtomicOp Egress Blocking (BIT7)
> +  //
> +  if ((PciIoDevice->DeviceState.AtomicOp >> 2) != 0) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (!PciIoDevice->PciExpressCapability.DeviceCapability2.Bits.AtomicOpRouting) {
> +    PciIoDevice->DeviceState.AtomicOp &= ~BIT1;
> +  }
> +  if (PciIoDevice->DeviceState.AtomicOp !=
> +      BitFieldRead16 (PciIoDevice->PciExpressCapability.DeviceControl2.Uint16, 6, 7)) {
> +
> +      DEBUG ((
> +        DEBUG_INFO, "  %a [%02d|%02d|%02d]: %x -> %x.\n",
> +        __FUNCTION__, PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber,
> +        BitFieldRead16 (PciIoDevice->PciExpressCapability.DeviceControl2.Uint16, 6, 7),
> +        PciIoDevice->DeviceState.AtomicOp
> +        ));
> +      BitFieldWrite16 (
> +        PciIoDevice->PciExpressCapability.DeviceControl2.Uint16, 6, 7,
> +        PciIoDevice->DeviceState.AtomicOp
> +        );
> +      return PciIoDevice->PciIo.Pci.Write (
> +                                    &PciIoDevice->PciIo,
> +                                    EfiPciIoWidthUint16,
> +                                    PciIoDevice->PciExpressCapabilityOffset
> +                                    + OFFSET_OF (PCI_CAPABILITY_PCIEXP, DeviceControl2),
> +                                    1,
> +                                    &PciIoDevice->PciExpressCapability.DeviceControl2.Uint16
> +                                    );
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
> index a9dacf3..5c70e41 100644
> --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
> +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PcieFeatures.h
> @@ -94,4 +94,20 @@ LtrProgram (
>    IN  VOID          **Context
>    );
> 
> +/**
> +  Program AtomicOp.
> +
> +  @param PciIoDevice  A pointer to the PCI_IO_DEVICE.
> +  @param Level        The level of the PCI device in the heirarchy.
> +                      Level of root ports is 0.
> +  @param Context      Pointer to feature specific context.
> +
> +  @retval EFI_SUCCESS setup of PCI feature LTR is successful.
> +**/
> +EFI_STATUS
> +AtomicOpProgram (
> +  IN  PCI_IO_DEVICE *PciIoDevice,
> +  IN  UINTN         Level,
> +  IN  VOID          **Context
> +  );
>  #endif
> --
> 2.21.0.windows.1
> 
> 
> 


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 07/15] MdeModulePkg/PciBusDxe: Enable MaxPayloadSize feature
  2020-05-13  6:45   ` Ni, Ray
@ 2020-05-13  6:54     ` Javeed, Ashraf
  0 siblings, 0 replies; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-13  6:54 UTC (permalink / raw)
  To: Ni, Ray, devel@edk2.groups.io; +Cc: Wang, Jian J, Wu, Hao A

My response in line.
Thanks
Ashraf

> -----Original Message-----
> From: Ni, Ray <ray.ni@intel.com>
> Sent: Wednesday, May 13, 2020 12:16 PM
> To: Javeed, Ashraf <ashraf.javeed@intel.com>; devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A
> <hao.a.wu@intel.com>
> Subject: RE: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 07/15]
> MdeModulePkg/PciBusDxe: Enable MaxPayloadSize feature
> 
> >  /**
> > @@ -220,6 +226,7 @@ PcieNotifyDeviceState (
> >
> >    CopyMem (&PcieDeviceState, &PciIoDevice->DeviceState, sizeof
> (PciIoDevice->DeviceState));
> >
> > +  PcieDeviceState.MaxPayloadSize      = (UINT8)PciIoDevice-
> >PciExpressCapability.DeviceControl.Bits.MaxPayloadSize;
> 
> My original idea is to directly use the PciIoDevice->DeviceState.
> Your patch is even better because if the policy value is AUTO, it's better to
> report the actual value in HW to platform instead of AUTO.
> 
Yes, that was the intent.

> Can you remove the CopyMem() call?
> 
The CopyMem() shall maintain the PCIe features that are not yet supported by the driver, or if the platform has chose to not initialize that PCIe feature(s) using the NOT_APPLICABLE.
Are you suggesting to explicitly assign NOT_APPLICABLE to those features?

> Thanks,
> Ray


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 12/15] MdeModulePkg/PciBusDxe: Enable LTR feature
  2020-05-13  6:49   ` Ni, Ray
@ 2020-05-13  7:10     ` Javeed, Ashraf
  0 siblings, 0 replies; 33+ messages in thread
From: Javeed, Ashraf @ 2020-05-13  7:10 UTC (permalink / raw)
  To: Ni, Ray, devel@edk2.groups.io; +Cc: Wang, Jian J, Wu, Hao A

Thanks
Ashraf

> -----Original Message-----
> From: Ni, Ray <ray.ni@intel.com>
> Sent: Wednesday, May 13, 2020 12:19 PM
> To: Javeed, Ashraf <ashraf.javeed@intel.com>; devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A
> <hao.a.wu@intel.com>
> Subject: RE: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 12/15]
> MdeModulePkg/PciBusDxe: Enable LTR feature
> 
> > +EFI_STATUS
> > +LtrScan (
> > +  IN  PCI_IO_DEVICE *PciIoDevice,
> > +  IN  UINTN         Level,
> > +  IN  VOID          **Context
> > +  )
> > +{
> > +  BOOLEAN           *Ltr;
> > +  ASSERT (Level <= PCI_MAX_BUS);
> > +  //ASSERT (Context != NULL);
> 
> Why the "ASSERT (Context != NULL)" is commented out?
> 
I thought this check is not necessary for LTR alone, wanted to remove this later but missed.
What is your suggestion? If it is used for LTR Scan than it has to also used for other features.

> Thanks,
> Ray
> 


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-devel] [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 14/15] MdeModulePkg/PciBusDxe: Enable ExtendedTag feature
  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   ` Ni, Ray
  0 siblings, 0 replies; 33+ messages in thread
From: Ni, Ray @ 2020-05-13  8:09 UTC (permalink / raw)
  To: devel@edk2.groups.io, Javeed, Ashraf; +Cc: Wang, Jian J, Wu, Hao A

> +
> +  //
> +  // BIT0 of the policy value is for 5b or 8b Extended Tag (DeviceControl BIT8)
> +  // BIT1 of the policy value is for 10b Extended Tag (DeviceControl2 BIT12)
> +  //
> +  if ((PciIoDevice->DeviceState.ExtendedTag >> 2) != 0) {
> +    return EFI_INVALID_PARAMETER;
> +  }

Because there is a separate routine to formalize all policy values, this parameter check may be unnecessary.
Similar comments apply to all the scan/program routines for different features.
What do you think?


> +  //
> +  // the device should be capable of 10b Extended Tag Requester
> +  //
> +  if ((PciIoDevice->DeviceState.ExtendedTag & BIT1) &&
> +      (PciIoDevice->PciExpressCapability.DeviceCapability2.Bits.TenBitTagRequesterSupported)) {
> +    //
> +    // for the Endpoint device 10b Extended Tag Requester Enable, the RC should be
> +    // 10b Completer capable
> +    //
> +    if (PciIoDevice->PciExpressCapability.Capability.Bits.DevicePortType == PCIE_DEVICE_PORT_TYPE_PCIE_ENDPOINT ||
> +        PciIoDevice->PciExpressCapability.Capability.Bits.DevicePortType ==
> PCIE_DEVICE_PORT_TYPE_LEGACY_PCIE_ENDPOINT) {
> +      //
> +      // check the parent Root Port 10b Extended Tag Completer Capability
> +      //
> +      TenBitCompleterCapable = *Context;
> +      if (*TenBitCompleterCapable == TRUE) {
> +        //
> +        // since the RC is 10b COmpleter capable, enable the EP as 10b Requester
> +        //
> +        DeviceCtl2.Bits.TenBitTagRequesterEnable = 1;


I read through PCIE spec 5.0 chapter 2.2.6.2 but cannot find any statement that says:
Enable EP only when RP supports.

My understanding is:
Each EP can have its own 8-bit/10-bit enable setting.
Can you please help to explain?

> +      }
> +    } else {
> +      //
> +      // enable the device as 10b Requester if it is capable and per platform ask
> +      //
> +      DeviceCtl2.Bits.TenBitTagRequesterEnable = 1;

My understanding is for switches, the enable is not necessary.
Because spec says switches forward the request without modifying the Transaction ID.

> +
> +  //
> +  // if no 10b Extended Tag Requester for this device than consider 8b or 5b Extended Requester
> +  //
> +  if (!DeviceCtl2.Bits.TenBitTagRequesterEnable) {
> +    //
> +    // the device should be capable of 8b Extended Tag Requester
> +    //
> +    DeviceCtl.Bits.ExtendedTagField = (UINT16)
> +              ((PciIoDevice->DeviceState.ExtendedTag & BIT0) &&
> +               (PciIoDevice->PciExpressCapability.DeviceCapability.Bits.ExtendedTagField));

Why you don't check the RP's capability for 8bit case?


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 15/15] MdeModulePkg/PciBusDxe: Enable CommonClockConfiguration feature
  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
  0 siblings, 0 replies; 33+ messages in thread
From: Ni, Ray @ 2020-05-13  8:19 UTC (permalink / raw)
  To: Javeed, Ashraf, devel@edk2.groups.io; +Cc: Wang, Jian J, Wu, Hao A

> +    //
> +    // retrain the link at Root Port level, if its link is active
> +    //
> +    if (Level == 1 && PciIoDevice->PciExpressCapability.LinkStatus.Bits.DataLinkLayerLinkActive) {
Should use "PciIoDevice->PciExpressCapability.LinkStatus.Bits.DataLinkLayerLinkActive != 0" to following EDK II coding style.
Do you want to retrain the link from the root port? Then we need compare the Level against 0 instead of 1.

> +    //
> +    if (Level == 1 && PciIoDevice->PciExpressCapability.LinkStatus.Bits.DataLinkLayerLinkActive) {
Similar comments to above line.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 01/15] MdePkg/Protocols: Deprecated the EFI encoded macros
  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
  0 siblings, 0 replies; 33+ messages in thread
From: Ni, Ray @ 2020-05-13  8:21 UTC (permalink / raw)
  To: Javeed, Ashraf, devel@edk2.groups.io; +Cc: Kinney, Michael D, Gao, Liming

> +  // The device policy AUTO or NOT_APPLICABLE shall be treated as "do not touch".
> +  // The device policy from platform can be different for the RP and its EP device;
> +  // however if the device capability does not match with the policy than it shall
> +  // be ignored. For example; if the policy for EP is to set the 10b Extended Tag
> +  // than EP device capability as a requester and its RP completer capability is
> +  // checked. If platform ask policy change only for RP than its device capability
> +  // is checked to enable the 10b Extended Tag.
> +  //
> +  UINT8                          ExtendedTag;

I am not sure of the comments for ExtendedTag right now.
Let's discuss on the ExtendedTag implementation patch.

> 
> 
> +  // The device policy AUTO or NOT_APPLICABLE provided to EP shall be treated as
> +  // mo LTR programming from the path of EP to parent RP. If same is provided for

"mo LTR programming". Is "mo" "no"?



^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2020-05-13  8:21 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [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 ` [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 06/15] MdeModulePkg/PciBusDxe: Add the framework to init PCIe features Javeed, Ashraf
2020-05-13  6:39   ` 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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox