1 /** @file
2   Virtio Device
3 
4   DISCLAIMER: the VIRTIO_DEVICE_PROTOCOL introduced here is a work in progress,
5   and should not be used outside of the EDK II tree.
6 
7   Copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
8 
9   This program and the accompanying materials are licensed and made available
10   under the terms and conditions of the BSD License which accompanies this
11   distribution. The full text of the license may be found at
12   http://opensource.org/licenses/bsd-license.php
13 
14   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
15   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 
17 **/
18 
19 #ifndef __VIRTIO_DEVICE_H__
20 #define __VIRTIO_DEVICE_H__
21 
22 #include <IndustryStandard/Virtio.h>
23 
24 // VirtIo Specification Revision: Major[31:24].Minor[23:16].Revision[15:0
25 #define VIRTIO_SPEC_REVISION(major,minor,revision) \
26   ((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | ((revision) & 0xFFFF))
27 
28 #define VIRTIO_DEVICE_PROTOCOL_GUID { \
29   0xfa920010, 0x6785, 0x4941, {0xb6, 0xec, 0x49, 0x8c, 0x57, 0x9f, 0x16, 0x0a }\
30   }
31 
32 typedef struct _VIRTIO_DEVICE_PROTOCOL  VIRTIO_DEVICE_PROTOCOL;
33 
34 /**
35 
36   Read a word from the device-specific I/O region of the Virtio Header.
37 
38   @param[in] This         This instance of VIRTIO_DEVICE_PROTOCOL
39 
40   @param[in] FieldOffset  Source offset.
41 
42   @param[in] FieldSize    Source field size in bytes, must be in {1, 2, 4, 8}.
43 
44   @param[in] BufferSize   Number of bytes available in the target buffer. Must
45                           equal FieldSize.
46 
47   @param[out] Buffer      Target buffer.
48 
49   @retval EFI_SUCCESS           The data was read successfully.
50   @retval EFI_UNSUPPORTED       The underlying IO device doesn't support the
51                                 provided address offset and read size.
52   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a
53                                 lack of resources.
54   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
55 
56 **/
57 typedef
58 EFI_STATUS
59 (EFIAPI *VIRTIO_DEVICE_READ) (
60   IN  VIRTIO_DEVICE_PROTOCOL *This,
61   IN  UINTN                  FieldOffset,
62   IN  UINTN                  FieldSize,
63   IN  UINTN                  BufferSize,
64   OUT VOID                   *Buffer
65   );
66 
67 /**
68 
69   Write a word to the device-specific I/O region of the Virtio Header.
70 
71   @param[in] This         This instance of VIRTIO_DEVICE_PROTOCOL
72 
73   @param[in] FieldOffset  Destination offset.
74 
75   @param[in] FieldSize    Destination field size in bytes,
76                           must be in {1, 2, 4, 8}.
77 
78   @param[out] Value       Value to write.
79 
80   @retval EFI_SUCCESS           The data was written successfully.
81   @retval EFI_UNSUPPORTED       The underlying IO device doesn't support the
82                                 provided address offset and write size.
83   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a
84                                 lack of resources.
85   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
86 
87 **/
88 typedef
89 EFI_STATUS
90 (EFIAPI *VIRTIO_DEVICE_WRITE) (
91   IN VIRTIO_DEVICE_PROTOCOL *This,
92   IN UINTN                  FieldOffset,
93   IN UINTN                  FieldSize,
94   IN UINT64                 Value
95   );
96 
97 /**
98   Read the device features field from the Virtio Header.
99 
100   @param[in] This                 This instance of VIRTIO_DEVICE_PROTOCOL
101 
102   @param[out] DeviceFeatures      The device features field.
103 
104   @retval EFI_SUCCESS             The data was read successfully.
105   @retval EFI_UNSUPPORTED         The underlying IO device doesn't support the
106                                   provided address offset and read size.
107   @retval EFI_INVALID_PARAMETER   DeviceFeatures is NULL
108 **/
109 typedef
110 EFI_STATUS
111 (EFIAPI *VIRTIO_GET_DEVICE_FEATURES) (
112   IN VIRTIO_DEVICE_PROTOCOL *This,
113   OUT UINT64                *DeviceFeatures
114   );
115 
116 /**
117   Write the guest features field in the Virtio Header.
118 
119   @param[in] This         This instance of VIRTIO_DEVICE_PROTOCOL
120 
121   @param[in] Features     The guest features field
122 
123 **/
124 typedef
125 EFI_STATUS
126 (EFIAPI *VIRTIO_SET_GUEST_FEATURES) (
127   IN VIRTIO_DEVICE_PROTOCOL  *This,
128   IN UINT64                   Features
129   );
130 
131 /**
132   Write the queue address field(s) in the Virtio Header.
133 
134   @param[in] This             This instance of VIRTIO_DEVICE_PROTOCOL
135 
136   @param[in] Ring             The initialized VRING object to take the
137                               addresses from.
138 
139   @retval EFI_SUCCESS         The data was written successfully.
140   @retval EFI_UNSUPPORTED     The underlying IO device doesn't support the
141                               provided address offset and write size.
142 **/
143 typedef
144 EFI_STATUS
145 (EFIAPI *VIRTIO_SET_QUEUE_ADDRESS) (
146   IN VIRTIO_DEVICE_PROTOCOL  *This,
147   IN VRING                   *Ring
148   );
149 
150 /**
151 
152   Write the queue select field in the Virtio Header.
153 
154   Writing to the queue select field sets the index of the queue to which
155   operations such as SetQueueAlign and GetQueueNumMax apply.
156 
157   @param[in] This         This instance of VIRTIO_DEVICE_PROTOCOL
158 
159   @param[in] Index        The index of the queue to select
160 
161   @retval EFI_SUCCESS         The data was written successfully.
162   @retval EFI_UNSUPPORTED     The underlying IO device doesn't support the
163                               provided address offset and write size.
164 **/
165 typedef
166 EFI_STATUS
167 (EFIAPI *VIRTIO_SET_QUEUE_SEL) (
168   IN VIRTIO_DEVICE_PROTOCOL  *This,
169   IN UINT16                   Index
170   );
171 
172 /**
173 
174   Write the queue notify field in the Virtio Header.
175 
176   @param[in] This         This instance of VIRTIO_DEVICE_PROTOCOL
177 
178   @param[in] Address      The 32-bit Queue Notify field
179 
180   @retval EFI_SUCCESS         The data was written successfully.
181   @retval EFI_UNSUPPORTED     The underlying IO device doesn't support the
182                               provided address offset and write size.
183 **/
184 typedef
185 EFI_STATUS
186 (EFIAPI *VIRTIO_SET_QUEUE_NOTIFY) (
187   IN VIRTIO_DEVICE_PROTOCOL  *This,
188   IN UINT16                   Index
189   );
190 
191 /**
192   Write the queue alignment field in the Virtio Header.
193 
194   The queue to which the alignment applies is selected by the Queue Select
195   field.
196 
197   Note: This operation is not implemented by the VirtIo over PCI. The PCI
198   implementation of this protocol returns EFI_SUCCESS.
199 
200   @param[in] This         This instance of VIRTIO_DEVICE_PROTOCOL
201 
202   @param[in] Alignment    The alignment boundary of the Used Ring in bytes.
203                           Must be a power of 2.
204 
205   @retval EFI_SUCCESS         The data was written successfully.
206   @retval EFI_UNSUPPORTED     The underlying IO device doesn't support the
207                               provided address offset and write size.
208 **/
209 typedef
210 EFI_STATUS
211 (EFIAPI *VIRTIO_SET_QUEUE_ALIGN) (
212   IN VIRTIO_DEVICE_PROTOCOL  *This,
213   IN UINT32                   Alignment
214   );
215 
216 /**
217   Write the guest page size.
218 
219   Note: This operation is not implemented by the VirtIo over PCI. The PCI
220   implementation of this protocol returns EFI_SUCCESS.
221 
222   @param[in] This             This instance of VIRTIO_DEVICE_PROTOCOL
223 
224   @param[in] PageSize         Size of the Guest page in bytes.
225                               Must be a power of 2.
226 
227   @retval EFI_SUCCESS         The data was written successfully.
228   @retval EFI_UNSUPPORTED     The underlying IO device doesn't support the
229                               provided address offset and write size.
230 **/
231 typedef
232 EFI_STATUS
233 (EFIAPI *VIRTIO_SET_PAGE_SIZE) (
234   IN VIRTIO_DEVICE_PROTOCOL  *This,
235   IN UINT32                   PageSize
236   );
237 
238 /**
239 
240   Get the size of the virtqueue selected by the queue select field.
241 
242   See Virtio spec Section 2.3
243 
244   @param[in] This                 This instance of VIRTIO_DEVICE_PROTOCOL
245 
246   @param[out] QueueNumMax         The size of the virtqueue in bytes.
247                                   Always a power of 2.
248 
249   @retval EFI_SUCCESS             The data was read successfully.
250   @retval EFI_UNSUPPORTED         The underlying IO device doesn't support the
251                                   provided address offset and read size.
252   @retval EFI_INVALID_PARAMETER   QueueNumMax is NULL
253 **/
254 typedef
255 EFI_STATUS
256 (EFIAPI *VIRTIO_GET_QUEUE_NUM_MAX) (
257   IN  VIRTIO_DEVICE_PROTOCOL  *This,
258   OUT UINT16                  *QueueNumMax
259   );
260 
261 /**
262 
263   Write to the QueueNum field in the Virtio Header.
264 
265   This function only applies to Virtio-MMIO and may be a stub for other
266   implementations. See Virtio Spec appendix X.
267 
268   @param[in] This         This instance of VIRTIO_DEVICE_PROTOCOL
269 
270   @param[in] QueueSize    The number of elements in the queue.
271 
272   @retval EFI_SUCCESS         The data was written successfully.
273   @retval EFI_UNSUPPORTED     The underlying IO device doesn't support the
274                               provided address offset and write size.
275 **/
276 typedef
277 EFI_STATUS
278 (EFIAPI *VIRTIO_SET_QUEUE_NUM) (
279   IN VIRTIO_DEVICE_PROTOCOL  *This,
280   IN UINT16                   QueueSize
281   );
282 
283 /**
284 
285   Get the DeviceStatus field from the Virtio Header.
286 
287   @param[in] This                 This instance of VIRTIO_DEVICE_PROTOCOL
288 
289   @param[out] DeviceStatus        The 8-bit value for the Device status field
290 
291   @retval EFI_SUCCESS             The data was read successfully.
292   @retval EFI_UNSUPPORTED         The underlying IO device doesn't support the
293                                   provided address offset and read size.
294   @retval EFI_INVALID_PARAMETER   DeviceStatus is NULL
295 **/
296 typedef
297 EFI_STATUS
298 (EFIAPI *VIRTIO_GET_DEVICE_STATUS) (
299   IN  VIRTIO_DEVICE_PROTOCOL  *This,
300   OUT UINT8                   *DeviceStatus
301   );
302 
303 /**
304 
305   Write the DeviceStatus field in the Virtio Header.
306 
307   @param[in] This         This instance of VIRTIO_DEVICE_PROTOCOL
308 
309   @param[in] DeviceStatus The 8-bit value for the Device status field
310 
311   @retval EFI_SUCCESS         The data was written successfully.
312   @retval EFI_UNSUPPORTED     The underlying IO device doesn't support the
313                               provided address offset and write size.
314 **/
315 typedef
316 EFI_STATUS
317 (EFIAPI *VIRTIO_SET_DEVICE_STATUS) (
318   IN VIRTIO_DEVICE_PROTOCOL  *This,
319   IN UINT8                   DeviceStatus
320   );
321 
322 
323 ///
324 ///  This protocol provides an abstraction over the VirtIo transport layer
325 ///
326 ///  DISCLAIMER: this protocol is a work in progress, and should not be used
327 ///  outside of the EDK II tree.
328 ///
329 struct _VIRTIO_DEVICE_PROTOCOL {
330   /// VirtIo Specification Revision encoded with VIRTIO_SPEC_REVISION()
331   UINT32                      Revision;
332   /// From the Virtio Spec
333   INT32                       SubSystemDeviceId;
334 
335   VIRTIO_GET_DEVICE_FEATURES  GetDeviceFeatures;
336   VIRTIO_SET_GUEST_FEATURES   SetGuestFeatures;
337 
338   VIRTIO_SET_QUEUE_ADDRESS    SetQueueAddress;
339 
340   VIRTIO_SET_QUEUE_SEL        SetQueueSel;
341 
342   VIRTIO_SET_QUEUE_NOTIFY     SetQueueNotify;
343 
344   VIRTIO_SET_QUEUE_ALIGN      SetQueueAlign;
345   VIRTIO_SET_PAGE_SIZE        SetPageSize;
346 
347   VIRTIO_GET_QUEUE_NUM_MAX    GetQueueNumMax;
348   VIRTIO_SET_QUEUE_NUM        SetQueueNum;
349 
350   VIRTIO_GET_DEVICE_STATUS    GetDeviceStatus;
351   VIRTIO_SET_DEVICE_STATUS    SetDeviceStatus;
352 
353   // Functions to read/write Device Specific headers
354   VIRTIO_DEVICE_WRITE         WriteDevice;
355   VIRTIO_DEVICE_READ          ReadDevice;
356 };
357 
358 extern EFI_GUID gVirtioDeviceProtocolGuid;
359 
360 #endif
361