1 /** @file
2 
3   Declarations of utility functions used by virtio device drivers.
4 
5   Copyright (C) 2012-2016, Red Hat, Inc.
6 
7   This program and the accompanying materials are licensed and made available
8   under the terms and conditions of the BSD License which accompanies this
9   distribution. The full text of the license may be found at
10   http://opensource.org/licenses/bsd-license.php
11 
12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
13   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 
15 **/
16 
17 #ifndef _VIRTIO_LIB_H_
18 #define _VIRTIO_LIB_H_
19 
20 #include <Protocol/VirtioDevice.h>
21 
22 #include <IndustryStandard/Virtio.h>
23 
24 
25 /**
26 
27   Configure a virtio ring.
28 
29   This function sets up internal storage (the guest-host communication area)
30   and lays out several "navigation" (ie. no-ownership) pointers to parts of
31   that storage.
32 
33   Relevant sections from the virtio-0.9.5 spec:
34   - 1.1 Virtqueues,
35   - 2.3 Virtqueue Configuration.
36 
37   @param[in]                    The number of descriptors to allocate for the
38                                 virtio ring, as requested by the host.
39 
40   @param[out] Ring              The virtio ring to set up.
41 
42   @retval EFI_OUT_OF_RESOURCES  AllocatePages() failed to allocate contiguous
43                                 pages for the requested QueueSize. Fields of
44                                 Ring have indeterminate value.
45 
46   @retval EFI_SUCCESS           Allocation and setup successful. Ring->Base
47                                 (and nothing else) is responsible for
48                                 deallocation.
49 
50 **/
51 EFI_STATUS
52 EFIAPI
53 VirtioRingInit (
54   IN  UINT16 QueueSize,
55   OUT VRING  *Ring
56   );
57 
58 
59 /**
60 
61   Tear down the internal resources of a configured virtio ring.
62 
63   The caller is responsible to stop the host from using this ring before
64   invoking this function: the VSTAT_DRIVER_OK bit must be clear in
65   VhdrDeviceStatus.
66 
67   @param[out] Ring  The virtio ring to clean up.
68 
69 **/
70 VOID
71 EFIAPI
72 VirtioRingUninit (
73   IN OUT VRING *Ring
74   );
75 
76 
77 //
78 // Internal use structure for tracking the submission of a multi-descriptor
79 // request.
80 //
81 typedef struct {
82   UINT16 HeadDescIdx;
83   UINT16 NextDescIdx;
84 } DESC_INDICES;
85 
86 
87 /**
88 
89   Turn off interrupt notifications from the host, and prepare for appending
90   multiple descriptors to the virtio ring.
91 
92   The calling driver must be in VSTAT_DRIVER_OK state.
93 
94   @param[in,out] Ring  The virtio ring we intend to append descriptors to.
95 
96   @param[out] Indices  The DESC_INDICES structure to initialize.
97 
98 **/
99 VOID
100 EFIAPI
101 VirtioPrepare (
102   IN OUT VRING        *Ring,
103   OUT    DESC_INDICES *Indices
104   );
105 
106 
107 /**
108 
109   Append a contiguous buffer for transmission / reception via the virtio ring.
110 
111   This function implements the following section from virtio-0.9.5:
112   - 2.4.1.1 Placing Buffers into the Descriptor Table
113 
114   Free space is taken as granted, since the individual drivers support only
115   synchronous requests and host side status is processed in lock-step with
116   request submission. It is the calling driver's responsibility to verify the
117   ring size in advance.
118 
119   The caller is responsible for initializing *Indices with VirtioPrepare()
120   first.
121 
122   @param[in,out] Ring        The virtio ring to append the buffer to, as a
123                              descriptor.
124 
125   @param[in] BufferPhysAddr  (Guest pseudo-physical) start address of the
126                              transmit / receive buffer.
127 
128   @param[in] BufferSize      Number of bytes to transmit or receive.
129 
130   @param[in] Flags           A bitmask of VRING_DESC_F_* flags. The caller
131                              computes this mask dependent on further buffers to
132                              append and transfer direction.
133                              VRING_DESC_F_INDIRECT is unsupported. The
134                              VRING_DESC.Next field is always set, but the host
135                              only interprets it dependent on VRING_DESC_F_NEXT.
136 
137   @param[in,out] Indices     Indices->HeadDescIdx is not accessed.
138                              On input, Indices->NextDescIdx identifies the next
139                              descriptor to carry the buffer. On output,
140                              Indices->NextDescIdx is incremented by one, modulo
141                              2^16.
142 
143 **/
144 VOID
145 EFIAPI
146 VirtioAppendDesc (
147   IN OUT VRING        *Ring,
148   IN     UINTN        BufferPhysAddr,
149   IN     UINT32       BufferSize,
150   IN     UINT16       Flags,
151   IN OUT DESC_INDICES *Indices
152   );
153 
154 
155 /**
156 
157   Notify the host about the descriptor chain just built, and wait until the
158   host processes it.
159 
160   @param[in] VirtIo       The target virtio device to notify.
161 
162   @param[in] VirtQueueId  Identifies the queue for the target device.
163 
164   @param[in,out] Ring     The virtio ring with descriptors to submit.
165 
166   @param[in] Indices      Indices->NextDescIdx is not accessed.
167                           Indices->HeadDescIdx identifies the head descriptor
168                           of the descriptor chain.
169 
170   @param[out] UsedLen     On success, the total number of bytes, consecutively
171                           across the buffers linked by the descriptor chain,
172                           that the host wrote. May be NULL if the caller
173                           doesn't care, or can compute the same information
174                           from device-specific request structures linked by the
175                           descriptor chain.
176 
177   @return              Error code from VirtIo->SetQueueNotify() if it fails.
178 
179   @retval EFI_SUCCESS  Otherwise, the host processed all descriptors.
180 
181 **/
182 EFI_STATUS
183 EFIAPI
184 VirtioFlush (
185   IN     VIRTIO_DEVICE_PROTOCOL *VirtIo,
186   IN     UINT16                 VirtQueueId,
187   IN OUT VRING                  *Ring,
188   IN     DESC_INDICES           *Indices,
189   OUT    UINT32                 *UsedLen    OPTIONAL
190   );
191 
192 
193 /**
194 
195   Report the feature bits to the VirtIo 1.0 device that the VirtIo 1.0 driver
196   understands.
197 
198   In VirtIo 1.0, a device can reject a self-inconsistent feature bitmap through
199   the new VSTAT_FEATURES_OK status bit. (For example if the driver requests a
200   higher level feature but clears a prerequisite feature.) This function is a
201   small wrapper around VIRTIO_DEVICE_PROTOCOL.SetGuestFeatures() that also
202   verifies if the VirtIo 1.0 device accepts the feature bitmap.
203 
204   @param[in]     VirtIo        Report feature bits to this device.
205 
206   @param[in]     Features      The set of feature bits that the driver wishes
207                                to report. The caller is responsible to perform
208                                any masking before calling this function; the
209                                value is directly written with
210                                VIRTIO_DEVICE_PROTOCOL.SetGuestFeatures().
211 
212   @param[in,out] DeviceStatus  On input, the status byte most recently written
213                                to the device's status register. On output (even
214                                on error), DeviceStatus will be updated so that
215                                it is suitable for further status bit
216                                manipulation and writing to the device's status
217                                register.
218 
219   @retval  EFI_SUCCESS      The device accepted the configuration in Features.
220 
221   @return  EFI_UNSUPPORTED  The device rejected the configuration in Features.
222 
223   @retval  EFI_UNSUPPORTED  VirtIo->Revision is smaller than 1.0.0.
224 
225   @return                   Error codes from the SetGuestFeatures(),
226                             SetDeviceStatus(), GetDeviceStatus() member
227                             functions.
228 
229 **/
230 EFI_STATUS
231 EFIAPI
232 Virtio10WriteFeatures (
233   IN     VIRTIO_DEVICE_PROTOCOL *VirtIo,
234   IN     UINT64                 Features,
235   IN OUT UINT8                  *DeviceStatus
236   );
237 
238 #endif // _VIRTIO_LIB_H_
239