57 volatile UINT8 *RingPagesPtr;
60 sizeof *Ring->Desc * QueueSize +
61 sizeof *Ring->Avail.Flags +
62 sizeof *Ring->Avail.Idx +
63 sizeof *Ring->Avail.Ring * QueueSize +
64 sizeof *Ring->Avail.UsedEvent,
69 sizeof *Ring->Used.Flags +
70 sizeof *Ring->Used.Idx +
71 sizeof *Ring->Used.UsedElem * QueueSize +
72 sizeof *Ring->Used.AvailEvent,
80 Status = VirtIo->AllocateSharedPages (
85 if (EFI_ERROR (Status)) {
89 SetMem (Ring->Base, RingSize, 0x00);
90 RingPagesPtr = Ring->Base;
92 Ring->Desc = (
volatile VOID *)RingPagesPtr;
93 RingPagesPtr +=
sizeof *Ring->Desc * QueueSize;
95 Ring->Avail.Flags = (
volatile VOID *)RingPagesPtr;
96 RingPagesPtr +=
sizeof *Ring->Avail.Flags;
98 Ring->Avail.Idx = (
volatile VOID *)RingPagesPtr;
99 RingPagesPtr +=
sizeof *Ring->Avail.Idx;
101 Ring->Avail.Ring = (
volatile VOID *)RingPagesPtr;
102 RingPagesPtr +=
sizeof *Ring->Avail.Ring * QueueSize;
104 Ring->Avail.UsedEvent = (
volatile VOID *)RingPagesPtr;
105 RingPagesPtr +=
sizeof *Ring->Avail.UsedEvent;
107 RingPagesPtr = (
volatile UINT8 *)Ring->Base +
109 RingPagesPtr - (
volatile UINT8 *)Ring->Base,
113 Ring->Used.Flags = (
volatile VOID *)RingPagesPtr;
114 RingPagesPtr +=
sizeof *Ring->Used.Flags;
116 Ring->Used.Idx = (
volatile VOID *)RingPagesPtr;
117 RingPagesPtr +=
sizeof *Ring->Used.Idx;
119 Ring->Used.UsedElem = (
volatile VOID *)RingPagesPtr;
120 RingPagesPtr +=
sizeof *Ring->Used.UsedElem * QueueSize;
122 Ring->Used.AvailEvent = (
volatile VOID *)RingPagesPtr;
123 RingPagesPtr +=
sizeof *Ring->Used.AvailEvent;
125 Ring->QueueSize = QueueSize;
149 VirtIo->FreeSharedPages (VirtIo, Ring->NumPages, Ring->Base);
150 SetMem (Ring,
sizeof *Ring, 0x00);
176 *Ring->Avail.Flags = (UINT16)VRING_AVAIL_F_NO_INTERRUPT;
184 Indices->HeadDescIdx = 0;
185 Indices->NextDescIdx = Indices->HeadDescIdx;
230 IN UINT64 BufferDeviceAddress,
231 IN UINT32 BufferSize,
238 Desc = &Ring->Desc[Indices->NextDescIdx++ % Ring->QueueSize];
239 Desc->Addr = BufferDeviceAddress;
240 Desc->Len = BufferSize;
242 Desc->Next = Indices->NextDescIdx % Ring->QueueSize;
276 IN UINT16 VirtQueueId,
279 OUT UINT32 *UsedLen OPTIONAL
285 UINTN PollPeriodUsecs;
294 NextAvailIdx = *Ring->Avail.Idx;
299 LastUsedIdx = NextAvailIdx;
300 Ring->Avail.Ring[NextAvailIdx++ % Ring->QueueSize] =
301 Indices->HeadDescIdx % Ring->QueueSize;
307 *Ring->Avail.Idx = NextAvailIdx;
314 Status = VirtIo->SetQueueNotify (VirtIo, VirtQueueId);
315 if (EFI_ERROR (Status)) {
329 while (*Ring->Used.Idx != NextAvailIdx) {
330 gBS->Stall (PollPeriodUsecs);
332 if (PollPeriodUsecs < 1024) {
333 PollPeriodUsecs *= 2;
341 if (UsedLen !=
NULL) {
344 UsedElem = &Ring->Used.UsedElem[LastUsedIdx % Ring->QueueSize];
345 ASSERT (UsedElem->Id == Indices->HeadDescIdx);
346 *UsedLen = UsedElem->Len;
394 IN OUT UINT8 *DeviceStatus
399 if (VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {
400 return EFI_UNSUPPORTED;
403 Status = VirtIo->SetGuestFeatures (VirtIo, Features);
404 if (EFI_ERROR (Status)) {
408 *DeviceStatus |= VSTAT_FEATURES_OK;
409 Status = VirtIo->SetDeviceStatus (VirtIo, *DeviceStatus);
410 if (EFI_ERROR (Status)) {
414 Status = VirtIo->GetDeviceStatus (VirtIo, DeviceStatus);
415 if (EFI_ERROR (Status)) {
419 if ((*DeviceStatus & VSTAT_FEATURES_OK) == 0) {
420 Status = EFI_UNSUPPORTED;
471 IN VIRTIO_MAP_OPERATION Operation,
472 IN VOID *HostAddress,
483 Size = NumberOfBytes;
484 Status = VirtIo->MapSharedBuffer (
492 if (EFI_ERROR (Status)) {
496 if (Size < NumberOfBytes) {
501 *DeviceAddress = PhysicalAddress;
506 VirtIo->UnmapSharedBuffer (VirtIo, MapInfo);
507 return EFI_OUT_OF_RESOURCES;
532 OUT UINT64 *RingBaseShift,
541 VirtioOperationBusMasterCommonBuffer,
547 if (EFI_ERROR (Status)) {
551 *RingBaseShift = DeviceAddress - (UINT64)(
UINTN)Ring->Base;
VOID EFIAPI MemoryFence(VOID)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
#define ALIGN_VALUE(Value, Alignment)
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_PAGES_TO_SIZE(Pages)
#define EFI_SIZE_TO_PAGES(Size)
EFI_STATUS EFIAPI VirtioMapAllBytesInSharedBuffer(IN VIRTIO_DEVICE_PROTOCOL *VirtIo, IN VIRTIO_MAP_OPERATION Operation, IN VOID *HostAddress, IN UINTN NumberOfBytes, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping)
VOID EFIAPI VirtioAppendDesc(IN OUT VRING *Ring, IN UINT64 BufferDeviceAddress, IN UINT32 BufferSize, IN UINT16 Flags, IN OUT DESC_INDICES *Indices)
EFI_STATUS EFIAPI VirtioFlush(IN VIRTIO_DEVICE_PROTOCOL *VirtIo, IN UINT16 VirtQueueId, IN OUT VRING *Ring, IN DESC_INDICES *Indices, OUT UINT32 *UsedLen OPTIONAL)
EFI_STATUS EFIAPI VirtioRingMap(IN VIRTIO_DEVICE_PROTOCOL *VirtIo, IN VRING *Ring, OUT UINT64 *RingBaseShift, OUT VOID **Mapping)
EFI_STATUS EFIAPI Virtio10WriteFeatures(IN VIRTIO_DEVICE_PROTOCOL *VirtIo, IN UINT64 Features, IN OUT UINT8 *DeviceStatus)
VOID EFIAPI VirtioPrepare(IN OUT VRING *Ring, OUT DESC_INDICES *Indices)
EFI_STATUS EFIAPI VirtioRingInit(IN VIRTIO_DEVICE_PROTOCOL *VirtIo, IN UINT16 QueueSize, OUT VRING *Ring)
VOID EFIAPI VirtioRingUninit(IN VIRTIO_DEVICE_PROTOCOL *VirtIo, IN OUT VRING *Ring)