]> 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
 /** @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
 \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
 \r
 **/\r
 \r
+#include <IndustryStandard/VmwareSvga.h>\r
 #include "Qemu.h"\r
 \r
 STATIC\r
 #include "Qemu.h"\r
 \r
 STATIC\r
@@ -75,6 +76,42 @@ QemuVideoCompleteModeData (
   return EFI_SUCCESS;\r
 }\r
 \r
   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
 \r
 //\r
 // Graphics Output Protocol Member Functions\r
@@ -124,10 +161,14 @@ Routine Description:
 \r
   *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
 \r
 \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
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -155,9 +196,10 @@ Routine Description:
 \r
 --*/\r
 {\r
 \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
 \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_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
   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
   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
 \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
   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
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -299,7 +366,7 @@ Returns:
 \r
   default:\r
     Status = EFI_INVALID_PARAMETER;\r
 \r
   default:\r
     Status = EFI_INVALID_PARAMETER;\r
-    ASSERT (FALSE);\r
+    break;\r
   }\r
 \r
   gBS->RestoreTPL (OriginalTPL);\r
   }\r
 \r
   gBS->RestoreTPL (OriginalTPL);\r