[Spice-devel,1/4] qxl-wddm-dod: Startup case when OS does not supply frame buffer address

Submitted by Yuri Benditovich on Jan. 30, 2017, 1:25 p.m.

Details

Message ID 1485782738-155840-2-git-send-email-yuri.benditovich@daynix.com
State New
Headers show
Series "qxl-wddm-dod: fix for black screen after VGA driver enable" ( rev: 1 ) in Spice

Not browsing as part of any series.

Commit Message

Yuri Benditovich Jan. 30, 2017, 1:25 p.m.
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 <yuri.benditovich@daynix.com>
---
 qxldod/QxlDod.cpp | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

Patch hide | download patch | download mbox

diff --git a/qxldod/QxlDod.cpp b/qxldod/QxlDod.cpp
index 001cd67..46176f0 100755
--- a/qxldod/QxlDod.cpp
+++ b/qxldod/QxlDod.cpp
@@ -2534,6 +2534,24 @@  NTSTATUS VgaDevice::GetCurrentMode(ULONG* pMode)
     return Status;
 }
 
+static void GetVgaFrameBuffer(PCM_RESOURCE_LIST pResList, PPHYSICAL_ADDRESS pPhys)
+{
+    for (ULONG i = 0; i < pResList->Count; ++i)
+    {
+        CM_PARTIAL_RESOURCE_DESCRIPTOR *prd = pResList->List[i].PartialResourceList.PartialDescriptors;
+        for (ULONG j = 0; j < pResList->List[i].PartialResourceList.Count; ++j)
+        {
+            if (prd[j].Type == CmResourceTypeMemory)
+            {
+                // bar 0 is VGA area
+                *pPhys = prd[j].u.Memory.Start;
+                break;
+            }
+        }
+    }
+    DbgPrint(TRACE_LEVEL_INFORMATION, ("%s: found %I64x\n", __FUNCTION__, pPhys->QuadPart));
+}
+
 NTSTATUS VgaDevice::HWInit(PCM_RESOURCE_LIST pResList, DXGK_DISPLAY_INFORMATION* pDispInfo)
 {
     PAGED_CODE();
@@ -2541,6 +2559,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)
+    {
+        GetVgaFrameBuffer(pResList, &pDispInfo->PhysicAddress);
+    }
     DbgPrint(TRACE_LEVEL_VERBOSE, ("<--- %s\n", __FUNCTION__));
     return GetModeList(pDispInfo);
 }

Comments

> 
> 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 <yuri.benditovich@daynix.com>
> ---
>  qxldod/QxlDod.cpp | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> diff --git a/qxldod/QxlDod.cpp b/qxldod/QxlDod.cpp
> index 001cd67..46176f0 100755
> --- a/qxldod/QxlDod.cpp
> +++ b/qxldod/QxlDod.cpp
> @@ -2534,6 +2534,24 @@ NTSTATUS VgaDevice::GetCurrentMode(ULONG* pMode)
>      return Status;
>  }
>  
> +static void GetVgaFrameBuffer(PCM_RESOURCE_LIST pResList, PPHYSICAL_ADDRESS
> pPhys)

This looks like a lot C instead of C++. From declaration looks like pResList
can be changed by the function, why not a

static ULONGLONG GetVgaFrameBuffer(const CM_RESOURCE_LIST& resList)

?

> +{
> +    for (ULONG i = 0; i < pResList->Count; ++i)
> +    {
> +        CM_PARTIAL_RESOURCE_DESCRIPTOR *prd =
> pResList->List[i].PartialResourceList.PartialDescriptors;
> +        for (ULONG j = 0; j < pResList->List[i].PartialResourceList.Count;
> ++j)
> +        {
> +            if (prd[j].Type == CmResourceTypeMemory)
> +            {
> +                // bar 0 is VGA area
> +                *pPhys = prd[j].u.Memory.Start;
> +                break;

here would be just "return prd[j].u.Memory.Start.QuadPart";

> +            }
> +        }
> +    }
> +    DbgPrint(TRACE_LEVEL_INFORMATION, ("%s: found %I64x\n", __FUNCTION__,
> pPhys->QuadPart));
> +}
> +
>  NTSTATUS VgaDevice::HWInit(PCM_RESOURCE_LIST pResList,
>  DXGK_DISPLAY_INFORMATION* pDispInfo)
>  {
>      PAGED_CODE();
> @@ -2541,6 +2559,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)
> +    {
> +        GetVgaFrameBuffer(pResList, &pDispInfo->PhysicAddress);
> +    }
>      DbgPrint(TRACE_LEVEL_VERBOSE, ("<--- %s\n", __FUNCTION__));
>      return GetModeList(pDispInfo);
>  }

Beside the style patch looks fine

Frediano