X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=OvmfPkg%2FQemuVideoDxe%2FGop.c;h=0c4dea7fb6f2f7f65e42b6d63081acb195c96152;hb=HEAD;hp=f6e9b6c14f4790aedfc1f02140eeb360f1cc8025;hpb=54f9b9accbcb6dc7f965342fc75b478464de21a3;p=mirror_edk2.git diff --git a/OvmfPkg/QemuVideoDxe/Gop.c b/OvmfPkg/QemuVideoDxe/Gop.c index f6e9b6c14f..7a9fe208c9 100644 --- a/OvmfPkg/QemuVideoDxe/Gop.c +++ b/OvmfPkg/QemuVideoDxe/Gop.c @@ -1,81 +1,88 @@ /** @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 - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "Qemu.h" -#include -#include STATIC VOID QemuVideoCompleteModeInfo ( - IN QEMU_VIDEO_MODE_DATA *ModeData, + IN QEMU_VIDEO_MODE_DATA *ModeData, OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info ) { Info->Version = 0; if (ModeData->ColorDepth == 8) { - Info->PixelFormat = PixelBitMask; - Info->PixelInformation.RedMask = PIXEL_RED_MASK; - Info->PixelInformation.GreenMask = PIXEL_GREEN_MASK; - Info->PixelInformation.BlueMask = PIXEL_BLUE_MASK; + Info->PixelFormat = PixelBitMask; + Info->PixelInformation.RedMask = PIXEL_RED_MASK; + Info->PixelInformation.GreenMask = PIXEL_GREEN_MASK; + Info->PixelInformation.BlueMask = PIXEL_BLUE_MASK; Info->PixelInformation.ReservedMask = 0; } else if (ModeData->ColorDepth == 24) { - Info->PixelFormat = PixelBitMask; - Info->PixelInformation.RedMask = PIXEL24_RED_MASK; - Info->PixelInformation.GreenMask = PIXEL24_GREEN_MASK; - Info->PixelInformation.BlueMask = PIXEL24_BLUE_MASK; + Info->PixelFormat = PixelBitMask; + Info->PixelInformation.RedMask = PIXEL24_RED_MASK; + Info->PixelInformation.GreenMask = PIXEL24_GREEN_MASK; + Info->PixelInformation.BlueMask = PIXEL24_BLUE_MASK; Info->PixelInformation.ReservedMask = 0; } else if (ModeData->ColorDepth == 32) { - DEBUG ((EFI_D_INFO, "PixelBlueGreenRedReserved8BitPerColor\n")); - Info->PixelFormat = PixelBlueGreenRedReserved8BitPerColor; + DEBUG ((DEBUG_INFO, "PixelBlueGreenRedReserved8BitPerColor\n")); + Info->PixelFormat = PixelBlueGreenRedReserved8BitPerColor; + Info->PixelInformation.RedMask = 0; + Info->PixelInformation.GreenMask = 0; + Info->PixelInformation.BlueMask = 0; + Info->PixelInformation.ReservedMask = 0; + } else { + DEBUG ((DEBUG_ERROR, "%a: Invalid ColorDepth %u", __FUNCTION__, ModeData->ColorDepth)); + ASSERT (FALSE); } + Info->PixelsPerScanLine = Info->HorizontalResolution; } - STATIC EFI_STATUS QemuVideoCompleteModeData ( - IN QEMU_VIDEO_PRIVATE_DATA *Private, - OUT EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode + IN QEMU_VIDEO_PRIVATE_DATA *Private, + OUT EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode ) { EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *FrameBufDesc; - QEMU_VIDEO_MODE_DATA *ModeData; + QEMU_VIDEO_MODE_DATA *ModeData; ModeData = &Private->ModeData[Mode->Mode]; - Info = Mode->Info; + Info = Mode->Info; QemuVideoCompleteModeInfo (ModeData, Info); Private->PciIo->GetBarAttributes ( - Private->PciIo, - 0, - NULL, - (VOID**) &FrameBufDesc - ); + Private->PciIo, + Private->FrameBufferVramBarIndex, + NULL, + (VOID **)&FrameBufDesc + ); Mode->FrameBufferBase = FrameBufDesc->AddrRangeMin; Mode->FrameBufferSize = Info->HorizontalResolution * Info->VerticalResolution; Mode->FrameBufferSize = Mode->FrameBufferSize * ((ModeData->ColorDepth + 7) / 8); - DEBUG ((EFI_D_INFO, "FrameBufferBase: 0x%x, FrameBufferSize: 0x%x\n", Mode->FrameBufferBase, Mode->FrameBufferSize)); - + Mode->FrameBufferSize = EFI_PAGES_TO_SIZE ( + EFI_SIZE_TO_PAGES (Mode->FrameBufferSize) + ); + DEBUG (( + DEBUG_INFO, + "FrameBufferBase: 0x%Lx, FrameBufferSize: 0x%Lx\n", + Mode->FrameBufferBase, + (UINT64)Mode->FrameBufferSize + )); + + FreePool (FrameBufDesc); return EFI_SUCCESS; } - // // Graphics Output Protocol Member Functions // @@ -87,6 +94,7 @@ QemuVideoGraphicsOutputQueryMode ( OUT UINTN *SizeOfInfo, OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info ) + /*++ Routine Description: @@ -113,11 +121,7 @@ Routine Description: Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This); - if (Private->HardwareNeedsStarting) { - return EFI_NOT_STARTED; - } - - if (Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) { + if ((Info == NULL) || (SizeOfInfo == NULL) || (ModeNumber >= This->Mode->MaxMode)) { return EFI_INVALID_PARAMETER; } @@ -128,7 +132,7 @@ Routine Description: *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); - ModeData = &Private->ModeData[ModeNumber]; + ModeData = &Private->ModeData[ModeNumber]; (*Info)->HorizontalResolution = ModeData->HorizontalResolution; (*Info)->VerticalResolution = ModeData->VerticalResolution; QemuVideoCompleteModeInfo (ModeData, *Info); @@ -139,9 +143,10 @@ Routine Description: EFI_STATUS EFIAPI QemuVideoGraphicsOutputSetMode ( - IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, - IN UINT32 ModeNumber + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber ) + /*++ Routine Description: @@ -159,9 +164,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); @@ -171,44 +177,78 @@ Routine Description: ModeData = &Private->ModeData[ModeNumber]; - if (Private->LineBuffer) { - gBS->FreePool (Private->LineBuffer); - } - - Private->LineBuffer = NULL; - 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: - InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData->ModeNumber]); - break; - case QEMU_VIDEO_BOCHS: - InitializeBochsGraphicsMode (Private, &QemuVideoBochsModes[ModeData->ModeNumber]); - break; - default: - ASSERT (FALSE); - gBS->FreePool (Private->LineBuffer); - Private->LineBuffer = NULL; - return EFI_DEVICE_ERROR; + case QEMU_VIDEO_CIRRUS_5430: + case QEMU_VIDEO_CIRRUS_5446: + InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData->InternalModeIndex]); + break; + case QEMU_VIDEO_BOCHS_MMIO: + case QEMU_VIDEO_BOCHS: + InitializeBochsGraphicsMode (Private, ModeData); + break; + default: + ASSERT (FALSE); + return EFI_DEVICE_ERROR; } - This->Mode->Mode = ModeNumber; + This->Mode->Mode = ModeNumber; This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution; - This->Mode->Info->VerticalResolution = ModeData->VerticalResolution; - This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + This->Mode->Info->VerticalResolution = ModeData->VerticalResolution; + This->Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); 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 + ); + } - Private->HardwareNeedsStarting = FALSE; + 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; } @@ -216,17 +256,18 @@ Routine Description: EFI_STATUS EFIAPI QemuVideoGraphicsOutputBlt ( - IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, - IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL - IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, - IN UINTN SourceX, - IN UINTN SourceY, - IN UINTN DestinationX, - IN UINTN DestinationY, - IN UINTN Width, - IN UINTN Height, - IN UINTN Delta + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL, + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta ) + /*++ Routine Description: @@ -256,9 +297,11 @@ Returns: --*/ { - EFI_STATUS Status; - EFI_TPL OriginalTPL; + 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,26 +310,27 @@ Returns: OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY); switch (BltOperation) { - case EfiBltVideoToBltBuffer: - case EfiBltBufferToVideo: - case EfiBltVideoFill: - case EfiBltVideoToVideo: - Status = BltLibGopBlt ( - BltBuffer, - BltOperation, - SourceX, - SourceY, - DestinationX, - DestinationY, - Width, - Height, - Delta - ); - break; - - default: - Status = EFI_INVALID_PARAMETER; - ASSERT (FALSE); + case EfiBltVideoToBltBuffer: + case EfiBltBufferToVideo: + case EfiBltVideoFill: + case EfiBltVideoToVideo: + Status = FrameBufferBlt ( + Private->FrameBufferBltConfigure, + BltBuffer, + BltOperation, + SourceX, + SourceY, + DestinationX, + DestinationY, + Width, + Height, + Delta + ); + break; + + default: + Status = EFI_INVALID_PARAMETER; + break; } gBS->RestoreTPL (OriginalTPL); @@ -299,9 +343,8 @@ QemuVideoGraphicsOutputConstructor ( QEMU_VIDEO_PRIVATE_DATA *Private ) { - EFI_STATUS Status; - EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; - + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; GraphicsOutput = &Private->GraphicsOutput; GraphicsOutput->QueryMode = QemuVideoGraphicsOutputQueryMode; @@ -314,28 +357,34 @@ QemuVideoGraphicsOutputConstructor ( Status = gBS->AllocatePool ( EfiBootServicesData, sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE), - (VOID **) &Private->GraphicsOutput.Mode + (VOID **)&Private->GraphicsOutput.Mode ); if (EFI_ERROR (Status)) { return Status; } + Status = gBS->AllocatePool ( EfiBootServicesData, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), - (VOID **) &Private->GraphicsOutput.Mode->Info + (VOID **)&Private->GraphicsOutput.Mode->Info ); if (EFI_ERROR (Status)) { - return Status; + goto FreeMode; } - Private->GraphicsOutput.Mode->MaxMode = (UINT32) Private->MaxMode; + + Private->GraphicsOutput.Mode->MaxMode = (UINT32)Private->MaxMode; Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER; - Private->HardwareNeedsStarting = TRUE; - Private->LineBuffer = NULL; + Private->FrameBufferBltConfigure = NULL; + Private->FrameBufferBltConfigureSize = 0; // // Initialize the hardware // - GraphicsOutput->SetMode (GraphicsOutput, 0); + Status = GraphicsOutput->SetMode (GraphicsOutput, 0); + if (EFI_ERROR (Status)) { + goto FreeInfo; + } + DrawLogo ( Private, Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution, @@ -343,12 +392,22 @@ QemuVideoGraphicsOutputConstructor ( ); return EFI_SUCCESS; + +FreeInfo: + FreePool (Private->GraphicsOutput.Mode->Info); + +FreeMode: + FreePool (Private->GraphicsOutput.Mode); + Private->GraphicsOutput.Mode = NULL; + + return Status; } EFI_STATUS QemuVideoGraphicsOutputDestructor ( QEMU_VIDEO_PRIVATE_DATA *Private ) + /*++ Routine Description: @@ -361,14 +420,17 @@ Returns: --*/ { + if (Private->FrameBufferBltConfigure != NULL) { + FreePool (Private->FrameBufferBltConfigure); + } + if (Private->GraphicsOutput.Mode != NULL) { if (Private->GraphicsOutput.Mode->Info != NULL) { gBS->FreePool (Private->GraphicsOutput.Mode->Info); } + gBS->FreePool (Private->GraphicsOutput.Mode); } return EFI_SUCCESS; } - -