summaryrefslogtreecommitdiffstats
path: root/OvmfPkg
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2017-08-26 17:34:51 +0200
committerLaszlo Ersek <lersek@redhat.com>2017-09-01 14:28:15 +0200
commit067b648332790be91d95dd84e2549a0dfe52185a (patch)
treedffc4af45bb44a40e846fea5747cbf4eb9ba6921 /OvmfPkg
parent9bc5026c19a5b698d49c5228c70a32ea4675591a (diff)
downloadedk2-067b648332790be91d95dd84e2549a0dfe52185a.tar.gz
edk2-067b648332790be91d95dd84e2549a0dfe52185a.tar.bz2
edk2-067b648332790be91d95dd84e2549a0dfe52185a.zip
OvmfPkg/VirtioGpuDxe: map virtio GPU command objects to device addresses
Every virtio GPU command used by VirtioGpuDxe is synchronous and formatted as a two-descriptor chain: request, response. The internal workhorse function that all the command-specific functions call for such messaging is VirtioGpuSendCommand(). In VirtioGpuSendCommand(), map the request from system memory to bus master device address for BusMasterRead operation, and map the response from system memory to bus master device address for BusMasterWrite operation. Pass the bus master device addresses to VirtioAppendDesc(). (See also commit 4b725858de68, "OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to UINT64", 2017-08-23.) Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Diffstat (limited to 'OvmfPkg')
-rw-r--r--OvmfPkg/VirtioGpuDxe/Commands.c83
1 files changed, 75 insertions, 8 deletions
diff --git a/OvmfPkg/VirtioGpuDxe/Commands.c b/OvmfPkg/VirtioGpuDxe/Commands.c
index 4e19bac606..bdedea1df6 100644
--- a/OvmfPkg/VirtioGpuDxe/Commands.c
+++ b/OvmfPkg/VirtioGpuDxe/Commands.c
@@ -278,7 +278,8 @@ VirtioGpuExitBoot (
code has been logged on the EFI_D_ERROR level.
@return Codes for unexpected errors in VirtIo
- messaging.
+ messaging, or request/response
+ mapping/unmapping.
**/
STATIC
EFI_STATUS
@@ -294,6 +295,10 @@ VirtioGpuSendCommand (
volatile VIRTIO_GPU_CONTROL_HEADER Response;
EFI_STATUS Status;
UINT32 ResponseSize;
+ EFI_PHYSICAL_ADDRESS RequestDeviceAddress;
+ VOID *RequestMap;
+ EFI_PHYSICAL_ADDRESS ResponseDeviceAddress;
+ VOID *ResponseMap;
//
// Initialize Header.
@@ -313,13 +318,49 @@ VirtioGpuSendCommand (
ASSERT (RequestSize <= MAX_UINT32);
//
+ // Map request and response to bus master device addresses.
+ //
+ Status = VirtioMapAllBytesInSharedBuffer (
+ VgpuDev->VirtIo,
+ VirtioOperationBusMasterRead,
+ (VOID *)Header,
+ RequestSize,
+ &RequestDeviceAddress,
+ &RequestMap
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Status = VirtioMapAllBytesInSharedBuffer (
+ VgpuDev->VirtIo,
+ VirtioOperationBusMasterWrite,
+ (VOID *)&Response,
+ sizeof Response,
+ &ResponseDeviceAddress,
+ &ResponseMap
+ );
+ if (EFI_ERROR (Status)) {
+ goto UnmapRequest;
+ }
+
+ //
// Compose the descriptor chain.
//
VirtioPrepare (&VgpuDev->Ring, &Indices);
- VirtioAppendDesc (&VgpuDev->Ring, (UINTN)Header, (UINT32)RequestSize,
- VRING_DESC_F_NEXT, &Indices);
- VirtioAppendDesc (&VgpuDev->Ring, (UINTN)&Response, sizeof Response,
- VRING_DESC_F_WRITE, &Indices);
+ VirtioAppendDesc (
+ &VgpuDev->Ring,
+ RequestDeviceAddress,
+ (UINT32)RequestSize,
+ VRING_DESC_F_NEXT,
+ &Indices
+ );
+ VirtioAppendDesc (
+ &VgpuDev->Ring,
+ ResponseDeviceAddress,
+ (UINT32)sizeof Response,
+ VRING_DESC_F_WRITE,
+ &Indices
+ );
//
// Send the command.
@@ -327,18 +368,36 @@ VirtioGpuSendCommand (
Status = VirtioFlush (VgpuDev->VirtIo, VIRTIO_GPU_CONTROL_QUEUE,
&VgpuDev->Ring, &Indices, &ResponseSize);
if (EFI_ERROR (Status)) {
- return Status;
+ goto UnmapResponse;
}
//
- // Parse the response.
+ // Verify response size.
//
if (ResponseSize != sizeof Response) {
DEBUG ((EFI_D_ERROR, "%a: malformed response to Request=0x%x\n",
__FUNCTION__, (UINT32)RequestType));
- return EFI_PROTOCOL_ERROR;
+ Status = EFI_PROTOCOL_ERROR;
+ goto UnmapResponse;
}
+ //
+ // Unmap response and request, in reverse order of mapping. On error, the
+ // respective mapping is invalidated anyway, only the data may not have been
+ // committed to system memory (in case of VirtioOperationBusMasterWrite).
+ //
+ Status = VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, ResponseMap);
+ if (EFI_ERROR (Status)) {
+ goto UnmapRequest;
+ }
+ Status = VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, RequestMap);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Parse the response.
+ //
if (Response.Type == VirtioGpuRespOkNodata) {
return EFI_SUCCESS;
}
@@ -346,6 +405,14 @@ VirtioGpuSendCommand (
DEBUG ((EFI_D_ERROR, "%a: Request=0x%x Response=0x%x\n", __FUNCTION__,
(UINT32)RequestType, Response.Type));
return EFI_DEVICE_ERROR;
+
+UnmapResponse:
+ VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, ResponseMap);
+
+UnmapRequest:
+ VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, RequestMap);
+
+ return Status;
}
/**