From 9ae81b279d2cd2433d6cd7bdf430f28c66664dcd Mon Sep 17 00:00:00 2001 From: "yuri.benditovich@daynix.com" Date: Tue, 7 Feb 2017 00:29:20 +0200 Subject: [PATCH] qxl-wddm-dod: Startup case when OS does not supply frame buffer address https://bugzilla.redhat.com/show_bug.cgi?id=1417448 When the OS does not provide physical address of the frame buffer, the driver retrieves it from allocated PCI resource for BAR0. https://msdn.microsoft.com/en-us/library/hh451339(v=vs.85).aspx In DxgkCbAcquirePostDisplayOwnership OS not always fills the DXGK_DISPLAY_INFORMATION structure with valid data. Signed-off-by: Yuri Benditovich Acked-by: Frediano Ziglio --- qxldod/QxlDod.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/qxldod/QxlDod.cpp b/qxldod/QxlDod.cpp index 22eea7d..cb64209 100755 --- a/qxldod/QxlDod.cpp +++ b/qxldod/QxlDod.cpp @@ -2534,6 +2534,26 @@ NTSTATUS VgaDevice::GetCurrentMode(ULONG* pMode) return Status; } +static LONGLONG GetVgaFrameBuffer(const CM_RESOURCE_LIST& resList) +{ + PAGED_CODE(); + for (ULONG i = 0; i < resList.Count; ++i) + { + const CM_PARTIAL_RESOURCE_DESCRIPTOR *prd = resList.List[i].PartialResourceList.PartialDescriptors; + for (ULONG j = 0; j < resList.List[i].PartialResourceList.Count; ++j) + { + if (prd[j].Type == CmResourceTypeMemory) + { + // bar 0 is VGA area + DbgPrint(TRACE_LEVEL_INFORMATION, ("%s: found %I64x\n", __FUNCTION__, prd[j].u.Memory.Start.QuadPart)); + return prd[j].u.Memory.Start.QuadPart; + } + } + } + DbgPrint(TRACE_LEVEL_ERROR, ("%s: not found in resources\n", __FUNCTION__)); + return 0; +} + NTSTATUS VgaDevice::HWInit(PCM_RESOURCE_LIST pResList, DXGK_DISPLAY_INFORMATION* pDispInfo) { PAGED_CODE(); @@ -2541,6 +2561,13 @@ NTSTATUS VgaDevice::HWInit(PCM_RESOURCE_LIST pResList, DXGK_DISPLAY_INFORMATION* DbgPrint(TRACE_LEVEL_VERBOSE, ("---> %s\n", __FUNCTION__)); UNREFERENCED_PARAMETER(pResList); AcquireDisplayInfo(*(pDispInfo)); + // it is possible that the OS does not have current display information + // in this case the driver uses defaults, but physical address + // is still not initialized + if (!pDispInfo->PhysicAddress.QuadPart) + { + pDispInfo->PhysicAddress.QuadPart = GetVgaFrameBuffer(*pResList); + } DbgPrint(TRACE_LEVEL_VERBOSE, ("<--- %s\n", __FUNCTION__)); return GetModeList(pDispInfo); }