BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2499
This code change enables the PCI Express feature Extended Tag, in
compliance with the PCI Express Base Specification 5, and uses the device
policy under the following conditions:
(1) As per the PCI Express Base Specification, all the devices under the
root bridge has to be set to a common applicable value
(2) The 5b or 8b Extended Tag capability is defined in the Device Capabi-
lity register, and the 10b requester as well as completer is defined
in the Device Capability 2 register
(3) The Extended Tag device policy would be overruled for any device if
it does not match with its device capabilities register
(4) In case of multiple device policies, due to multiple devices under
the root bridge, the lowest applicable value will be programmed for
all the devices
(5) There is no Extended Tag disable state; hence the default would be
5b or 8b depending upon device HW-state. The 10b requester is disabled
by default; hence any device policy request of 10b shall lead to 10b
Requester enable state from root bridge to all end devices; if all the
devices support 10b Requester as well as the completer capability. In
this scenario, the default state of 5b/8b Extended Tag state in Device
Control register is ignored as 10b capable devices should be able to
handle lower size Extended Tag packet IDs autonomously.
This programming of Extended Tag, gets the device-specific platform policy
using the new PCI Express Platform Protocol interface (ECR version 0.8),
defined in the below feature request:-
https://bugzilla.tianocore.org/show_bug.cgi?id=1954
Signed-off-by: Ashraf Javeed <ashraf.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.h | 1 +
MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c | 278 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c | 15 ++++++++++++++-
MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h | 4 ++++
MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c | 36 ++++++++++++++++++++++++++++++++++++
6 files changed, 383 insertions(+), 1 deletion(-)
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
index 7e43a26..6a6f648 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
@@ -297,6 +297,7 @@ struct _PCI_IO_DEVICE {
PCI_FEATURE_POLICY SetupCTO;
EFI_PCI_EXPRESS_ATOMIC_OP SetupAtomicOp;
BOOLEAN SetupLtr;
+ UINT8 SetupExtTag;
};
#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c
index 63a243b..eaef3d3 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.c
@@ -1240,3 +1240,281 @@ ProgramLtr (
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;
+}
+
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h
index 374fe49..1cfca54 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciExpressFeatures.h
@@ -243,4 +243,54 @@ ProgramLtr (
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
+ );
+
#endif
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c
index bdeb0d2..58d3780 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c
@@ -38,7 +38,7 @@ EFI_PCI_EXPRESS_PLATFORM_POLICY mPciExpressPlatformPolicy = {
//
// support for PCI Express feature - Extended Tag
//
- FALSE,
+ TRUE,
//
// support for PCI Express feature - Relax Order
//
@@ -140,6 +140,15 @@ PCI_EXPRESS_FEATURE_INITIALIZATION_POINT mPciExpressFeatureInitializationList[]
},
{
PciExpressFeatureProgramPhase, PciExpressLtr, ProgramLtr
+ },
+ {
+ PciExpressFeatureSetupPhase, PciExpressExtTag, SetupExtTag
+ },
+ {
+ PciExpressFeatureEntendedSetupPhase, PciExpressExtTag, AlignExtTag
+ },
+ {
+ PciExpressFeatureProgramPhase, PciExpressExtTag, ProgramExtTag
}
};
@@ -675,6 +684,10 @@ CreatePciRootBridgeDeviceNode (
// tree
//
PciConfigTable->AtomicOpRoutingSupported = TRUE;
+ //
+ // start by assuming the Extended Tag is 10b Requester capable
+ //
+ PciConfigTable->ExtendedTag = EFI_PCI_EXPRESS_EXTENDED_TAG_10BIT;
}
RootBridgeNode->PciExFeaturesConfigurationTable = PciConfigTable;
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h
index 5dded7c..c7cc7e5 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.h
@@ -94,6 +94,10 @@ struct _PCI_EXPRESS_FEATURES_CONFIGURATION_TABLE {
// 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;
};
//
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c
index 83b3aa7..98d9875 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c
@@ -368,6 +368,12 @@ SetupDefaultPciExpressDevicePolicy (
PciDevice->SetupLtr = FALSE;
+ if (mPciExpressPlatformPolicy.ExtTag) {
+ PciDevice->SetupExtTag = EFI_PCI_EXPRESS_EXTENDED_TAG_AUTO;
+ } else {
+ PciDevice->SetupExtTag = EFI_PCI_EXPRESS_NOT_APPLICABLE;
+ }
+
}
/**
@@ -502,6 +508,15 @@ GetPciExpressDevicePolicy (
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;
+ }
+
DEBUG ((
DEBUG_INFO,
@@ -668,6 +683,19 @@ GetPciExpressCto (
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;
+ }
+}
/**
Notifies the platform about the current PCI Express state of the device.
@@ -768,6 +796,14 @@ PciExpressPlatformNotifyDeviceState (
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;
+ }
if (mPciExPlatformProtocol != NULL) {
return mPciExPlatformProtocol->NotifyDeviceState (
--
2.21.0.windows.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#54073): https://edk2.groups.io/g/devel/message/54073
Mute This Topic: https://groups.io/mt/71063091/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2024 Red Hat, Inc.