std::vector<ThermalRelationshipTableEntry> BinaryParse::passiveTrtObject(UInt32 dataLength, void* esifData) { std::vector<ThermalRelationshipTableEntry> controls; UInt8* data = reinterpret_cast<UInt8*>(esifData); struct EsifDataBinaryTrtPackage* currentRow = reinterpret_cast<struct EsifDataBinaryTrtPackage*>(data); validateData(dataLength); UIntN rows = countTrtRows(dataLength, data); // Reset currentRow to point to the beginning of the data block data = reinterpret_cast<UInt8*>(esifData); 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); ThermalRelationshipTableEntry temp( normalizeAcpiScope(source), normalizeAcpiScope(target), static_cast<UInt32>(currentRow->thermalInfluence.integer.value), static_cast<UInt32>(currentRow->thermalSamplingPeriod.integer.value)); controls.push_back(temp); // 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 controls; }
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); }