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; }
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; }