From ec88061ec82d3ebf6a83d562d17583b70e32ce13 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Mon, 3 Mar 2014 08:41:08 +0000 Subject: [PATCH] OvmfPkg: QemuVideoDxe: filter BOCHS modes vs. available frame buffer size In the next patch we'll add many new BOCHS modes, some of which require large frame buffers. The size of the QXL VGA compatibility framebuffer can be changed with the -global qxl-vga.vgamem_mb=$NUM_MB QEMU option. If $NUM_MB would exceed 32, then the following two QEMU options are necessary instead: -global qxl-vga.vgamem_mb=$NUM_MB \ -global qxl-vga.ram_size_mb=$((NUM_MB*2)) because the compatibility framebuffer can't cover more than half of PCI BAR #0. The latter defaults to 64MB in size, and is controlled by "ram_size_mb". Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek Reviewed-by: Jordan Justen git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15288 6f19259b-4bc3-4df7-8a09-765794883524 --- OvmfPkg/QemuVideoDxe/Initialize.c | 52 ++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/OvmfPkg/QemuVideoDxe/Initialize.c b/OvmfPkg/QemuVideoDxe/Initialize.c index af3b6af47c..80e9b3a936 100644 --- a/OvmfPkg/QemuVideoDxe/Initialize.c +++ b/OvmfPkg/QemuVideoDxe/Initialize.c @@ -200,7 +200,7 @@ QemuVideoCirrusModeSetup ( ModeData ++ ; VideoMode ++; } - Private->MaxMode = QEMU_VIDEO_CIRRUS_MODE_COUNT; + Private->MaxMode = ModeData - Private->ModeData; return EFI_SUCCESS; } @@ -222,10 +222,19 @@ QemuVideoBochsModeSetup ( QEMU_VIDEO_PRIVATE_DATA *Private ) { + UINT32 AvailableFbSize; UINT32 Index; QEMU_VIDEO_MODE_DATA *ModeData; QEMU_VIDEO_BOCHS_MODES *VideoMode; + // + // fetch available framebuffer size + // + AvailableFbSize = BochsRead (Private, VBE_DISPI_INDEX_VIDEO_MEMORY_64K); + AvailableFbSize *= SIZE_64KB; + DEBUG ((EFI_D_VERBOSE, "%a: AvailableFbSize=0x%x\n", __FUNCTION__, + AvailableFbSize)); + // // Setup Video Modes // @@ -238,25 +247,32 @@ QemuVideoBochsModeSetup ( ModeData = Private->ModeData; VideoMode = &QemuVideoBochsModes[0]; for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index ++) { - ModeData->InternalModeIndex = Index; - ModeData->HorizontalResolution = VideoMode->Width; - ModeData->VerticalResolution = VideoMode->Height; - ModeData->ColorDepth = VideoMode->ColorDepth; - ModeData->RefreshRate = 60; - DEBUG ((EFI_D_INFO, - "Adding Mode %d as Bochs Internal Mode %d: %dx%d, %d-bit, %d Hz\n", - (INT32) (ModeData - Private->ModeData), - ModeData->InternalModeIndex, - ModeData->HorizontalResolution, - ModeData->VerticalResolution, - ModeData->ColorDepth, - ModeData->RefreshRate - )); - - ModeData ++ ; + UINTN RequiredFbSize; + + ASSERT (VideoMode->ColorDepth % 8 == 0); + RequiredFbSize = (UINTN) VideoMode->Width * VideoMode->Height * + (VideoMode->ColorDepth / 8); + if (RequiredFbSize <= AvailableFbSize) { + ModeData->InternalModeIndex = Index; + ModeData->HorizontalResolution = VideoMode->Width; + ModeData->VerticalResolution = VideoMode->Height; + ModeData->ColorDepth = VideoMode->ColorDepth; + ModeData->RefreshRate = 60; + DEBUG ((EFI_D_INFO, + "Adding Mode %d as Bochs Internal Mode %d: %dx%d, %d-bit, %d Hz\n", + (INT32) (ModeData - Private->ModeData), + ModeData->InternalModeIndex, + ModeData->HorizontalResolution, + ModeData->VerticalResolution, + ModeData->ColorDepth, + ModeData->RefreshRate + )); + + ModeData ++ ; + } VideoMode ++; } - Private->MaxMode = QEMU_VIDEO_BOCHS_MODE_COUNT; + Private->MaxMode = ModeData - Private->ModeData; return EFI_SUCCESS; } -- 2.39.2