4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Copyright (C) 2009-2012 Oracle Corporation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * available from http://www.virtualbox.org. This file is free software;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * you can redistribute it and/or modify it under the terms of the GNU
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * General Public License (GPL) as published by the Free Software
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * The contents of this file may alternatively be used under the terms
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * of the Common Development and Distribution License Version 1.0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox OSE distribution, in which case the provisions of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * CDDL are applicable instead of those of the GPL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * You may elect to license modified versions of this file under the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * terms and conditions of either the GPL or the CDDL or both.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This code is based on:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (c) 2007, Intel Corporation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAll rights reserved. This program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncare licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhich accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncModule Name:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This file produces the graphics abstraction of Graphics Output Protocol. It is called by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxVga.c file which deals with the EFI 1.1 driver model.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This file just does graphics.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Info->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Info->PixelsPerScanLine = Info->HorizontalResolution;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG((DEBUG_INFO, "%a:%d FrameBufferBase:%x\n", __FILE__, __LINE__, FrameBufDesc->AddrRangeMin));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mode->FrameBufferBase = FrameBufDesc->AddrRangeMin;
5fbfcf789a4ea7c50c3c0a6a4e1d4640d8235822vboxsync Mode->FrameBufferSize = Info->PixelsPerScanLine * Info->VerticalResolution
5fbfcf789a4ea7c50c3c0a6a4e1d4640d8235822vboxsync * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL); /* 32bpp only! */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// Graphics Output Protocol Member Functions
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Graphics Output protocol interface to query video mode
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ModeNumber - The mode number to return information on.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Info - Caller allocated buffer that returns information about ModeNumber.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SizeOfInfo - A pointer to the size, in bytes, of the Info buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SUCCESS - Mode information returned.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_BUFFER_TOO_SMALL - The Info buffer was too small.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DEVICE_ERROR - A hardware error occurred trying to retrieve the video mode.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_INVALID_PARAMETER - One of the input args was NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private = VBOX_VGA_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*Info)->HorizontalResolution = Private->ModeData[ModeNumber].HorizontalResolution;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*Info)->VerticalResolution = Private->ModeData[ModeNumber].VerticalResolution;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Graphics Output protocol interface to set video mode
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ModeNumber - The mode number to be set.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SUCCESS - Graphics mode was changed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DEVICE_ERROR - The device had an error and could not complete the request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_UNSUPPORTED - ModeNumber is not supported by this device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private = VBOX_VGA_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG((DEBUG_INFO, "%a:%d mode:%d\n", __FILE__, __LINE__, ModeNumber));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private->LineBuffer = AllocatePool (ModeData->HorizontalResolution * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeGraphicsMode (Private, &VBoxVgaVideoModes[ModeData->ModeNumber]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private->TmpBuf = AllocatePool(ModeData->HorizontalResolution * ModeData->VerticalResolution * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* update current mode */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Graphics Output protocol instance to block transfer for CirrusLogic device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This - Pointer to Graphics Output protocol instance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BltBuffer - The data to transfer to screen
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BltOperation - The operation to perform
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SourceX - The X coordinate of the source for BltOperation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SourceY - The Y coordinate of the source for BltOperation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DestinationX - The X coordinate of the destination for BltOperation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DestinationY - The Y coordinate of the destination for BltOperation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Width - The width of a rectangle in the blt rectangle in pixels
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Height - The height of a rectangle in the blt rectangle in pixels
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If a Delta of 0 is used, the entire BltBuffer will be operated on.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If a subrectangle of the BltBuffer is used, then Delta represents
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the number of bytes in a row of the BltBuffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_INVALID_PARAMETER - Invalid parameter passed in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SUCCESS - Blt operation success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private = VBOX_VGA_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((BltOperation < 0) || (BltOperation >= EfiGraphicsOutputBltOperationMax)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If Delta is zero, then the entire BltBuffer is being used, so Delta
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the number of bytes in each row can be computed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* vvl: Delta passed in bytes to use it for coordinate arithmetic
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync we need convert it to pixels value.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // We need to fill the Virtual Screen buffer with the blt data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The virtual screen is upside down, as the first row is the bootom row of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the image.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width, and Height parameters
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // are valid for the operation and the current screen geometry.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Video to BltBuffer: Source is Video, destination is BltBuffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (SourceY + Height > Private->ModeData[CurrentMode].VerticalResolution) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (SourceX + Width > Private->ModeData[CurrentMode].HorizontalResolution) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // BltBuffer to Video: Source is BltBuffer, destination is Video
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DestinationY + Height > Private->ModeData[CurrentMode].VerticalResolution) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DestinationX + Width > Private->ModeData[CurrentMode].HorizontalResolution) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // We would not want a timer based event (Cursor, ...) to come in while we are
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // doing this operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Video to BltBuffer: Source is Video, destination is BltBuffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY) && BltBuffer; SrcY++, DstY++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Offset = (SrcY * Private->ModeData[CurrentMode].HorizontalResolution) + SourceX;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (X = 0; X < Width; X++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltBuffer + (DstY * Delta) + (DestinationX + X);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Perform hardware acceleration for Video to Video operations
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ScreenWidth = Private->ModeData[CurrentMode].HorizontalResolution;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ScreenHeight = Private->ModeData[CurrentMode].VerticalResolution;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SourceOffset = (SourceY * Private->ModeData[CurrentMode].HorizontalResolution) + (SourceX);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Offset = (DestinationY * Private->ModeData[CurrentMode].HorizontalResolution) + (DestinationX);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxVgaGraphicsOutputBlt(This, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL*)Private->TmpBuf, EfiBltVideoToBltBuffer, SourceX, SourceY, 0, 0, ScreenWidth - SourceX, ScreenHeight - SourceY, 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxVgaGraphicsOutputBlt(This, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL*)Private->TmpBuf, EfiBltBufferToVideo, 0, 0, DestinationX, DestinationY, ScreenWidth - SourceX, ScreenHeight - SourceY, 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DestinationX == 0 && Width == Private->ModeData[CurrentMode].HorizontalResolution) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Offset = DestinationY * Private->ModeData[CurrentMode].HorizontalResolution;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Offset = (DstY * Private->ModeData[CurrentMode].HorizontalResolution) + DestinationX;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (X = 0; X < Width; X++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Offset = (DstY * Private->ModeData[CurrentMode].HorizontalResolution) + DestinationX;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GraphicsOutput->QueryMode = VBoxVgaGraphicsOutputQueryMode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GraphicsOutput->SetMode = VBoxVgaGraphicsOutputSetMode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the private data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private->GraphicsOutput.Mode->MaxMode = (UINT32) Private->MaxMode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the hardware
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResolution
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRoutine Description: