void DomainPerformanceControl_002::restore(void) { if (m_initialStatus.isValid()) { try { auto restoreIndex = m_initialStatus.get().getCurrentUpperLimitIndex(); auto domainIndex = getDomainIndex(); getParticipantServices()->writeMessageDebug(ParticipantMessage( FLF, "Restoring... P-state = P" + StlOverride::to_string(restoreIndex) + " & T-state = T0.")); auto throttlingStateSet = getThrottlingStateSet(domainIndex); // 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, restoreIndex, domainIndex); } catch (...) { // best effort getParticipantServices()->writeMessageDebug(ParticipantMessage( FLF, "Failed to restore the initial performance control status. ")); } } }
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.")); }
TemperatureStatus DomainTemperature_002::getTemperatureStatus(UIntN participantIndex, UIntN domainIndex) { try { Temperature temperature = getParticipantServices()->primitiveExecuteGetAsTemperatureTenthK( esif_primitive_type::GET_TEMPERATURE, domainIndex); if (!temperature.isValid()) { getParticipantServices()->writeMessageWarning( ParticipantMessage(FLF, "Last set temperature for virtual sensor is invalid.")); return TemperatureStatus(Temperature::minValidTemperature); } return TemperatureStatus(temperature); } catch (primitive_destination_unavailable) { return TemperatureStatus(Temperature::minValidTemperature); } catch (dptf_exception& ex) { getParticipantServices()->writeMessageWarning(ParticipantMessage(FLF, ex.what())); return TemperatureStatus(Temperature::minValidTemperature); } }
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.")); }
UIntN DomainDisplayControl_001::getUserPreferredDisplayIndex(UIntN participantIndex, UIntN domainIndex) { if ((getParticipantServices()->isUserPreferredDisplayCacheValid(participantIndex, domainIndex)) == true) { getParticipantServices()->writeMessageDebug(ParticipantMessage( FLF, "Attempting to get the user preferred index from the display cache.")); m_userPreferredIndex = getParticipantServices()->getUserPreferredDisplayCacheValue(participantIndex, domainIndex); getParticipantServices()->writeMessageDebug(ParticipantMessage( FLF, "Retrieved the user preferred index of " + StlOverride::to_string(m_userPreferredIndex) + " .")); getParticipantServices()->invalidateUserPreferredDisplayCache(participantIndex, domainIndex); } else { auto currentStatus = getDisplayControlStatus(participantIndex, domainIndex); auto currentIndex = currentStatus.getBrightnessLimitIndex(); if (m_userPreferredIndex == Constants::Invalid || (m_lastSetDisplayBrightness != Constants::Invalid && currentIndex != m_lastSetDisplayBrightness)) { m_userPreferredIndex = currentIndex; m_isUserPreferredIndexModified = true; } else { m_isUserPreferredIndexModified = false; } } return m_userPreferredIndex; }
void DomainDisplayControl_001::restore(void) { if (m_userPreferredIndex != Constants::Invalid) { try { getParticipantServices()->setUserPreferredDisplayCacheValue(getParticipantIndex(), getDomainIndex(), m_userPreferredIndex); auto displaySet = getDisplayControlSet(getParticipantIndex(), getDomainIndex()); auto upperLimitIndex = getDisplayControlDynamicCaps(getParticipantIndex(), getDomainIndex()).getCurrentUpperLimit(); if (m_userPreferredIndex < upperLimitIndex) { m_userPreferredIndex = upperLimitIndex; } Percentage newBrightness = displaySet[m_userPreferredIndex].getBrightness(); getParticipantServices()->writeMessageDebug(ParticipantMessage( FLF, "Saved the user preferred index of " + StlOverride::to_string(m_userPreferredIndex) + ". Attempting to set the brightness to the user preferred value .")); getParticipantServices()->primitiveExecuteSetAsPercentage( esif_primitive_type::SET_DISPLAY_BRIGHTNESS, newBrightness, getDomainIndex()); } catch (...) { // best effort getParticipantServices()->writeMessageDebug(ParticipantMessage( FLF, "Failed to restore the user preferred display status. ")); } } }
CoreControlLpoPreference DomainCoreControl_001::createCoreControlLpoPreference(UIntN domainIndex) { Bool useDefault = false; DptfBuffer buffer; try { buffer = getParticipantServices()->primitiveExecuteGet( esif_primitive_type::GET_PROC_CURRENT_LOGICAL_PROCESSOR_OFFLINING, ESIF_DATA_BINARY, domainIndex); } catch (...) { getParticipantServices()->writeMessageWarning(ParticipantMessage(FLF, "CLPO not found. Using defaults.")); useDefault = true; } if (useDefault == false) { try { return CoreControlLpoPreference::createFromClpo(buffer); } catch (...) { getParticipantServices()->writeMessageWarning( ParticipantMessage(FLF, "Could not parse CLPO data. Using defaults.")); useDefault = true; } } return CoreControlLpoPreference( true, 0, Percentage(.50), CoreControlOffliningMode::Smt, CoreControlOffliningMode::Core); }
void DomainPerformanceControl_002::calculateThrottlingStateLimits(UIntN& tStateUpperLimitIndex, UIntN& tStateLowerLimitIndex, UIntN domainIndex) { // Required object if T-states are supported try { tStateUpperLimitIndex = getParticipantServices()->primitiveExecuteGetAsUInt32( esif_primitive_type::GET_PROC_PERF_THROTTLE_PRESENT_CAPABILITY, domainIndex); } catch (dptf_exception) { getParticipantServices()->writeMessageWarning( ParticipantMessage(FLF, "Bad upper T-state limit.")); tStateUpperLimitIndex = 0; } auto throttlingStateSetSize = getThrottlingStateSet(domainIndex).getCount(); try { // _TDL is an optional object tStateLowerLimitIndex = getParticipantServices()->primitiveExecuteGetAsUInt32( esif_primitive_type::GET_PROC_PERF_TSTATE_DEPTH_LIMIT, domainIndex); } catch (dptf_exception) { // Optional object. Default value is T(n) tStateLowerLimitIndex = static_cast<UIntN>(throttlingStateSetSize - 1); } if (isFirstTstateDeleted(domainIndex) && tStateLowerLimitIndex != 0) { tStateLowerLimitIndex--; } if (tStateUpperLimitIndex >= throttlingStateSetSize) { throw dptf_exception("Retrieved upper T-state index limit out of control set bounds. (T-States)"); } if (tStateLowerLimitIndex >= throttlingStateSetSize) { throw dptf_exception("Retrieved lower T-state index limit is out of control set bounds. (T-States)"); } if (tStateUpperLimitIndex > tStateLowerLimitIndex) { // If the limits are bad, ignore the lower limit. Don't fail this control. getParticipantServices()->writeMessageWarning( ParticipantMessage(FLF, "Limit index mismatch, ignoring lower limit.")); tStateLowerLimitIndex = static_cast<UIntN>(throttlingStateSetSize - 1); } }
void DomainDisplayControl_001::createDisplayControlDynamicCaps(UIntN domainIndex) { UIntN upperLimitIndex; UIntN lowerLimitIndex; UInt32 uint32val; // Get dynamic caps // The caps are stored in BIOS as brightness percentage. They must be converted // to indices before they can be used. // FIXME: ESIF treats this as a UInt32 but we treat this as a percentage. Need to get this in sync. uint32val = m_participantServicesInterface->primitiveExecuteGetAsUInt32( esif_primitive_type::GET_DISPLAY_DEPTH_LIMIT, domainIndex); Percentage lowerLimitBrightness = Percentage::fromWholeNumber(uint32val / 100); lowerLimitIndex = m_displayControlSet->getControlIndex(lowerLimitBrightness); try { // FIXME: ESIF treats this as a UInt32 but we treat this as a percentage. Need to get this in sync. uint32val = m_participantServicesInterface->primitiveExecuteGetAsUInt32( esif_primitive_type::GET_DISPLAY_CAPABILITY, domainIndex); Percentage upperLimitBrightness = static_cast<double>(uint32val) / 100.0; upperLimitIndex = m_displayControlSet->getControlIndex(upperLimitBrightness); } catch (...) { // DDPC is optional m_participantServicesInterface->writeMessageDebug( ParticipantMessage(FLF, "DDPC was not present. Setting upper limit to 100.")); upperLimitIndex = 0; // Max brightness } if (m_displayControlSet == nullptr) { createDisplayControlSet(domainIndex); } if (upperLimitIndex >= (m_displayControlSet->getCount()) || lowerLimitIndex >= (m_displayControlSet->getCount())) { throw dptf_exception("Retrieved control index out of control set bounds."); } if (upperLimitIndex > lowerLimitIndex) { lowerLimitIndex = m_displayControlSet->getCount() - 1; m_participantServicesInterface->writeMessageWarning( ParticipantMessage(FLF, "Limit index mismatch, ignoring lower limit.")); } m_displayControlDynamicCaps = new DisplayControlDynamicCaps(upperLimitIndex, lowerLimitIndex); }
void DomainCoreControl_001::createCoreControlLpoPreferenceIfNeeded(UIntN domainIndex) { if (m_coreControlLpoPreference == nullptr) { Bool useDefault = false; UInt32 dataLength = 0; DptfMemory binaryData(Constants::DefaultBufferSize); try { m_participantServicesInterface->primitiveExecuteGet( esif_primitive_type::GET_PROC_CURRENT_LOGICAL_PROCESSOR_OFFLINING, ESIF_DATA_BINARY, binaryData, binaryData.getSize(), &dataLength, domainIndex); } catch (...) { m_participantServicesInterface->writeMessageWarning( ParticipantMessage(FLF, "CLPO not found. Using defaults.")); useDefault = true; } if (useDefault == false) { try { m_coreControlLpoPreference = BinaryParse::processorClpoObject(dataLength, binaryData); } catch (...) { m_participantServicesInterface->writeMessageWarning( ParticipantMessage(FLF, "Could not parse CLPO data. Using defaults.")); DELETE_MEMORY_TC(m_coreControlLpoPreference); useDefault = true; } } if (useDefault == true) { m_coreControlLpoPreference = new CoreControlLpoPreference(true, 0, Percentage(.50), CoreControlOffliningMode::Smt, CoreControlOffliningMode::Core); } binaryData.deallocate(); } }
void DomainPowerControl_001::programPowerControl(const PowerControlStatus& powerControlStatusSet, UIntN domainIndex) { if (m_canProgramPowerLimit[powerControlStatusSet.getPowerControlType()] == true) { m_participantServicesInterface->primitiveExecuteSetAsPower( esif_primitive_type::SET_RAPL_POWER_LIMIT, powerControlStatusSet.getCurrentPowerLimit(), domainIndex, static_cast<UInt8>(powerControlStatusSet.getPowerControlType())); try { m_participantServicesInterface->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_RAPL_POWER_LIMIT_ENABLE, 1, //Enable the bit domainIndex, static_cast<UInt8>(powerControlStatusSet.getPowerControlType())); } catch (dptf_exception& ex) { // It is expected to hit this for the CPU's PL1 enable. It is read only. ParticipantMessage message = ParticipantMessage(FLF, "Power limit enabled ignored."); message.setEsifPrimitive(esif_primitive_type::SET_RAPL_POWER_LIMIT_ENABLE, powerControlStatusSet.getPowerControlType()); message.setExceptionCaught("primitiveExecuteSetAsUInt32", ex.what()); m_participantServicesInterface->writeMessageWarning(message); } } else { std::stringstream msg; msg << PowerControlType::ToString(powerControlStatusSet.getPowerControlType()) << " power control is not programmable. Ignoring."; m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, msg.str())); } if (m_canProgramTimeWindow[powerControlStatusSet.getPowerControlType()] == true) { m_participantServicesInterface->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_RAPL_TIME_WINDOW, powerControlStatusSet.getCurrentTimeWindow(), domainIndex, static_cast<UInt8>(powerControlStatusSet.getPowerControlType())); } else { std::stringstream msg; msg << PowerControlType::ToString(powerControlStatusSet.getPowerControlType()) << " time window is not programmable. Ignoring."; m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, msg.str())); } }
void DomainPerformanceControl_001::setPerformanceControl(UIntN participantIndex, UIntN domainIndex, UIntN performanceControlIndex) { if (performanceControlIndex == getCurrentPerformanceControlIndex(participantIndex, domainIndex)) { getParticipantServices()->writeMessageDebug( ParticipantMessage(FLF, "Requested limit = current limit. Ignoring.")); return; } try { throwIfPerformanceControlIndexIsOutOfBounds(domainIndex, performanceControlIndex); getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_PERF_PRESENT_CAPABILITY, performanceControlIndex, domainIndex); // Refresh the status m_performanceControlStatus.set(PerformanceControlStatus(performanceControlIndex)); } catch (...) { // eat any errors } }
PerformanceControlSet DomainPerformanceControl_002::createCombinedPerformanceControlSet(UIntN domainIndex) { PerformanceControlSet performanceStateSet = getPerformanceStateSet(domainIndex); PerformanceControlSet throttlingStateSet; // Get T-States if (performanceStateSet.getCount() > 0) { throttlingStateSet = getThrottlingStateSet(domainIndex); } // Create all encompassing set (P and T states) // P-States PerformanceControlSet combinedStateSet(performanceStateSet); // T-States auto tStateStartIndex = isFirstTstateDeleted(domainIndex) ? 1 : 0; combinedStateSet.append(throttlingStateSet, tStateStartIndex); ParticipantMessage message = ParticipantMessage(FLF, "Performance controls created."); message.addMessage("Total Entries", combinedStateSet.getCount()); message.addMessage("P-State Count", performanceStateSet.getCount()); message.addMessage("T-State Count", throttlingStateSet.getCount()); getParticipantServices()->writeMessageDebug(message); return PerformanceControlSet(combinedStateSet); }
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_002::capture(void) { try { m_initialStatus.set(getPerformanceControlDynamicCaps(getParticipantIndex(), getDomainIndex())); getParticipantServices()->writeMessageDebug(ParticipantMessage( FLF, "Initial performance capabilities are captured. MIN = " + StlOverride::to_string(m_initialStatus.get().getCurrentLowerLimitIndex()) + " & MAX = " + StlOverride::to_string(m_initialStatus.get().getCurrentUpperLimitIndex()))); } catch (dptf_exception& e) { m_initialStatus.invalidate(); std::string warningMsg = e.what(); getParticipantServices()->writeMessageWarning(ParticipantMessage( FLF, "Failed to get the initial processor performance control dynamic capabilities. " + warningMsg)); } }
void DomainDisplayControl_001::setDisplayControlDynamicCaps(UIntN participantIndex, UIntN domainIndex, DisplayControlDynamicCaps newCapabilities) { auto displaySet = getDisplayControlSet(participantIndex, domainIndex); auto upperLimitIndex = newCapabilities.getCurrentUpperLimit(); auto lowerLimitIndex = newCapabilities.getCurrentLowerLimit(); if (upperLimitIndex != Constants::Invalid && lowerLimitIndex != Constants::Invalid) { auto size = displaySet.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_displayControlDynamicCaps.invalidate(); Percentage upperLimitBrightness = displaySet[upperLimitIndex].getBrightness(); UInt32 uint32UpperLimit = upperLimitBrightness.toWholeNumber(); getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_DISPLAY_CAPABILITY, uint32UpperLimit, domainIndex, Constants::Esif::NoPersistInstance); Percentage lowerLimitBrightness = displaySet[lowerLimitIndex].getBrightness(); UInt32 uint32LowerLimit = lowerLimitBrightness.toWholeNumber(); getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_DISPLAY_DEPTH_LIMIT, uint32LowerLimit, domainIndex, Constants::Esif::NoPersistInstance); } else { m_displayControlDynamicCaps.invalidate(); getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_DISPLAY_CAPABILITY, upperLimitIndex, domainIndex, Constants::Esif::NoPersistInstance); getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_DISPLAY_DEPTH_LIMIT, lowerLimitIndex, domainIndex, Constants::Esif::NoPersistInstance); } }
void DomainPerformanceControl_003::capture(void) { try { m_initialStatus.set(getPerformanceControlDynamicCaps(getParticipantIndex(), getDomainIndex())); } catch (dptf_exception& e) { m_initialStatus.invalidate(); std::string warningMsg = e.what(); getParticipantServices()->writeMessageWarning(ParticipantMessage( FLF, "Failed to get the initial graphics performance control dynamic capabilities. " + warningMsg)); } }
void DomainCoreControl_001::restore(void) { try { getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_PROC_NUMBER_OFFLINE_CORES, 0, // No cores are parked getDomainIndex()); } catch (...) { // best effort getParticipantServices()->writeMessageWarning( ParticipantMessage(FLF, "Failed to restore the initial core status. ")); } }
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); }
void DomainPerformanceControl_002::calculatePerformanceStateLimits(UIntN& pStateUpperLimitIndex, UIntN& pStateLowerLimitIndex, UIntN domainIndex) { // TODO: Revisit whether we should even call this to get the upper limit as opposed to just defaulting the upper // limit to 0 and arbitrate with ConfigTDP. This primitive simply gives us the last set P-state index. If 3rd // party tools set this or if we have throttled P-states and then crash and reload, our upper limit will be // whatever the last set P-state index was, which is wrong. pStateUpperLimitIndex = getParticipantServices()->primitiveExecuteGetAsUInt32( esif_primitive_type::GET_PROC_PERF_PRESENT_CAPABILITY, domainIndex); auto performanceStateSetSize = getPerformanceStateSet(domainIndex).getCount(); try { // _PDL is an optional object pStateLowerLimitIndex = getParticipantServices()->primitiveExecuteGetAsUInt32( esif_primitive_type::GET_PROC_PERF_PSTATE_DEPTH_LIMIT, domainIndex); } catch (dptf_exception) { // _PDL wasn't supported. Default to P(n) pStateLowerLimitIndex = static_cast<UIntN>(performanceStateSetSize - 1); } if (pStateUpperLimitIndex >= performanceStateSetSize) { throw dptf_exception("Retrieved upper P-state index limit is out of control set bounds. (P-States)"); } if (pStateLowerLimitIndex >= performanceStateSetSize) { throw dptf_exception("Retrieved lower P-state index limit is out of control set bounds. (P-States)"); } if (pStateUpperLimitIndex > pStateLowerLimitIndex) { // If the limits are bad, ignore the lower limit. Don't fail this control. getParticipantServices()->writeMessageWarning( ParticipantMessage(FLF, "Limit index mismatch, ignoring lower limit.")); pStateLowerLimitIndex = static_cast<UIntN>(performanceStateSetSize - 1); } }
UIntN DomainDisplayControl_001::getUpperLimitIndex(UIntN domainIndex, DisplayControlSet displaySet) { UIntN upperLimitIndex; try { UInt32 uint32val = getParticipantServices()->primitiveExecuteGetAsUInt32( esif_primitive_type::GET_DISPLAY_CAPABILITY, domainIndex); Percentage upperLimitBrightness = Percentage::fromWholeNumber(uint32val); upperLimitIndex = displaySet.getControlIndex(upperLimitBrightness); } catch (...) { // DDPC is optional getParticipantServices()->writeMessageDebug( ParticipantMessage(FLF, "DDPC was not present. Setting upper limit to 100.")); upperLimitIndex = 0; // Max brightness } return upperLimitIndex; }
void DomainPerformanceControl_003::restore(void) { if (m_initialStatus.isValid()) { try { getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_PERF_PRESENT_CAPABILITY, m_initialStatus.get().getCurrentUpperLimitIndex(), getDomainIndex()); } catch (...) { // best effort getParticipantServices()->writeMessageDebug(ParticipantMessage( FLF, "Failed to restore the initial performance control status. ")); } } }
void DomainCoreControl_001::sendActivityLoggingDataIfEnabled(UIntN participantIndex, UIntN domainIndex) { try { if (isActivityLoggingEnabled() == true) { createCoreControlStaticCaps(domainIndex); UInt32 activeCores = getCoreControlStatus(participantIndex, domainIndex).getNumActiveLogicalProcessors(); if (activeCores == Constants::Invalid) { activeCores = getCoreControlStaticCaps(participantIndex, domainIndex).getTotalLogicalProcessors(); } EsifCapabilityData capability; capability.type = ESIF_CAPABILITY_TYPE_CORE_CONTROL; capability.size = sizeof(capability); capability.data.coreControl.activeLogicalProcessors = activeCores; capability.data.coreControl.minimumActiveCores = 1; capability.data.coreControl.maximumActiveCores = getCoreControlStaticCaps(participantIndex, domainIndex).getTotalLogicalProcessors(); getParticipantServices()->sendDptfEvent( ParticipantEvent::DptfParticipantControlAction, domainIndex, Capability::getEsifDataFromCapabilityData(&capability)); std::stringstream message; message << "Published activity for participant " << getParticipantIndex() << ", " << "domain " << getName() << " " << "(" << "Core Control" << ")"; getParticipantServices()->writeMessageInfo(ParticipantMessage(FLF, message.str())); } } catch (...) { // skip if there are any issue in sending log data } }
void DomainDisplayControl_001::setDisplayControl(UIntN participantIndex, UIntN domainIndex, UIntN displayControlIndex, Bool isOverridable) { checkAndCreateControlStructures(domainIndex); if (displayControlIndex == m_currentDisplayControlIndex) { m_participantServicesInterface->writeMessageDebug( ParticipantMessage(FLF, "Requested limit = current limit. Ignoring.")); return; } verifyDisplayControlIndex(displayControlIndex); Percentage newBrightness = (*m_displayControlSet)[m_currentDisplayControlIndex].getBrightness(); if (isOverridable == true) { m_participantServicesInterface->primitiveExecuteSetAsPercentage( esif_primitive_type::SET_DISPLAY_BRIGHTNESS_SOFT, newBrightness, domainIndex); } else { m_participantServicesInterface->primitiveExecuteSetAsPercentage( esif_primitive_type::SET_DISPLAY_BRIGHTNESS_HARD, newBrightness, domainIndex); } // Refresh the status m_currentDisplayControlIndex = displayControlIndex; DELETE_MEMORY_TC(m_displayControlStatus); m_displayControlStatus = new DisplayControlStatus(m_currentDisplayControlIndex); }
Bool DomainConfigTdpControl_001::isLockBitSet(UIntN domainIndex) { // Check to see if the TAR or if cTDP is locked Bool tarLock = (getParticipantServices()->primitiveExecuteGetAsUInt32( esif_primitive_type::GET_PROC_CTDP_TAR_LOCK_STATUS, domainIndex) == 1) ? true : false; Bool configTdpLock = (getParticipantServices()->primitiveExecuteGetAsUInt32( esif_primitive_type::GET_PROC_CTDP_LOCK_STATUS, domainIndex) == 1) ? true : false; if (tarLock || configTdpLock) { getParticipantServices()->writeMessageWarning( ParticipantMessage(FLF, "cTDP is supported, but the lock bit is set!")); return true; } else { return false; } }
void DomainConfigTdpControl_001::setConfigTdpControl(UIntN participantIndex, UIntN domainIndex, UIntN configTdpControlIndex) { checkAndCreateControlStructures(domainIndex); // If any of the lock bits are set, we cannot program cTDP if (m_configTdpLock) { getParticipantServices()->writeMessageWarning( ParticipantMessage(FLF, "cTDP set level ignored, lock bit is set!")); return; } // Bounds checking verifyConfigTdpControlIndex(configTdpControlIndex); getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_PROC_CTDP_CONTROL, (UInt32)(*m_configTdpControlSet)[configTdpControlIndex].getControlId(), // This is what 7.x does domainIndex); getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_PROC_TURBO_ACTIVATION_RATIO, (UInt32)((*m_configTdpControlSet)[configTdpControlIndex].getTdpRatio() - 1), // This is what 7.x does domainIndex); // Then BIOS getParticipantServices()->primitiveExecuteSetAsUInt32( esif_primitive_type::SET_CTDP_POINT, configTdpControlIndex, domainIndex); // Refresh the status DELETE_MEMORY_TC(m_configTdpControlStatus); m_configTdpControlStatus = new ConfigTdpControlStatus(configTdpControlIndex); }
DisplayControlDynamicCaps DomainDisplayControl_001::createDisplayControlDynamicCaps(UIntN domainIndex) { auto displaySet = getDisplayControlSet(getParticipantIndex(), domainIndex); // Get dynamic caps // The caps are stored in BIOS as brightness percentage. They must be converted // to indices before they can be used. UIntN lowerLimitIndex = getLowerLimitIndex(domainIndex, displaySet); UIntN upperLimitIndex = getUpperLimitIndex(domainIndex, displaySet); auto size = displaySet.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, ignoring lower limit.")); } return DisplayControlDynamicCaps(upperLimitIndex, lowerLimitIndex); }
XmlNode* UnifiedDomain::getXml() { XmlNode* domain = XmlNode::createWrapperElement("domain"); domain->addChild(XmlNode::createDataElement("index", StatusFormat::friendlyValue(m_domainIndex))); domain->addChild(XmlNode::createDataElement("name", getName())); domain->addChild(XmlNode::createDataElement("description", getDescription())); // Active Control XML Status try { domain->addChild(getActiveControlInterfaceExPtr()->getXml(m_domainIndex)); } catch (not_implemented) { } catch (...) { // Write message log error m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, "Unable to get active control XML status!")); } // cTDP Control XML Status try { domain->addChild(getConfigTdpControlInterfaceExPtr()->getXml(m_domainIndex)); } catch (not_implemented) { } catch (...) { // Write message log error m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, "Unable to get cTDP control XML status!")); } // Core Control XML Status try { domain->addChild(getCoreControlInterfaceExPtr()->getXml(m_domainIndex)); } catch (not_implemented) { } catch (...) { // Write message log error m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, "Unable to get core control XML status!")); } // Display Control XML Status try { domain->addChild(getDisplayControlInterfaceExPtr()->getXml(m_domainIndex)); } catch (not_implemented) { } catch (...) { // Write message log error m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, "Unable to get display control XML status!")); } // Performance Control XML Status try { domain->addChild(getPerformanceControlInterfaceExPtr()->getXml(m_domainIndex)); } catch (not_implemented) { } catch (...) { // Write message log error m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, "Unable to get performance control XML status!")); } // Pixel Clock Control try { domain->addChild(getPixelClockControlInterfaceExPtr()->getXml(m_domainIndex)); } catch (not_implemented) { } catch (...) { // Write message log error m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, "Unable to get pixel clock control XML!")); } // Pixel Clock Status try { domain->addChild(getPixelClockStatusInterfaceExPtr()->getXml(m_domainIndex)); } catch (not_implemented) { } catch (...) { // Write message log error m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, "Unable to get pixel clock status XML!")); } // Power Control XML Status try { domain->addChild(getPowerControlInterfaceExPtr()->getXml(m_domainIndex)); } catch (not_implemented) { } catch (...) { // Write message log error m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, "Unable to get power control XML status!")); } // Power Status XML Status try { domain->addChild(getPowerStatusInterfaceExPtr()->getXml(m_domainIndex)); } catch (not_implemented) { } catch (...) { // Write message log error m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, "Unable to get power reporting XML status!")); } // Domain Priority XML Status try { domain->addChild(getDomainPriorityInterfaceExPtr()->getXml(m_domainIndex)); } catch (not_implemented) { } catch (...) { // Write message log error m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, "Unable to get domain priority XML status!")); } // RF Profile Control XML Status try { domain->addChild(getRfProfileControlInterfaceExPtr()->getXml(m_domainIndex)); } catch (not_implemented) { } catch (...) { // Write message log error m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, "Unable to get rf profile control XML status!")); } // RF Profile Status XML Status try { domain->addChild(getRfProfileStatusInterfaceExPtr()->getXml(m_domainIndex)); } catch (not_implemented) { } catch (...) { // Write message log error m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, "Unable to get rf profile status XML status!")); } // Temperature XML Status try { domain->addChild(getTemperatureInterfaceExPtr()->getXml(m_domainIndex)); } catch (not_implemented) { } catch (...) { // Write message log error m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, "Unable to get temperature XML status!")); } // Utilization XML Status try { domain->addChild(getUtilizationInterfaceExPtr()->getXml(m_domainIndex)); } catch (not_implemented) { } catch (...) { // Write message log error m_participantServicesInterface->writeMessageWarning(ParticipantMessage(FLF, "Unable to get utilization XML status!")); } return domain; }
void DomainPerformanceControl_002::arbitratePerformanceStateLimits( UIntN domainIndex, UIntN pStateUpperLimitIndex, UIntN pStateLowerLimitIndex, UIntN tStateUpperLimitIndex, UIntN tStateLowerLimitIndex, UIntN& performanceUpperLimitIndex, UIntN& performanceLowerLimitIndex) { auto performanceStateSetSize = getPerformanceStateSet(domainIndex).getCount(); auto throttlingStateSetSize = getThrottlingStateSet(domainIndex).getCount(); if (pStateUpperLimitIndex == (performanceStateSetSize - 1) && pStateLowerLimitIndex == (performanceStateSetSize - 1)) { if (throttlingStateSetSize > 0) { performanceUpperLimitIndex = static_cast<UIntN>(performanceStateSetSize + tStateUpperLimitIndex); } else { performanceUpperLimitIndex = pStateUpperLimitIndex; } } else { // Ignore PPC/PDL if TPC is non-zero, ignore P-states if (tStateUpperLimitIndex != 0) { getParticipantServices()->writeMessageDebug( ParticipantMessage(FLF, "P-states are being ignored because of the T-State upper dynamic cap.")); performanceUpperLimitIndex = static_cast<UIntN>(performanceStateSetSize + tStateUpperLimitIndex); } performanceUpperLimitIndex = pStateUpperLimitIndex; } performanceUpperLimitIndex = std::max(performanceUpperLimitIndex, m_tdpFrequencyLimitControlIndex); getParticipantServices()->writeMessageDebug( ParticipantMessage(FLF, "Performance upper limit index is: " + StlOverride::to_string(performanceUpperLimitIndex))); // Lower Limit if (pStateLowerLimitIndex == (performanceStateSetSize - 1)) { // Lower P is P(n) if (throttlingStateSetSize == 0) { performanceLowerLimitIndex = pStateLowerLimitIndex; } else { performanceLowerLimitIndex = static_cast<UIntN>(performanceStateSetSize + tStateLowerLimitIndex); } } else { //Lower P is NOT P(n), ignore T-states performanceLowerLimitIndex = pStateLowerLimitIndex; if (throttlingStateSetSize > 0) { getParticipantServices()->writeMessageWarning( ParticipantMessage(FLF, "T-states are being ignored because of the P-State lower dynamic cap.")); } } getParticipantServices()->writeMessageDebug( ParticipantMessage(FLF, "Performance lower limit index is: " + StlOverride::to_string(performanceLowerLimitIndex))); }
RfProfileCapabilities DomainRfProfileControl_001::getRfProfileCapabilities(UIntN participantIndex, UIntN domainIndex) { Frequency defaultCenterFrequency(0); Frequency centerFrequency(0); Frequency frequencyAdjustResolution(0); Frequency minFrequency(0); Frequency maxFrequency(0); Percentage ssc(0.0); try { defaultCenterFrequency = getParticipantServices()->primitiveExecuteGetAsFrequency( esif_primitive_type::GET_RFPROFILE_DEFAULT_CENTER_FREQUENCY, domainIndex); } catch (...) { getParticipantServices()->writeMessageDebug( ParticipantMessage(FLF, "Failed to get default center frequency. ")); } try { centerFrequency = getParticipantServices()->primitiveExecuteGetAsFrequency( esif_primitive_type::GET_RFPROFILE_CENTER_FREQUENCY, domainIndex); } catch (...) { getParticipantServices()->writeMessageDebug( ParticipantMessage(FLF, "Failed to get center frequency. ")); } try { frequencyAdjustResolution = getParticipantServices()->primitiveExecuteGetAsFrequency( esif_primitive_type::GET_RFPROFILE_FREQUENCY_ADJUST_RESOLUTION, domainIndex); } catch (...) { getParticipantServices()->writeMessageDebug( ParticipantMessage(FLF, "Failed to get frequency adjust resolution. ")); } try { minFrequency = getParticipantServices()->primitiveExecuteGetAsFrequency( esif_primitive_type::GET_RFPROFILE_MIN_FREQUENCY, domainIndex); } catch (...) { getParticipantServices()->writeMessageDebug( ParticipantMessage(FLF, "Failed to get min frequency. ")); } try { maxFrequency = getParticipantServices()->primitiveExecuteGetAsFrequency( esif_primitive_type::GET_RFPROFILE_MAX_FREQUENCY, domainIndex); } catch (...) { getParticipantServices()->writeMessageDebug( ParticipantMessage(FLF, "Failed to get max frequency. ")); } try { ssc = getParticipantServices()->primitiveExecuteGetAsPercentage(esif_primitive_type::GET_RFPROFILE_SSC, domainIndex); } catch (...) { getParticipantServices()->writeMessageDebug( ParticipantMessage(FLF, "Failed to get ssc. ")); } RfProfileCapabilities rfProfileCapabilities( defaultCenterFrequency, centerFrequency, frequencyAdjustResolution, minFrequency, maxFrequency, ssc); return rfProfileCapabilities; }