예제 #1
0
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());
    }
}
예제 #2
0
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."));
}
예제 #3
0
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));
}
예제 #4
0
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."));
}
예제 #5
0
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;
}
예제 #6
0
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();
}
예제 #7
0
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));
}
예제 #8
0
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);
}
예제 #9
0
PerformanceControlDynamicCaps DomainPerformanceControl_003::createPerformanceControlDynamicCaps(UIntN domainIndex)
{
    auto controlSetSize = getPerformanceControlSet(getParticipantIndex(), domainIndex).getCount();
    return PerformanceControlDynamicCaps(controlSetSize - 1, 0);
}