Exemple #1
0
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);
}