LpmTable BinaryParse::lpmTableObject(UInt32 dataLength, void* binaryData) { std::vector<LpmEntry> lpmTableEntries; UInt8* data = reinterpret_cast<UInt8*>(binaryData); struct EsifDataBinaryLpmtPackage* currentRow = reinterpret_cast<struct EsifDataBinaryLpmtPackage*>(data); esif_data_variant* dataVariant; LpmConfigurationVersion::Type version; validateData(dataLength); UIntN rows = countLpmtRows(dataLength, data); dataVariant = reinterpret_cast<esif_data_variant*>(binaryData); version = static_cast<LpmConfigurationVersion::Type>(dataVariant->integer.value); // Reset currentRow to point to the beginning of the data block data = reinterpret_cast<UInt8*>(binaryData); data += sizeof(esif_data_variant); currentRow = reinterpret_cast<struct EsifDataBinaryLpmtPackage*>(data); for (UIntN i = 0; i < rows; i++) { 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 EsifDataBinaryLpmtPackage*>(data); // Convert from esif/acpi type to dptf type. esif_domain_type esifDomainType = static_cast<esif_domain_type>(currentRow->domainType.integer.value); DomainType::Type domainType = EsifDomainTypeToDptfDomainType(esifDomainType); LpmEntry lpmEntry( normalizeAcpiScope(target), domainType, static_cast<ControlKnobType::Type>(currentRow->controlKnob.integer.value), static_cast<UInt32>(currentRow->controlValue.integer.value)); lpmTableEntries.push_back(lpmEntry); // 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 EsifDataBinaryLpmtPackage); currentRow = reinterpret_cast<struct EsifDataBinaryLpmtPackage*>(data); } return (LpmTable(version, lpmTableEntries)); }
LpmTable PolicyServicesPlatformConfigurationData::getLpmTable(void) { throwIfNotWorkItemThread(); UInt32 dataLength = 0; DptfMemory binaryData; binaryData.allocate(Constants::DefaultBufferSize, true); LpmTable lpmTable(LpmConfigurationVersion::vInvalid, vector<LpmEntry>()); try { getEsifServices()->primitiveExecuteGet( esif_primitive_type::GET_LPM_TABLE, ESIF_DATA_BINARY, binaryData, binaryData.getSize(), &dataLength ); lpmTable = BinaryParse::lpmTableObject(dataLength, binaryData); } catch (buffer_too_small e) { binaryData.deallocate(); binaryData.allocate(e.getNeededBufferSize(), true); getEsifServices()->primitiveExecuteGet( esif_primitive_type::GET_LPM_TABLE, ESIF_DATA_BINARY, binaryData, binaryData.getSize(), &dataLength ); lpmTable = BinaryParse::lpmTableObject(dataLength, binaryData); } catch (...) { // TODO: This is still under discussion so leaving the v0 part commented. // We assume version:v0 if we come here. //lpmTable = LpmTable(LpmConfigurationVersion::v0, vector<LpmEntry>()); lpmTable = LpmTable(LpmConfigurationVersion::v1, vector<LpmEntry>()); } binaryData.deallocate(); return (lpmTable); }