X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=OvmfPkg%2FQemuVideoDxe%2FGop.c;h=d51efc2a83d56a4496c9de592ad1863b86f18224;hp=18d0779896ca494c1765577cfede6ad428710a29;hb=e1fb441624cdb50bdf7b45afdb8071534e2cdbc3;hpb=6394c35a7db3d7a7cc68f491179a45fe430a335a diff --git a/OvmfPkg/QemuVideoDxe/Gop.c b/OvmfPkg/QemuVideoDxe/Gop.c index 18d0779896..d51efc2a83 100644 --- a/OvmfPkg/QemuVideoDxe/Gop.c +++ b/OvmfPkg/QemuVideoDxe/Gop.c @@ -1,7 +1,7 @@ /** @file Graphics Output Protocol functions for the QEMU video controller. - Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -13,9 +13,8 @@ **/ +#include #include "Qemu.h" -#include -#include STATIC VOID @@ -77,6 +76,42 @@ QemuVideoCompleteModeData ( return EFI_SUCCESS; } +STATIC +EFI_STATUS +QemuVideoVmwareSvgaCompleteModeData ( + IN QEMU_VIDEO_PRIVATE_DATA *Private, + OUT EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode + ) +{ + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *FrameBufDesc; + UINT32 BytesPerLine, FbOffset, BytesPerPixel; + + Info = Mode->Info; + CopyMem (Info, &Private->VmwareSvgaModeInfo[Mode->Mode], sizeof (*Info)); + BytesPerPixel = Private->ModeData[Mode->Mode].ColorDepth / 8; + BytesPerLine = Info->PixelsPerScanLine * BytesPerPixel; + + FbOffset = VmwareSvgaRead (Private, VmwareSvgaRegFbOffset); + + Status = Private->PciIo->GetBarAttributes ( + Private->PciIo, + PCI_BAR_IDX1, + NULL, + (VOID**) &FrameBufDesc + ); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + Mode->FrameBufferBase = FrameBufDesc->AddrRangeMin + FbOffset; + Mode->FrameBufferSize = BytesPerLine * Info->VerticalResolution; + + FreePool (FrameBufDesc); + return Status; +} + // // Graphics Output Protocol Member Functions @@ -126,10 +161,14 @@ Routine Description: *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); - ModeData = &Private->ModeData[ModeNumber]; - (*Info)->HorizontalResolution = ModeData->HorizontalResolution; - (*Info)->VerticalResolution = ModeData->VerticalResolution; - QemuVideoCompleteModeInfo (ModeData, *Info); + if (Private->Variant == QEMU_VIDEO_VMWARE_SVGA) { + CopyMem (*Info, &Private->VmwareSvgaModeInfo[ModeNumber], sizeof (**Info)); + } else { + ModeData = &Private->ModeData[ModeNumber]; + (*Info)->HorizontalResolution = ModeData->HorizontalResolution; + (*Info)->VerticalResolution = ModeData->VerticalResolution; + QemuVideoCompleteModeInfo (ModeData, *Info); + } return EFI_SUCCESS; } @@ -157,9 +196,10 @@ Routine Description: --*/ { - QEMU_VIDEO_PRIVATE_DATA *Private; - QEMU_VIDEO_MODE_DATA *ModeData; -// UINTN Count; + QEMU_VIDEO_PRIVATE_DATA *Private; + QEMU_VIDEO_MODE_DATA *ModeData; + RETURN_STATUS Status; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black; Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This); @@ -169,15 +209,6 @@ Routine Description: ModeData = &Private->ModeData[ModeNumber]; - if (Private->LineBuffer) { - gBS->FreePool (Private->LineBuffer); - } - - Private->LineBuffer = AllocatePool (4 * ModeData->HorizontalResolution); - if (Private->LineBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - switch (Private->Variant) { case QEMU_VIDEO_CIRRUS_5430: case QEMU_VIDEO_CIRRUS_5446: @@ -187,10 +218,14 @@ Routine Description: case QEMU_VIDEO_BOCHS: InitializeBochsGraphicsMode (Private, &QemuVideoBochsModes[ModeData->InternalModeIndex]); break; + case QEMU_VIDEO_VMWARE_SVGA: + InitializeVmwareSvgaGraphicsMode ( + Private, + &QemuVideoBochsModes[ModeData->InternalModeIndex] + ); + break; default: ASSERT (FALSE); - gBS->FreePool (Private->LineBuffer); - Private->LineBuffer = NULL; return EFI_DEVICE_ERROR; } @@ -199,12 +234,58 @@ Routine Description: This->Mode->Info->VerticalResolution = ModeData->VerticalResolution; This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); - QemuVideoCompleteModeData (Private, This->Mode); + if (Private->Variant == QEMU_VIDEO_VMWARE_SVGA) { + QemuVideoVmwareSvgaCompleteModeData (Private, This->Mode); + } else { + QemuVideoCompleteModeData (Private, This->Mode); + } - BltLibConfigure ( - (VOID*)(UINTN) This->Mode->FrameBufferBase, - This->Mode->Info - ); + // + // Re-initialize the frame buffer configure when mode changes. + // + Status = FrameBufferBltConfigure ( + (VOID*) (UINTN) This->Mode->FrameBufferBase, + This->Mode->Info, + Private->FrameBufferBltConfigure, + &Private->FrameBufferBltConfigureSize + ); + if (Status == RETURN_BUFFER_TOO_SMALL) { + // + // Frame buffer configure may be larger in new mode. + // + if (Private->FrameBufferBltConfigure != NULL) { + FreePool (Private->FrameBufferBltConfigure); + } + Private->FrameBufferBltConfigure = + AllocatePool (Private->FrameBufferBltConfigureSize); + ASSERT (Private->FrameBufferBltConfigure != NULL); + + // + // Create the configuration for FrameBufferBltLib + // + Status = FrameBufferBltConfigure ( + (VOID*) (UINTN) This->Mode->FrameBufferBase, + This->Mode->Info, + Private->FrameBufferBltConfigure, + &Private->FrameBufferBltConfigureSize + ); + } + ASSERT (Status == RETURN_SUCCESS); + + // + // Per UEFI Spec, need to clear the visible portions of the output display to black. + // + ZeroMem (&Black, sizeof (Black)); + Status = FrameBufferBlt ( + Private->FrameBufferBltConfigure, + &Black, + EfiBltVideoFill, + 0, 0, + 0, 0, + This->Mode->Info->HorizontalResolution, This->Mode->Info->VerticalResolution, + 0 + ); + ASSERT_RETURN_ERROR (Status); return EFI_SUCCESS; } @@ -254,7 +335,9 @@ Returns: { EFI_STATUS Status; EFI_TPL OriginalTPL; + QEMU_VIDEO_PRIVATE_DATA *Private; + Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This); // // We have to raise to TPL Notify, so we make an atomic write the frame buffer. // We would not want a timer based event (Cursor, ...) to come in while we are @@ -267,7 +350,8 @@ Returns: case EfiBltBufferToVideo: case EfiBltVideoFill: case EfiBltVideoToVideo: - Status = BltLibGopBlt ( + Status = FrameBufferBlt ( + Private->FrameBufferBltConfigure, BltBuffer, BltOperation, SourceX, @@ -282,7 +366,7 @@ Returns: default: Status = EFI_INVALID_PARAMETER; - ASSERT (FALSE); + break; } gBS->RestoreTPL (OriginalTPL); @@ -326,7 +410,8 @@ QemuVideoGraphicsOutputConstructor ( } Private->GraphicsOutput.Mode->MaxMode = (UINT32) Private->MaxMode; Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER; - Private->LineBuffer = NULL; + Private->FrameBufferBltConfigure = NULL; + Private->FrameBufferBltConfigureSize = 0; // // Initialize the hardware @@ -370,8 +455,8 @@ Returns: --*/ { - if (Private->LineBuffer != NULL) { - FreePool (Private->LineBuffer); + if (Private->FrameBufferBltConfigure != NULL) { + FreePool (Private->FrameBufferBltConfigure); } if (Private->GraphicsOutput.Mode != NULL) {