This patch is also uploaded in the following Repo for review:- https://github.com/ashrafj/edk2-staging/commit/fc451a1bb20fc774f7542ea06eb4e1b9ce369c0c
Thanks Ashraf > -----Original Message----- > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Javeed, > Ashraf > Sent: Friday, November 1, 2019 8:40 PM > To: devel@edk2.groups.io > Cc: Wang, Jian J <jian.j.w...@intel.com>; Wu, Hao A <hao.a...@intel.com>; > Ni, Ray <ray...@intel.com> > Subject: [edk2-devel] [edk2-staging/UEFI_PCI_ENHANCE-2 PATCH 12/12] > PciBusDxe: New PCI feature Completion Timeout > > BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2313 > > The code changes are made; as per the PCI Base Specification 4 Revision 1; to > enable the configuration of new PCI feature Completion Timeout (CTO), which > enables the PCI function to wait on programmed duration for its transactions > before timeout, or disable its detection mechanism. > > The code changes are made to configure only those PCI devices which are > requested to override by platform through the new PCI Platform protocol > interface for device-specific policies. The changes are made to also com- ply > with the device-specific capability attributes. > > The code follows the below implementation specific rules in case the req- > uested platform policy does not match with the device-specific capability > attributes:- > (1) 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 > (2) 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 > (3) if the device is capable of Range B only, or the ranges A & B; and if > the platform ask for Range C, or Range D values, than this implement- > ation will only program the Range B value for the duration of 65ms to > 210ms > (4) 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 > > > Signed-off-by: Ashraf Javeed <ashraf.jav...@intel.com> > Cc: Jian J Wang <jian.j.w...@intel.com> > Cc: Hao A Wu <hao.a...@intel.com> > Cc: Ray Ni <ray...@intel.com> > --- > MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 1 + > MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c | 413 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++ > MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c | 84 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++ > 3 files changed, 498 insertions(+) > > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > index be1c341..b6ec14f 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > @@ -294,6 +294,7 @@ struct _PCI_IO_DEVICE { > UINT8 SetupMRRS; > PCI_FEATURE_POLICY SetupRO; > PCI_FEATURE_POLICY SetupNS; > + PCI_FEATURE_POLICY SetupCTO; > }; > > #define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \ diff --git > a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c > index a7f0a2f..ba0de0d 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciFeatureSupport.c > @@ -765,6 +765,294 @@ ProcessMaxReadReqSize ( > return EFI_SUCCESS; > } > > +/** > + 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 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: > + PciFeatureGetDevicePolicy & > + PciFeatureSetupPhase > + > + @retval EFI_SUCCESS processing of PCI feature CTO is > successful. > +**/ > +EFI_STATUS > +ProcessCompletionTimeout ( > + IN PCI_IO_DEVICE *PciDevice, > + IN PCI_FEATURE_CONFIGURATION_PHASE PciConfigPhase > + ) > +{ > + PCI_REG_PCIE_DEVICE_CAPABILITY2 DeviceCap2; > + UINT8 CtoRangeValue; > + > + if (PciConfigPhase != PciFeatureGetDevicePolicy) { > + // > + // no reprocessing required for device CTO configuration > + // > + return EFI_SUCCESS; > + } > + > + 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->PciExpStruct.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 Control register MaxPayloadSize register field; if > the hardware value is different than the intended value. > @@ -1061,6 +1349,119 @@ OverrideNoSnoop ( > return Status; > } > > +/** > + 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 > +OverrideCompletionTimeout ( > + IN PCI_IO_DEVICE *PciDevice > + ) > +{ > + 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->PciExpStruct.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 > + ); > + if (EFI_ERROR(Status)){ > + DEBUG (( DEBUG_ERROR, "Unexpected DeviceControl2 register (0x%x) read > error!", > + Offset > + )); > + return Status; > + } > + } 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->PciExpStruct.DeviceControl2.Uint16 = DeviceCtl2.Uint16; > + } else { > + DEBUG (( DEBUG_ERROR, "Unexpected DeviceControl2 register (0x%x) write > error!", > + Offset > + )); > + } > + return Status; > +} > + > /** > helper routine to dump the PCIe Device Port Type **/ @@ -1169,6 +1570,15 > @@ SetupDevicePciFeatures ( > OtherPciFeaturesConfigTable > ); > } > + // > + // process the PCI device CTO range values to be configured // if > + (SetupCompletionTimeout ()) { > + Status = ProcessCompletionTimeout ( > + PciDevice, > + PciConfigPhase > + ); > + } > DEBUG ((DEBUG_INFO, "]\n")); > return Status; > } > @@ -1278,6 +1688,9 @@ ProgramDevicePciFeatures ( > if (SetupNoSnoop ()) { > Status = OverrideNoSnoop (PciDevice); > } > + if (SetupCompletionTimeout()) { > + Status = OverrideCompletionTimeout (PciDevice); } > DEBUG (( DEBUG_INFO, "\n")); > return Status; > } > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c > index 47295cd..7ee0d7d 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPlatformSupport.c > @@ -549,6 +549,85 @@ SetDevicePolicyNoSnoop ( > } > } > > +/** > + 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_CONF_CTO_SUPPORT > + @param PciDevice A pointer to PCI_IO_DEVICE > +**/ > +VOID > +SetDevicePolicyCTO ( > + IN EFI_PCI_CONF_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_CONF_CTO_AUTO: > + PciDevice->SetupCTO.Override = 0; > + break; > + case EFI_PCI_CONF_CTO_DEFAULT: > + PciDevice->SetupCTO.Override = 1; > + PciDevice->SetupCTO.Act = 1; > + PciDevice->SetupCTO.Support = > PCIE_COMPLETION_TIMEOUT_50US_50MS; > + break; > + case EFI_PCI_CONF_CTO_RANGE_A1: > + PciDevice->SetupCTO.Override = 1; > + PciDevice->SetupCTO.Act = 1; > + PciDevice->SetupCTO.Support = > PCIE_COMPLETION_TIMEOUT_50US_100US; > + break; > + case EFI_PCI_CONF_CTO_RANGE_A2: > + PciDevice->SetupCTO.Override = 1; > + PciDevice->SetupCTO.Act = 1; > + PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_1MS_10MS; > + break; > + case EFI_PCI_CONF_CTO_RANGE_B1: > + PciDevice->SetupCTO.Override = 1; > + PciDevice->SetupCTO.Act = 1; > + PciDevice->SetupCTO.Support = > PCIE_COMPLETION_TIMEOUT_16MS_55MS; > + break; > + case EFI_PCI_CONF_CTO_RANGE_B2: > + PciDevice->SetupCTO.Override = 1; > + PciDevice->SetupCTO.Act = 1; > + PciDevice->SetupCTO.Support = > PCIE_COMPLETION_TIMEOUT_65MS_210MS; > + break; > + case EFI_PCI_CONF_CTO_RANGE_C1: > + PciDevice->SetupCTO.Override = 1; > + PciDevice->SetupCTO.Act = 1; > + PciDevice->SetupCTO.Support = > PCIE_COMPLETION_TIMEOUT_260MS_900MS; > + break; > + case EFI_PCI_CONF_CTO_RANGE_C2: > + PciDevice->SetupCTO.Override = 1; > + PciDevice->SetupCTO.Act = 1; > + PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_1S_3_5S; > + break; > + case EFI_PCI_CONF_CTO_RANGE_D1: > + PciDevice->SetupCTO.Override = 1; > + PciDevice->SetupCTO.Act = 1; > + PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_4S_13S; > + break; > + case EFI_PCI_CONF_CTO_RANGE_D2: > + PciDevice->SetupCTO.Override = 1; > + PciDevice->SetupCTO.Act = 1; > + PciDevice->SetupCTO.Support = PCIE_COMPLETION_TIMEOUT_17S_64S; > + break; > + case EFI_PCI_CONF_CTO_DET_DISABLE: > + PciDevice->SetupCTO.Override = 1; > + PciDevice->SetupCTO.Act = 0; > + PciDevice->SetupCTO.Support = > PCIE_COMPLETION_TIMEOUT_50US_50MS; > + break; > + } > +} > + > /** > Generic routine to setup the PCI features as per its predetermined > defaults. > **/ > @@ -561,6 +640,7 @@ SetupDefaultsDevicePlatformPolicy ( > PciDevice->SetupMRRS = EFI_PCI_CONF_MAX_READ_REQ_SIZE_AUTO; > PciDevice->SetupRO.Override = 0; > PciDevice->SetupNS.Override = 0; > + PciDevice->SetupCTO.Override = 0; > } > > /** > @@ -606,6 +686,10 @@ GetPciDevicePlatformPolicyEx ( > // set the device specific policy for No-Snoop > // > SetDevicePolicyNoSnoop (PciPlatformExtendedPolicy.DeviceCtlNoSnoop, > PciIoDevice); > + // > + // set the device specific policy for Completion Timeout (CTO) > + // > + SetDevicePolicyCTO (PciPlatformExtendedPolicy.CTOsupport, > + PciIoDevice); > > DEBUG (( > DEBUG_INFO, "[device policy: platform]" > -- > 2.21.0.windows.1 > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#50551): https://edk2.groups.io/g/devel/message/50551 Mute This Topic: https://groups.io/mt/55166435/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-