mirror of https://github.com/acidanthera/audk.git
OvmfPkg/VirtioGpuDxe: provide functions for sending VirtIo GPU commands
In this patch we add a "workhorse" function called VirtioGpuSendCommand(), and implement seven simple RPCs atop, for the command types listed in "OvmfPkg/Include/IndustryStandard/VirtioGpu.h". These functions will be called by our EFI_GRAPHICS_OUTPUT_PROTOCOL implementation. Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Jordan Justen <jordan.l.justen@intel.com> Ref: https://tianocore.acgmultimedia.com/show_bug.cgi?id=66 Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
This commit is contained in:
parent
c5f235bbf2
commit
a66ea3b557
|
@ -14,7 +14,6 @@
|
|||
|
||||
**/
|
||||
|
||||
#include <IndustryStandard/VirtioGpu.h>
|
||||
#include <Library/VirtioLib.h>
|
||||
|
||||
#include "VirtioGpu.h"
|
||||
|
@ -212,3 +211,349 @@ VirtioGpuExitBoot (
|
|||
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);
|
||||
|
||||
//
|
||||
// Compose the descriptor chain.
|
||||
//
|
||||
VirtioPrepare (&VgpuDev->Ring, &Indices);
|
||||
VirtioAppendDesc (&VgpuDev->Ring, (UINTN)Header, 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
|
||||
);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#ifndef _VIRTIO_GPU_DXE_H_
|
||||
#define _VIRTIO_GPU_DXE_H_
|
||||
|
||||
#include <IndustryStandard/VirtioGpu.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Protocol/VirtioDevice.h>
|
||||
|
@ -58,6 +59,11 @@ typedef struct {
|
|||
//
|
||||
EFI_EVENT ExitBoot;
|
||||
|
||||
//
|
||||
// Common running counter for all VirtIo GPU requests that ask for fencing.
|
||||
//
|
||||
UINT64 FenceId;
|
||||
|
||||
//
|
||||
// The Child field references the GOP wrapper structure. If this pointer is
|
||||
// NULL, then the hybrid driver has bound (i.e., started) the
|
||||
|
@ -171,4 +177,91 @@ VirtioGpuExitBoot (
|
|||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
VirtioGpuResourceUnref (
|
||||
IN OUT VGPU_DEV *VgpuDev,
|
||||
IN UINT32 ResourceId
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
VirtioGpuResourceAttachBacking (
|
||||
IN OUT VGPU_DEV *VgpuDev,
|
||||
IN UINT32 ResourceId,
|
||||
IN VOID *FirstBackingPage,
|
||||
IN UINTN NumberOfPages
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
VirtioGpuResourceDetachBacking (
|
||||
IN OUT VGPU_DEV *VgpuDev,
|
||||
IN UINT32 ResourceId
|
||||
);
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
VirtioGpuResourceFlush (
|
||||
IN OUT VGPU_DEV *VgpuDev,
|
||||
IN UINT32 X,
|
||||
IN UINT32 Y,
|
||||
IN UINT32 Width,
|
||||
IN UINT32 Height,
|
||||
IN UINT32 ResourceId
|
||||
);
|
||||
|
||||
#endif // _VIRTIO_GPU_DXE_H_
|
||||
|
|
Loading…
Reference in New Issue