]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/VirtioGpuDxe/Commands.c
OvmfPkg/VirtioGpuDxe: map virtio GPU command objects to device addresses
[mirror_edk2.git] / OvmfPkg / VirtioGpuDxe / Commands.c
index 4e19bac606eea0d1fda3e757344c49b3dbb784f5..bdedea1df6a70887c0664f6a79ec38ef623853bb 100644 (file)
@@ -278,7 +278,8 @@ VirtioGpuExitBoot (
                                  code has been logged on the EFI_D_ERROR level.\r
 \r
   @return                        Codes for unexpected errors in VirtIo\r
-                                 messaging.\r
+                                 messaging, or request/response\r
+                                 mapping/unmapping.\r
 **/\r
 STATIC\r
 EFI_STATUS\r
@@ -294,6 +295,10 @@ VirtioGpuSendCommand (
   volatile VIRTIO_GPU_CONTROL_HEADER Response;\r
   EFI_STATUS                         Status;\r
   UINT32                             ResponseSize;\r
+  EFI_PHYSICAL_ADDRESS               RequestDeviceAddress;\r
+  VOID                               *RequestMap;\r
+  EFI_PHYSICAL_ADDRESS               ResponseDeviceAddress;\r
+  VOID                               *ResponseMap;\r
 \r
   //\r
   // Initialize Header.\r
@@ -312,14 +317,50 @@ VirtioGpuSendCommand (
   ASSERT (RequestSize >= sizeof *Header);\r
   ASSERT (RequestSize <= MAX_UINT32);\r
 \r
+  //\r
+  // Map request and response to bus master device addresses.\r
+  //\r
+  Status = VirtioMapAllBytesInSharedBuffer (\r
+             VgpuDev->VirtIo,\r
+             VirtioOperationBusMasterRead,\r
+             (VOID *)Header,\r
+             RequestSize,\r
+             &RequestDeviceAddress,\r
+             &RequestMap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  Status = VirtioMapAllBytesInSharedBuffer (\r
+             VgpuDev->VirtIo,\r
+             VirtioOperationBusMasterWrite,\r
+             (VOID *)&Response,\r
+             sizeof Response,\r
+             &ResponseDeviceAddress,\r
+             &ResponseMap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    goto UnmapRequest;\r
+  }\r
+\r
   //\r
   // Compose the descriptor chain.\r
   //\r
   VirtioPrepare (&VgpuDev->Ring, &Indices);\r
-  VirtioAppendDesc (&VgpuDev->Ring, (UINTN)Header, (UINT32)RequestSize,\r
-    VRING_DESC_F_NEXT, &Indices);\r
-  VirtioAppendDesc (&VgpuDev->Ring, (UINTN)&Response, sizeof Response,\r
-    VRING_DESC_F_WRITE, &Indices);\r
+  VirtioAppendDesc (\r
+    &VgpuDev->Ring,\r
+    RequestDeviceAddress,\r
+    (UINT32)RequestSize,\r
+    VRING_DESC_F_NEXT,\r
+    &Indices\r
+    );\r
+  VirtioAppendDesc (\r
+    &VgpuDev->Ring,\r
+    ResponseDeviceAddress,\r
+    (UINT32)sizeof Response,\r
+    VRING_DESC_F_WRITE,\r
+    &Indices\r
+    );\r
 \r
   //\r
   // Send the command.\r
@@ -327,18 +368,36 @@ VirtioGpuSendCommand (
   Status = VirtioFlush (VgpuDev->VirtIo, VIRTIO_GPU_CONTROL_QUEUE,\r
              &VgpuDev->Ring, &Indices, &ResponseSize);\r
   if (EFI_ERROR (Status)) {\r
-    return Status;\r
+    goto UnmapResponse;\r
   }\r
 \r
   //\r
-  // Parse the response.\r
+  // Verify response size.\r
   //\r
   if (ResponseSize != sizeof Response) {\r
     DEBUG ((EFI_D_ERROR, "%a: malformed response to Request=0x%x\n",\r
       __FUNCTION__, (UINT32)RequestType));\r
-    return EFI_PROTOCOL_ERROR;\r
+    Status = EFI_PROTOCOL_ERROR;\r
+    goto UnmapResponse;\r
   }\r
 \r
+  //\r
+  // Unmap response and request, in reverse order of mapping. On error, the\r
+  // respective mapping is invalidated anyway, only the data may not have been\r
+  // committed to system memory (in case of VirtioOperationBusMasterWrite).\r
+  //\r
+  Status = VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, ResponseMap);\r
+  if (EFI_ERROR (Status)) {\r
+    goto UnmapRequest;\r
+  }\r
+  Status = VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, RequestMap);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Parse the response.\r
+  //\r
   if (Response.Type == VirtioGpuRespOkNodata) {\r
     return EFI_SUCCESS;\r
   }\r
@@ -346,6 +405,14 @@ VirtioGpuSendCommand (
   DEBUG ((EFI_D_ERROR, "%a: Request=0x%x Response=0x%x\n", __FUNCTION__,\r
     (UINT32)RequestType, Response.Type));\r
   return EFI_DEVICE_ERROR;\r
+\r
+UnmapResponse:\r
+  VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, ResponseMap);\r
+\r
+UnmapRequest:\r
+  VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, RequestMap);\r
+\r
+  return Status;\r
 }\r
 \r
 /**\r