]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/QemuVideoDxe/Gop.c
OvmfPkg/QemuVideoDxe: handle invalid BltOperation gracefully
[mirror_edk2.git] / OvmfPkg / QemuVideoDxe / Gop.c
index 359e9217d3d143fbbe90c6a742cd15b9e74cd73b..d51efc2a83d56a4496c9de592ad1863b86f18224 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Graphics Output Protocol functions for the QEMU video controller.\r
 \r
-  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -13,6 +13,7 @@
 \r
 **/\r
 \r
+#include <IndustryStandard/VmwareSvga.h>\r
 #include "Qemu.h"\r
 \r
 STATIC\r
@@ -75,6 +76,42 @@ QemuVideoCompleteModeData (
   return EFI_SUCCESS;\r
 }\r
 \r
+STATIC\r
+EFI_STATUS\r
+QemuVideoVmwareSvgaCompleteModeData (\r
+  IN  QEMU_VIDEO_PRIVATE_DATA           *Private,\r
+  OUT EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode\r
+  )\r
+{\r
+  EFI_STATUS                            Status;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *FrameBufDesc;\r
+  UINT32                                BytesPerLine, FbOffset, BytesPerPixel;\r
+\r
+  Info = Mode->Info;\r
+  CopyMem (Info, &Private->VmwareSvgaModeInfo[Mode->Mode], sizeof (*Info));\r
+  BytesPerPixel = Private->ModeData[Mode->Mode].ColorDepth / 8;\r
+  BytesPerLine = Info->PixelsPerScanLine * BytesPerPixel;\r
+\r
+  FbOffset = VmwareSvgaRead (Private, VmwareSvgaRegFbOffset);\r
+\r
+  Status = Private->PciIo->GetBarAttributes (\r
+                             Private->PciIo,\r
+                             PCI_BAR_IDX1,\r
+                             NULL,\r
+                             (VOID**) &FrameBufDesc\r
+                             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  Mode->FrameBufferBase = FrameBufDesc->AddrRangeMin + FbOffset;\r
+  Mode->FrameBufferSize = BytesPerLine * Info->VerticalResolution;\r
+\r
+  FreePool (FrameBufDesc);\r
+  return Status;\r
+}\r
+\r
 \r
 //\r
 // Graphics Output Protocol Member Functions\r
@@ -124,10 +161,14 @@ Routine Description:
 \r
   *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
 \r
-  ModeData = &Private->ModeData[ModeNumber];\r
-  (*Info)->HorizontalResolution = ModeData->HorizontalResolution;\r
-  (*Info)->VerticalResolution   = ModeData->VerticalResolution;\r
-  QemuVideoCompleteModeInfo (ModeData, *Info);\r
+  if (Private->Variant == QEMU_VIDEO_VMWARE_SVGA) {\r
+    CopyMem (*Info, &Private->VmwareSvgaModeInfo[ModeNumber], sizeof (**Info));\r
+  } else {\r
+    ModeData = &Private->ModeData[ModeNumber];\r
+    (*Info)->HorizontalResolution = ModeData->HorizontalResolution;\r
+    (*Info)->VerticalResolution   = ModeData->VerticalResolution;\r
+    QemuVideoCompleteModeInfo (ModeData, *Info);\r
+  }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -155,9 +196,10 @@ Routine Description:
 \r
 --*/\r
 {\r
-  QEMU_VIDEO_PRIVATE_DATA    *Private;\r
-  QEMU_VIDEO_MODE_DATA       *ModeData;\r
-  RETURN_STATUS              Status;\r
+  QEMU_VIDEO_PRIVATE_DATA       *Private;\r
+  QEMU_VIDEO_MODE_DATA          *ModeData;\r
+  RETURN_STATUS                 Status;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;\r
 \r
   Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);\r
 \r
@@ -176,6 +218,12 @@ Routine Description:
   case QEMU_VIDEO_BOCHS:\r
     InitializeBochsGraphicsMode (Private, &QemuVideoBochsModes[ModeData->InternalModeIndex]);\r
     break;\r
+  case QEMU_VIDEO_VMWARE_SVGA:\r
+    InitializeVmwareSvgaGraphicsMode (\r
+      Private,\r
+      &QemuVideoBochsModes[ModeData->InternalModeIndex]\r
+      );\r
+    break;\r
   default:\r
     ASSERT (FALSE);\r
     return EFI_DEVICE_ERROR;\r
@@ -186,7 +234,11 @@ Routine Description:
   This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;\r
   This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
 \r
-  QemuVideoCompleteModeData (Private, This->Mode);\r
+  if (Private->Variant == QEMU_VIDEO_VMWARE_SVGA) {\r
+    QemuVideoVmwareSvgaCompleteModeData (Private, This->Mode);\r
+  } else {\r
+    QemuVideoCompleteModeData (Private, This->Mode);\r
+  }\r
 \r
   //\r
   // Re-initialize the frame buffer configure when mode changes.\r
@@ -220,6 +272,21 @@ Routine Description:
   }\r
   ASSERT (Status == RETURN_SUCCESS);\r
 \r
+  //\r
+  // Per UEFI Spec, need to clear the visible portions of the output display to black.\r
+  //\r
+  ZeroMem (&Black, sizeof (Black));\r
+  Status = FrameBufferBlt (\r
+             Private->FrameBufferBltConfigure,\r
+             &Black,\r
+             EfiBltVideoFill,\r
+             0, 0,\r
+             0, 0,\r
+             This->Mode->Info->HorizontalResolution, This->Mode->Info->VerticalResolution,\r
+             0\r
+             );\r
+  ASSERT_RETURN_ERROR (Status);\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -299,7 +366,7 @@ Returns:
 \r
   default:\r
     Status = EFI_INVALID_PARAMETER;\r
-    ASSERT (FALSE);\r
+    break;\r
   }\r
 \r
   gBS->RestoreTPL (OriginalTPL);\r