summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/QemuVideoDxe/Driver.c
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2014-08-29 17:27:20 +0000
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2014-08-29 17:27:20 +0000
commitb37bcfd6bd0254cd7a67ca6af3743d28eaffceec (patch)
tree3ee8ae449c216e727f08fb68a1ecd7b11af8ca6f /OvmfPkg/QemuVideoDxe/Driver.c
parentfd9abd045e41387ef8e5cfbb4588220cf7a1261d (diff)
downloadedk2-b37bcfd6bd0254cd7a67ca6af3743d28eaffceec.tar.gz
edk2-b37bcfd6bd0254cd7a67ca6af3743d28eaffceec.tar.bz2
edk2-b37bcfd6bd0254cd7a67ca6af3743d28eaffceec.zip
OvmfPkg: QemuVideoDxe: work around misreported QXL framebuffer size
When setting up the list of GOP modes offered on QEMU's stdvga ("VGA") and QXL ("qxl-vga") video devices, QemuVideoBochsModeSetup() filters those modes against the available framebuffer size. (Refer to SVN r15288 / git commit ec88061e.) The VBE_DISPI_INDEX_VIDEO_MEMORY_64K register of both stdvga and QXL is supposed to report the size of the drawable, VGA-compatibility framebuffer. Instead, up to and including qemu-2.1, this register actually reports the full video RAM (PCI BAR 0) size. In case of stdvga, this happens to be correct, because on that card the full PCI BAR 0 is usable for drawing; there is no difference between "drawable framebuffer size" and "video RAM (PCI BAR 0) size". However, on the QXL card, only an initial portion of the video RAM is suitable for drawing, as compatibility framebuffer; and the value currently reported by VBE_DISPI_INDEX_VIDEO_MEMORY_64K overshoots the valid size. Beyond the drawable range, the video RAM contains buffers and structures for the QXL guest-host protocol. Luckily, the size of the drawable QXL framebuffer can also be read from a register in the QXL ROM BAR (PCI BAR 2), so let's retrieve it from there. Without this fix, OVMF offers too large resolutions on the QXL card (up to the full size of the video RAM). If a GOP client selects such a resolution and draws into the video RAM past the compatibility segment, then the guest corrupts its communication structures (which is invalid guest behavior). Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15978 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'OvmfPkg/QemuVideoDxe/Driver.c')
-rw-r--r--OvmfPkg/QemuVideoDxe/Driver.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/OvmfPkg/QemuVideoDxe/Driver.c b/OvmfPkg/QemuVideoDxe/Driver.c
index 2194cbef44..17bd4cc2cc 100644
--- a/OvmfPkg/QemuVideoDxe/Driver.c
+++ b/OvmfPkg/QemuVideoDxe/Driver.c
@@ -173,6 +173,7 @@ QemuVideoControllerDriverStart (
EFI_TPL OldTpl;
EFI_STATUS Status;
QEMU_VIDEO_PRIVATE_DATA *Private;
+ BOOLEAN IsQxl;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
ACPI_ADR_DEVICE_PATH AcpiDeviceNode;
PCI_TYPE00 Pci;
@@ -235,6 +236,12 @@ QemuVideoControllerDriverStart (
Private->Variant = Card->Variant;
//
+ // IsQxl is based on the detected Card->Variant, which at a later point might
+ // not match Private->Variant.
+ //
+ IsQxl = (BOOLEAN)(Card->Variant == QEMU_VIDEO_BOCHS);
+
+ //
// Save original PCI attributes
//
Status = Private->PciIo->Attributes (
@@ -354,7 +361,7 @@ QemuVideoControllerDriverStart (
break;
case QEMU_VIDEO_BOCHS_MMIO:
case QEMU_VIDEO_BOCHS:
- Status = QemuVideoBochsModeSetup (Private);
+ Status = QemuVideoBochsModeSetup (Private, IsQxl);
break;
default:
ASSERT (FALSE);