-/**\r
-\r
- Configure a virtio ring.\r
-\r
- This function sets up internal storage (the guest-host communication area)\r
- and lays out several "navigation" (ie. no-ownership) pointers to parts of\r
- that storage.\r
-\r
- Relevant sections from the virtio-0.9.5 spec:\r
- - 1.1 Virtqueues,\r
- - 2.3 Virtqueue Configuration.\r
-\r
- @param[in] The number of descriptors to allocate for the\r
- virtio ring, as requested by the host.\r
-\r
- @param[out] Ring The virtio ring to set up.\r
-\r
- @retval EFI_OUT_OF_RESOURCES AllocatePages() failed to allocate contiguous\r
- pages for the requested QueueSize. Fields of\r
- Ring have indeterminate value.\r
-\r
- @retval EFI_SUCCESS Allocation and setup successful. Ring->Base\r
- (and nothing else) is responsible for\r
- deallocation.\r
-\r
-**/\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-VirtioRingInit (\r
- IN UINT16 QueueSize,\r
- OUT VRING *Ring\r
- )\r
-{\r
- UINTN RingSize;\r
- volatile UINT8 *RingPagesPtr;\r
-\r
- RingSize = ALIGN_VALUE (\r
- sizeof *Ring->Desc * QueueSize +\r
- sizeof *Ring->Avail.Flags +\r
- sizeof *Ring->Avail.Idx +\r
- sizeof *Ring->Avail.Ring * QueueSize +\r
- sizeof *Ring->Avail.UsedEvent,\r
- EFI_PAGE_SIZE);\r
-\r
- RingSize += ALIGN_VALUE (\r
- sizeof *Ring->Used.Flags +\r
- sizeof *Ring->Used.Idx +\r
- sizeof *Ring->Used.UsedElem * QueueSize +\r
- sizeof *Ring->Used.AvailEvent,\r
- EFI_PAGE_SIZE);\r
-\r
- Ring->NumPages = EFI_SIZE_TO_PAGES (RingSize);\r
- Ring->Base = AllocatePages (Ring->NumPages);\r
- if (Ring->Base == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- SetMem (Ring->Base, RingSize, 0x00);\r
- RingPagesPtr = Ring->Base;\r
-\r
- Ring->Desc = (volatile VOID *) RingPagesPtr;\r
- RingPagesPtr += sizeof *Ring->Desc * QueueSize;\r
-\r
- Ring->Avail.Flags = (volatile VOID *) RingPagesPtr;\r
- RingPagesPtr += sizeof *Ring->Avail.Flags;\r
-\r
- Ring->Avail.Idx = (volatile VOID *) RingPagesPtr;\r
- RingPagesPtr += sizeof *Ring->Avail.Idx;\r
-\r
- Ring->Avail.Ring = (volatile VOID *) RingPagesPtr;\r
- RingPagesPtr += sizeof *Ring->Avail.Ring * QueueSize;\r
-\r
- Ring->Avail.UsedEvent = (volatile VOID *) RingPagesPtr;\r
- RingPagesPtr += sizeof *Ring->Avail.UsedEvent;\r
-\r
- RingPagesPtr = (volatile UINT8 *) Ring->Base +\r
- ALIGN_VALUE (RingPagesPtr - (volatile UINT8 *) Ring->Base,\r
- EFI_PAGE_SIZE);\r
-\r
- Ring->Used.Flags = (volatile VOID *) RingPagesPtr;\r
- RingPagesPtr += sizeof *Ring->Used.Flags;\r
-\r
- Ring->Used.Idx = (volatile VOID *) RingPagesPtr;\r
- RingPagesPtr += sizeof *Ring->Used.Idx;\r
-\r
- Ring->Used.UsedElem = (volatile VOID *) RingPagesPtr;\r
- RingPagesPtr += sizeof *Ring->Used.UsedElem * QueueSize;\r
-\r
- Ring->Used.AvailEvent = (volatile VOID *) RingPagesPtr;\r
- RingPagesPtr += sizeof *Ring->Used.AvailEvent;\r
-\r
- Ring->QueueSize = QueueSize;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-\r
- Tear down the internal resources of a configured virtio ring.\r
-\r
- The caller is responsible to stop the host from using this ring before\r
- invoking this function: the VSTAT_DRIVER_OK bit must be clear in\r
- VhdrDeviceStatus.\r
-\r
- @param[out] Ring The virtio ring to clean up.\r
-\r
-**/\r
-\r
-\r
-STATIC\r
-VOID\r
-EFIAPI\r
-VirtioRingUninit (\r
- IN OUT VRING *Ring\r
- )\r
-{\r
- FreePages (Ring->Base, Ring->NumPages);\r
- SetMem (Ring, sizeof *Ring, 0x00);\r
-}\r
-\r
-\r