mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-02 13:03:28 +01:00
521 lines
17 KiB
C
521 lines
17 KiB
C
/** @file
|
|
Virtio Device
|
|
|
|
DISCLAIMER: the VIRTIO_DEVICE_PROTOCOL introduced here is a work in progress,
|
|
and should not be used outside of the EDK II tree.
|
|
|
|
Copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
|
|
Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#ifndef __VIRTIO_DEVICE_H__
|
|
#define __VIRTIO_DEVICE_H__
|
|
|
|
#include <IndustryStandard/Virtio.h>
|
|
|
|
//
|
|
// VirtIo Specification Revision: Major[31:24].Minor[23:16].Revision[15:0]
|
|
//
|
|
#define VIRTIO_SPEC_REVISION(major, minor, revision) \
|
|
((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | ((revision) & 0xFFFF))
|
|
|
|
#define VIRTIO_DEVICE_PROTOCOL_GUID {\
|
|
0xfa920010, 0x6785, 0x4941, {0xb6, 0xec, 0x49, 0x8c, 0x57, 0x9f, 0x16, 0x0a }\
|
|
}
|
|
|
|
typedef struct _VIRTIO_DEVICE_PROTOCOL VIRTIO_DEVICE_PROTOCOL;
|
|
|
|
//
|
|
// VIRTIO Operation for VIRTIO_MAP_SHARED
|
|
//
|
|
typedef enum {
|
|
//
|
|
// A read operation from system memory by a bus master
|
|
//
|
|
VirtioOperationBusMasterRead,
|
|
//
|
|
// A write operation to system memory by a bus master
|
|
//
|
|
VirtioOperationBusMasterWrite,
|
|
//
|
|
// Provides both read and write access to system memory by both the
|
|
// processor and a bus master
|
|
//
|
|
VirtioOperationBusMasterCommonBuffer,
|
|
} VIRTIO_MAP_OPERATION;
|
|
|
|
/**
|
|
|
|
Read a word from the device-specific I/O region of the Virtio Header.
|
|
|
|
@param[in] This This instance of VIRTIO_DEVICE_PROTOCOL
|
|
|
|
@param[in] FieldOffset Source offset.
|
|
|
|
@param[in] FieldSize Source field size in bytes, must be in {1, 2, 4, 8}.
|
|
|
|
@param[in] BufferSize Number of bytes available in the target buffer. Must
|
|
equal FieldSize.
|
|
|
|
@param[out] Buffer Target buffer.
|
|
|
|
@retval EFI_SUCCESS The data was read successfully.
|
|
@retval EFI_UNSUPPORTED The underlying IO device doesn't support the
|
|
provided address offset and read size.
|
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
|
|
lack of resources.
|
|
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_DEVICE_READ)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
IN UINTN FieldOffset,
|
|
IN UINTN FieldSize,
|
|
IN UINTN BufferSize,
|
|
OUT VOID *Buffer
|
|
);
|
|
|
|
/**
|
|
|
|
Write a word to the device-specific I/O region of the Virtio Header.
|
|
|
|
@param[in] This This instance of VIRTIO_DEVICE_PROTOCOL
|
|
|
|
@param[in] FieldOffset Destination offset.
|
|
|
|
@param[in] FieldSize Destination field size in bytes,
|
|
must be in {1, 2, 4, 8}.
|
|
|
|
@param[out] Value Value to write.
|
|
|
|
@retval EFI_SUCCESS The data was written successfully.
|
|
@retval EFI_UNSUPPORTED The underlying IO device doesn't support the
|
|
provided address offset and write size.
|
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
|
|
lack of resources.
|
|
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_DEVICE_WRITE)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
IN UINTN FieldOffset,
|
|
IN UINTN FieldSize,
|
|
IN UINT64 Value
|
|
);
|
|
|
|
/**
|
|
Read the device features field from the Virtio Header.
|
|
|
|
@param[in] This This instance of VIRTIO_DEVICE_PROTOCOL
|
|
|
|
@param[out] DeviceFeatures The device features field.
|
|
|
|
@retval EFI_SUCCESS The data was read successfully.
|
|
@retval EFI_UNSUPPORTED The underlying IO device doesn't support the
|
|
provided address offset and read size.
|
|
@retval EFI_INVALID_PARAMETER DeviceFeatures is NULL
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_GET_DEVICE_FEATURES)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
OUT UINT64 *DeviceFeatures
|
|
);
|
|
|
|
/**
|
|
Write the guest features field in the Virtio Header.
|
|
|
|
@param[in] This This instance of VIRTIO_DEVICE_PROTOCOL
|
|
|
|
@param[in] Features The guest features field
|
|
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_SET_GUEST_FEATURES)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
IN UINT64 Features
|
|
);
|
|
|
|
/**
|
|
Write the queue address field(s) in the Virtio Header.
|
|
|
|
@param[in] This This instance of VIRTIO_DEVICE_PROTOCOL
|
|
|
|
@param[in] Ring The initialized VRING object to take the
|
|
addresses from. The caller is responsible for
|
|
ensuring that on input, all Ring->NumPages pages,
|
|
starting at Ring->Base, have been successfully
|
|
mapped with a single call to
|
|
This->MapSharedBuffer() for CommonBuffer bus
|
|
master operation.
|
|
|
|
@param[in] RingBaseShift Adding this value using UINT64 arithmetic to the
|
|
addresses found in Ring translates them from
|
|
system memory to bus addresses. The caller shall
|
|
calculate RingBaseShift as
|
|
(DeviceAddress - (UINT64)(UINTN)HostAddress),
|
|
where DeviceAddress and HostAddress (i.e.,
|
|
Ring->Base) were output and input parameters of
|
|
This->MapSharedBuffer(), respectively.
|
|
|
|
@retval EFI_SUCCESS The data was written successfully.
|
|
@retval EFI_UNSUPPORTED The underlying IO device doesn't support the
|
|
provided address offset and write size.
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_SET_QUEUE_ADDRESS)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
IN VRING *Ring,
|
|
IN UINT64 RingBaseShift
|
|
);
|
|
|
|
/**
|
|
|
|
Write the queue select field in the Virtio Header.
|
|
|
|
Writing to the queue select field sets the index of the queue to which
|
|
operations such as SetQueueAlign and GetQueueNumMax apply.
|
|
|
|
@param[in] This This instance of VIRTIO_DEVICE_PROTOCOL
|
|
|
|
@param[in] Index The index of the queue to select
|
|
|
|
@retval EFI_SUCCESS The data was written successfully.
|
|
@retval EFI_UNSUPPORTED The underlying IO device doesn't support the
|
|
provided address offset and write size.
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_SET_QUEUE_SEL)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
IN UINT16 Index
|
|
);
|
|
|
|
/**
|
|
|
|
Write the queue notify field in the Virtio Header.
|
|
|
|
@param[in] This This instance of VIRTIO_DEVICE_PROTOCOL
|
|
|
|
@param[in] Address The 32-bit Queue Notify field
|
|
|
|
@retval EFI_SUCCESS The data was written successfully.
|
|
@retval EFI_UNSUPPORTED The underlying IO device doesn't support the
|
|
provided address offset and write size.
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_SET_QUEUE_NOTIFY)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
IN UINT16 Index
|
|
);
|
|
|
|
/**
|
|
Write the queue alignment field in the Virtio Header.
|
|
|
|
The queue to which the alignment applies is selected by the Queue Select
|
|
field.
|
|
|
|
Note: This operation is not implemented by the VirtIo over PCI. The PCI
|
|
implementation of this protocol returns EFI_SUCCESS.
|
|
|
|
@param[in] This This instance of VIRTIO_DEVICE_PROTOCOL
|
|
|
|
@param[in] Alignment The alignment boundary of the Used Ring in bytes.
|
|
Must be a power of 2.
|
|
|
|
@retval EFI_SUCCESS The data was written successfully.
|
|
@retval EFI_UNSUPPORTED The underlying IO device doesn't support the
|
|
provided address offset and write size.
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_SET_QUEUE_ALIGN)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
IN UINT32 Alignment
|
|
);
|
|
|
|
/**
|
|
Write the guest page size.
|
|
|
|
Note: This operation is not implemented by the VirtIo over PCI. The PCI
|
|
implementation of this protocol returns EFI_SUCCESS.
|
|
|
|
@param[in] This This instance of VIRTIO_DEVICE_PROTOCOL
|
|
|
|
@param[in] PageSize Size of the Guest page in bytes.
|
|
Must be a power of 2.
|
|
|
|
@retval EFI_SUCCESS The data was written successfully.
|
|
@retval EFI_UNSUPPORTED The underlying IO device doesn't support the
|
|
provided address offset and write size.
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_SET_PAGE_SIZE)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
IN UINT32 PageSize
|
|
);
|
|
|
|
/**
|
|
|
|
Get the size of the virtqueue selected by the queue select field.
|
|
|
|
See Virtio spec Section 2.3
|
|
|
|
@param[in] This This instance of VIRTIO_DEVICE_PROTOCOL
|
|
|
|
@param[out] QueueNumMax The size of the virtqueue in bytes.
|
|
Always a power of 2.
|
|
|
|
@retval EFI_SUCCESS The data was read successfully.
|
|
@retval EFI_UNSUPPORTED The underlying IO device doesn't support the
|
|
provided address offset and read size.
|
|
@retval EFI_INVALID_PARAMETER QueueNumMax is NULL
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_GET_QUEUE_NUM_MAX)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
OUT UINT16 *QueueNumMax
|
|
);
|
|
|
|
/**
|
|
|
|
Write to the QueueNum field in the Virtio Header.
|
|
|
|
This function only applies to Virtio-MMIO and may be a stub for other
|
|
implementations. See Virtio Spec appendix X.
|
|
|
|
@param[in] This This instance of VIRTIO_DEVICE_PROTOCOL
|
|
|
|
@param[in] QueueSize The number of elements in the queue.
|
|
|
|
@retval EFI_SUCCESS The data was written successfully.
|
|
@retval EFI_UNSUPPORTED The underlying IO device doesn't support the
|
|
provided address offset and write size.
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_SET_QUEUE_NUM)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
IN UINT16 QueueSize
|
|
);
|
|
|
|
/**
|
|
|
|
Get the DeviceStatus field from the Virtio Header.
|
|
|
|
@param[in] This This instance of VIRTIO_DEVICE_PROTOCOL
|
|
|
|
@param[out] DeviceStatus The 8-bit value for the Device status field
|
|
|
|
@retval EFI_SUCCESS The data was read successfully.
|
|
@retval EFI_UNSUPPORTED The underlying IO device doesn't support the
|
|
provided address offset and read size.
|
|
@retval EFI_INVALID_PARAMETER DeviceStatus is NULL
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_GET_DEVICE_STATUS)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
OUT UINT8 *DeviceStatus
|
|
);
|
|
|
|
/**
|
|
|
|
Write the DeviceStatus field in the Virtio Header.
|
|
|
|
@param[in] This This instance of VIRTIO_DEVICE_PROTOCOL
|
|
|
|
@param[in] DeviceStatus The 8-bit value for the Device status field
|
|
|
|
@retval EFI_SUCCESS The data was written successfully.
|
|
@retval EFI_UNSUPPORTED The underlying IO device doesn't support the
|
|
provided address offset and write size.
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_SET_DEVICE_STATUS)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
IN UINT8 DeviceStatus
|
|
);
|
|
|
|
/**
|
|
|
|
Allocates pages that are suitable for an VirtioOperationBusMasterCommonBuffer
|
|
mapping. This means that the buffer allocated by this function supports
|
|
simultaneous access by both the processor and the bus master. The device
|
|
address that the bus master uses to access the buffer must be retrieved with
|
|
a call to VIRTIO_MAP_SHARED.
|
|
|
|
@param[in] This The protocol instance pointer.
|
|
|
|
@param[in] Pages The number of pages to allocate.
|
|
|
|
@param[in,out] HostAddress A pointer to store the system memory base
|
|
address of the allocated range.
|
|
|
|
@retval EFI_SUCCESS The requested memory pages were allocated.
|
|
@retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
|
|
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_ALLOCATE_SHARED)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
IN UINTN Pages,
|
|
IN OUT VOID **HostAddress
|
|
);
|
|
|
|
/**
|
|
Frees memory that was allocated with VIRTIO_ALLOCATE_SHARED.
|
|
|
|
@param[in] This The protocol instance pointer.
|
|
|
|
@param[in] Pages The number of pages to free.
|
|
|
|
@param[in] HostAddress The system memory base address of the allocated
|
|
range.
|
|
|
|
**/
|
|
typedef
|
|
VOID
|
|
(EFIAPI *VIRTIO_FREE_SHARED)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
IN UINTN Pages,
|
|
IN VOID *HostAddress
|
|
);
|
|
|
|
/**
|
|
Provides the virtio device address required to access system memory from a
|
|
DMA bus master.
|
|
|
|
The interface follows the same usage pattern as defined in UEFI spec 2.6
|
|
(Section 13.2 PCI Root Bridge I/O Protocol)
|
|
|
|
@param[in] This The protocol instance pointer.
|
|
|
|
@param[in] Operation Indicates if the bus master is going to
|
|
read or write to system memory.
|
|
|
|
@param[in] HostAddress The system memory address to map to shared
|
|
buffer address.
|
|
|
|
@param[in,out] NumberOfBytes On input the number of bytes to map.
|
|
On output the number of bytes that were
|
|
mapped.
|
|
|
|
@param[out] DeviceAddress The resulting shared map address for the
|
|
bus master to access the hosts HostAddress.
|
|
|
|
@param[out] Mapping A resulting token to pass to
|
|
VIRTIO_UNMAP_SHARED.
|
|
|
|
@retval EFI_SUCCESS The range was mapped for the returned
|
|
NumberOfBytes.
|
|
@retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a
|
|
common buffer.
|
|
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to
|
|
a lack of resources.
|
|
@retval EFI_DEVICE_ERROR The system hardware could not map the
|
|
requested address.
|
|
**/
|
|
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_MAP_SHARED)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
IN VIRTIO_MAP_OPERATION Operation,
|
|
IN VOID *HostAddress,
|
|
IN OUT UINTN *NumberOfBytes,
|
|
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
|
|
OUT VOID **Mapping
|
|
);
|
|
|
|
/**
|
|
Completes the VIRTIO_MAP_SHARED operation and releases any corresponding
|
|
resources.
|
|
|
|
@param[in] This The protocol instance pointer.
|
|
|
|
@param[in] Mapping The mapping token returned from
|
|
VIRTIO_MAP_SHARED.
|
|
|
|
@retval EFI_SUCCESS The range was unmapped.
|
|
@retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by
|
|
VIRTIO_MAP_SHARED. Passing an invalid Mapping
|
|
token can cause undefined behavior.
|
|
@retval EFI_DEVICE_ERROR The data was not committed to the target
|
|
system memory.
|
|
**/
|
|
typedef
|
|
EFI_STATUS
|
|
(EFIAPI *VIRTIO_UNMAP_SHARED)(
|
|
IN VIRTIO_DEVICE_PROTOCOL *This,
|
|
IN VOID *Mapping
|
|
);
|
|
|
|
///
|
|
/// This protocol provides an abstraction over the VirtIo transport layer
|
|
///
|
|
/// DISCLAIMER: this protocol is a work in progress, and should not be used
|
|
/// outside of the EDK II tree.
|
|
///
|
|
struct _VIRTIO_DEVICE_PROTOCOL {
|
|
//
|
|
// VirtIo Specification Revision encoded with VIRTIO_SPEC_REVISION()
|
|
//
|
|
UINT32 Revision;
|
|
//
|
|
// From the Virtio Spec
|
|
//
|
|
INT32 SubSystemDeviceId;
|
|
|
|
VIRTIO_GET_DEVICE_FEATURES GetDeviceFeatures;
|
|
VIRTIO_SET_GUEST_FEATURES SetGuestFeatures;
|
|
|
|
VIRTIO_SET_QUEUE_ADDRESS SetQueueAddress;
|
|
|
|
VIRTIO_SET_QUEUE_SEL SetQueueSel;
|
|
|
|
VIRTIO_SET_QUEUE_NOTIFY SetQueueNotify;
|
|
|
|
VIRTIO_SET_QUEUE_ALIGN SetQueueAlign;
|
|
VIRTIO_SET_PAGE_SIZE SetPageSize;
|
|
|
|
VIRTIO_GET_QUEUE_NUM_MAX GetQueueNumMax;
|
|
VIRTIO_SET_QUEUE_NUM SetQueueNum;
|
|
|
|
VIRTIO_GET_DEVICE_STATUS GetDeviceStatus;
|
|
VIRTIO_SET_DEVICE_STATUS SetDeviceStatus;
|
|
|
|
//
|
|
// Functions to read/write Device Specific headers
|
|
//
|
|
VIRTIO_DEVICE_WRITE WriteDevice;
|
|
VIRTIO_DEVICE_READ ReadDevice;
|
|
|
|
//
|
|
// Functions to allocate, free, map and unmap shared buffer
|
|
//
|
|
VIRTIO_ALLOCATE_SHARED AllocateSharedPages;
|
|
VIRTIO_FREE_SHARED FreeSharedPages;
|
|
VIRTIO_MAP_SHARED MapSharedBuffer;
|
|
VIRTIO_UNMAP_SHARED UnmapSharedBuffer;
|
|
};
|
|
|
|
extern EFI_GUID gVirtioDeviceProtocolGuid;
|
|
|
|
#endif
|