In the next patch we'll add many new BOCHS modes, some of which require large frame buffers.
The size of the primary bar (frame buffer) can be changed with the -global qxl-vga.ram_size=NUM_BYTES QEMU option. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <[email protected]> --- OvmfPkg/QemuVideoDxe/Initialize.c | 56 ++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/OvmfPkg/QemuVideoDxe/Initialize.c b/OvmfPkg/QemuVideoDxe/Initialize.c index c27ba55..b268dda 100644 --- a/OvmfPkg/QemuVideoDxe/Initialize.c +++ b/OvmfPkg/QemuVideoDxe/Initialize.c @@ -14,6 +14,7 @@ **/ #include "Qemu.h" +#include <IndustryStandard/Acpi.h> /// @@ -219,11 +220,29 @@ QemuVideoBochsModeSetup ( QEMU_VIDEO_PRIVATE_DATA *Private ) { + EFI_STATUS Status; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *FrameBufDesc; + UINT64 AvailableFbSize; UINT32 Index; QEMU_VIDEO_MODE_DATA *ModeData; QEMU_VIDEO_BOCHS_MODES *VideoMode; // + // fetch available framebuffer size + // + Status = Private->PciIo->GetBarAttributes (Private->PciIo, PCI_BAR_IDX0, + NULL, (VOID**) &FrameBufDesc); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a: failed to get framebuffer size: %r\n", + __FUNCTION__, Status)); + return Status; + } + AvailableFbSize = FrameBufDesc->AddrLen; + FreePool (FrameBufDesc); + DEBUG ((EFI_D_VERBOSE, "%a: AvailableFbSize=0x%Lx\n", __FUNCTION__, + AvailableFbSize)); + + // // Setup Video Modes // Private->ModeData = AllocatePool ( @@ -232,22 +251,29 @@ 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 - )); + UINTN RequiredFbSize; - ModeData ++ ; + 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 = ModeData - Private->ModeData; -- 1.8.3.1 ------------------------------------------------------------------------------ WatchGuard Dimension instantly turns raw network data into actionable security intelligence. It gives you real-time visual feedback on key security issues and trends. Skip the complicated setup - simply import a virtual appliance and go from zero to informed in seconds. http://pubads.g.doubleclick.net/gampad/clk?id=123612991&iu=/4140/ostg.clktrk _______________________________________________ edk2-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/edk2-devel
