<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jan 18, 2019 at 4:02 PM Frediano Ziglio <<a href="mailto:fziglio@redhat.com">fziglio@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">By the way, the name of the function was not a regression, I acked and merged the patch.</blockquote><div><br></div><div>It looks like the patch is not merged, BTW</div><div>If I'm mistaken, this means the repository migrated somewhere.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br>
<br>
Maybe I'll think about a better name <br>
<br>
Frediano <br>
<br>
> On Thu, Jan 17, 2019 at 6:20 PM Frediano Ziglio < <a href="mailto:fziglio@redhat.com" target="_blank">fziglio@redhat.com</a> > wrote:<br>
<br>
> > ><br>
> <br>
> > > <a href="https://bugzilla.redhat.com/show_bug.cgi?id=1661147" rel="noreferrer" target="_blank">https://bugzilla.redhat.com/show_bug.cgi?id=1661147</a><br>
> <br>
> > > If display miniport driver does not pass valid display info to<br>
> <br>
> > > the basic display driver on disable/uninstall, the basic<br>
> <br>
> > > display driver raises run-time error and stays with yellow<br>
> <br>
> > > bang. This behavior is specific to UEFI machines.<br>
> <br>
> > > Reference:<br>
> <br>
> > > <a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/dispmprt/nc-dispmprt-dxgkddi_stop_device_and_release_post_display_ownership" rel="noreferrer" target="_blank">https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/dispmprt/nc-dispmprt-dxgkddi_stop_device_and_release_post_display_ownership</a><br>
> <br>
> > ><br>
> <br>
> > > Signed-off-by: Yuri Benditovich < <a href="mailto:yuri.benditovich@daynix.com" target="_blank">yuri.benditovich@daynix.com</a> ><br>
> <br>
> > > ---<br>
> <br>
> > > qxldod/QxlDod.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++++-<br>
> <br>
> > > qxldod/QxlDod.h | 6 +++++-<br>
> <br>
> > > 2 files changed, 51 insertions(+), 2 deletions(-)<br>
> <br>
> > ><br>
> <br>
> > > diff --git a/qxldod/QxlDod.cpp b/qxldod/QxlDod.cpp<br>
> <br>
> > > index b72e12c..dea78e2 100755<br>
> <br>
> > > --- a/qxldod/QxlDod.cpp<br>
> <br>
> > > +++ b/qxldod/QxlDod.cpp<br>
> <br>
> > > @@ -189,6 +189,12 @@ NTSTATUS QxlDod::StartDevice(_In_ DXGK_START_INFO*<br>
> <br>
> > > pDxgkStartInfo,<br>
> <br>
> > > return Status;<br>
> <br>
> > > }<br>
> <br>
> > ><br>
> <br>
> > > + DXGK_DISPLAY_INFORMATION *pInfo = &m_CurrentModes[0].DispInfo;<br>
> <br>
> > > + DbgPrint(TRACE_LEVEL_INFORMATION, ("%s: Initial display info:\n",<br>
> <br>
> > > __FUNCTION__));<br>
> <br>
> > > + DbgPrint(TRACE_LEVEL_INFORMATION, ("ACPI/Target Id: %d:%d\n",<br>
> <br>
> > > pInfo->AcpiId, pInfo->TargetId));<br>
> <br>
> > > + DbgPrint(TRACE_LEVEL_INFORMATION, ("W/H/Pitch/Color:%d:%d:%d:%d\n",<br>
> <br>
> > > pInfo->Width, pInfo->Height, pInfo->Pitch, pInfo->ColorFormat));<br>
> <br>
> > > + DbgPrint(TRACE_LEVEL_INFORMATION, ("Physical address:%I64x\n",<br>
> <br>
> > > pInfo->PhysicAddress.QuadPart));<br>
> <br>
> > > +<br>
> <br>
> > > Status = RegisterHWInfo(m_pHWDevice->GetId());<br>
> <br>
> > > if (!NT_SUCCESS(Status))<br>
> <br>
> > > {<br>
> <br>
> > > @@ -668,6 +674,12 @@ NTSTATUS<br>
> <br>
> > > QxlDod::StopDeviceAndReleasePostDisplayOwnership(_In_ D3DDDI_VIDEO_PRE<br>
> <br>
> > > m_pHWDevice->BlackOutScreen(&m_CurrentModes[SourceId]);<br>
> <br>
> > ><br>
> <br>
> > > *pDisplayInfo = m_CurrentModes[SourceId].DispInfo;<br>
> <br>
> > > + m_pHWDevice->GetFinalDisplayInfo(pDisplayInfo);<br>
> <br>
> > > +<br>
> <br>
> > > + DbgPrint(TRACE_LEVEL_INFORMATION, ("%s: Final display info:\n",<br>
> <br>
> > > __FUNCTION__));<br>
> <br>
> > > + DbgPrint(TRACE_LEVEL_INFORMATION, ("ACPI/Target Id: %d:%d\n",<br>
> <br>
> > > pDisplayInfo->AcpiId, pDisplayInfo->TargetId));<br>
> <br>
> > > + DbgPrint(TRACE_LEVEL_INFORMATION, ("W/H/Pitch/Color:%d:%d:%d:%d\n",<br>
> <br>
> > > pDisplayInfo->Width, pDisplayInfo->Height, pDisplayInfo->Pitch,<br>
> <br>
> > > pDisplayInfo->ColorFormat));<br>
> <br>
> > > + DbgPrint(TRACE_LEVEL_INFORMATION, ("Physical address:%I64x\n",<br>
> <br>
> > > pDisplayInfo->PhysicAddress.QuadPart));<br>
> <br>
> > ><br>
> <br>
> > > return StopDevice();<br>
> <br>
> > > }<br>
> <br>
> > > @@ -3055,6 +3067,19 @@ NTSTATUS VgaDevice::Escape(_In_ CONST<br>
> > > DXGKARG_ESCAPE*<br>
> <br>
> > > pEscap)<br>
> <br>
> > > return STATUS_NOT_IMPLEMENTED;<br>
> <br>
> > > }<br>
> <br>
> > ><br>
> <br>
> > > +static BOOLEAN IsUefiMode()<br>
> <br>
> > > +{<br>
> <br>
> > > + PAGED_CODE();<br>
> <br>
> > > + UNICODE_STRING usName;<br>
> <br>
> > > + GUID guid = {};<br>
> <br>
> > > + ULONG res, len = sizeof(res);<br>
> <br>
> > > + RtlInitUnicodeString(&usName, L"dummy");<br>
> <br>
> > > + NTSTATUS status = ExGetFirmwareEnvironmentVariable(&usName, &guid,<br>
> > > &res,<br>
> <br>
> > > &len, NULL);<br>
> <br>
> > > + DbgPrint(TRACE_LEVEL_VERBOSE, ("%s, status %X\n", __FUNCTION__,<br>
> <br>
> > > status));<br>
> <br>
> > > + // on UEFI system the status is STATUS_VARIABLE_NOT_FOUND<br>
> <br>
> > > + return status != STATUS_NOT_IMPLEMENTED;<br>
> <br>
> > > +}<br>
> <br>
> > > +<br>
> <br>
> > > QxlDevice::QxlDevice(_In_ QxlDod* pQxlDod)<br>
> <br>
> > > {<br>
> <br>
> > > PAGED_CODE();<br>
> <br>
> > > @@ -3068,6 +3093,8 @@ QxlDevice::QxlDevice(_In_ QxlDod* pQxlDod)<br>
> <br>
> > > m_Pending = 0;<br>
> <br>
> > > m_PresentThread = NULL;<br>
> <br>
> > > m_bActive = FALSE;<br>
> <br>
> > > + m_bUefiMode = IsUefiMode();<br>
> <br>
> > > + DbgPrint(TRACE_LEVEL_VERBOSE, ("%s, %s mode\n", __FUNCTION__,<br>
> <br>
> > > m_bUefiMode ? "UEFI" : "BIOS"));<br>
> <br>
> > > }<br>
> <br>
> > ><br>
> <br>
> > > QxlDevice::~QxlDevice(void)<br>
> <br>
> > > @@ -3331,6 +3358,17 @@ NTSTATUS<br>
> > > QxlDevice::SetPowerState(DEVICE_POWER_STATE<br>
> <br>
> > > DevicePowerState, DXGK_DISP<br>
> <br>
> > > return STATUS_SUCCESS;<br>
> <br>
> > > }<br>
> <br>
> > ><br>
> <br>
> > > +void QxlDevice::GetFinalDisplayInfo(DXGK_DISPLAY_INFORMATION*<br>
> > > pDisplayInfo)<br>
> <br>
> > > +{<br>
> <br>
> > > + PAGED_CODE();<br>
> <br>
> > > + *pDisplayInfo = m_InitialDisplayInfo;<br>
> <br>
> > > + pDisplayInfo->TargetId = pDisplayInfo->AcpiId = 0;<br>
> <br>
> > > + if (!pDisplayInfo->PhysicAddress.QuadPart)<br>
> <br>
> > > + {<br>
> <br>
> > > + pDisplayInfo->PhysicAddress = m_RamPA;<br>
> <br>
> > > + }<br>
> <br>
> > > +}<br>
> <br>
> > > +<br>
> <br>
> > > NTSTATUS QxlDevice::HWInit(PCM_RESOURCE_LIST pResList,<br>
> <br>
> > > DXGK_DISPLAY_INFORMATION* pDispInfo)<br>
> <br>
> > > {<br>
> <br>
> > > PAGED_CODE();<br>
> <br>
> > > @@ -3530,10 +3568,11 @@ NTSTATUS<br>
> > > QxlDevice::QxlInit(DXGK_DISPLAY_INFORMATION*<br>
> <br>
> > > pDispInfo)<br>
> <br>
> > > DbgPrint(TRACE_LEVEL_ERROR, ("InitMonitorConfig failed with status<br>
> <br>
> > > 0x%X\n", Status));<br>
> <br>
> > > return Status;<br>
> <br>
> > > }<br>
> <br>
> > > - Status = AcquireDisplayInfo(*(pDispInfo));<br>
> <br>
> > > + Status = AcquireDisplayInfo(m_InitialDisplayInfo);<br>
> <br>
> > > if (NT_SUCCESS(Status))<br>
> <br>
> > > {<br>
> <br>
> > > m_bActive = TRUE;<br>
> <br>
> > > + *pDispInfo = m_InitialDisplayInfo;<br>
> <br>
> > > Status = StartPresentThread();<br>
> <br>
> > > }<br>
> <br>
> > > if (!NT_SUCCESS(Status)) {<br>
> <br>
> > > @@ -4728,6 +4767,11 @@ NTSTATUS QxlDevice::HWClose(void)<br>
> <br>
> > > {<br>
> <br>
> > > PAGED_CODE();<br>
> <br>
> > > QxlClose();<br>
> <br>
> > > + if (m_bUefiMode)<br>
> <br>
> > > + {<br>
> <br>
> > > + DbgPrint(TRACE_LEVEL_INFORMATION, ("%s: Resetting the device\n",<br>
> <br>
> > > __FUNCTION__));<br>
> <br>
> > > + WRITE_PORT_UCHAR((PUCHAR)(m_IoBase + QXL_IO_RESET), 0);<br>
> <br>
> > > + }<br>
> <br>
> > > UnmapMemory();<br>
> <br>
> > > return STATUS_SUCCESS;<br>
> <br>
> > > }<br>
> <br>
> > > @@ -5143,6 +5187,7 @@ NTSTATUS<br>
> <br>
> > > HwDeviceInterface::AcquireDisplayInfo(DXGK_DISPLAY_INFORMATION& DispInf<br>
> <br>
> > ><br>
> <br>
> > > if (DispInfo.Width == 0)<br>
> <br>
> > > {<br>
> <br>
> > > + DbgPrint(TRACE_LEVEL_WARNING, ("QxlDod::AcquireDisplayInfo has zero<br>
> <br>
> > > width!\n"));<br>
> <br>
> > > DispInfo.ColorFormat = D3DDDIFMT_A8R8G8B8;<br>
> <br>
> > > DispInfo.Width = INITIAL_WIDTH;<br>
> <br>
> > > DispInfo.Height = INITIAL_HEIGHT;<br>
> <br>
> > > diff --git a/qxldod/QxlDod.h b/qxldod/QxlDod.h<br>
> <br>
> > > index eb6b78d..d889b9d 100755<br>
> <br>
> > > --- a/qxldod/QxlDod.h<br>
> <br>
> > > +++ b/qxldod/QxlDod.h<br>
> <br>
> > > @@ -285,6 +285,7 @@ public:<br>
> <br>
> > > QXL_NON_PAGED virtual VOID VSyncInterruptPostProcess(_In_<br>
> <br>
> > > PDXGKRNL_INTERFACE) = 0;<br>
> <br>
> > > virtual NTSTATUS AcquireFrameBuffer(CURRENT_BDD_MODE* pCurrentBddMode) {<br>
> <br>
> > > return STATUS_SUCCESS; }<br>
> <br>
> > > virtual NTSTATUS ReleaseFrameBuffer(CURRENT_BDD_MODE* pCurrentBddMode) {<br>
> <br>
> > > return STATUS_SUCCESS; }<br>
> <br>
> > > + virtual void GetFinalDisplayInfo(DXGK_DISPLAY_INFORMATION*<br>
> > > pDisplayInfo)<br>
> <br>
> > > {}<br>
> <br>
> > ><br>
> <br>
> > > ULONG GetModeCount(void) const {return m_ModeCount;}<br>
> <br>
> > > PVIDEO_MODE_INFORMATION GetModeInfo(UINT idx) {return &m_ModeInfo[idx];}<br>
> <br>
> > > @@ -555,7 +556,8 @@ public:<br>
> <br>
> > > NTSTATUS SetPointerShape(_In_ CONST DXGKARG_SETPOINTERSHAPE*<br>
> <br>
> > > pSetPointerShape);<br>
> <br>
> > > NTSTATUS SetPointerPosition(_In_ CONST DXGKARG_SETPOINTERPOSITION*<br>
> <br>
> > > pSetPointerPosition);<br>
> <br>
> > > NTSTATUS Escape(_In_ CONST DXGKARG_ESCAPE* pEscap);<br>
> <br>
> > > - BOOLEAN IsBIOSCompatible() { return FALSE; }<br>
> <br>
> > > + BOOLEAN IsBIOSCompatible() { return m_bUefiMode; }<br>
> <br>
<br>
> > So when is UEFI is BIOS compatible and when is BIOS is not BIOS compatible?<br>
> <br>
> > It looks a bit odd, I'm sure it works but is confusing.<br>
> <br>
<br>
> Indeed, this looks confusing, but in fact it is not.<br>
<br>
> When the system has a BIOS the BDD obtains video modes from the BIOS.<br>
> In MSFT headers the respective field has name 'SupportNonVGA', which does not<br>
> explain<br>
> anything at all, but used by class driver to understand whether the miniport<br>
> will provide on<br>
> leaving meaningful display info to BDD (Basic display driver), so the BDD can<br>
> continue with it.<br>
> For example, QXL driver in 'revision=3' mode uses video modes from the BIOS<br>
> and can report<br>
> exact BIOS-compatible mode when it leaves. So, the name 'BIOS compatible' in<br>
> the code<br>
> reflects the real ability to comply with BIOS-defined set of video modes.<br>
> QXL driver obtains video modes from the device and there is no compatibility<br>
> between device's video modes<br>
> and BIOS ones. So, in case of BIOS system for the QXL driver it is not so<br>
> simple to leave<br>
> the adapter in video mode compatible with BIOS mode list, so we do not make<br>
> such effort<br>
> (according to the documentation this is OK and certification test allows it).<br>
> When the system is UEFI, we do not have a choice, on driver stop we must<br>
> provide<br>
> such data to BDD.<br>
<br>
> If you have in mind better name for the field, please write it in response, I<br>
> will change it.<br>
<br>
> > > + void GetFinalDisplayInfo(DXGK_DISPLAY_INFORMATION* pDisplayInfo);<br>
> <br>
> > > protected:<br>
> <br>
> > > NTSTATUS GetModeList(DXGK_DISPLAY_INFORMATION* pDispInfo);<br>
> <br>
> > > QXLDrawable *PrepareBltBits (BLT_INFO* pDst,<br>
> <br>
> > > @@ -695,6 +697,8 @@ private:<br>
> <br>
> > > uint16_t m_DrawGeneration;<br>
> <br>
> > > HANDLE m_PresentThread;<br>
> <br>
> > > BOOLEAN m_bActive;<br>
> <br>
> > > + BOOLEAN m_bUefiMode;<br>
> <br>
> > > + DXGK_DISPLAY_INFORMATION m_InitialDisplayInfo;<br>
> <br>
> > > };<br>
> <br>
> > ><br>
> <br>
> > > class QxlDod {<br>
> <br>
<br>
> > Frediano<br>
> <br>
</blockquote></div></div>