コード例 #1
0
NTSTATUS
RosKmAdapter::InitializePowerComponentInfo()
{
    NTSTATUS Status;

    RosKmAcpiReader acpiReader(this, DISPLAY_ADAPTER_HW_ID);
    Status = acpiReader.Read('DCMP'); // Invoke Method(PMCD).
    if (NT_SUCCESS(Status) &&
        (acpiReader.GetOutputArgumentCount() == 3)) // must return 3 output arguments
    {
        RosKmAcpiArgumentParser acpiParser(&acpiReader, NULL);

        // Validate Version.
        ULONG Version;
        Status = acpiParser.GetValue<ULONG>(&Version);
        if (!NT_SUCCESS(Status) || (Version != 1)) // currently Version must be 1.
        {
            return STATUS_ACPI_INVALID_DATA;
        }

        // Validate number of power compoment
        ULONG numPowerCompoment;
        Status = acpiParser.GetValue<ULONG>(&numPowerCompoment);
        if (!NT_SUCCESS(Status) || (numPowerCompoment != C_ROSD_GPU_ENGINE_COUNT)) // currently only GPU node
        {
            return STATUS_ACPI_INVALID_DATA;
        }

        UNALIGNED ACPI_METHOD_ARGUMENT* pPowerComponentPackage;
        pPowerComponentPackage = acpiParser.GetPackage();
        NT_ASSERT(pPowerComponentPackage);

        RosKmAcpiArgumentParser acpiPowerComponentParser(&acpiReader, pPowerComponentPackage);
        for (ULONG i = 0; i < numPowerCompoment; i++)
        {
            UNALIGNED ACPI_METHOD_ARGUMENT* pComponentPackage;
            pComponentPackage = acpiPowerComponentParser.GetPackage();
            NT_ASSERT(pComponentPackage);

            RosKmAcpiArgumentParser acpiComponentParser(&acpiReader, pComponentPackage);

            ULONG componentIndex;
            Status = acpiComponentParser.GetValue<ULONG>(&componentIndex);
            NT_ASSERT(componentIndex == 0);

            Status = acpiComponentParser.GetValue<DXGK_POWER_COMPONENT_TYPE>(&m_PowerComponents[componentIndex].ComponentMapping.ComponentType);
            NT_ASSERT(NT_SUCCESS(Status));

            Status = acpiComponentParser.GetValue<UINT>(&m_PowerComponents[componentIndex].ComponentMapping.EngineDesc.NodeIndex);
            NT_ASSERT(NT_SUCCESS(Status));

            GUID* pComponentGuid = NULL;
            ULONG ComponentGuidLength = 0;
            Status = acpiComponentParser.GetBuffer((BYTE**)&pComponentGuid, &ComponentGuidLength);
            NT_ASSERT(NT_SUCCESS(Status));
            NT_ASSERT(pComponentGuid != NULL);
            NT_ASSERT(ComponentGuidLength == sizeof(GUID));
            RtlCopyMemory(&m_PowerComponents[componentIndex].ComponentGuid, pComponentGuid, sizeof(GUID));

            char *pComponentName = NULL;
            ULONG ComponentNameLength = 0;
            Status = acpiComponentParser.GetAnsiString(&pComponentName, &ComponentNameLength);
            NT_ASSERT(NT_SUCCESS(Status));
            NT_ASSERT(pComponentName);
            RtlCopyMemory(
                &m_PowerComponents[componentIndex].ComponentName[0],
                pComponentName,
                min(ComponentNameLength, sizeof(m_PowerComponents[componentIndex].ComponentName)));

            Status = acpiComponentParser.GetValue<ULONG>(&m_PowerComponents[componentIndex].StateCount);
            NT_ASSERT(NT_SUCCESS(Status));
            NT_ASSERT(m_PowerComponents[componentIndex].StateCount);

            UNALIGNED ACPI_METHOD_ARGUMENT* pPowerStatePackage;
            pPowerStatePackage = acpiComponentParser.GetPackage();
            NT_ASSERT(pPowerStatePackage);

            RosKmAcpiArgumentParser acpiPowerStateParser(&acpiReader, pPowerStatePackage);
            for (ULONG j = 0; j < m_PowerComponents[componentIndex].StateCount; j++)
            {
                UNALIGNED ACPI_METHOD_ARGUMENT* pStatePackage;
                pStatePackage = acpiPowerStateParser.GetPackage();
                NT_ASSERT(pStatePackage);

                RosKmAcpiArgumentParser acpiStateParser(&acpiReader, pStatePackage);

                Status = acpiStateParser.GetValue<ULONGLONG>(&m_PowerComponents[componentIndex].States[j].TransitionLatency);
                NT_ASSERT(NT_SUCCESS(Status));

                Status = acpiStateParser.GetValue<ULONGLONG>(&m_PowerComponents[componentIndex].States[j].ResidencyRequirement);
                NT_ASSERT(NT_SUCCESS(Status));

                Status = acpiStateParser.GetValue<ULONG>(&m_PowerComponents[componentIndex].States[j].NominalPower);
                NT_ASSERT(NT_SUCCESS(Status));
            }

            //
            // No dependent provider.
            //
            m_PowerComponents[componentIndex].ProviderCount = 0;
            RtlZeroMemory(&m_PowerComponents[componentIndex].Providers, sizeof(m_PowerComponents[componentIndex].Providers));

            //
            // Driver makes callback to complete transition.
            //
            m_PowerComponents[componentIndex].Flags.Value = 0;
            m_PowerComponents[componentIndex].Flags.DriverCompletesFStateTransition = 1;
        }

        //
        // If everything work out good, set number of power components.
        //
        m_NumPowerComponents = numPowerCompoment;

        return STATUS_SUCCESS;
    }

    return  STATUS_ACPI_INVALID_DATA;
}
コード例 #2
0
NTSTATUS
RosKmAdapter::Start(
    IN_PDXGK_START_INFO     DxgkStartInfo,
    IN_PDXGKRNL_INTERFACE   DxgkInterface,
    OUT_PULONG              NumberOfVideoPresentSources,
    OUT_PULONG              NumberOfChildren)
{
    m_DxgkStartInfo = *DxgkStartInfo;
    m_DxgkInterface = *DxgkInterface;

    //
    // Render only device has no VidPn source and target
    //
    *NumberOfVideoPresentSources = 0;
    *NumberOfChildren = 0;

    //
    // Sample for 1.3 model currently
    //
    m_WDDMVersion = DXGKDDI_WDDMv1_3;

    m_NumNodes = C_ROSD_GPU_ENGINE_COUNT;

    //
    // Initialize worker
    //

    KeInitializeEvent(&m_workerThreadEvent, SynchronizationEvent, FALSE);

    m_workerExit = false;

    OBJECT_ATTRIBUTES   ObjectAttributes;
    HANDLE              hWorkerThread;

    InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

    NTSTATUS status = PsCreateSystemThread(
        &hWorkerThread,
        THREAD_ALL_ACCESS,
        &ObjectAttributes,
        NULL,
        NULL,
        (PKSTART_ROUTINE) RosKmAdapter::WorkerThread,
        this);

    if (status != STATUS_SUCCESS)
    {
        return status;
    }

    status = ObReferenceObjectByHandle(
        hWorkerThread,
        THREAD_ALL_ACCESS,
        *PsThreadType,
        KernelMode,
        (PVOID *)&m_pWorkerThread,
        NULL);

    ZwClose(hWorkerThread);

    if (status != STATUS_SUCCESS)
    {
        return status;
    }

    status = m_DxgkInterface.DxgkCbGetDeviceInformation(
        m_DxgkInterface.DeviceHandle,
        &m_deviceInfo);
    NT_ASSERT(status == STATUS_SUCCESS);

    //
    // Query APCI device ID
    //
    {
        NTSTATUS acpiStatus;

        RosKmAcpiReader acpiReader(this, DISPLAY_ADAPTER_HW_ID);
        acpiStatus = acpiReader.Read(ACPI_METHOD_HARDWARE_ID);
        if (NT_SUCCESS(acpiStatus) && (acpiReader.GetOutputArgumentCount() == 1))
        {
            RosKmAcpiArgumentParser acpiParser(&acpiReader, NULL);
            char *pDeviceId;
            ULONG DeviceIdLength;
            acpiStatus = acpiParser.GetAnsiString(&pDeviceId, &DeviceIdLength);
            if (NT_SUCCESS(acpiStatus) && DeviceIdLength)
            {
                m_deviceIdLength = min(DeviceIdLength, sizeof(m_deviceId));
                RtlCopyMemory(&m_deviceId[0], pDeviceId, m_deviceIdLength);
            }
        }
    }

    //
    // Initialize power component data.
    //
    InitializePowerComponentInfo();

    //
    // Initialize apperture state
    //

    memset(m_aperturePageTable, 0, sizeof(m_aperturePageTable));

    //
    // Intialize DMA buffer queue and lock
    //

    InitializeListHead(&m_dmaBufSubmissionFree);
    for (UINT i = 0; i < m_maxDmaBufQueueLength; i++)
    {
        InsertHeadList(&m_dmaBufSubmissionFree, &m_dmaBufSubssions[i].m_QueueEntry);
    }

    InitializeListHead(&m_dmaBufQueue);
    KeInitializeSpinLock(&m_dmaBufQueueLock);

    //
    // Initialize HW DMA buffer compeletion DPC and event
    //

    KeInitializeEvent(&m_hwDmaBufCompletionEvent, SynchronizationEvent, FALSE);
    KeInitializeDpc(&m_hwDmaBufCompletionDpc, HwDmaBufCompletionDpcRoutine, this);

    return STATUS_SUCCESS;
}