void DomainPerformanceControl_002::throwIfPerformanceControlIndexIsOutOfBounds(UIntN domainIndex, UIntN performanceControlIndex) { auto controlSetSize = getPerformanceControlSet(getParticipantIndex(), domainIndex).getCount(); if (performanceControlIndex >= controlSetSize) { std::stringstream infoMessage; infoMessage << "Control index out of control set bounds." << std::endl << "Desired Index : " << performanceControlIndex << std::endl << "PerformanceControlSet size :" << controlSetSize << std::endl; throw dptf_exception(infoMessage.str()); } auto caps = getPerformanceControlDynamicCaps(getParticipantIndex(), domainIndex); if (performanceControlIndex < caps.getCurrentUpperLimitIndex() || performanceControlIndex > caps.getCurrentLowerLimitIndex()) { std::stringstream infoMessage; infoMessage << "Got a performance control index that was outside the allowable range." << std::endl << "Desired Index : " << performanceControlIndex << std::endl << "Upper Limit Index : " << caps.getCurrentUpperLimitIndex() << std::endl << "Lower Limit Index : " << caps.getCurrentLowerLimitIndex() << std::endl; throw dptf_exception(infoMessage.str()); } }
void DomainPerformanceControl_002::setPerformanceControlDynamicCaps(UIntN participantIndex, UIntN domainIndex, PerformanceControlDynamicCaps newCapabilities) { auto upperLimitIndex = newCapabilities.getCurrentUpperLimitIndex(); auto lowerLimitIndex = newCapabilities.getCurrentLowerLimitIndex(); auto throttlingStateSet = getThrottlingStateSet(domainIndex); auto performanceStateSet = getPerformanceStateSet(domainIndex); auto pstateLowerLimit = 0; auto tstateLowerLimit = 0; if (upperLimitIndex != Constants::Invalid && lowerLimitIndex != Constants::Invalid) { auto pstateSetSize = performanceStateSet.getCount(); auto tstateSetSize = throttlingStateSet.getCount(); auto combinedSet = getPerformanceControlSet(participantIndex, domainIndex); auto combinedSetSize = combinedSet.getCount(); if (upperLimitIndex >= combinedSetSize) { throw dptf_exception("Upper Limit index is out of control set bounds."); } else if (upperLimitIndex > lowerLimitIndex || lowerLimitIndex >= combinedSetSize) { pstateLowerLimit = pstateSetSize - 1; tstateLowerLimit = tstateSetSize - 1; getParticipantServices()->writeMessageWarning( ParticipantMessage(FLF, "Limit index mismatch, setting lower limit to lowest possible index.")); } else if (lowerLimitIndex > pstateSetSize - 1) { pstateLowerLimit = pstateSetSize - 1; if (isFirstTstateDeleted(domainIndex)) { tstateLowerLimit = combinedSetSize - tstateSetSize; } else { tstateLowerLimit = combinedSetSize - tstateSetSize - 1; } } } m_performanceControlDynamicCaps.invalidate(); getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_PROC_PERF_PSTATE_DEPTH_LIMIT, pstateLowerLimit, domainIndex, Constants::Esif::NoPersistInstance); getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_PROC_PERF_TSTATE_DEPTH_LIMIT, tstateLowerLimit, domainIndex, Constants::Esif::NoPersistInstance); // TODO: allow DPTF to change the MAX limit getParticipantServices()->writeMessageInfo( ParticipantMessage(FLF, "Currently DPTF cannot change the MAX limit.")); }
void DomainPerformanceControl_003::setPerformanceControlDynamicCaps(UIntN participantIndex, UIntN domainIndex, PerformanceControlDynamicCaps newCapabilities) { auto upperLimitIndex = newCapabilities.getCurrentUpperLimitIndex(); auto lowerLimitIndex = newCapabilities.getCurrentLowerLimitIndex(); if (upperLimitIndex == Constants::Invalid && lowerLimitIndex == Constants::Invalid) { if (m_capabilitiesLocked == false) { m_performanceControlDynamicCaps.invalidate(); } return; } auto size = getPerformanceControlSet(participantIndex, domainIndex).getCount(); if (upperLimitIndex >= size) { throw dptf_exception("Upper Limit index is out of control set bounds."); } else if (upperLimitIndex > lowerLimitIndex || lowerLimitIndex >= size) { lowerLimitIndex = size - 1; getParticipantServices()->writeMessageWarning( ParticipantMessage(FLF, "Limit index mismatch, setting lower limit to lowest possible index.")); } m_performanceControlDynamicCaps.invalidate(); m_performanceControlDynamicCaps.set(PerformanceControlDynamicCaps(lowerLimitIndex, upperLimitIndex)); }
void DomainPerformanceControl_001::setPerformanceControlDynamicCaps(UIntN participantIndex, UIntN domainIndex, PerformanceControlDynamicCaps newCapabilities) { auto upperLimitIndex = newCapabilities.getCurrentUpperLimitIndex(); auto lowerLimitIndex = newCapabilities.getCurrentLowerLimitIndex(); if (upperLimitIndex != Constants::Invalid && lowerLimitIndex != Constants::Invalid) { auto controlSetSize = getPerformanceControlSet(participantIndex, domainIndex).getCount(); if (upperLimitIndex >= controlSetSize) { throw dptf_exception("Upper Limit index is out of control set bounds."); } else if (upperLimitIndex > lowerLimitIndex || lowerLimitIndex >= controlSetSize) { lowerLimitIndex = controlSetSize - 1; getParticipantServices()->writeMessageWarning( ParticipantMessage(FLF, "Limit index mismatch, setting lower limit to lowest possible index.")); } } m_performanceControlDynamicCaps.invalidate(); getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_PERF_PSTATE_DEPTH_LIMIT, lowerLimitIndex, domainIndex, Constants::Esif::NoPersistInstance); // TODO: allow DPTF to change the MAX limit getParticipantServices()->writeMessageInfo( ParticipantMessage(FLF, "Currently DPTF cannot change the MAX limit.")); }
std::shared_ptr<XmlNode> DomainPerformanceControl_002::getXml(UIntN domainIndex) { auto root = XmlNode::createWrapperElement("performance_control"); root->addChild(getPerformanceControlStatus(getParticipantIndex(), domainIndex).getXml()); root->addChild(getPerformanceControlDynamicCaps(getParticipantIndex(), domainIndex).getXml()); root->addChild(getPerformanceControlStaticCaps(getParticipantIndex(), domainIndex).getXml()); root->addChild(getPerformanceControlSet(getParticipantIndex(), domainIndex).getXml()); root->addChild(XmlNode::createDataElement("control_knob_version", "002")); return root; }
void DomainPerformanceControl_002::updateBasedOnConfigTdpInformation(UIntN participantIndex, UIntN domainIndex, ConfigTdpControlSet configTdpControlSet, ConfigTdpControlStatus configTdpControlStatus) { UInt64 tdpFrequencyLimit = configTdpControlSet[configTdpControlStatus.getCurrentControlIndex()].getTdpFrequency(); PerformanceControlSet controlSet = getPerformanceControlSet(participantIndex, domainIndex); for (UIntN controlIndex = 0; controlIndex < controlSet.getCount(); controlIndex++) { if (tdpFrequencyLimit >= controlSet[controlIndex].getControlAbsoluteValue()) { m_tdpFrequencyLimitControlIndex = controlIndex; break; } } m_performanceControlDynamicCaps.invalidate(); }
void DomainPerformanceControl_002::setPerformanceControl(UIntN participantIndex, UIntN domainIndex, UIntN performanceControlIndex) { throwIfPerformanceControlIndexIsOutOfBounds(domainIndex, performanceControlIndex); auto performanceControlSet = getPerformanceControlSet(participantIndex, domainIndex); PerformanceControlType::Type targetType = (performanceControlSet)[performanceControlIndex].getPerformanceControlType(); auto throttlingStateSet = getThrottlingStateSet(domainIndex); auto performanceStateSet = getPerformanceStateSet(domainIndex); switch (targetType) { case PerformanceControlType::PerformanceState: // Set T0 if (throttlingStateSet.getCount() > 0) { getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_TSTATE_CURRENT, throttlingStateSet[0].getControlId(), domainIndex); } getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_PERF_PRESENT_CAPABILITY, performanceControlIndex, domainIndex); break; case PerformanceControlType::ThrottleState: // Set Pn getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_PERF_PRESENT_CAPABILITY, static_cast<UIntN>(performanceStateSet.getCount()) - 1, domainIndex); getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_TSTATE_CURRENT, (performanceControlSet)[performanceControlIndex].getControlId(), domainIndex); break; default: throw dptf_exception("Invalid performance state requested."); break; } // Refresh the status m_performanceControlStatus.set(PerformanceControlStatus(performanceControlIndex)); }
PerformanceControlDynamicCaps DomainPerformanceControl_001::createPerformanceControlDynamicCaps(UIntN domainIndex) { //Get dynamic caps UInt32 lowerLimitIndex; UInt32 upperLimitIndex; auto controlSetSize = getPerformanceControlSet(getParticipantIndex(), domainIndex).getCount(); try { lowerLimitIndex = getParticipantServices()->primitiveExecuteGetAsUInt32( esif_primitive_type::GET_PERF_PSTATE_DEPTH_LIMIT, domainIndex); } catch (...) { // If PPDL is not supported, default to Pn. lowerLimitIndex = controlSetSize - 1; } try { // If PPPC is not supported, default to P0 upperLimitIndex = getParticipantServices()->primitiveExecuteGetAsUInt32( esif_primitive_type::GET_PARTICIPANT_PERF_PRESENT_CAPABILITY, domainIndex); } catch (...) { upperLimitIndex = 0; } if (upperLimitIndex >= controlSetSize || lowerLimitIndex >= controlSetSize) { throw dptf_exception("Retrieved control index out of control set bounds."); } if (upperLimitIndex > lowerLimitIndex) { lowerLimitIndex = controlSetSize - 1; getParticipantServices()->writeMessageWarning( ParticipantMessage(FLF, "Limit index mismatch, ignoring lower limit.")); } return PerformanceControlDynamicCaps(lowerLimitIndex, upperLimitIndex); }
PerformanceControlDynamicCaps DomainPerformanceControl_003::createPerformanceControlDynamicCaps(UIntN domainIndex) { auto controlSetSize = getPerformanceControlSet(getParticipantIndex(), domainIndex).getCount(); return PerformanceControlDynamicCaps(controlSetSize - 1, 0); }