__FUNCTION__ is a pre-standard extension that gcc and Visual C++ among others support, while __func__ was standardized in C99. Since it's more standard, replace __FUNCTION__ with __func__ throughout OvmfPkg. Signed-off-by: Rebecca Cran <rebecca@bsdio.com> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Ard Biesheuvel <ardb@kernel.org> Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
		
			
				
	
	
		
			437 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			437 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Graphics Output Protocol functions for the QEMU video controller.
 | |
| 
 | |
|   Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
 | |
| 
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "Qemu.h"
 | |
| 
 | |
| STATIC
 | |
| VOID
 | |
| QemuVideoCompleteModeInfo (
 | |
|   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->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->PixelInformation.ReservedMask = 0;
 | |
|   } else if (ModeData->ColorDepth == 32) {
 | |
|     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", __func__, 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
 | |
|   )
 | |
| {
 | |
|   EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;
 | |
|   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *FrameBufDesc;
 | |
|   QEMU_VIDEO_MODE_DATA                  *ModeData;
 | |
| 
 | |
|   ModeData = &Private->ModeData[Mode->Mode];
 | |
|   Info     = Mode->Info;
 | |
|   QemuVideoCompleteModeInfo (ModeData, Info);
 | |
| 
 | |
|   Private->PciIo->GetBarAttributes (
 | |
|                     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);
 | |
|   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
 | |
| //
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| QemuVideoGraphicsOutputQueryMode (
 | |
|   IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
 | |
|   IN  UINT32                                ModeNumber,
 | |
|   OUT UINTN                                 *SizeOfInfo,
 | |
|   OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info
 | |
|   )
 | |
| 
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
| 
 | |
|   Graphics Output protocol interface to query video mode
 | |
| 
 | |
|   Arguments:
 | |
|     This                  - Protocol instance pointer.
 | |
|     ModeNumber            - The mode number to return information on.
 | |
|     Info                  - Caller allocated buffer that returns information about ModeNumber.
 | |
|     SizeOfInfo            - A pointer to the size, in bytes, of the Info buffer.
 | |
| 
 | |
|   Returns:
 | |
|     EFI_SUCCESS           - Mode information returned.
 | |
|     EFI_BUFFER_TOO_SMALL  - The Info buffer was too small.
 | |
|     EFI_DEVICE_ERROR      - A hardware error occurred trying to retrieve the video mode.
 | |
|     EFI_NOT_STARTED       - Video display is not initialized. Call SetMode ()
 | |
|     EFI_INVALID_PARAMETER - One of the input args was NULL.
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   QEMU_VIDEO_PRIVATE_DATA  *Private;
 | |
|   QEMU_VIDEO_MODE_DATA     *ModeData;
 | |
| 
 | |
|   Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
 | |
| 
 | |
|   if ((Info == NULL) || (SizeOfInfo == NULL) || (ModeNumber >= This->Mode->MaxMode)) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
 | |
|   if (*Info == NULL) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
 | |
| 
 | |
|   ModeData                      = &Private->ModeData[ModeNumber];
 | |
|   (*Info)->HorizontalResolution = ModeData->HorizontalResolution;
 | |
|   (*Info)->VerticalResolution   = ModeData->VerticalResolution;
 | |
|   QemuVideoCompleteModeInfo (ModeData, *Info);
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| QemuVideoGraphicsOutputSetMode (
 | |
|   IN  EFI_GRAPHICS_OUTPUT_PROTOCOL  *This,
 | |
|   IN  UINT32                        ModeNumber
 | |
|   )
 | |
| 
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
| 
 | |
|   Graphics Output protocol interface to set video mode
 | |
| 
 | |
|   Arguments:
 | |
|     This             - Protocol instance pointer.
 | |
|     ModeNumber       - The mode number to be set.
 | |
| 
 | |
|   Returns:
 | |
|     EFI_SUCCESS      - Graphics mode was changed.
 | |
|     EFI_DEVICE_ERROR - The device had an error and could not complete the request.
 | |
|     EFI_UNSUPPORTED  - ModeNumber is not supported by this device.
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   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);
 | |
| 
 | |
|   if (ModeNumber >= This->Mode->MaxMode) {
 | |
|     return EFI_UNSUPPORTED;
 | |
|   }
 | |
| 
 | |
|   ModeData = &Private->ModeData[ModeNumber];
 | |
| 
 | |
|   switch (Private->Variant) {
 | |
|     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->Info->HorizontalResolution = ModeData->HorizontalResolution;
 | |
|   This->Mode->Info->VerticalResolution   = ModeData->VerticalResolution;
 | |
|   This->Mode->SizeOfInfo                 = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
 | |
| 
 | |
|   QemuVideoCompleteModeData (Private, This->Mode);
 | |
| 
 | |
|   //
 | |
|   // 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;
 | |
| }
 | |
| 
 | |
| 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
 | |
|   )
 | |
| 
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
| 
 | |
|   Graphics Output protocol instance to block transfer for CirrusLogic device
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   This          - Pointer to Graphics Output protocol instance
 | |
|   BltBuffer     - The data to transfer to screen
 | |
|   BltOperation  - The operation to perform
 | |
|   SourceX       - The X coordinate of the source for BltOperation
 | |
|   SourceY       - The Y coordinate of the source for BltOperation
 | |
|   DestinationX  - The X coordinate of the destination for BltOperation
 | |
|   DestinationY  - The Y coordinate of the destination for BltOperation
 | |
|   Width         - The width of a rectangle in the blt rectangle in pixels
 | |
|   Height        - The height of a rectangle in the blt rectangle in pixels
 | |
|   Delta         - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
 | |
|                   If a Delta of 0 is used, the entire BltBuffer will be operated on.
 | |
|                   If a subrectangle of the BltBuffer is used, then Delta represents
 | |
|                   the number of bytes in a row of the BltBuffer.
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   EFI_INVALID_PARAMETER - Invalid parameter passed in
 | |
|   EFI_SUCCESS - Blt operation success
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   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
 | |
|   // doing this operation.
 | |
|   //
 | |
|   OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
 | |
| 
 | |
|   switch (BltOperation) {
 | |
|     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);
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| QemuVideoGraphicsOutputConstructor (
 | |
|   QEMU_VIDEO_PRIVATE_DATA  *Private
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                    Status;
 | |
|   EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;
 | |
| 
 | |
|   GraphicsOutput            = &Private->GraphicsOutput;
 | |
|   GraphicsOutput->QueryMode = QemuVideoGraphicsOutputQueryMode;
 | |
|   GraphicsOutput->SetMode   = QemuVideoGraphicsOutputSetMode;
 | |
|   GraphicsOutput->Blt       = QemuVideoGraphicsOutputBlt;
 | |
| 
 | |
|   //
 | |
|   // Initialize the private data
 | |
|   //
 | |
|   Status = gBS->AllocatePool (
 | |
|                   EfiBootServicesData,
 | |
|                   sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_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
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto FreeMode;
 | |
|   }
 | |
| 
 | |
|   Private->GraphicsOutput.Mode->MaxMode = (UINT32)Private->MaxMode;
 | |
|   Private->GraphicsOutput.Mode->Mode    = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;
 | |
|   Private->FrameBufferBltConfigure      = NULL;
 | |
|   Private->FrameBufferBltConfigureSize  = 0;
 | |
| 
 | |
|   //
 | |
|   // Initialize the hardware
 | |
|   //
 | |
|   Status = GraphicsOutput->SetMode (GraphicsOutput, 0);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto FreeInfo;
 | |
|   }
 | |
| 
 | |
|   DrawLogo (
 | |
|     Private,
 | |
|     Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution,
 | |
|     Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResolution
 | |
|     );
 | |
| 
 | |
|   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:
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   None
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   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;
 | |
| }
 |