123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850 |
- /** @file
- VirtIo GPU initialization, and commands (primitives) for the GPU device.
- Copyright (C) 2016, Red Hat, Inc.
- Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #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;
- UINT64 RingBaseShift;
- //
- // 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 | VIRTIO_F_IOMMU_PLATFORM;
- //
- // ... 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 (VgpuDev->VirtIo, QueueSize, &VgpuDev->Ring);
- if (EFI_ERROR (Status)) {
- goto Failed;
- }
- //
- // If anything fails from here on, we have to release the ring.
- //
- Status = VirtioRingMap (
- VgpuDev->VirtIo,
- &VgpuDev->Ring,
- &RingBaseShift,
- &VgpuDev->RingMap
- );
- if (EFI_ERROR (Status)) {
- goto ReleaseQueue;
- }
- //
- // If anything fails from here on, we have to unmap the ring.
- //
- Status = VgpuDev->VirtIo->SetQueueAddress (
- VgpuDev->VirtIo,
- &VgpuDev->Ring,
- RingBaseShift
- );
- if (EFI_ERROR (Status)) {
- goto UnmapQueue;
- }
- //
- // 8. Set the DRIVER_OK status bit.
- //
- NextDevStat |= VSTAT_DRIVER_OK;
- Status = VgpuDev->VirtIo->SetDeviceStatus (VgpuDev->VirtIo, NextDevStat);
- if (EFI_ERROR (Status)) {
- goto UnmapQueue;
- }
- return EFI_SUCCESS;
- UnmapQueue:
- VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, VgpuDev->RingMap);
- ReleaseQueue:
- VirtioRingUninit (VgpuDev->VirtIo, &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);
- VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, VgpuDev->RingMap);
- VirtioRingUninit (VgpuDev->VirtIo, &VgpuDev->Ring);
- }
- /**
- Allocate, zero and map memory, for bus master common buffer operation, to be
- attached as backing store to a host-side VirtIo GPU resource.
- @param[in] VgpuDev The VGPU_DEV object that represents the VirtIo GPU
- device.
- @param[in] NumberOfPages The number of whole pages to allocate and map.
- @param[out] HostAddress The system memory address of the allocated area.
- @param[out] DeviceAddress The bus master device address of the allocated
- area. The VirtIo GPU device may be programmed to
- access the allocated area through DeviceAddress;
- DeviceAddress is to be passed to the
- VirtioGpuResourceAttachBacking() function, as the
- BackingStoreDeviceAddress parameter.
- @param[out] Mapping A resulting token to pass to
- VirtioGpuUnmapAndFreeBackingStore().
- @retval EFI_SUCCESS The requested number of pages has been allocated, zeroed
- and mapped.
- @return Status codes propagated from
- VgpuDev->VirtIo->AllocateSharedPages() and
- VirtioMapAllBytesInSharedBuffer().
- **/
- EFI_STATUS
- VirtioGpuAllocateZeroAndMapBackingStore (
- IN VGPU_DEV *VgpuDev,
- IN UINTN NumberOfPages,
- OUT VOID **HostAddress,
- OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
- OUT VOID **Mapping
- )
- {
- EFI_STATUS Status;
- VOID *NewHostAddress;
- Status = VgpuDev->VirtIo->AllocateSharedPages (
- VgpuDev->VirtIo,
- NumberOfPages,
- &NewHostAddress
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Avoid exposing stale data to the device even temporarily: zero the area
- // before mapping it.
- //
- ZeroMem (NewHostAddress, EFI_PAGES_TO_SIZE (NumberOfPages));
- Status = VirtioMapAllBytesInSharedBuffer (
- VgpuDev->VirtIo, // VirtIo
- VirtioOperationBusMasterCommonBuffer, // Operation
- NewHostAddress, // HostAddress
- EFI_PAGES_TO_SIZE (NumberOfPages), // NumberOfBytes
- DeviceAddress, // DeviceAddress
- Mapping // Mapping
- );
- if (EFI_ERROR (Status)) {
- goto FreeSharedPages;
- }
- *HostAddress = NewHostAddress;
- return EFI_SUCCESS;
- FreeSharedPages:
- VgpuDev->VirtIo->FreeSharedPages (
- VgpuDev->VirtIo,
- NumberOfPages,
- NewHostAddress
- );
- return Status;
- }
- /**
- Unmap and free memory originally allocated and mapped with
- VirtioGpuAllocateZeroAndMapBackingStore().
- If the memory allocated and mapped with
- VirtioGpuAllocateZeroAndMapBackingStore() was attached to a host-side VirtIo
- GPU resource with VirtioGpuResourceAttachBacking(), then the caller is
- responsible for detaching the backing store from the same resource, with
- VirtioGpuResourceDetachBacking(), before calling this function.
- @param[in] VgpuDev The VGPU_DEV object that represents the VirtIo GPU
- device.
- @param[in] NumberOfPages The NumberOfPages parameter originally passed to
- VirtioGpuAllocateZeroAndMapBackingStore().
- @param[in] HostAddress The HostAddress value originally output by
- VirtioGpuAllocateZeroAndMapBackingStore().
- @param[in] Mapping The token that was originally output by
- VirtioGpuAllocateZeroAndMapBackingStore().
- **/
- VOID
- VirtioGpuUnmapAndFreeBackingStore (
- IN VGPU_DEV *VgpuDev,
- IN UINTN NumberOfPages,
- IN VOID *HostAddress,
- IN VOID *Mapping
- )
- {
- VgpuDev->VirtIo->UnmapSharedBuffer (
- VgpuDev->VirtIo,
- Mapping
- );
- VgpuDev->VirtIo->FreeSharedPages (
- VgpuDev->VirtIo,
- NumberOfPages,
- HostAddress
- );
- }
- /**
- 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;
- DEBUG ((DEBUG_VERBOSE, "%a: Context=0x%p\n", __FUNCTION__, Context));
- 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.
- @param[in] ResponseType The type of the response (VirtioGpuResp*).
- @param[in,out] Response Pointer to the caller-allocated response object. The
- request must start with VIRTIO_GPU_CONTROL_HEADER.
- @param[in] ResponseSize Size of the entire caller-allocated response 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 DEBUG_ERROR level.
- @return Codes for unexpected errors in VirtIo
- messaging, or request/response
- mapping/unmapping.
- **/
- STATIC
- EFI_STATUS
- VirtioGpuSendCommandWithReply (
- 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,
- IN VIRTIO_GPU_CONTROL_TYPE ResponseType,
- IN OUT volatile VIRTIO_GPU_CONTROL_HEADER *Response,
- IN UINTN ResponseSize
- )
- {
- DESC_INDICES Indices;
- EFI_STATUS Status;
- UINT32 ResponseSizeRet;
- EFI_PHYSICAL_ADDRESS RequestDeviceAddress;
- VOID *RequestMap;
- EFI_PHYSICAL_ADDRESS ResponseDeviceAddress;
- VOID *ResponseMap;
- //
- // 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);
- //
- // 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,
- ResponseSize,
- &ResponseDeviceAddress,
- &ResponseMap
- );
- if (EFI_ERROR (Status)) {
- goto UnmapRequest;
- }
- //
- // Compose the descriptor chain.
- //
- VirtioPrepare (&VgpuDev->Ring, &Indices);
- VirtioAppendDesc (
- &VgpuDev->Ring,
- RequestDeviceAddress,
- (UINT32)RequestSize,
- VRING_DESC_F_NEXT,
- &Indices
- );
- VirtioAppendDesc (
- &VgpuDev->Ring,
- ResponseDeviceAddress,
- (UINT32)ResponseSize,
- VRING_DESC_F_WRITE,
- &Indices
- );
- //
- // Send the command.
- //
- Status = VirtioFlush (
- VgpuDev->VirtIo,
- VIRTIO_GPU_CONTROL_QUEUE,
- &VgpuDev->Ring,
- &Indices,
- &ResponseSizeRet
- );
- if (EFI_ERROR (Status)) {
- goto UnmapResponse;
- }
- //
- // Verify response size.
- //
- if (ResponseSize != ResponseSizeRet) {
- DEBUG ((
- DEBUG_ERROR,
- "%a: malformed response to Request=0x%x\n",
- __FUNCTION__,
- (UINT32)RequestType
- ));
- 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 == (UINT32)ResponseType) {
- return EFI_SUCCESS;
- }
- DEBUG ((
- DEBUG_ERROR,
- "%a: Request=0x%x Response=0x%x (expected 0x%x)\n",
- __FUNCTION__,
- (UINT32)RequestType,
- Response->Type,
- ResponseType
- ));
- return EFI_DEVICE_ERROR;
- UnmapResponse:
- VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, ResponseMap);
- UnmapRequest:
- VgpuDev->VirtIo->UnmapSharedBuffer (VgpuDev->VirtIo, RequestMap);
- return Status;
- }
- /**
- Simplified version of VirtioGpuSendCommandWithReply() for commands
- which do not send back any data.
- **/
- 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
- )
- {
- volatile VIRTIO_GPU_CONTROL_HEADER Response;
- return VirtioGpuSendCommandWithReply (
- VgpuDev,
- RequestType,
- Fence,
- Header,
- RequestSize,
- VirtioGpuRespOkNodata,
- &Response,
- sizeof (Response)
- );
- }
- /**
- 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 DEBUG_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 EFI_PHYSICAL_ADDRESS BackingStoreDeviceAddress,
- 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 = BackingStoreDeviceAddress;
- 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
- );
- }
- EFI_STATUS
- VirtioGpuGetDisplayInfo (
- IN OUT VGPU_DEV *VgpuDev,
- volatile VIRTIO_GPU_RESP_DISPLAY_INFO *Response
- )
- {
- volatile VIRTIO_GPU_CONTROL_HEADER Request;
- return VirtioGpuSendCommandWithReply (
- VgpuDev,
- VirtioGpuCmdGetDisplayInfo,
- FALSE, // Fence
- &Request,
- sizeof Request,
- VirtioGpuRespOkDisplayInfo,
- &Response->Header,
- sizeof *Response
- );
- }
|