27 return Ring->Buffers + Ring->BufferSize * BufferNr;
37 return Ring->DeviceAddress + Ring->BufferSize * BufferNr;
46 return Ring->Indices.NextDescIdx % Ring->Ring.QueueSize;
65 Status = Dev->VirtIo->SetQueueSel (Dev->VirtIo, Index);
66 if (EFI_ERROR (Status)) {
70 Status = Dev->VirtIo->GetQueueNumMax (Dev->VirtIo, &QueueSize);
71 if (EFI_ERROR (Status)) {
79 Status = EFI_UNSUPPORTED;
84 if (EFI_ERROR (Status)) {
97 if (EFI_ERROR (Status)) {
105 Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
106 if (EFI_ERROR (Status)) {
110 Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
111 if (EFI_ERROR (Status)) {
118 Status = Dev->VirtIo->SetQueueAddress (
123 if (EFI_ERROR (Status)) {
127 Ring->BufferCount = QueueSize;
128 Ring->BufferSize = BufferSize;
131 Status = Dev->VirtIo->AllocateSharedPages (Dev->VirtIo, Ring->BufferPages, (VOID **)&Ring->Buffers);
132 if (EFI_ERROR (Status)) {
138 VirtioOperationBusMasterCommonBuffer,
141 &Ring->DeviceAddress,
144 if (EFI_ERROR (Status)) {
154 Dev->VirtIo->FreeSharedPages (
159 Ring->Buffers =
NULL;
162 Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Ring->RingMap);
163 Ring->RingMap =
NULL;
174VirtioSerialUninitRing (
181 if (Ring->BufferMap) {
182 Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Ring->BufferMap);
183 Ring->BufferMap =
NULL;
187 Dev->VirtIo->FreeSharedPages (
192 Ring->Buffers =
NULL;
195 if (!Ring->RingMap) {
196 Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Ring->RingMap);
197 Ring->RingMap =
NULL;
200 if (Ring->Ring.Base) {
204 ZeroMem (Ring,
sizeof (*Ring));
209VirtioSerialRingFillRx (
217 for (BufferNr = 0; BufferNr < Ring->BufferCount; BufferNr++) {
218 VirtioSerialRingSendBuffer (Dev, Index,
NULL, Ring->BufferSize,
FALSE);
221 Dev->VirtIo->SetQueueNotify (Dev->VirtIo, Index);
226VirtioSerialRingClearTx (
231 while (VirtioSerialRingGetBuffer (Dev, Index,
NULL,
NULL)) {
237VirtioSerialRingSendBuffer (
246 UINT32 BufferNr = BufferNext (Ring);
247 UINT16 Idx = *Ring->Ring.Avail.Idx;
250 ASSERT (DataSize <= Ring->BufferSize);
254 CopyMem (BufferPtr (Ring, BufferNr), Data, DataSize);
257 Flags |= VRING_DESC_F_WRITE;
262 BufferAddr (Ring, BufferNr),
268 Ring->Ring.Avail.Ring[Idx % Ring->Ring.QueueSize] =
269 Ring->Indices.HeadDescIdx % Ring->Ring.QueueSize;
270 Ring->Indices.HeadDescIdx = Ring->Indices.NextDescIdx;
274 *Ring->Ring.Avail.Idx = Idx;
278 Dev->VirtIo->SetQueueNotify (Dev->VirtIo, Index);
286VirtioSerialRingHasBuffer (
292 UINT16 UsedIdx = *Ring->Ring.Used.Idx;
298 if (Ring->LastUsedIdx == UsedIdx) {
307VirtioSerialRingGetBuffer (
315 UINT16 UsedIdx = *Ring->Ring.Used.Idx;
322 if (Ring->LastUsedIdx == UsedIdx) {
326 UsedElem = Ring->Ring.Used.UsedElem + (Ring->LastUsedIdx % Ring->Ring.QueueSize);
328 if (UsedElem->Len > Ring->BufferSize) {
329 DEBUG ((DEBUG_ERROR,
"%a:%d: %d: invalid length\n", __func__, __LINE__, Index));
333 if (Data && DataSize) {
334 CopyMem (Data, BufferPtr (Ring, UsedElem->Id), UsedElem->Len);
335 *DataSize = UsedElem->Len;
338 if (Index % 2 == 0) {
340 VirtioSerialRingSendBuffer (Dev, Index,
NULL, Ring->BufferSize,
FALSE);
VOID EFIAPI MemoryFence(VOID)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define DEBUG(Expression)
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 VirtioRingMap(IN VIRTIO_DEVICE_PROTOCOL *VirtIo, IN VRING *Ring, OUT UINT64 *RingBaseShift, OUT VOID **Mapping)
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)