]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/QemuVideoDxe: VMWare SVGA device support
authorPhil Dennis-Jordan <phil@philjordan.eu>
Fri, 7 Apr 2017 06:25:58 +0000 (18:25 +1200)
committerLaszlo Ersek <lersek@redhat.com>
Fri, 7 Apr 2017 10:34:11 +0000 (12:34 +0200)
In addition to the QXL, Cirrus, etc. VGA adapters, Qemu also implements
a basic version of VMWare's SVGA display device. Drivers for this
device exist for some guest OSes which do not support Qemu's other
display adapters, so supporting it in OVMF is useful in conjunction
with those OSes.

This change adds support for the SVGA device's framebuffer to
QemuVideoDxe's graphics output protocol implementation, based on
VMWare's documentation. The most basic initialisation, framebuffer
layout query, and mode setting operations are implemented.

The device relies on port-based 32-bit I/O, unfortunately on misaligned
addresses. This limits the driver's support to the x86 family of
platforms.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
OvmfPkg/QemuVideoDxe/Driver.c
OvmfPkg/QemuVideoDxe/Gop.c
OvmfPkg/QemuVideoDxe/Initialize.c
OvmfPkg/QemuVideoDxe/Qemu.h

index fc8025ec46dea025ba6171be596a06f10f1549a2..0dce80e59ba8af4e01e8c6b586d104974e54431c 100644 (file)
 \r
 **/\r
 \r
 \r
 **/\r
 \r
-#include "Qemu.h"\r
+#include <IndustryStandard/VmwareSvga.h>\r
 #include <IndustryStandard/Acpi.h>\r
 #include <IndustryStandard/Acpi.h>\r
+#include "Qemu.h"\r
+#include "UnalignedIoInternal.h"\r
 \r
 EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = {\r
   QemuVideoControllerDriverSupported,\r
 \r
 EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = {\r
   QemuVideoControllerDriverSupported,\r
@@ -57,6 +59,11 @@ QEMU_VIDEO_CARD gQemuVideoCardList[] = {
         0x1050,\r
         QEMU_VIDEO_BOCHS_MMIO,\r
         L"QEMU VirtIO VGA"\r
         0x1050,\r
         QEMU_VIDEO_BOCHS_MMIO,\r
         L"QEMU VirtIO VGA"\r
+    },{\r
+        VMWARE_PCI_VENDOR_ID_VMWARE,\r
+        VMWARE_PCI_DEVICE_ID_VMWARE_SVGA2,\r
+        QEMU_VIDEO_VMWARE_SVGA,\r
+        L"QEMU VMWare SVGA"\r
     },{\r
         0 /* end of list */\r
     }\r
     },{\r
         0 /* end of list */\r
     }\r
@@ -242,6 +249,7 @@ QemuVideoControllerDriverStart (
     goto ClosePciIo;\r
   }\r
   Private->Variant = Card->Variant;\r
     goto ClosePciIo;\r
   }\r
   Private->Variant = Card->Variant;\r
+  Private->FrameBufferVramBarIndex = PCI_BAR_IDX0;\r
 \r
   //\r
   // IsQxl is based on the detected Card->Variant, which at a later point might\r
 \r
   //\r
   // IsQxl is based on the detected Card->Variant, which at a later point might\r
@@ -316,6 +324,58 @@ QemuVideoControllerDriverStart (
     }\r
   }\r
 \r
     }\r
   }\r
 \r
+  //\r
+  // Check if accessing Vmware SVGA interface works\r
+  //\r
+  if (Private->Variant == QEMU_VIDEO_VMWARE_SVGA) {\r
+    EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *IoDesc;\r
+    UINT32                            TargetId;\r
+    UINT32                            SvgaIdRead;\r
+\r
+    IoDesc = NULL;\r
+    Status = Private->PciIo->GetBarAttributes (\r
+                               Private->PciIo,\r
+                               PCI_BAR_IDX0,\r
+                               NULL,\r
+                               (VOID**) &IoDesc\r
+                               );\r
+    if (EFI_ERROR (Status) ||\r
+        IoDesc->ResType != ACPI_ADDRESS_SPACE_TYPE_IO ||\r
+        IoDesc->AddrRangeMin > MAX_UINT16 + 1 - (VMWARE_SVGA_VALUE_PORT + 4)) {\r
+      if (IoDesc != NULL) {\r
+        FreePool (IoDesc);\r
+      }\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto RestoreAttributes;\r
+    }\r
+    Private->VmwareSvgaBasePort = (UINT16) IoDesc->AddrRangeMin;\r
+    FreePool (IoDesc);\r
+\r
+    TargetId = VMWARE_SVGA_ID_2;\r
+    while (TRUE) {\r
+      VmwareSvgaWrite (Private, VmwareSvgaRegId, TargetId);\r
+      SvgaIdRead = VmwareSvgaRead (Private, VmwareSvgaRegId);\r
+      if ((SvgaIdRead == TargetId) || (TargetId <= VMWARE_SVGA_ID_0)) {\r
+        break;\r
+      }\r
+      TargetId--;\r
+    }\r
+\r
+    if (SvgaIdRead != TargetId) {\r
+      DEBUG ((\r
+        DEBUG_ERROR,\r
+        "QemuVideo: QEMU_VIDEO_VMWARE_SVGA ID mismatch "\r
+        "(got 0x%x, base address 0x%x)\n",\r
+        SvgaIdRead,\r
+        Private->VmwareSvgaBasePort\r
+        ));\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto RestoreAttributes;\r
+    }\r
+\r
+    Private->FrameBufferVramBarIndex = PCI_BAR_IDX1;\r
+  }\r
+\r
   //\r
   // Get ParentDevicePath\r
   //\r
   //\r
   // Get ParentDevicePath\r
   //\r
@@ -371,6 +431,9 @@ QemuVideoControllerDriverStart (
   case QEMU_VIDEO_BOCHS:\r
     Status = QemuVideoBochsModeSetup (Private, IsQxl);\r
     break;\r
   case QEMU_VIDEO_BOCHS:\r
     Status = QemuVideoBochsModeSetup (Private, IsQxl);\r
     break;\r
+  case QEMU_VIDEO_VMWARE_SVGA:\r
+    Status = QemuVideoVmwareSvgaModeSetup (Private);\r
+    break;\r
   default:\r
     ASSERT (FALSE);\r
     Status = EFI_DEVICE_ERROR;\r
   default:\r
     ASSERT (FALSE);\r
     Status = EFI_DEVICE_ERROR;\r
@@ -432,6 +495,9 @@ DestructQemuVideoGraphics:
 \r
 FreeModeData:\r
   FreePool (Private->ModeData);\r
 \r
 FreeModeData:\r
   FreePool (Private->ModeData);\r
+  if (Private->VmwareSvgaModeInfo != NULL) {\r
+    FreePool (Private->VmwareSvgaModeInfo);\r
+  }\r
 \r
 UninstallGopDevicePath:\r
   gBS->UninstallProtocolInterface (Private->Handle,\r
 \r
 UninstallGopDevicePath:\r
   gBS->UninstallProtocolInterface (Private->Handle,\r
@@ -553,6 +619,9 @@ QemuVideoControllerDriverStop (
         );\r
 \r
   FreePool (Private->ModeData);\r
         );\r
 \r
   FreePool (Private->ModeData);\r
+  if (Private->VmwareSvgaModeInfo != NULL) {\r
+    FreePool (Private->VmwareSvgaModeInfo);\r
+  }\r
   gBS->UninstallProtocolInterface (Private->Handle,\r
          &gEfiDevicePathProtocolGuid, Private->GopDevicePath);\r
   FreePool (Private->GopDevicePath);\r
   gBS->UninstallProtocolInterface (Private->Handle,\r
          &gEfiDevicePathProtocolGuid, Private->GopDevicePath);\r
   FreePool (Private->GopDevicePath);\r
@@ -750,7 +819,7 @@ ClearScreen (
   Private->PciIo->Mem.Write (\r
                         Private->PciIo,\r
                         EfiPciIoWidthFillUint32,\r
   Private->PciIo->Mem.Write (\r
                         Private->PciIo,\r
                         EfiPciIoWidthFillUint32,\r
-                        0,\r
+                        Private->FrameBufferVramBarIndex,\r
                         0,\r
                         0x400000 >> 2,\r
                         &Color\r
                         0,\r
                         0x400000 >> 2,\r
                         &Color\r
@@ -887,6 +956,38 @@ BochsRead (
   return Data;\r
 }\r
 \r
   return Data;\r
 }\r
 \r
+VOID\r
+VmwareSvgaWrite (\r
+  QEMU_VIDEO_PRIVATE_DATA   *Private,\r
+  UINT16                    Register,\r
+  UINT32                    Value\r
+  )\r
+{\r
+  UnalignedIoWrite32 (\r
+    Private->VmwareSvgaBasePort + VMWARE_SVGA_INDEX_PORT,\r
+    Register\r
+    );\r
+  UnalignedIoWrite32 (\r
+    Private->VmwareSvgaBasePort + VMWARE_SVGA_VALUE_PORT,\r
+    Value\r
+    );\r
+}\r
+\r
+UINT32\r
+VmwareSvgaRead (\r
+  QEMU_VIDEO_PRIVATE_DATA   *Private,\r
+  UINT16                    Register\r
+  )\r
+{\r
+  UnalignedIoWrite32 (\r
+    Private->VmwareSvgaBasePort + VMWARE_SVGA_INDEX_PORT,\r
+    Register\r
+    );\r
+  return UnalignedIoRead32 (\r
+           Private->VmwareSvgaBasePort + VMWARE_SVGA_VALUE_PORT\r
+           );\r
+}\r
+\r
 VOID\r
 VgaOutb (\r
   QEMU_VIDEO_PRIVATE_DATA  *Private,\r
 VOID\r
 VgaOutb (\r
   QEMU_VIDEO_PRIVATE_DATA  *Private,\r
@@ -941,6 +1042,35 @@ InitializeBochsGraphicsMode (
   ClearScreen (Private);\r
 }\r
 \r
   ClearScreen (Private);\r
 }\r
 \r
+VOID\r
+InitializeVmwareSvgaGraphicsMode (\r
+  QEMU_VIDEO_PRIVATE_DATA  *Private,\r
+  QEMU_VIDEO_BOCHS_MODES   *ModeData\r
+  )\r
+{\r
+  UINT32 Capabilities;\r
+\r
+  VmwareSvgaWrite (Private, VmwareSvgaRegWidth, ModeData->Width);\r
+  VmwareSvgaWrite (Private, VmwareSvgaRegHeight, ModeData->Height);\r
+\r
+  Capabilities = VmwareSvgaRead (\r
+                   Private,\r
+                   VmwareSvgaRegCapabilities\r
+                   );\r
+  if ((Capabilities & VMWARE_SVGA_CAP_8BIT_EMULATION) != 0) {\r
+    VmwareSvgaWrite (\r
+      Private,\r
+      VmwareSvgaRegBitsPerPixel,\r
+      ModeData->ColorDepth\r
+      );\r
+  }\r
+\r
+  VmwareSvgaWrite (Private, VmwareSvgaRegEnable, 1);\r
+\r
+  SetDefaultPalette (Private);\r
+  ClearScreen (Private);\r
+}\r
+\r
 EFI_STATUS\r
 EFIAPI\r
 InitializeQemuVideo (\r
 EFI_STATUS\r
 EFIAPI\r
 InitializeQemuVideo (\r
index 359e9217d3d143fbbe90c6a742cd15b9e74cd73b..512fd27acbda08a4ed7ee9ddacd0b3a1a6875b83 100644 (file)
@@ -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
@@ -176,6 +217,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 +233,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
index d5d8cfef9661727a83c96b25f1d09df75bada77a..357124d628e7c6bc425ca27e310e8905f96f432a 100644 (file)
@@ -13,6 +13,7 @@
 \r
 **/\r
 \r
 \r
 **/\r
 \r
+#include <IndustryStandard/VmwareSvga.h>\r
 #include "Qemu.h"\r
 \r
 \r
 #include "Qemu.h"\r
 \r
 \r
@@ -346,3 +347,159 @@ QemuVideoBochsModeSetup (
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
+EFI_STATUS\r
+QemuVideoVmwareSvgaModeSetup (\r
+  QEMU_VIDEO_PRIVATE_DATA *Private\r
+  )\r
+{\r
+  EFI_STATUS                            Status;\r
+  UINT32                                FbSize;\r
+  UINT32                                MaxWidth, MaxHeight;\r
+  UINT32                                Capabilities;\r
+  UINT32                                BitsPerPixel;\r
+  UINT32                                Index;\r
+  QEMU_VIDEO_MODE_DATA                  *ModeData;\r
+  QEMU_VIDEO_BOCHS_MODES                *VideoMode;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *ModeInfo;\r
+\r
+  VmwareSvgaWrite (Private, VmwareSvgaRegEnable, 0);\r
+\r
+  Private->ModeData =\r
+    AllocatePool (sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT);\r
+  if (Private->ModeData == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ModeDataAllocError;\r
+  }\r
+\r
+  Private->VmwareSvgaModeInfo =\r
+    AllocatePool (\r
+      sizeof (Private->VmwareSvgaModeInfo[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT\r
+      );\r
+  if (Private->VmwareSvgaModeInfo == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ModeInfoAllocError;\r
+  }\r
+\r
+  FbSize =       VmwareSvgaRead (Private, VmwareSvgaRegFbSize);\r
+  MaxWidth =     VmwareSvgaRead (Private, VmwareSvgaRegMaxWidth);\r
+  MaxHeight =    VmwareSvgaRead (Private, VmwareSvgaRegMaxHeight);\r
+  Capabilities = VmwareSvgaRead (Private, VmwareSvgaRegCapabilities);\r
+  if ((Capabilities & VMWARE_SVGA_CAP_8BIT_EMULATION) != 0) {\r
+    BitsPerPixel = VmwareSvgaRead (\r
+                     Private,\r
+                     VmwareSvgaRegHostBitsPerPixel\r
+                     );\r
+    VmwareSvgaWrite (\r
+      Private,\r
+      VmwareSvgaRegBitsPerPixel,\r
+      BitsPerPixel\r
+      );\r
+  } else {\r
+    BitsPerPixel = VmwareSvgaRead (\r
+                     Private,\r
+                     VmwareSvgaRegBitsPerPixel\r
+                     );\r
+  }\r
+\r
+  if (FbSize == 0       ||\r
+      MaxWidth == 0     ||\r
+      MaxHeight == 0    ||\r
+      BitsPerPixel == 0 ||\r
+      BitsPerPixel % 8 != 0) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Rollback;\r
+  }\r
+\r
+  ModeData = Private->ModeData;\r
+  ModeInfo = Private->VmwareSvgaModeInfo;\r
+  VideoMode = &QemuVideoBochsModes[0];\r
+  for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index++) {\r
+    UINTN RequiredFbSize;\r
+\r
+    RequiredFbSize = (UINTN) VideoMode->Width * VideoMode->Height *\r
+                     (BitsPerPixel / 8);\r
+    if (RequiredFbSize <= FbSize     &&\r
+        VideoMode->Width <= MaxWidth &&\r
+        VideoMode->Height <= MaxHeight) {\r
+      UINT32  BytesPerLine;\r
+      UINT32  RedMask, GreenMask, BlueMask, PixelMask;\r
+\r
+      VmwareSvgaWrite (\r
+        Private,\r
+        VmwareSvgaRegWidth,\r
+        VideoMode->Width\r
+        );\r
+      VmwareSvgaWrite (\r
+        Private,\r
+        VmwareSvgaRegHeight,\r
+        VideoMode->Height\r
+        );\r
+\r
+      ModeData->InternalModeIndex    = Index;\r
+      ModeData->HorizontalResolution = VideoMode->Width;\r
+      ModeData->VerticalResolution   = VideoMode->Height;\r
+      ModeData->ColorDepth           = BitsPerPixel;\r
+\r
+      //\r
+      // Setting VmwareSvgaRegWidth/VmwareSvgaRegHeight actually changes\r
+      // the device's display mode, so we save all properties of each mode up\r
+      // front to avoid inadvertent mode changes later.\r
+      //\r
+      ModeInfo->Version = 0;\r
+      ModeInfo->HorizontalResolution = ModeData->HorizontalResolution;\r
+      ModeInfo->VerticalResolution   = ModeData->VerticalResolution;\r
+\r
+      ModeInfo->PixelFormat = PixelBitMask;\r
+\r
+      RedMask   = VmwareSvgaRead (Private, VmwareSvgaRegRedMask);\r
+      ModeInfo->PixelInformation.RedMask = RedMask;\r
+\r
+      GreenMask = VmwareSvgaRead (Private, VmwareSvgaRegGreenMask);\r
+      ModeInfo->PixelInformation.GreenMask = GreenMask;\r
+\r
+      BlueMask  = VmwareSvgaRead (Private, VmwareSvgaRegBlueMask);\r
+      ModeInfo->PixelInformation.BlueMask = BlueMask;\r
+\r
+      //\r
+      // Reserved mask is whatever bits in the pixel not containing RGB data,\r
+      // so start with binary 1s for every bit in the pixel, then mask off\r
+      // bits already used for RGB. Special case 32 to avoid undefined\r
+      // behaviour in the shift.\r
+      //\r
+      if (BitsPerPixel == 32) {\r
+        if (BlueMask == 0xff && GreenMask == 0xff00 && RedMask == 0xff0000) {\r
+          ModeInfo->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;\r
+        } else if (BlueMask == 0xff0000 &&\r
+                   GreenMask == 0xff00 &&\r
+                   RedMask == 0xff) {\r
+          ModeInfo->PixelFormat = PixelRedGreenBlueReserved8BitPerColor;\r
+        }\r
+        PixelMask = MAX_UINT32;\r
+      } else {\r
+        PixelMask = (1u << BitsPerPixel) - 1;\r
+      }\r
+      ModeInfo->PixelInformation.ReservedMask =\r
+        PixelMask & ~(RedMask | GreenMask | BlueMask);\r
+\r
+      BytesPerLine = VmwareSvgaRead (Private, VmwareSvgaRegBytesPerLine);\r
+      ModeInfo->PixelsPerScanLine = BytesPerLine / (BitsPerPixel / 8);\r
+\r
+      ModeData++;\r
+      ModeInfo++;\r
+    }\r
+    VideoMode++;\r
+  }\r
+  Private->MaxMode = ModeData - Private->ModeData;\r
+  return EFI_SUCCESS;\r
+\r
+Rollback:\r
+  FreePool (Private->VmwareSvgaModeInfo);\r
+  Private->VmwareSvgaModeInfo = NULL;\r
+\r
+ModeInfoAllocError:\r
+  FreePool (Private->ModeData);\r
+  Private->ModeData = NULL;\r
+\r
+ModeDataAllocError:\r
+  return Status;\r
+}\r
index 2ce37defc5b8807938af7db186d33d65d81a741c..7fbb25b3efd35c47bb88ac31bda9d92653f7f145 100644 (file)
@@ -92,6 +92,7 @@ typedef enum {
   QEMU_VIDEO_CIRRUS_5446,\r
   QEMU_VIDEO_BOCHS,\r
   QEMU_VIDEO_BOCHS_MMIO,\r
   QEMU_VIDEO_CIRRUS_5446,\r
   QEMU_VIDEO_BOCHS,\r
   QEMU_VIDEO_BOCHS_MMIO,\r
+  QEMU_VIDEO_VMWARE_SVGA,\r
 } QEMU_VIDEO_VARIANT;\r
 \r
 typedef struct {\r
 } QEMU_VIDEO_VARIANT;\r
 \r
 typedef struct {\r
@@ -115,10 +116,13 @@ typedef struct {
   //\r
   UINTN                                 MaxMode;\r
   QEMU_VIDEO_MODE_DATA                  *ModeData;\r
   //\r
   UINTN                                 MaxMode;\r
   QEMU_VIDEO_MODE_DATA                  *ModeData;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *VmwareSvgaModeInfo;\r
 \r
   QEMU_VIDEO_VARIANT                    Variant;\r
   FRAME_BUFFER_CONFIGURE                *FrameBufferBltConfigure;\r
   UINTN                                 FrameBufferBltConfigureSize;\r
 \r
   QEMU_VIDEO_VARIANT                    Variant;\r
   FRAME_BUFFER_CONFIGURE                *FrameBufferBltConfigure;\r
   UINTN                                 FrameBufferBltConfigureSize;\r
+  UINT8                                 FrameBufferVramBarIndex;\r
+  UINT16                                VmwareSvgaBasePort;\r
 } QEMU_VIDEO_PRIVATE_DATA;\r
 \r
 ///\r
 } QEMU_VIDEO_PRIVATE_DATA;\r
 \r
 ///\r
@@ -502,9 +506,34 @@ QemuVideoBochsModeSetup (
   BOOLEAN                  IsQxl\r
   );\r
 \r
   BOOLEAN                  IsQxl\r
   );\r
 \r
+EFI_STATUS\r
+QemuVideoVmwareSvgaModeSetup (\r
+  QEMU_VIDEO_PRIVATE_DATA *Private\r
+  );\r
+\r
 VOID\r
 InstallVbeShim (\r
   IN CONST CHAR16         *CardName,\r
   IN EFI_PHYSICAL_ADDRESS FrameBufferBase\r
   );\r
 VOID\r
 InstallVbeShim (\r
   IN CONST CHAR16         *CardName,\r
   IN EFI_PHYSICAL_ADDRESS FrameBufferBase\r
   );\r
+\r
+VOID\r
+VmwareSvgaWrite (\r
+  QEMU_VIDEO_PRIVATE_DATA *Private,\r
+  UINT16                  Register,\r
+  UINT32                  Value\r
+  );\r
+\r
+UINT32\r
+VmwareSvgaRead (\r
+  QEMU_VIDEO_PRIVATE_DATA *Private,\r
+  UINT16                  Register\r
+  );\r
+\r
+VOID\r
+InitializeVmwareSvgaGraphicsMode (\r
+  QEMU_VIDEO_PRIVATE_DATA  *Private,\r
+  QEMU_VIDEO_BOCHS_MODES   *ModeData\r
+  );\r
+\r
 #endif\r
 #endif\r