]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/VirtioGpuDxe/Gop.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / VirtioGpuDxe / Gop.c
index 507e1a770d10afe8188ec70b38df36c2dcdffdf3..2c15d542e3b1e0c7aedd2564918b1576d39e9522 100644 (file)
@@ -4,13 +4,7 @@
 \r
   Copyright (C) 2016, Red Hat, Inc.\r
 \r
-  This program and the accompanying materials are licensed and made available\r
-  under the terms and conditions of the BSD License which accompanies this\r
-  distribution. The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
-  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 **/\r
 VOID\r
 ReleaseGopResources (\r
-  IN OUT VGPU_GOP *VgpuGop,\r
-  IN     BOOLEAN  DisableHead\r
+  IN OUT VGPU_GOP  *VgpuGop,\r
+  IN     BOOLEAN   DisableHead\r
   )\r
 {\r
-  EFI_STATUS Status;\r
+  EFI_STATUS  Status;\r
 \r
   ASSERT (VgpuGop->ResourceId != 0);\r
   ASSERT (VgpuGop->BackingStore != NULL);\r
@@ -64,7 +58,10 @@ ReleaseGopResources (
     //\r
     Status = VirtioGpuSetScanout (\r
                VgpuGop->ParentBus, // VgpuDev\r
-               0, 0, 0, 0,         // X, Y, Width, Height\r
+               0,\r
+               0,\r
+               0,\r
+               0,                  // X, Y, Width, Height\r
                0,                  // ScanoutId\r
                0                   // ResourceId\r
                );\r
@@ -114,11 +111,17 @@ ReleaseGopResources (
   }\r
 \r
   //\r
-  // Release backing pages.\r
+  // Unmap and release backing pages.\r
   //\r
-  FreePages (VgpuGop->BackingStore, VgpuGop->NumberOfPages);\r
-  VgpuGop->BackingStore  = NULL;\r
-  VgpuGop->NumberOfPages = 0;\r
+  VirtioGpuUnmapAndFreeBackingStore (\r
+    VgpuGop->ParentBus,      // VgpuDev\r
+    VgpuGop->NumberOfPages,  // NumberOfPages\r
+    VgpuGop->BackingStore,   // HostAddress\r
+    VgpuGop->BackingStoreMap // Mapping\r
+    );\r
+  VgpuGop->BackingStore    = NULL;\r
+  VgpuGop->NumberOfPages   = 0;\r
+  VgpuGop->BackingStoreMap = NULL;\r
 \r
   //\r
   // Destroy the currently used 2D host resource.\r
@@ -131,6 +134,7 @@ ReleaseGopResources (
   if (EFI_ERROR (Status)) {\r
     CpuDeadLoop ();\r
   }\r
+\r
   VgpuGop->ResourceId = 0;\r
 }\r
 \r
@@ -138,31 +142,31 @@ ReleaseGopResources (
 // The resolutions supported by this driver.\r
 //\r
 typedef struct {\r
-  UINT32 Width;\r
-  UINT32 Height;\r
+  UINT32    Width;\r
+  UINT32    Height;\r
 } GOP_RESOLUTION;\r
 \r
-STATIC CONST GOP_RESOLUTION mGopResolutions[] = {\r
-  {  640,  480 },\r
-  {  800,  480 },\r
-  {  800,  600 },\r
-  {  832,  624 },\r
-  {  960,  640 },\r
-  { 1024,  600 },\r
-  { 1024,  768 },\r
-  { 1152,  864 },\r
-  { 1152,  870 },\r
-  { 1280,  720 },\r
-  { 1280,  760 },\r
-  { 1280,  768 },\r
-  { 1280,  800 },\r
-  { 1280,  960 },\r
+STATIC CONST GOP_RESOLUTION  mGopResolutions[] = {\r
+  { 640,  480  },\r
+  { 800,  480  },\r
+  { 800,  600  },\r
+  { 832,  624  },\r
+  { 960,  640  },\r
+  { 1024, 600  },\r
+  { 1024, 768  },\r
+  { 1152, 864  },\r
+  { 1152, 870  },\r
+  { 1280, 720  },\r
+  { 1280, 760  },\r
+  { 1280, 768  },\r
+  { 1280, 800  },\r
+  { 1280, 960  },\r
   { 1280, 1024 },\r
-  { 1360,  768 },\r
-  { 1366,  768 },\r
+  { 1360, 768  },\r
+  { 1366, 768  },\r
   { 1400, 1050 },\r
-  { 1440,  900 },\r
-  { 1600,  900 },\r
+  { 1440, 900  },\r
+  { 1600, 900  },\r
   { 1600, 1200 },\r
   { 1680, 1050 },\r
   { 1920, 1080 },\r
@@ -195,13 +199,13 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 GopQueryMode (\r
-  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL         *This,\r
-  IN  UINT32                               ModeNumber,\r
-  OUT UINTN                                *SizeOfInfo,\r
-  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,\r
+  IN  UINT32                                ModeNumber,\r
+  OUT UINTN                                 *SizeOfInfo,\r
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info\r
   )\r
 {\r
-  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *GopModeInfo;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *GopModeInfo;\r
 \r
   if (ModeNumber >= ARRAY_SIZE (mGopResolutions)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -218,7 +222,7 @@ GopQueryMode (
   GopModeInfo->PixelsPerScanLine    = mGopResolutions[ModeNumber].Width;\r
 \r
   *SizeOfInfo = sizeof *GopModeInfo;\r
-  *Info = GopModeInfo;\r
+  *Info       = GopModeInfo;\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -226,17 +230,20 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 GopSetMode (\r
-  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
-  IN  UINT32                       ModeNumber\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL  *This,\r
+  IN  UINT32                        ModeNumber\r
   )\r
 {\r
-  VGPU_GOP   *VgpuGop;\r
-  UINT32     NewResourceId;\r
-  UINTN      NewNumberOfBytes;\r
-  UINTN      NewNumberOfPages;\r
-  VOID       *NewBackingStore;\r
-  EFI_STATUS Status;\r
-  EFI_STATUS Status2;\r
+  VGPU_GOP              *VgpuGop;\r
+  UINT32                NewResourceId;\r
+  UINTN                 NewNumberOfBytes;\r
+  UINTN                 NewNumberOfPages;\r
+  VOID                  *NewBackingStore;\r
+  EFI_PHYSICAL_ADDRESS  NewBackingStoreDeviceAddress;\r
+  VOID                  *NewBackingStoreMap;\r
+\r
+  EFI_STATUS  Status;\r
+  EFI_STATUS  Status2;\r
 \r
   if (ModeNumber >= ARRAY_SIZE (mGopResolutions)) {\r
     return EFI_UNSUPPORTED;\r
@@ -257,9 +264,9 @@ GopSetMode (
     //\r
     VgpuGop->Gop.Mode = &VgpuGop->GopMode;\r
 \r
-    VgpuGop->GopMode.MaxMode         = (UINT32)(ARRAY_SIZE (mGopResolutions));\r
-    VgpuGop->GopMode.Info            = &VgpuGop->GopModeInfo;\r
-    VgpuGop->GopMode.SizeOfInfo      = sizeof VgpuGop->GopModeInfo;\r
+    VgpuGop->GopMode.MaxMode    = (UINT32)(ARRAY_SIZE (mGopResolutions));\r
+    VgpuGop->GopMode.Info       = &VgpuGop->GopModeInfo;\r
+    VgpuGop->GopMode.SizeOfInfo = sizeof VgpuGop->GopModeInfo;\r
 \r
     VgpuGop->GopModeInfo.PixelFormat = PixelBltOnly;\r
 \r
@@ -293,20 +300,22 @@ GopSetMode (
   }\r
 \r
   //\r
-  // Allocate guest backing store.\r
+  // Allocate, zero and map guest backing store, for bus master common buffer\r
+  // operation.\r
   //\r
   NewNumberOfBytes = mGopResolutions[ModeNumber].Width *\r
                      mGopResolutions[ModeNumber].Height * sizeof (UINT32);\r
   NewNumberOfPages = EFI_SIZE_TO_PAGES (NewNumberOfBytes);\r
-  NewBackingStore = AllocatePages (NewNumberOfPages);\r
-  if (NewBackingStore == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
+  Status           = VirtioGpuAllocateZeroAndMapBackingStore (\r
+                       VgpuGop->ParentBus,            // VgpuDev\r
+                       NewNumberOfPages,              // NumberOfPages\r
+                       &NewBackingStore,              // HostAddress\r
+                       &NewBackingStoreDeviceAddress, // DeviceAddress\r
+                       &NewBackingStoreMap            // Mapping\r
+                       );\r
+  if (EFI_ERROR (Status)) {\r
     goto DestroyHostResource;\r
   }\r
-  //\r
-  // Fill visible part of backing store with black.\r
-  //\r
-  ZeroMem (NewBackingStore, NewNumberOfBytes);\r
 \r
   //\r
   // Attach backing store to the host resource.\r
@@ -314,11 +323,11 @@ GopSetMode (
   Status = VirtioGpuResourceAttachBacking (\r
              VgpuGop->ParentBus,           // VgpuDev\r
              NewResourceId,                // ResourceId\r
-             (UINTN)NewBackingStore,       // BackingStoreDeviceAddress\r
+             NewBackingStoreDeviceAddress, // BackingStoreDeviceAddress\r
              NewNumberOfPages              // NumberOfPages\r
              );\r
   if (EFI_ERROR (Status)) {\r
-    goto FreeBackingStore;\r
+    goto UnmapAndFreeBackingStore;\r
   }\r
 \r
   //\r
@@ -370,6 +379,7 @@ GopSetMode (
       if (EFI_ERROR (Status2)) {\r
         CpuDeadLoop ();\r
       }\r
+\r
       goto DetachBackingStore;\r
     }\r
 \r
@@ -388,18 +398,19 @@ GopSetMode (
   ASSERT (VgpuGop->ResourceId == 0);\r
   ASSERT (VgpuGop->BackingStore == NULL);\r
 \r
-  VgpuGop->ResourceId = NewResourceId;\r
-  VgpuGop->BackingStore = NewBackingStore;\r
-  VgpuGop->NumberOfPages = NewNumberOfPages;\r
+  VgpuGop->ResourceId      = NewResourceId;\r
+  VgpuGop->BackingStore    = NewBackingStore;\r
+  VgpuGop->NumberOfPages   = NewNumberOfPages;\r
+  VgpuGop->BackingStoreMap = NewBackingStoreMap;\r
 \r
   //\r
   // Populate Mode and ModeInfo (mutable fields only).\r
   //\r
-  VgpuGop->GopMode.Mode = ModeNumber;\r
+  VgpuGop->GopMode.Mode                     = ModeNumber;\r
   VgpuGop->GopModeInfo.HorizontalResolution =\r
-                                             mGopResolutions[ModeNumber].Width;\r
+    mGopResolutions[ModeNumber].Width;\r
   VgpuGop->GopModeInfo.VerticalResolution = mGopResolutions[ModeNumber].Height;\r
-  VgpuGop->GopModeInfo.PixelsPerScanLine = mGopResolutions[ModeNumber].Width;\r
+  VgpuGop->GopModeInfo.PixelsPerScanLine  = mGopResolutions[ModeNumber].Width;\r
   return EFI_SUCCESS;\r
 \r
 DetachBackingStore:\r
@@ -409,8 +420,13 @@ DetachBackingStore:
     CpuDeadLoop ();\r
   }\r
 \r
-FreeBackingStore:\r
-  FreePages (NewBackingStore, NewNumberOfPages);\r
+UnmapAndFreeBackingStore:\r
+  VirtioGpuUnmapAndFreeBackingStore (\r
+    VgpuGop->ParentBus, // VgpuDev\r
+    NewNumberOfPages,   // NumberOfPages\r
+    NewBackingStore,    // HostAddress\r
+    NewBackingStoreMap  // Mapping\r
+    );\r
 \r
 DestroyHostResource:\r
   Status2 = VirtioGpuResourceUnref (VgpuGop->ParentBus, NewResourceId);\r
@@ -426,27 +442,27 @@ STATIC
 EFI_STATUS\r
 EFIAPI\r
 GopBlt (\r
-  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL      *This,\r
-  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL     *BltBuffer,   OPTIONAL\r
-  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,\r
-  IN  UINTN                             SourceX,\r
-  IN  UINTN                             SourceY,\r
-  IN  UINTN                             DestinationX,\r
-  IN  UINTN                             DestinationY,\r
-  IN  UINTN                             Width,\r
-  IN  UINTN                             Height,\r
-  IN  UINTN                             Delta         OPTIONAL\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL       *This,\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BltBuffer    OPTIONAL,\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION  BltOperation,\r
+  IN  UINTN                              SourceX,\r
+  IN  UINTN                              SourceY,\r
+  IN  UINTN                              DestinationX,\r
+  IN  UINTN                              DestinationY,\r
+  IN  UINTN                              Width,\r
+  IN  UINTN                              Height,\r
+  IN  UINTN                              Delta         OPTIONAL\r
   )\r
 {\r
-  VGPU_GOP   *VgpuGop;\r
-  UINT32     CurrentHorizontal;\r
-  UINT32     CurrentVertical;\r
-  UINTN      SegmentSize;\r
-  UINTN      Y;\r
-  UINTN      ResourceOffset;\r
-  EFI_STATUS Status;\r
-\r
-  VgpuGop = VGPU_GOP_FROM_GOP (This);\r
+  VGPU_GOP    *VgpuGop;\r
+  UINT32      CurrentHorizontal;\r
+  UINT32      CurrentVertical;\r
+  UINTN       SegmentSize;\r
+  UINTN       Y;\r
+  UINTN       ResourceOffset;\r
+  EFI_STATUS  Status;\r
+\r
+  VgpuGop           = VGPU_GOP_FROM_GOP (This);\r
   CurrentHorizontal = VgpuGop->GopModeInfo.HorizontalResolution;\r
   CurrentVertical   = VgpuGop->GopModeInfo.VerticalResolution;\r
 \r
@@ -465,8 +481,9 @@ GopBlt (
   // zero, then Width is the entire width of BltBuffer, and the stride is\r
   // supposed to be calculated from Width.\r
   //\r
-  if (BltOperation == EfiBltVideoToBltBuffer ||\r
-      BltOperation == EfiBltBufferToVideo) {\r
+  if ((BltOperation == EfiBltVideoToBltBuffer) ||\r
+      (BltOperation == EfiBltBufferToVideo))\r
+  {\r
     if (Delta == 0) {\r
       Delta = SegmentSize;\r
     }\r
@@ -476,13 +493,15 @@ GopBlt (
   // For operations that write to the display, check if the destination fits\r
   // onto the display.\r
   //\r
-  if (BltOperation == EfiBltVideoFill ||\r
-      BltOperation == EfiBltBufferToVideo ||\r
-      BltOperation == EfiBltVideoToVideo) {\r
-    if (DestinationX > CurrentHorizontal ||\r
-        Width > CurrentHorizontal - DestinationX ||\r
-        DestinationY > CurrentVertical ||\r
-        Height > CurrentVertical - DestinationY) {\r
+  if ((BltOperation == EfiBltVideoFill) ||\r
+      (BltOperation == EfiBltBufferToVideo) ||\r
+      (BltOperation == EfiBltVideoToVideo))\r
+  {\r
+    if ((DestinationX > CurrentHorizontal) ||\r
+        (Width > CurrentHorizontal - DestinationX) ||\r
+        (DestinationY > CurrentVertical) ||\r
+        (Height > CurrentVertical - DestinationY))\r
+    {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
   }\r
@@ -491,12 +510,14 @@ GopBlt (
   // For operations that read from the display, check if the source fits onto\r
   // the display.\r
   //\r
-  if (BltOperation == EfiBltVideoToBltBuffer ||\r
-      BltOperation == EfiBltVideoToVideo) {\r
-    if (SourceX > CurrentHorizontal ||\r
-        Width > CurrentHorizontal - SourceX ||\r
-        SourceY > CurrentVertical ||\r
-        Height > CurrentVertical - SourceY) {\r
+  if ((BltOperation == EfiBltVideoToBltBuffer) ||\r
+      (BltOperation == EfiBltVideoToVideo))\r
+  {\r
+    if ((SourceX > CurrentHorizontal) ||\r
+        (Width > CurrentHorizontal - SourceX) ||\r
+        (SourceY > CurrentVertical) ||\r
+        (Height > CurrentVertical - SourceY))\r
+    {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
   }\r
@@ -506,99 +527,103 @@ GopBlt (
   // won't be further steps.\r
   //\r
   switch (BltOperation) {\r
-  case EfiBltVideoFill:\r
-    //\r
-    // Write data from the BltBuffer pixel (0, 0) directly to every pixel of\r
-    // the video display rectangle (DestinationX, DestinationY) (DestinationX +\r
-    // Width, DestinationY + Height). Only one pixel will be used from the\r
-    // BltBuffer. Delta is NOT used.\r
-    //\r
-    for (Y = 0; Y < Height; ++Y) {\r
-      SetMem32 (\r
-        VgpuGop->BackingStore +\r
+    case EfiBltVideoFill:\r
+      //\r
+      // Write data from the BltBuffer pixel (0, 0) directly to every pixel of\r
+      // the video display rectangle (DestinationX, DestinationY) (DestinationX +\r
+      // Width, DestinationY + Height). Only one pixel will be used from the\r
+      // BltBuffer. Delta is NOT used.\r
+      //\r
+      for (Y = 0; Y < Height; ++Y) {\r
+        SetMem32 (\r
+          VgpuGop->BackingStore +\r
           (DestinationY + Y) * CurrentHorizontal + DestinationX,\r
-        SegmentSize,\r
-        *(UINT32 *)BltBuffer\r
-        );\r
-    }\r
-    break;\r
-\r
-  case EfiBltVideoToBltBuffer:\r
-    //\r
-    // Read data from the video display rectangle (SourceX, SourceY) (SourceX +\r
-    // Width, SourceY + Height) and place it in the BltBuffer rectangle\r
-    // (DestinationX, DestinationY ) (DestinationX + Width, DestinationY +\r
-    // Height). If DestinationX or DestinationY is not zero then Delta must be\r
-    // set to the length in bytes of a row in the BltBuffer.\r
-    //\r
-    for (Y = 0; Y < Height; ++Y) {\r
-      CopyMem (\r
-        (UINT8 *)BltBuffer +\r
-          (DestinationY + Y) * Delta + DestinationX * sizeof *BltBuffer,\r
-        VgpuGop->BackingStore +\r
-          (SourceY + Y) * CurrentHorizontal + SourceX,\r
-        SegmentSize\r
-        );\r
-    }\r
-    return EFI_SUCCESS;\r
+          SegmentSize,\r
+          *(UINT32 *)BltBuffer\r
+          );\r
+      }\r
 \r
-  case EfiBltBufferToVideo:\r
-    //\r
-    // Write data from the BltBuffer rectangle (SourceX, SourceY) (SourceX +\r
-    // Width, SourceY + Height) directly to the video display rectangle\r
-    // (DestinationX, DestinationY) (DestinationX + Width, DestinationY +\r
-    // Height). If SourceX or SourceY is not zero then Delta must be set to the\r
-    // length in bytes of a row in the BltBuffer.\r
-    //\r
-    for (Y = 0; Y < Height; ++Y) {\r
-      CopyMem (\r
-        VgpuGop->BackingStore +\r
-          (DestinationY + Y) * CurrentHorizontal + DestinationX,\r
-        (UINT8 *)BltBuffer +\r
-          (SourceY + Y) * Delta + SourceX * sizeof *BltBuffer,\r
-        SegmentSize\r
-        );\r
-    }\r
-    break;\r
+      break;\r
 \r
-  case EfiBltVideoToVideo:\r
-    //\r
-    // Copy from the video display rectangle (SourceX, SourceY) (SourceX +\r
-    // Width, SourceY + Height) to the video display rectangle (DestinationX,\r
-    // DestinationY) (DestinationX + Width, DestinationY + Height). The\r
-    // BltBuffer and Delta are not used in this mode.\r
-    //\r
-    // A single invocation of CopyMem() handles overlap between source and\r
-    // destination (that is, within a single line), but for multiple\r
-    // invocations, we must handle overlaps.\r
-    //\r
-    if (SourceY < DestinationY) {\r
-      Y = Height;\r
-      while (Y > 0) {\r
-        --Y;\r
+    case EfiBltVideoToBltBuffer:\r
+      //\r
+      // Read data from the video display rectangle (SourceX, SourceY) (SourceX +\r
+      // Width, SourceY + Height) and place it in the BltBuffer rectangle\r
+      // (DestinationX, DestinationY ) (DestinationX + Width, DestinationY +\r
+      // Height). If DestinationX or DestinationY is not zero then Delta must be\r
+      // set to the length in bytes of a row in the BltBuffer.\r
+      //\r
+      for (Y = 0; Y < Height; ++Y) {\r
         CopyMem (\r
+          (UINT8 *)BltBuffer +\r
+          (DestinationY + Y) * Delta + DestinationX * sizeof *BltBuffer,\r
           VgpuGop->BackingStore +\r
-            (DestinationY + Y) * CurrentHorizontal + DestinationX,\r
-          VgpuGop->BackingStore +\r
-            (SourceY + Y) * CurrentHorizontal + SourceX,\r
+          (SourceY + Y) * CurrentHorizontal + SourceX,\r
           SegmentSize\r
           );\r
       }\r
-    } else {\r
+\r
+      return EFI_SUCCESS;\r
+\r
+    case EfiBltBufferToVideo:\r
+      //\r
+      // Write data from the BltBuffer rectangle (SourceX, SourceY) (SourceX +\r
+      // Width, SourceY + Height) directly to the video display rectangle\r
+      // (DestinationX, DestinationY) (DestinationX + Width, DestinationY +\r
+      // Height). If SourceX or SourceY is not zero then Delta must be set to the\r
+      // length in bytes of a row in the BltBuffer.\r
+      //\r
       for (Y = 0; Y < Height; ++Y) {\r
         CopyMem (\r
           VgpuGop->BackingStore +\r
-            (DestinationY + Y) * CurrentHorizontal + DestinationX,\r
-          VgpuGop->BackingStore +\r
-            (SourceY + Y) * CurrentHorizontal + SourceX,\r
+          (DestinationY + Y) * CurrentHorizontal + DestinationX,\r
+          (UINT8 *)BltBuffer +\r
+          (SourceY + Y) * Delta + SourceX * sizeof *BltBuffer,\r
           SegmentSize\r
           );\r
       }\r
-    }\r
-    break;\r
 \r
-  default:\r
-    return EFI_INVALID_PARAMETER;\r
+      break;\r
+\r
+    case EfiBltVideoToVideo:\r
+      //\r
+      // Copy from the video display rectangle (SourceX, SourceY) (SourceX +\r
+      // Width, SourceY + Height) to the video display rectangle (DestinationX,\r
+      // DestinationY) (DestinationX + Width, DestinationY + Height). The\r
+      // BltBuffer and Delta are not used in this mode.\r
+      //\r
+      // A single invocation of CopyMem() handles overlap between source and\r
+      // destination (that is, within a single line), but for multiple\r
+      // invocations, we must handle overlaps.\r
+      //\r
+      if (SourceY < DestinationY) {\r
+        Y = Height;\r
+        while (Y > 0) {\r
+          --Y;\r
+          CopyMem (\r
+            VgpuGop->BackingStore +\r
+            (DestinationY + Y) * CurrentHorizontal + DestinationX,\r
+            VgpuGop->BackingStore +\r
+            (SourceY + Y) * CurrentHorizontal + SourceX,\r
+            SegmentSize\r
+            );\r
+        }\r
+      } else {\r
+        for (Y = 0; Y < Height; ++Y) {\r
+          CopyMem (\r
+            VgpuGop->BackingStore +\r
+            (DestinationY + Y) * CurrentHorizontal + DestinationX,\r
+            VgpuGop->BackingStore +\r
+            (SourceY + Y) * CurrentHorizontal + SourceX,\r
+            SegmentSize\r
+            );\r
+        }\r
+      }\r
+\r
+      break;\r
+\r
+    default:\r
+      return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   //\r
@@ -637,7 +662,7 @@ GopBlt (
 //\r
 // Template for initializing VGPU_GOP.Gop.\r
 //\r
-CONST EFI_GRAPHICS_OUTPUT_PROTOCOL mGopTemplate = {\r
+CONST EFI_GRAPHICS_OUTPUT_PROTOCOL  mGopTemplate = {\r
   GopQueryMode,\r
   GopSetMode,\r
   GopBlt,\r