summaryrefslogtreecommitdiff
path: root/OvmfPkg/VirtioGpuDxe/Commands.c
diff options
context:
space:
mode:
Diffstat (limited to 'OvmfPkg/VirtioGpuDxe/Commands.c')
-rw-r--r--OvmfPkg/VirtioGpuDxe/Commands.c560
1 files changed, 0 insertions, 560 deletions
diff --git a/OvmfPkg/VirtioGpuDxe/Commands.c b/OvmfPkg/VirtioGpuDxe/Commands.c
deleted file mode 100644
index 962087cfec..0000000000
--- a/OvmfPkg/VirtioGpuDxe/Commands.c
+++ /dev/null
@@ -1,560 +0,0 @@
-/** @file
-
- VirtIo GPU initialization, and commands (primitives) for the GPU device.
-
- Copyright (C) 2016, Red Hat, Inc.
-
- This program and the accompanying materials are licensed and made available
- under the terms and conditions of the BSD License which accompanies this
- distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
- WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include <Library/VirtioLib.h>
-
-#include "VirtioGpu.h"
-
-/**
- Configure the VirtIo GPU device that underlies VgpuDev.
-
- @param[in,out] VgpuDev The VGPU_DEV object to set up VirtIo messaging for.
- On input, the caller is responsible for having
- initialized VgpuDev->VirtIo. On output, VgpuDev->Ring
- has been initialized, and synchronous VirtIo GPU
- commands (primitives) can be submitted to the device.
-
- @retval EFI_SUCCESS VirtIo GPU configuration successful.
-
- @retval EFI_UNSUPPORTED The host-side configuration of the VirtIo GPU is not
- supported by this driver.
-
- @retval Error codes from underlying functions.
-**/
-EFI_STATUS
-VirtioGpuInit (
- IN OUT VGPU_DEV *VgpuDev
- )
-{
- UINT8 NextDevStat;
- EFI_STATUS Status;
- UINT64 Features;
- UINT16 QueueSize;
-
- //
- // Execute virtio-v1.0-cs04, 3.1.1 Driver Requirements: Device
- // Initialization.
- //
- // 1. Reset the device.
- //
- NextDevStat = 0;
- Status = VgpuDev->VirtIo->SetDeviceStatus (VgpuDev->VirtIo, NextDevStat);
- if (EFI_ERROR (Status)) {
- goto Failed;
- }
-
- //
- // 2. Set the ACKNOWLEDGE status bit [...]
- //
- NextDevStat |= VSTAT_ACK;
- Status = VgpuDev->VirtIo->SetDeviceStatus (VgpuDev->VirtIo, NextDevStat);
- if (EFI_ERROR (Status)) {
- goto Failed;
- }
-
- //
- // 3. Set the DRIVER status bit [...]
- //
- NextDevStat |= VSTAT_DRIVER;
- Status = VgpuDev->VirtIo->SetDeviceStatus (VgpuDev->VirtIo, NextDevStat);
- if (EFI_ERROR (Status)) {
- goto Failed;
- }
-
- //
- // 4. Read device feature bits...
- //
- Status = VgpuDev->VirtIo->GetDeviceFeatures (VgpuDev->VirtIo, &Features);
- if (EFI_ERROR (Status)) {
- goto Failed;
- }
- if ((Features & VIRTIO_F_VERSION_1) == 0) {
- Status = EFI_UNSUPPORTED;
- goto Failed;
- }
- //
- // We only want the most basic 2D features.
- //
- Features &= VIRTIO_F_VERSION_1;
-
- //
- // ... and write the subset of feature bits understood by the [...] driver to
- // the device. [...]
- // 5. Set the FEATURES_OK status bit.
- // 6. Re-read device status to ensure the FEATURES_OK bit is still set [...]
- //
- Status = Virtio10WriteFeatures (VgpuDev->VirtIo, Features, &NextDevStat);
- if (EFI_ERROR (Status)) {
- goto Failed;
- }
-
- //
- // 7. Perform device-specific setup, including discovery of virtqueues for
- // the device [...]
- //
- Status = VgpuDev->VirtIo->SetQueueSel (VgpuDev->VirtIo,
- VIRTIO_GPU_CONTROL_QUEUE);
- if (EFI_ERROR (Status)) {
- goto Failed;
- }
- Status = VgpuDev->VirtIo->GetQueueNumMax (VgpuDev->VirtIo, &QueueSize);
- if (EFI_ERROR (Status)) {
- goto Failed;
- }
-
- //
- // We implement each VirtIo GPU command that we use with two descriptors:
- // request, response.
- //
- if (QueueSize < 2) {
- Status = EFI_UNSUPPORTED;
- goto Failed;
- }
-
- //
- // [...] population of virtqueues [...]
- //
- Status = VirtioRingInit (QueueSize, &VgpuDev->Ring);
- if (EFI_ERROR (Status)) {
- goto Failed;
- }
- Status = VgpuDev->VirtIo->SetQueueAddress (VgpuDev->VirtIo, &VgpuDev->Ring);
- if (EFI_ERROR (Status)) {
- goto ReleaseQueue;
- }
-
- //
- // 8. Set the DRIVER_OK status bit.
- //
- NextDevStat |= VSTAT_DRIVER_OK;
- Status = VgpuDev->VirtIo->SetDeviceStatus (VgpuDev->VirtIo, NextDevStat);
- if (EFI_ERROR (Status)) {
- goto ReleaseQueue;
- }
-
- return EFI_SUCCESS;
-
-ReleaseQueue:
- VirtioRingUninit (&VgpuDev->Ring);
-
-Failed:
- //
- // If any of these steps go irrecoverably wrong, the driver SHOULD set the
- // FAILED status bit to indicate that it has given up on the device (it can
- // reset the device later to restart if desired). [...]
- //
- // VirtIo access failure here should not mask the original error.
- //
- NextDevStat |= VSTAT_FAILED;
- VgpuDev->VirtIo->SetDeviceStatus (VgpuDev->VirtIo, NextDevStat);
-
- return Status;
-}
-
-/**
- De-configure the VirtIo GPU device that underlies VgpuDev.
-
- @param[in,out] VgpuDev The VGPU_DEV object to tear down VirtIo messaging
- for. On input, the caller is responsible for having
- called VirtioGpuInit(). On output, VgpuDev->Ring has
- been uninitialized; VirtIo GPU commands (primitives)
- can no longer be submitted to the device.
-**/
-VOID
-VirtioGpuUninit (
- IN OUT VGPU_DEV *VgpuDev
- )
-{
- //
- // Resetting the VirtIo device makes it release its resources and forget its
- // configuration.
- //
- VgpuDev->VirtIo->SetDeviceStatus (VgpuDev->VirtIo, 0);
- VirtioRingUninit (&VgpuDev->Ring);
-}
-
-/**
- EFI_EVENT_NOTIFY function for the VGPU_DEV.ExitBoot event. It resets the
- VirtIo device, causing it to release its resources and to forget its
- configuration.
-
- This function may only be called (that is, VGPU_DEV.ExitBoot may only be
- signaled) after VirtioGpuInit() returns and before VirtioGpuUninit() is
- called.
-
- @param[in] Event Event whose notification function is being invoked.
-
- @param[in] Context Pointer to the associated VGPU_DEV object.
-**/
-VOID
-EFIAPI
-VirtioGpuExitBoot (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- VGPU_DEV *VgpuDev;
-
- VgpuDev = Context;
- VgpuDev->VirtIo->SetDeviceStatus (VgpuDev->VirtIo, 0);
-}
-
-/**
- Internal utility function that sends a request to the VirtIo GPU device
- model, awaits the answer from the host, and returns a status.
-
- @param[in,out] VgpuDev The VGPU_DEV object that represents the VirtIo GPU
- device. The caller is responsible to have
- successfully invoked VirtioGpuInit() on VgpuDev
- previously, while VirtioGpuUninit() must not have
- been called on VgpuDev.
-
- @param[in] RequestType The type of the request. The caller is responsible
- for providing a VirtioGpuCmd* RequestType which, on
- success, elicits a VirtioGpuRespOkNodata response
- from the host.
-
- @param[in] Fence Whether to enable fencing for this request. Fencing
- forces the host to complete the command before
- producing a response. If Fence is TRUE, then
- VgpuDev->FenceId is consumed, and incremented.
-
- @param[in,out] Header Pointer to the caller-allocated request object. The
- request must start with VIRTIO_GPU_CONTROL_HEADER.
- This function overwrites all fields of Header before
- submitting the request to the host:
-
- - it sets Type from RequestType,
-
- - it sets Flags and FenceId based on Fence,
-
- - it zeroes CtxId and Padding.
-
- @param[in] RequestSize Size of the entire caller-allocated request object,
- including the leading VIRTIO_GPU_CONTROL_HEADER.
-
- @retval EFI_SUCCESS Operation successful.
-
- @retval EFI_DEVICE_ERROR The host rejected the request. The host error
- code has been logged on the EFI_D_ERROR level.
-
- @return Codes for unexpected errors in VirtIo
- messaging.
-**/
-STATIC
-EFI_STATUS
-VirtioGpuSendCommand (
- IN OUT VGPU_DEV *VgpuDev,
- IN VIRTIO_GPU_CONTROL_TYPE RequestType,
- IN BOOLEAN Fence,
- IN OUT volatile VIRTIO_GPU_CONTROL_HEADER *Header,
- IN UINTN RequestSize
- )
-{
- DESC_INDICES Indices;
- volatile VIRTIO_GPU_CONTROL_HEADER Response;
- EFI_STATUS Status;
- UINT32 ResponseSize;
-
- //
- // Initialize Header.
- //
- Header->Type = RequestType;
- if (Fence) {
- Header->Flags = VIRTIO_GPU_FLAG_FENCE;
- Header->FenceId = VgpuDev->FenceId++;
- } else {
- Header->Flags = 0;
- Header->FenceId = 0;
- }
- Header->CtxId = 0;
- Header->Padding = 0;
-
- ASSERT (RequestSize >= sizeof *Header);
- ASSERT (RequestSize <= MAX_UINT32);
-
- //
- // 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);
-
- //
- // Send the command.
- //
- Status = VirtioFlush (VgpuDev->VirtIo, VIRTIO_GPU_CONTROL_QUEUE,
- &VgpuDev->Ring, &Indices, &ResponseSize);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Parse the response.
- //
- if (ResponseSize != sizeof Response) {
- DEBUG ((EFI_D_ERROR, "%a: malformed response to Request=0x%x\n",
- __FUNCTION__, (UINT32)RequestType));
- return EFI_PROTOCOL_ERROR;
- }
-
- if (Response.Type == VirtioGpuRespOkNodata) {
- return EFI_SUCCESS;
- }
-
- DEBUG ((EFI_D_ERROR, "%a: Request=0x%x Response=0x%x\n", __FUNCTION__,
- (UINT32)RequestType, Response.Type));
- return EFI_DEVICE_ERROR;
-}
-
-/**
- The following functions send requests to the VirtIo GPU device model, await
- the answer from the host, and return a status. They share the following
- interface details:
-
- @param[in,out] VgpuDev The VGPU_DEV object that represents the VirtIo GPU
- device. The caller is responsible to have
- successfully invoked VirtioGpuInit() on VgpuDev
- previously, while VirtioGpuUninit() must not have
- been called on VgpuDev.
-
- @retval EFI_INVALID_PARAMETER Invalid command-specific parameters were
- detected by this driver.
-
- @retval EFI_SUCCESS Operation successful.
-
- @retval EFI_DEVICE_ERROR The host rejected the request. The host error
- code has been logged on the EFI_D_ERROR level.
-
- @return Codes for unexpected errors in VirtIo
- messaging.
-
- For the command-specific parameters, please consult the GPU Device section of
- the VirtIo 1.0 specification (see references in
- "OvmfPkg/Include/IndustryStandard/VirtioGpu.h").
-**/
-EFI_STATUS
-VirtioGpuResourceCreate2d (
- IN OUT VGPU_DEV *VgpuDev,
- IN UINT32 ResourceId,
- IN VIRTIO_GPU_FORMATS Format,
- IN UINT32 Width,
- IN UINT32 Height
- )
-{
- volatile VIRTIO_GPU_RESOURCE_CREATE_2D Request;
-
- if (ResourceId == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- Request.ResourceId = ResourceId;
- Request.Format = (UINT32)Format;
- Request.Width = Width;
- Request.Height = Height;
-
- return VirtioGpuSendCommand (
- VgpuDev,
- VirtioGpuCmdResourceCreate2d,
- FALSE, // Fence
- &Request.Header,
- sizeof Request
- );
-}
-
-EFI_STATUS
-VirtioGpuResourceUnref (
- IN OUT VGPU_DEV *VgpuDev,
- IN UINT32 ResourceId
- )
-{
- volatile VIRTIO_GPU_RESOURCE_UNREF Request;
-
- if (ResourceId == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- Request.ResourceId = ResourceId;
- Request.Padding = 0;
-
- return VirtioGpuSendCommand (
- VgpuDev,
- VirtioGpuCmdResourceUnref,
- FALSE, // Fence
- &Request.Header,
- sizeof Request
- );
-}
-
-EFI_STATUS
-VirtioGpuResourceAttachBacking (
- IN OUT VGPU_DEV *VgpuDev,
- IN UINT32 ResourceId,
- IN VOID *FirstBackingPage,
- IN UINTN NumberOfPages
- )
-{
- volatile VIRTIO_GPU_RESOURCE_ATTACH_BACKING Request;
-
- if (ResourceId == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- Request.ResourceId = ResourceId;
- Request.NrEntries = 1;
- Request.Entry.Addr = (UINTN)FirstBackingPage;
- Request.Entry.Length = (UINT32)EFI_PAGES_TO_SIZE (NumberOfPages);
- Request.Entry.Padding = 0;
-
- return VirtioGpuSendCommand (
- VgpuDev,
- VirtioGpuCmdResourceAttachBacking,
- FALSE, // Fence
- &Request.Header,
- sizeof Request
- );
-}
-
-EFI_STATUS
-VirtioGpuResourceDetachBacking (
- IN OUT VGPU_DEV *VgpuDev,
- IN UINT32 ResourceId
- )
-{
- volatile VIRTIO_GPU_RESOURCE_DETACH_BACKING Request;
-
- if (ResourceId == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- Request.ResourceId = ResourceId;
- Request.Padding = 0;
-
- //
- // In this case, we set Fence to TRUE, because after this function returns,
- // the caller might reasonably want to repurpose the backing pages
- // immediately. Thus we should ensure that the host releases all references
- // to the backing pages before we return.
- //
- return VirtioGpuSendCommand (
- VgpuDev,
- VirtioGpuCmdResourceDetachBacking,
- TRUE, // Fence
- &Request.Header,
- sizeof Request
- );
-}
-
-EFI_STATUS
-VirtioGpuSetScanout (
- IN OUT VGPU_DEV *VgpuDev,
- IN UINT32 X,
- IN UINT32 Y,
- IN UINT32 Width,
- IN UINT32 Height,
- IN UINT32 ScanoutId,
- IN UINT32 ResourceId
- )
-{
- volatile VIRTIO_GPU_SET_SCANOUT Request;
-
- //
- // Unlike for most other commands, ResourceId=0 is valid; it
- // is used to disable a scanout.
- //
- Request.Rectangle.X = X;
- Request.Rectangle.Y = Y;
- Request.Rectangle.Width = Width;
- Request.Rectangle.Height = Height;
- Request.ScanoutId = ScanoutId;
- Request.ResourceId = ResourceId;
-
- return VirtioGpuSendCommand (
- VgpuDev,
- VirtioGpuCmdSetScanout,
- FALSE, // Fence
- &Request.Header,
- sizeof Request
- );
-}
-
-EFI_STATUS
-VirtioGpuTransferToHost2d (
- IN OUT VGPU_DEV *VgpuDev,
- IN UINT32 X,
- IN UINT32 Y,
- IN UINT32 Width,
- IN UINT32 Height,
- IN UINT64 Offset,
- IN UINT32 ResourceId
- )
-{
- volatile VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D Request;
-
- if (ResourceId == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- Request.Rectangle.X = X;
- Request.Rectangle.Y = Y;
- Request.Rectangle.Width = Width;
- Request.Rectangle.Height = Height;
- Request.Offset = Offset;
- Request.ResourceId = ResourceId;
- Request.Padding = 0;
-
- return VirtioGpuSendCommand (
- VgpuDev,
- VirtioGpuCmdTransferToHost2d,
- FALSE, // Fence
- &Request.Header,
- sizeof Request
- );
-}
-
-EFI_STATUS
-VirtioGpuResourceFlush (
- IN OUT VGPU_DEV *VgpuDev,
- IN UINT32 X,
- IN UINT32 Y,
- IN UINT32 Width,
- IN UINT32 Height,
- IN UINT32 ResourceId
- )
-{
- volatile VIRTIO_GPU_RESOURCE_FLUSH Request;
-
- if (ResourceId == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- Request.Rectangle.X = X;
- Request.Rectangle.Y = Y;
- Request.Rectangle.Width = Width;
- Request.Rectangle.Height = Height;
- Request.ResourceId = ResourceId;
- Request.Padding = 0;
-
- return VirtioGpuSendCommand (
- VgpuDev,
- VirtioGpuCmdResourceFlush,
- FALSE, // Fence
- &Request.Header,
- sizeof Request
- );
-}