void SupportedPolicyList::update(void) { m_guid.clear(); // TODO: This should be moved to a DPTF Initialization class. For now, ignore empty result buffer DptfBuffer ignore = m_dptfManager->getEsifServices()->primitiveExecuteGet( esif_primitive_type::GET_DPTF_CONFIGURATION, ESIF_DATA_BINARY); DptfBuffer buffer = m_dptfManager->getEsifServices()->primitiveExecuteGet( esif_primitive_type::GET_SUPPORTED_POLICIES, ESIF_DATA_BINARY); if ((buffer.size() % sizeof(AcpiEsifGuid)) != 0) { std::stringstream message; message << "Received invalid data length [" << buffer.size() << "] from primitive call: GET_SUPPORTED_POLICIES"; throw dptf_exception(message.str()); } UInt32 guidCount = buffer.size() / sizeof(AcpiEsifGuid); AcpiEsifGuid* acpiEsifGuid = reinterpret_cast<AcpiEsifGuid*>(buffer.get()); for (UInt32 i = 0; i < guidCount; i++) { UInt8 guidByteArray[GuidSize] = {0}; esif_ccb_memcpy(guidByteArray, &acpiEsifGuid[i].uuid, GuidSize); Guid guid(guidByteArray); m_dptfManager->getEsifServices()->writeMessageInfo("Supported GUID: " + guid.toString()); m_guid.push_back(guid); } }
void SupportedPolicyList::update(void) { try { DptfBuffer buffer = m_dptfManager->getEsifServices()->primitiveExecuteGet( esif_primitive_type::GET_SUPPORTED_POLICIES, ESIF_DATA_BINARY); if (isBufferValid(buffer)) { m_guid = parseBufferForPolicyGuids(buffer); } else { std::stringstream message; message << "Received invalid data length [" << buffer.size() << "] from primitive call: GET_SUPPORTED_POLICIES"; throw dptf_exception(message.str()); } } catch (const std::exception& ex) { m_dptfManager->getEsifServices()->writeMessageWarning(ex.what()); } postMessageWithSupportedGuids(); }
void DomainPowerControl_001::setPowerControlDynamicCapsSet(UIntN participantIndex, UIntN domainIndex, PowerControlDynamicCapsSet capsSet) { DptfBuffer buffer = capsSet.toPpccBinary(); getParticipantServices()->primitiveExecuteSet( esif_primitive_type::SET_RAPL_POWER_CONTROL_CAPABILITIES, ESIF_DATA_BINARY, buffer.get(), buffer.size(), buffer.size(), domainIndex, Constants::Esif::NoPersistInstance); m_powerControlDynamicCaps.set(getDynamicCapabilities()); }
PowerControlDynamicCapsSet PowerControlDynamicCapsSet::createFromPpcc(const DptfBuffer& buffer) { std::vector<PowerControlDynamicCaps> controls; UInt8* data = reinterpret_cast<UInt8*>(buffer.get()); data += sizeof(esif_data_variant); //Ignore revision field struct EsifDataBinaryPpccPackage* currentRow = reinterpret_cast<struct EsifDataBinaryPpccPackage*>(data); if (buffer.size() == 0) { throw dptf_exception("Received empty PPSS buffer."); } UIntN rows = (buffer.size() - sizeof(esif_data_variant)) / sizeof(EsifDataBinaryPpccPackage); if ((buffer.size() - sizeof(esif_data_variant)) % sizeof(EsifDataBinaryPpccPackage)) { throw dptf_exception("Expected binary data size mismatch. (PPSS)"); } for (UIntN i = 0; i < rows; i++) { PowerControlDynamicCaps temp( static_cast<PowerControlType::Type>(currentRow->powerLimitIndex.integer.value), static_cast<UIntN>(currentRow->powerLimitMinimum.integer.value), static_cast<UIntN>(currentRow->powerLimitMaximum.integer.value), static_cast<UIntN>(currentRow->stepSize.integer.value), TimeSpan::createFromMilliseconds(static_cast<UIntN>(currentRow->timeWindowMinimum.integer.value)), TimeSpan::createFromMilliseconds(static_cast<UIntN>(currentRow->timeWindowMaximum.integer.value)), Percentage(0.0), Percentage(0.0)); // TODO : Need to revisit if there are more than 2 power limits if (controls.empty()) { controls.push_back(temp); } else if (controls.front().getPowerControlType() < temp.getPowerControlType()) { controls.push_back(temp); } else { controls.insert(controls.begin(), temp); } data += sizeof(struct EsifDataBinaryPpccPackage); currentRow = reinterpret_cast<struct EsifDataBinaryPpccPackage*>(data); } return PowerControlDynamicCapsSet(controls); }
void DomainPowerControl_001::clearCachedData(void) { m_powerControlDynamicCaps.invalidate(); if (m_capabilitiesLocked == false) { DptfBuffer capabilitiesBuffer = createResetPrimitiveTupleBinary( esif_primitive_type::SET_RAPL_POWER_CONTROL_CAPABILITIES, Constants::Esif::NoPersistInstance); getParticipantServices()->primitiveExecuteSet( esif_primitive_type::SET_CONFIG_RESET, ESIF_DATA_BINARY, capabilitiesBuffer.get(), capabilitiesBuffer.size(), capabilitiesBuffer.size(), 0, Constants::Esif::NoInstance); } }
std::vector<Guid> SupportedPolicyList::parseBufferForPolicyGuids(const DptfBuffer& buffer) { UInt32 guidCount = buffer.size() / sizeof(AcpiEsifGuid); AcpiEsifGuid* acpiEsifGuid = reinterpret_cast<AcpiEsifGuid*>(buffer.get()); std::vector<Guid> guids; for (UInt32 i = 0; i < guidCount; i++) { UInt8 guidByteArray[GuidSize] = { 0 }; esif_ccb_memcpy(guidByteArray, &acpiEsifGuid[i].uuid, GuidSize); guids.push_back(Guid(guidByteArray)); } return guids; }
void DomainPerformanceControl_001::clearCachedData(void) { m_performanceControlSet.invalidate(); m_performanceControlDynamicCaps.invalidate(); m_performanceControlStaticCaps.invalidate(); m_performanceControlStatus.invalidate(); if (m_capabilitiesLocked == false) { DptfBuffer depthLimitBuffer = createResetPrimitiveTupleBinary( esif_primitive_type::SET_PERF_PSTATE_DEPTH_LIMIT, Constants::Esif::NoPersistInstance); getParticipantServices()->primitiveExecuteSet( esif_primitive_type::SET_CONFIG_RESET, ESIF_DATA_BINARY, depthLimitBuffer.get(), depthLimitBuffer.size(), depthLimitBuffer.size(), 0, Constants::Esif::NoInstance); } }
ActiveControlSet ActiveControlSet::createFromFps(const DptfBuffer& buffer) { std::vector<ActiveControl> controls; UInt8* data = reinterpret_cast<UInt8*>(buffer.get()); data += sizeof(esif_data_variant); // Ignore revision field struct EsifDataBinaryFpsPackage* currentRow = reinterpret_cast<struct EsifDataBinaryFpsPackage*>(data); if (buffer.size() == 0) { throw dptf_exception("Received empty FPS buffer."); } UIntN rows = (buffer.size() - sizeof(esif_data_variant)) / sizeof(EsifDataBinaryFpsPackage); if ((buffer.size() - sizeof(esif_data_variant)) % sizeof(EsifDataBinaryFpsPackage)) { throw dptf_exception("Expected binary data size mismatch. (FPS)"); } for (UIntN i = 0; i < rows; i++) { ActiveControl temp( static_cast<UInt32>(currentRow->control.integer.value), static_cast<UInt32>(currentRow->tripPoint.integer .value), // May want to represent this differently; -1 is MAX_INT for whatever type static_cast<UInt32>(currentRow->speed.integer.value), static_cast<UInt32>(currentRow->noiseLevel.integer.value), static_cast<UInt32>(currentRow->power.integer.value)); controls.push_back(temp); data += sizeof(struct EsifDataBinaryFpsPackage); currentRow = reinterpret_cast<struct EsifDataBinaryFpsPackage*>(data); } return ActiveControlSet(controls); }
void DomainDisplayControl_001::clearCachedData(void) { m_displayControlDynamicCaps.invalidate(); m_displayControlSet.invalidate(); m_currentDisplayControlIndex.invalidate(); if (m_capabilitiesLocked == false) { DptfBuffer capabilityBuffer = createResetPrimitiveTupleBinary( esif_primitive_type::SET_DISPLAY_CAPABILITY, Constants::Esif::NoPersistInstance); getParticipantServices()->primitiveExecuteSet( esif_primitive_type::SET_CONFIG_RESET, ESIF_DATA_BINARY, capabilityBuffer.get(), capabilityBuffer.size(), capabilityBuffer.size(), 0, Constants::Esif::NoInstance); DptfBuffer depthLimitBuffer = createResetPrimitiveTupleBinary( esif_primitive_type::SET_DISPLAY_DEPTH_LIMIT, Constants::Esif::NoPersistInstance); getParticipantServices()->primitiveExecuteSet( esif_primitive_type::SET_CONFIG_RESET, ESIF_DATA_BINARY, depthLimitBuffer.get(), depthLimitBuffer.size(), depthLimitBuffer.size(), 0, Constants::Esif::NoInstance); } }
Bool SupportedPolicyList::isBufferValid(const DptfBuffer& buffer) const { return ((buffer.size() % sizeof(AcpiEsifGuid)) == 0); }
ThermalRelationshipTable ThermalRelationshipTable::createTrtFromDptfBuffer(const DptfBuffer& buffer) { std::vector<std::shared_ptr<RelationshipTableEntryBase>> entries; UInt8* data = reinterpret_cast<UInt8*>(buffer.get()); struct EsifDataBinaryTrtPackage* currentRow = reinterpret_cast<struct EsifDataBinaryTrtPackage*>(data); if (buffer.size() != 0) { UIntN rows = countTrtRows(buffer.size(), data); // Reset currentRow to point to the beginning of the data block data = reinterpret_cast<UInt8*>(buffer.get()); currentRow = reinterpret_cast<struct EsifDataBinaryTrtPackage*>(data); for (UIntN i = 0; i < rows; i++) { // Since the TRT has 2 strings in it, the process for extracting them is: // 1. Extract the source at the beginning of the structure // 2. Since the actual string data is placed between the source and target, the pointer needs moved // 3. Move the pointer past the source string data and set current row // 4. Now the targetDevice field will actually point to the right spot // 5. Extract target device // 6. Move the pointer as before (past the targetDevice string data) and set current row // 7. Extract the remaining fields // 8. Point data and currentRow to the next row std::string source( reinterpret_cast<const char*>(&(currentRow->sourceDevice)) + sizeof(union esif_data_variant), currentRow->sourceDevice.string.length); data += currentRow->sourceDevice.string.length; currentRow = reinterpret_cast<struct EsifDataBinaryTrtPackage*>(data); std::string target( reinterpret_cast<const char*>(&(currentRow->targetDevice)) + sizeof(union esif_data_variant), currentRow->targetDevice.string.length); data += currentRow->targetDevice.string.length; currentRow = reinterpret_cast<struct EsifDataBinaryTrtPackage*>(data); auto newTrtEntry = std::make_shared<ThermalRelationshipTableEntry>( BinaryParse::normalizeAcpiScope(source), BinaryParse::normalizeAcpiScope(target), static_cast<UInt32>(currentRow->thermalInfluence.integer.value), TimeSpan::createFromTenthSeconds(static_cast<UInt32>(currentRow->thermalSamplingPeriod.integer.value))); if (newTrtEntry) { // Check for duplicate entries. Don't add entry if previous entry exists with same target/source pair Bool isDuplicateEntry = false; for (auto e = entries.begin(); e != entries.end(); e++) { auto trtEntry = std::dynamic_pointer_cast<ThermalRelationshipTableEntry>(*e); if (trtEntry && newTrtEntry->isSameAs(*trtEntry)) { isDuplicateEntry = true; break; } } if (isDuplicateEntry == false) { entries.push_back(newTrtEntry); } } // Since we've already accounted for the strings, we now move the pointer by the size of the structure // to get to the next row. data += sizeof(struct EsifDataBinaryTrtPackage); currentRow = reinterpret_cast<struct EsifDataBinaryTrtPackage*>(data); } } return ThermalRelationshipTable(entries); }
DptfBuffer ThermalRelationshipTable::toTrtBinary() const { DptfBuffer packages; UInt32 offset = 0; for (auto entry = m_entries.begin(); entry != m_entries.end(); entry++) { auto trtEntry = std::dynamic_pointer_cast<ThermalRelationshipTableEntry>(*entry); if (trtEntry) { UInt32 sourceScopeLength = (UInt32)(*entry)->getSourceDeviceScope().size(); UInt32 targetScopeLength = (UInt32)(*entry)->getTargetDeviceScope().size(); DptfBuffer packageBuffer; packageBuffer.allocate(sizeof(EsifDataBinaryTrtPackage) + sourceScopeLength + targetScopeLength); EsifDataBinaryTrtPackage entryPackage; UInt32 dataAddress = 0; // Source Scope entryPackage.sourceDevice.string.length = sourceScopeLength; entryPackage.sourceDevice.type = esif_data_type::ESIF_DATA_STRING; packageBuffer.put(dataAddress, (UInt8*)(&(entryPackage.sourceDevice)), sizeof(entryPackage.sourceDevice)); dataAddress += sizeof(entryPackage.sourceDevice); packageBuffer.put(dataAddress, (UInt8*)((*entry)->getSourceDeviceScope().c_str()), sourceScopeLength); dataAddress += sourceScopeLength; // Target Scope entryPackage.targetDevice.string.length = targetScopeLength; entryPackage.targetDevice.type = esif_data_type::ESIF_DATA_STRING; packageBuffer.put(dataAddress, (UInt8*)(&(entryPackage.targetDevice)), sizeof(entryPackage.targetDevice)); dataAddress += sizeof(entryPackage.targetDevice); packageBuffer.put(dataAddress, (UInt8*)((*entry)->getTargetDeviceScope().c_str()), targetScopeLength); dataAddress += targetScopeLength; // Thermal Influence entryPackage.thermalInfluence.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.thermalInfluence.integer.value = trtEntry->thermalInfluence(); packageBuffer.put(dataAddress, (UInt8*)(&(entryPackage.thermalInfluence)), sizeof(entryPackage.thermalInfluence)); dataAddress += sizeof(entryPackage.thermalInfluence); // Sampling Period entryPackage.thermalSamplingPeriod.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.thermalSamplingPeriod.integer.value = trtEntry->thermalSamplingPeriod().asTenthSecondsInt(); packageBuffer.put(dataAddress, (UInt8*)(&(entryPackage.thermalSamplingPeriod)), sizeof(entryPackage.thermalSamplingPeriod)); dataAddress += sizeof(entryPackage.thermalSamplingPeriod); // Reserved1 entryPackage.reserved1.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.reserved1.integer.value = 0; packageBuffer.put(dataAddress, (UInt8*)(&(entryPackage.reserved1)), sizeof(entryPackage.reserved1)); dataAddress += sizeof(entryPackage.reserved1); // Reserved2 entryPackage.reserved2.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.reserved2.integer.value = 0; packageBuffer.put(dataAddress, (UInt8*)(&(entryPackage.reserved2)), sizeof(entryPackage.reserved2)); dataAddress += sizeof(entryPackage.reserved2); // Reserved3 entryPackage.reserved3.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.reserved3.integer.value = 0; packageBuffer.put(dataAddress, (UInt8*)(&(entryPackage.reserved3)), sizeof(entryPackage.reserved3)); dataAddress += sizeof(entryPackage.reserved3); // Reserved4 entryPackage.reserved4.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.reserved4.integer.value = 0; packageBuffer.put(dataAddress, (UInt8*)(&(entryPackage.reserved4)), sizeof(entryPackage.reserved4)); dataAddress += sizeof(entryPackage.reserved4); packages.put(offset, packageBuffer.get(), packageBuffer.size()); offset += packageBuffer.size(); } } DptfBuffer buffer(packages.size()); buffer.put(0, packages.get(), packages.size()); return buffer; }
ActiveRelationshipTable ActiveRelationshipTable::createArtFromDptfBuffer(const DptfBuffer& buffer) { std::vector<std::shared_ptr<RelationshipTableEntryBase>> entries; UInt8* data = reinterpret_cast<UInt8*>(buffer.get()); struct EsifDataBinaryArtPackage* currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); if (buffer.size() == 0) { throw dptf_exception("There is no data to process."); } UIntN rows = countArtRows(buffer.size(), data); // Reset currentRow to point to the beginning of the data block data = reinterpret_cast<UInt8*>(buffer.get()); data += sizeof(esif_data_variant); // Ignore revision field currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); for (UIntN i = 0; i < rows; i++) { // Since the ART has 2 strings in it, the process for extracting them is: // 1. Extract the source at the beginning of the structure // 2. Since the actual string data is placed between the source and target, the pointer needs moved // 3. Move the pointer past the source string data and set current row // 4. Now the targetDevice field will actually point to the right spot // 5. Extract target device // 6. Move the pointer as before (past the targetDevice string data) and set current row // 7. Extract the remaining fields // 8. Point data and currentRow to the next row std::string source = TableStringParser::getDeviceString((currentRow->sourceDevice)); data += currentRow->sourceDevice.string.length; currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); std::string target = TableStringParser::getDeviceString((currentRow->targetDevice)); data += currentRow->targetDevice.string.length; currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); std::vector<UInt32> acEntries; acEntries.push_back(static_cast<UInt32>(currentRow->ac0MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac1MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac2MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac3MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac4MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac5MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac6MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac7MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac8MaxFanSpeed.integer.value)); acEntries.push_back(static_cast<UInt32>(currentRow->ac9MaxFanSpeed.integer.value)); auto newArtEntry = std::make_shared<ActiveRelationshipTableEntry>( BinaryParse::normalizeAcpiScope(source), BinaryParse::normalizeAcpiScope(target), static_cast<UInt32>(currentRow->weight.integer.value), acEntries); if (newArtEntry) { // Check for duplicate entries. Don't add entry if previous entry exists with same target/source pair Bool isDuplicateEntry = false; for (auto e = entries.begin(); e != entries.end(); e++) { auto artEntry = std::dynamic_pointer_cast<ActiveRelationshipTableEntry>(*e); if (artEntry && newArtEntry->isSameAs(*artEntry)) { isDuplicateEntry = true; break; } } if (isDuplicateEntry == false) { entries.push_back(newArtEntry); } } // Since we've already accounted for the strings, we now move the pointer by the size of the structure // to get to the next row. data += sizeof(struct EsifDataBinaryArtPackage); currentRow = reinterpret_cast<struct EsifDataBinaryArtPackage*>(data); } return ActiveRelationshipTable(entries); }
DptfBuffer ActiveRelationshipTable::toArtBinary() const { esif_data_variant revisionField; revisionField.integer.type = esif_data_type::ESIF_DATA_UINT64; revisionField.integer.value = 1; DptfBuffer packages; UInt32 offset = 0; for (auto entry = m_entries.begin(); entry != m_entries.end(); entry++) { auto artEntry = std::dynamic_pointer_cast<ActiveRelationshipTableEntry>(*entry); if (artEntry) { UInt32 sourceScopeLength = (UInt32)(*entry)->getSourceDeviceScope().size(); UInt32 targetScopeLength = (UInt32)(*entry)->getTargetDeviceScope().size(); DptfBuffer packageBuffer; packageBuffer.allocate(sizeof(EsifDataBinaryArtPackage) + sourceScopeLength + targetScopeLength); EsifDataBinaryArtPackage entryPackage; UInt32 dataAddress = 0; // Source Scope entryPackage.sourceDevice.string.length = sourceScopeLength; entryPackage.sourceDevice.type = esif_data_type::ESIF_DATA_STRING; packageBuffer.put(dataAddress, (UInt8*)(&(entryPackage.sourceDevice)), sizeof(entryPackage.sourceDevice)); dataAddress += sizeof(entryPackage.sourceDevice); packageBuffer.put(dataAddress, (UInt8*)((*entry)->getSourceDeviceScope().c_str()), sourceScopeLength); dataAddress += sourceScopeLength; // Target Scope entryPackage.targetDevice.string.length = targetScopeLength; entryPackage.targetDevice.type = esif_data_type::ESIF_DATA_STRING; packageBuffer.put(dataAddress, (UInt8*)(&(entryPackage.targetDevice)), sizeof(entryPackage.targetDevice)); dataAddress += sizeof(entryPackage.targetDevice); packageBuffer.put(dataAddress, (UInt8*)((*entry)->getTargetDeviceScope().c_str()), targetScopeLength); dataAddress += targetScopeLength; // Weight entryPackage.weight.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.weight.integer.value = artEntry->getWeight(); packageBuffer.put(dataAddress, (UInt8*)(&(entryPackage.weight)), sizeof(entryPackage.weight)); dataAddress += sizeof(entryPackage.weight); // AC0 entryPackage.ac0MaxFanSpeed.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.ac0MaxFanSpeed.integer.value = artEntry->ac(0); packageBuffer.put( dataAddress, (UInt8*)(&(entryPackage.ac0MaxFanSpeed)), sizeof(entryPackage.ac0MaxFanSpeed)); dataAddress += sizeof(entryPackage.ac0MaxFanSpeed); // AC1 entryPackage.ac1MaxFanSpeed.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.ac1MaxFanSpeed.integer.value = artEntry->ac(1); packageBuffer.put( dataAddress, (UInt8*)(&(entryPackage.ac1MaxFanSpeed)), sizeof(entryPackage.ac1MaxFanSpeed)); dataAddress += sizeof(entryPackage.ac1MaxFanSpeed); // AC2 entryPackage.ac2MaxFanSpeed.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.ac2MaxFanSpeed.integer.value = artEntry->ac(2); packageBuffer.put( dataAddress, (UInt8*)(&(entryPackage.ac2MaxFanSpeed)), sizeof(entryPackage.ac2MaxFanSpeed)); dataAddress += sizeof(entryPackage.ac2MaxFanSpeed); // AC3 entryPackage.ac3MaxFanSpeed.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.ac3MaxFanSpeed.integer.value = artEntry->ac(3); packageBuffer.put( dataAddress, (UInt8*)(&(entryPackage.ac3MaxFanSpeed)), sizeof(entryPackage.ac3MaxFanSpeed)); dataAddress += sizeof(entryPackage.ac3MaxFanSpeed); // AC4 entryPackage.ac4MaxFanSpeed.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.ac4MaxFanSpeed.integer.value = artEntry->ac(4); packageBuffer.put( dataAddress, (UInt8*)(&(entryPackage.ac4MaxFanSpeed)), sizeof(entryPackage.ac4MaxFanSpeed)); dataAddress += sizeof(entryPackage.ac4MaxFanSpeed); // AC5 entryPackage.ac5MaxFanSpeed.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.ac5MaxFanSpeed.integer.value = artEntry->ac(5); packageBuffer.put( dataAddress, (UInt8*)(&(entryPackage.ac5MaxFanSpeed)), sizeof(entryPackage.ac5MaxFanSpeed)); dataAddress += sizeof(entryPackage.ac5MaxFanSpeed); // AC6 entryPackage.ac6MaxFanSpeed.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.ac6MaxFanSpeed.integer.value = artEntry->ac(6); packageBuffer.put( dataAddress, (UInt8*)(&(entryPackage.ac6MaxFanSpeed)), sizeof(entryPackage.ac6MaxFanSpeed)); dataAddress += sizeof(entryPackage.ac6MaxFanSpeed); // AC7 entryPackage.ac7MaxFanSpeed.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.ac7MaxFanSpeed.integer.value = artEntry->ac(7); packageBuffer.put( dataAddress, (UInt8*)(&(entryPackage.ac7MaxFanSpeed)), sizeof(entryPackage.ac7MaxFanSpeed)); dataAddress += sizeof(entryPackage.ac7MaxFanSpeed); // AC8 entryPackage.ac8MaxFanSpeed.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.ac8MaxFanSpeed.integer.value = artEntry->ac(8); packageBuffer.put( dataAddress, (UInt8*)(&(entryPackage.ac8MaxFanSpeed)), sizeof(entryPackage.ac8MaxFanSpeed)); dataAddress += sizeof(entryPackage.ac8MaxFanSpeed); // AC9 entryPackage.ac9MaxFanSpeed.integer.type = esif_data_type::ESIF_DATA_UINT64; entryPackage.ac9MaxFanSpeed.integer.value = artEntry->ac(9); packageBuffer.put( dataAddress, (UInt8*)(&(entryPackage.ac9MaxFanSpeed)), sizeof(entryPackage.ac9MaxFanSpeed)); dataAddress += sizeof(entryPackage.ac9MaxFanSpeed); packages.put(offset, packageBuffer.get(), packageBuffer.size()); offset += packageBuffer.size(); } } UInt32 sizeOfRevision = (UInt32)sizeof(revisionField); DptfBuffer buffer(sizeOfRevision + packages.size()); buffer.put(0, (UInt8*)&revisionField, sizeOfRevision); buffer.put(sizeOfRevision, packages.get(), packages.size()); return buffer; }