1 | /* $Id: Virtio_1_0.h 79973 2019-07-25 08:10:25Z vboxsync $ */
|
---|
2 | /** @file
|
---|
3 | * Virtio_1_0p .h - Virtio Declarations
|
---|
4 | */
|
---|
5 |
|
---|
6 | /*
|
---|
7 | * Copyright (C) 2009-2019 Oracle Corporation
|
---|
8 | *
|
---|
9 | * This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
10 | * available from http://www.virtualbox.org. This file is free software;
|
---|
11 | * you can redistribute it and/or modify it under the terms of the GNU
|
---|
12 | * General Public License (GPL) as published by the Free Software
|
---|
13 | * Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
14 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
15 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
16 | */
|
---|
17 |
|
---|
18 | #ifndef VBOX_INCLUDED_SRC_VirtIO_Virtio_1_0_h
|
---|
19 | #define VBOX_INCLUDED_SRC_VirtIO_Virtio_1_0_h
|
---|
20 | #ifndef RT_WITHOUT_PRAGMA_ONCE
|
---|
21 | # pragma once
|
---|
22 | #endif
|
---|
23 |
|
---|
24 | #include <iprt/ctype.h>
|
---|
25 |
|
---|
26 | /** @name Saved state versions.
|
---|
27 | * The saved state version is changed if either common or any of specific
|
---|
28 | * parts are changed. That is, it is perfectly possible that the version
|
---|
29 | * of saved vnet state will increase as a result of change in vblk structure
|
---|
30 | * for example.
|
---|
31 | */
|
---|
32 | #define VIRTIO_SAVEDSTATE_VERSION_3_1_BETA1 1
|
---|
33 | #define VIRTIO_SAVEDSTATE_VERSION 2
|
---|
34 | /** @} */
|
---|
35 |
|
---|
36 | /** Mandatory for Virtio PCI device identification, per spec */
|
---|
37 | #define DEVICE_PCI_VENDOR_ID_VIRTIO 0x1AF4
|
---|
38 |
|
---|
39 | /** Virtio spec suggests >= 1 for non-transitional drivers */
|
---|
40 | #define DEVICE_PCI_REVISION_ID_VIRTIO 1
|
---|
41 |
|
---|
42 | /* Virtio Device PCI Capabilities type codes */
|
---|
43 | #define VIRTIO_PCI_CAP_COMMON_CFG 1
|
---|
44 | #define VIRTIO_PCI_CAP_NOTIFY_CFG 2
|
---|
45 | #define VIRTIO_PCI_CAP_ISR_CFG 3
|
---|
46 | #define VIRTIO_PCI_CAP_DEVICE_CFG 4
|
---|
47 | #define VIRTIO_PCI_CAP_PCI_CFG 5
|
---|
48 |
|
---|
49 | /** Device Status field constants (from Virtio 1.0 spec) */
|
---|
50 | #define VIRTIO_STATUS_ACKNOWLEDGE 0x01 /** Guest found this emulated PCI device */
|
---|
51 | #define VIRTIO_STATUS_DRIVER 0x02 /** Guest can drive this PCI device */
|
---|
52 | #define VIRTIO_STATUS_DRIVER_OK 0x04 /** Guest VirtIO driver setup and ready */
|
---|
53 | #define VIRTIO_STATUS_FEATURES_OK 0x08 /** Guest says feature negotiation complete */
|
---|
54 | #define VIRTIO_STATUS_FAILED 0x80 /** Fatal: Something wrong, guest gave up */
|
---|
55 | #define VIRTIO_STATUS_DEVICE_NEEDS_RESET 0x40 /** Device experienced unrecoverable error */
|
---|
56 |
|
---|
57 |
|
---|
58 | #define VIRTIO_MAX_NQUEUES 256 /** Max queues we allow guest to create */
|
---|
59 | #define VIRTQUEUEDESC_MAX_SIZE (2 * 1024 * 1024) /** Legacy only? */
|
---|
60 | #define VIRTQUEUE_MAX_SIZE 1024 /** According to? Legacy only? */
|
---|
61 | #define VIRTIO_ISR_QUEUE 0x1 /* Legacy only? Now derived from feature negotiation? */
|
---|
62 | #define VIRTIO_ISR_CONFIG 0x3 /* Legacy only? Now derived from feature negotiation? */
|
---|
63 |
|
---|
64 | #define VIRTIO_PCI_CAP_ID_VENDOR 0x09
|
---|
65 |
|
---|
66 | /* Vector value used to disable MSI for queue */
|
---|
67 | #define VIRTIO_MSI_NO_VECTOR 0xffff
|
---|
68 |
|
---|
69 | typedef DECLCALLBACK(uint32_t) FNGETHOSTFEATURES(void *pvState);
|
---|
70 | typedef FNGETHOSTFEATURES *PFNGETHOSTFEATURES;
|
---|
71 |
|
---|
72 | /** @name VirtIO port I/O callbacks.
|
---|
73 | * @{ */
|
---|
74 | typedef struct VIRTIOIOCALLBACKS
|
---|
75 | {
|
---|
76 | DECLCALLBACKMEMBER(uint32_t, pfnGetHostFeatures)(void *pvState);
|
---|
77 | DECLCALLBACKMEMBER(uint32_t, pfnGetHostMinimalFeatures)(void *pvState);
|
---|
78 | DECLCALLBACKMEMBER(void, pfnSetHostFeatures)(void *pvState, uint32_t fFeatures);
|
---|
79 | DECLCALLBACKMEMBER(int, pfnGetConfig)(void *pvState, uint32_t offCfg, uint32_t cb, void *pvData);
|
---|
80 | DECLCALLBACKMEMBER(int, pfnSetConfig)(void *pvState, uint32_t offCfg, uint32_t cb, void *pvData);
|
---|
81 | DECLCALLBACKMEMBER(int, pfnReset)(void *pvState);
|
---|
82 | DECLCALLBACKMEMBER(void, pfnReady)(void *pvState);
|
---|
83 | } VIRTIOIOCALLBACKS;
|
---|
84 | /** Pointer to a const VirtIO port I/O callback structure. */
|
---|
85 | typedef const VIRTIOIOCALLBACKS *PCVIRTIOIOCALLBACKS;
|
---|
86 | /** @} */
|
---|
87 |
|
---|
88 |
|
---|
89 | /** Most of the following definitions attempt to adhere to the names and
|
---|
90 | * and forms used by the VirtIO 1.0 specification to increase the maintainability
|
---|
91 | * and speed of ramp-up, in other words, to as unambiguously as possible
|
---|
92 | * map the spec to the VirtualBox implementation of it */
|
---|
93 |
|
---|
94 | /** Indicates that this descriptor chains to another */
|
---|
95 | #define VIRTQ_DESC_F_NEXT 1
|
---|
96 |
|
---|
97 | /** Marks buffer as write-only (default ro) */
|
---|
98 | #define VIRTQ_DESC_F_WRITE 2
|
---|
99 |
|
---|
100 | /** This means the buffer contains a list of buffer descriptors. */
|
---|
101 | #define VIRTQ_DESC_F_INDIRECT 4
|
---|
102 |
|
---|
103 | /** Optimization: Device advises driver (unreliably): Don't kick me when adding buffer */
|
---|
104 | #define VIRTQ_USED_F_NO_NOTIFY 1
|
---|
105 |
|
---|
106 | /** Optimization: Driver advises device (unreliably): Don't interrupt when buffer consumed */
|
---|
107 | #define VIRTQ_AVAIL_F_NO_INTERRUPT 1
|
---|
108 |
|
---|
109 | /** Using indirect descriptors */
|
---|
110 | #define VIRTIO_F_INDIRECT_DESC 28
|
---|
111 |
|
---|
112 | /** Indicates either avail_event, or used_event fields are in play */
|
---|
113 | #define VIRTIO_F_EVENT_IDX 29
|
---|
114 |
|
---|
115 | /** Allow aribtary descriptor layouts */
|
---|
116 | #define VIRTIO_F_ANY_LAYOUT 27
|
---|
117 |
|
---|
118 | typedef struct VIRTIOPCIPARAMS
|
---|
119 | {
|
---|
120 | uint16_t uDeviceId;
|
---|
121 | uint16_t uClassBase;
|
---|
122 | uint16_t uClassSub;
|
---|
123 | uint16_t uClassProg;
|
---|
124 | uint16_t uSubsystemId;
|
---|
125 | uint16_t uSubsystemVendorId;
|
---|
126 | uint16_t uRevisionId;
|
---|
127 | uint16_t uInterruptLine;
|
---|
128 | uint16_t uInterruptPin;
|
---|
129 | } VIRTIOPCIPARAMS, *PVIRTIOPCIPARAMS;
|
---|
130 |
|
---|
131 | typedef struct virtio_pci_cap
|
---|
132 | {
|
---|
133 | /* All little-endian */
|
---|
134 | uint8_t uCapVndr; /** Generic PCI field: PCI_CAP_ID_VNDR */
|
---|
135 | uint8_t uCapNext; /** Generic PCI field: next ptr. */
|
---|
136 | uint8_t uCapLen; /** Generic PCI field: capability length */
|
---|
137 | uint8_t uCfgType; /** Identifies the structure. */
|
---|
138 | uint8_t uBar; /** Where to find it. */
|
---|
139 | uint8_t uPadding[3]; /** Pad to full dword. */
|
---|
140 | uint32_t uOffset; /** Offset within bar. (L.E.) */
|
---|
141 | uint32_t uLength; /** Length of struct, in bytes. (L.E.) */
|
---|
142 | } VIRTIOPCICAP, *PVIRTIOPCICAP;
|
---|
143 |
|
---|
144 | typedef struct virtio_pci_common_cfg /* VirtIO 1.0 specification name of this struct */
|
---|
145 | {
|
---|
146 | /**
|
---|
147 | *
|
---|
148 | * RW = driver (guest) writes value into this field.
|
---|
149 | * RO = device (host) writes value into this field.
|
---|
150 | */
|
---|
151 |
|
---|
152 | /* Per device fields */
|
---|
153 | uint32_t uDeviceFeatureSelect; /** RW (driver selects device features) */
|
---|
154 | uint32_t uDeviceFeature; /** RO (device reports features to driver) */
|
---|
155 | uint32_t uDriverFeatureSelect; /** RW (driver selects driver features) */
|
---|
156 | uint32_t uDriverFeature; /** RW (driver accepts device features) */
|
---|
157 | uint16_t uMsixConfig; /** RW (driver sets MSI-X config vector) */
|
---|
158 | uint16_t uNumQueues; /** RO (device specifies max queues) */
|
---|
159 | uint8_t uDeviceStatus; /** RW (driver writes device status, 0 resets) */
|
---|
160 | uint8_t uConfigGeneration; /** RO (device changes when changing configs) */
|
---|
161 |
|
---|
162 | /* Per virtqueue fields (as determined by uQueueSelect) */
|
---|
163 | uint16_t uQueueSelect; /** RW (selects queue focus for these fields) */
|
---|
164 | uint16_t uQueueSize; /** RW (queue size, 0 - 2^n) */
|
---|
165 | uint16_t uQueueMsixVector; /** RW (driver selects MSI-X queue vector) */
|
---|
166 | uint16_t uQueueEnable; /** RW (driver controls usability of queue) */
|
---|
167 | uint16_t uQueueNotifyOff; /** RO (offset to virtqueue; see spec) */
|
---|
168 | uint64_t uQueueDesc; /** RW (driver writes desc table phys addr) */
|
---|
169 | uint64_t uQueueAvail; /** RW (driver writes avail ring phys addr) */
|
---|
170 | uint64_t uQueueUsed; /** RW (driver writes used ring phys addr) */
|
---|
171 | } VIRTIOCOMMONCFG, *PVIRTIOCOMMONCFG;
|
---|
172 |
|
---|
173 | typedef struct virtio_pci_notify_cap
|
---|
174 | {
|
---|
175 | struct virtio_pci_cap cap;
|
---|
176 | uint32_t uNotifyOffMultiplier; /* notify_off_multiplier */
|
---|
177 | } VIRTIONOTIFYCAP, *PVIRTIONOTIFYCAP;
|
---|
178 |
|
---|
179 | typedef uint8_t VIRTIOISRCAP, *PVIRTIOISRCAP;
|
---|
180 |
|
---|
181 | /* Device-specific configuration (if any) ... T.B.D. (if and when neeed), provide an
|
---|
182 | * interface/callback that lets the client of this code manage it, if and when needed.
|
---|
183 | * probably just passing in a struct length and a callback from our capabilities
|
---|
184 | * region handler */
|
---|
185 | typedef struct virtio_pci_dev_cfg
|
---|
186 | {
|
---|
187 | } VIRTIODEVCAP, *PVIRTIODEVCAP;
|
---|
188 |
|
---|
189 | typedef struct virtio_pci_cfg_cap {
|
---|
190 | struct virtio_pci_cap cap;
|
---|
191 | uint8_t pci_cfg_data[4]; /* Data for BAR access. */
|
---|
192 | } VIRTIOPCICFGCAP, *PVIRTIOPCICFGCAP;
|
---|
193 |
|
---|
194 | typedef struct virtq_desc /* VirtIO 1.0 specification formal name of this struct */
|
---|
195 | {
|
---|
196 | uint64_t pGcPhysBuf; /** addr GC physical address of buffer */
|
---|
197 | uint32_t cbBuf; /** len Buffer length */
|
---|
198 | uint16_t fFlags; /** flags Buffer specific flags */
|
---|
199 | uint16_t uNext; /** next Chain idx if VIRTIO_DESC_F_NEXT */
|
---|
200 | } VIRTQUEUEDESC, *PVIRTQUEUEDESC;
|
---|
201 |
|
---|
202 | typedef struct virtq_avail /* VirtIO 1.0 specification formal name of this struct */
|
---|
203 | {
|
---|
204 | uint16_t fFlags; /** flags avail ring guest-to-host flags */
|
---|
205 | uint16_t uIdx; /** idx Index of next free ring slot */
|
---|
206 | uint16_t auRing[1]; /** ring Ring: avail guest-to-host bufs */
|
---|
207 | uint16_t uUsedEventIdx; /** used_event (if VIRTQ_USED_F_NO_NOTIFY) */
|
---|
208 | } VIRTQUEUEAVAIL, *PVIRTQUEUEAVAIL;
|
---|
209 |
|
---|
210 | typedef struct virtq_used_elem /* VirtIO 1.0 specification formal name of this struct */
|
---|
211 | {
|
---|
212 | uint32_t uIdx; /** idx Start of used descriptor chain */
|
---|
213 | uint32_t cbElem; /** len Total len of used desc chain */
|
---|
214 | } VIRTQUEUEUSEDELEM;
|
---|
215 |
|
---|
216 | typedef struct virt_used /* VirtIO 1.0 specification formal name of this struct */
|
---|
217 | {
|
---|
218 | uint16_t fFlags; /** flags used ring host-to-guest flags */
|
---|
219 | uint16_t uIdx; /** idx Index of next ring slot */
|
---|
220 | VIRTQUEUEUSEDELEM aRing[1]; /** ring Ring: used host-to-guest bufs */
|
---|
221 | uint16_t uAvailEventIdx; /** avail_event if (VIRTQ_USED_F_NO_NOTIFY) */
|
---|
222 | } VIRTQUEUEUSED, *PVIRTQUEUEUSED;
|
---|
223 |
|
---|
224 |
|
---|
225 | typedef struct virtq
|
---|
226 | {
|
---|
227 | uint16_t cbQueue; /** virtq size */
|
---|
228 | uint16_t padding[3]; /** 64-bit-align phys ptrs to start of struct */
|
---|
229 | RTGCPHYS pGcPhysVirtqDescriptors; /** (struct virtq_desc *) */
|
---|
230 | RTGCPHYS pGcPhysVirtqAvail; /** (struct virtq_avail *) */
|
---|
231 | RTGCPHYS pGcPhysVirtqUsed; /** (struct virtq_used *) */
|
---|
232 | } VIRTQUEUE, *PVIRTQUEUE;
|
---|
233 |
|
---|
234 | /**
|
---|
235 | * Queue callback (consumer?).
|
---|
236 | *
|
---|
237 | * @param pvState Pointer to the VirtIO PCI core state, VIRTIOSTATE.
|
---|
238 | * @param pQueue Pointer to the queue structure.
|
---|
239 | */
|
---|
240 | typedef DECLCALLBACK(void) FNVIRTIOQUEUECALLBACK(void *pvState, struct VQueue *pQueue);
|
---|
241 | /** Pointer to a VQUEUE callback function. */
|
---|
242 | typedef FNVIRTIOQUEUECALLBACK *PFNVIRTIOQUEUECALLBACK;
|
---|
243 |
|
---|
244 | //PCIDevGetCapabilityList
|
---|
245 | //PCIDevSetCapabilityList
|
---|
246 | //DECLINLINE(void) PDMPciDevSetCapabilityList(PPDMPCIDEV pPciDev, uint8_t u8Offset)
|
---|
247 | // PDMPciDevSetByte(pPciDev, VBOX_PCI_CAPABILITY_LIST, u8Offset);
|
---|
248 | //DECLINLINE(uint8_t) PDMPciDevGetCapabilityList(PPDMPCIDEV pPciDev)
|
---|
249 | // return PDMPciDevGetByte(pPciDev, VBOX_PCI_CAPABILITY_LIST);
|
---|
250 |
|
---|
251 | typedef struct VQueue
|
---|
252 | {
|
---|
253 | VIRTQUEUE VirtQueue;
|
---|
254 | uint16_t uNextAvailIndex;
|
---|
255 | uint16_t uNextUsedIndex;
|
---|
256 | uint32_t uPageNumber;
|
---|
257 | R3PTRTYPE(PFNVIRTIOQUEUECALLBACK) pfnCallback;
|
---|
258 | R3PTRTYPE(const char *) pcszName;
|
---|
259 | } VQUEUE;
|
---|
260 | typedef VQUEUE *PVQUEUE;
|
---|
261 |
|
---|
262 | typedef struct VQueueElemSeg
|
---|
263 | {
|
---|
264 | RTGCPHYS addr;
|
---|
265 | void *pv;
|
---|
266 | uint32_t cb;
|
---|
267 | } VQUEUESEG;
|
---|
268 |
|
---|
269 | typedef struct VQueueElem
|
---|
270 | {
|
---|
271 | uint32_t idx;
|
---|
272 | uint32_t nIn;
|
---|
273 | uint32_t nOut;
|
---|
274 | VQUEUESEG aSegsIn[VIRTQUEUE_MAX_SIZE];
|
---|
275 | VQUEUESEG aSegsOut[VIRTQUEUE_MAX_SIZE];
|
---|
276 | } VQUEUEELEM;
|
---|
277 | typedef VQUEUEELEM *PVQUEUEELEM;
|
---|
278 |
|
---|
279 |
|
---|
280 | /**
|
---|
281 | * Interface this library uses to let the client handle VirtioIO device-specific capabilities I/O
|
---|
282 | */
|
---|
283 |
|
---|
284 | typedef DECLCALLBACK(int) FNVIRTIODEVCAPWRITE(PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbWrite);
|
---|
285 | typedef FNVIRTIODEVCAPWRITE *PFNVIRTIODEVCAPWRITE;
|
---|
286 |
|
---|
287 | typedef DECLCALLBACK(int) FNVIRTIODEVCAPREAD(PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbRead);
|
---|
288 | typedef FNVIRTIODEVCAPREAD *PFNVIRTIODEVCAPREAD;
|
---|
289 |
|
---|
290 | /**
|
---|
291 | * The core (/common) state of the VirtIO PCI device
|
---|
292 | *
|
---|
293 | * @implements PDMILEDPORTS
|
---|
294 | */
|
---|
295 | typedef struct VIRTIOSTATE
|
---|
296 | {
|
---|
297 | PDMPCIDEV dev;
|
---|
298 | PDMCRITSECT cs; /**< Critical section - what is it protecting? */
|
---|
299 | /* Read-only part, never changes after initialization. */
|
---|
300 | char szInstance[8]; /**< Instance name, e.g. VNet#1. */
|
---|
301 |
|
---|
302 | #if HC_ARCH_BITS != 64
|
---|
303 | uint32_t padding1;
|
---|
304 | #endif
|
---|
305 |
|
---|
306 | /** Status LUN: Base interface. */
|
---|
307 | PDMIBASE IBase;
|
---|
308 | /** Status LUN: LED port interface. */
|
---|
309 | PDMILEDPORTS ILeds;
|
---|
310 | /** Status LUN: LED connector (peer). */
|
---|
311 | R3PTRTYPE(PPDMILEDCONNECTORS) pLedsConnector;
|
---|
312 |
|
---|
313 | PPDMDEVINSR3 pDevInsR3; /**< Device instance - R3. */
|
---|
314 | PPDMDEVINSR0 pDevInsR0; /**< Device instance - R0. */
|
---|
315 | PPDMDEVINSRC pDevInsRC; /**< Device instance - RC. */
|
---|
316 |
|
---|
317 | /** Base address of PCI capabilities */
|
---|
318 | RTGCPHYS GCPhysPciCapBase;
|
---|
319 |
|
---|
320 | VIRTIOCOMMONCFG pGcPhysVirtioCommonCfg;
|
---|
321 | VIRTIONOTIFYCAP pGcPhysVirtioNotifyCap;
|
---|
322 | VIRTIOISRCAP pGcPhysVirtioIsrCap;
|
---|
323 | VIRTIODEVCAP pGcPhysVirtioDevCap;
|
---|
324 | VIRTIOPCICFGCAP pGcPhysVirtioPciCap;
|
---|
325 |
|
---|
326 | /** Callbacks when guest driver reads or writes VirtIO device-specific capabilities(s) */
|
---|
327 |
|
---|
328 | PFNVIRTIODEVCAPWRITE pfnVirtioDevCapWrite;
|
---|
329 | PFNVIRTIODEVCAPREAD pfnVirtioDevCapRead;
|
---|
330 |
|
---|
331 | #if HC_ARCH_BITS == 64
|
---|
332 | uint32_t padding2;
|
---|
333 | #endif
|
---|
334 |
|
---|
335 | /** Base port of I/O space region. */
|
---|
336 | RTIOPORT IOPortBase;
|
---|
337 |
|
---|
338 | /* Read/write part, protected with critical section. */
|
---|
339 | /** Status LED. */
|
---|
340 | PDMLED led;
|
---|
341 |
|
---|
342 | uint32_t uGuestFeatures;
|
---|
343 | uint16_t uQueueSelector; /**< An index in aQueues array. */
|
---|
344 | uint8_t uStatus; /**< Device Status (bits are device-specific). */
|
---|
345 | uint8_t uISR; /**< Interrupt Status Register. */
|
---|
346 |
|
---|
347 | #if HC_ARCH_BITS != 64
|
---|
348 | uint32_t padding3;
|
---|
349 | #endif
|
---|
350 |
|
---|
351 | uint32_t nQueues; /**< Actual number of queues used. */
|
---|
352 | VQUEUE Queues[VIRTIO_MAX_NQUEUES];
|
---|
353 |
|
---|
354 | PVIRTIOPCICAP pCommonCfg;
|
---|
355 | PVIRTIOPCICAP pNotifyCap;
|
---|
356 | PVIRTIOPCICAP pISRCap;
|
---|
357 | PVIRTIOPCICAP pPCICfgCap;
|
---|
358 | PVIRTIOPCICAP pDeviceCap;
|
---|
359 | } VIRTIOSTATE, *PVIRTIOSTATE;
|
---|
360 |
|
---|
361 | void virtioRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta);
|
---|
362 | void *virtioQueryInterface(struct PDMIBASE *pInterface, const char *pszIID);
|
---|
363 |
|
---|
364 | int virtioIOPortIn(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port,
|
---|
365 | uint32_t *pu32, unsigned cb, PCVIRTIOIOCALLBACKS pCallbacks);
|
---|
366 |
|
---|
367 | int virtioIOPortOut(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port,
|
---|
368 | uint32_t u32, unsigned cb, PCVIRTIOIOCALLBACKS pCallbacks);
|
---|
369 |
|
---|
370 | int virtioConstruct(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, int iInstance,
|
---|
371 | PVIRTIOPCIPARAMS pPciParams, const char *pcszNameFmt,
|
---|
372 | uint32_t nQueues, uint32_t uVirtioRegion,
|
---|
373 | PFNVIRTIODEVCAPREAD devCapReadCallback, PFNVIRTIODEVCAPWRITE devCapWriteCallback,
|
---|
374 | uint16_t cbDevSpecificCap);
|
---|
375 |
|
---|
376 |
|
---|
377 | int virtioDestruct( PVIRTIOSTATE pState);
|
---|
378 | void virtioReset( PVIRTIOSTATE pState);
|
---|
379 | int virtioSaveExec( PVIRTIOSTATE pState, PSSMHANDLE pSSM);
|
---|
380 | int virtioLoadExec( PVIRTIOSTATE pState, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass, uint32_t nQueues);
|
---|
381 | void virtioSetReadLed( PVIRTIOSTATE pState, bool fOn);
|
---|
382 | void virtioSetWriteLed( PVIRTIOSTATE pState, bool fOn);
|
---|
383 | int virtioRaiseInterrupt( PVIRTIOSTATE pState, int rcBusy, uint8_t uint8_tIntCause);
|
---|
384 |
|
---|
385 | PVQUEUE virtioAddQueue( PVIRTIOSTATE pState, unsigned uSize, PFNVIRTIOQUEUECALLBACK pfnCallback, const char *pcszName);
|
---|
386 | bool virtQueueSkip( PVIRTIOSTATE pState, PVQUEUE pQueue);
|
---|
387 | bool virtQueueGet( PVIRTIOSTATE pState, PVQUEUE pQueue, PVQUEUEELEM pElem, bool fRemove = true);
|
---|
388 | void virtQueuePut( PVIRTIOSTATE pState, PVQUEUE pQueue, PVQUEUEELEM pElem, uint32_t len, uint32_t uReserved = 0);
|
---|
389 | void virtQueueNotify( PVIRTIOSTATE pState, PVQUEUE pQueue);
|
---|
390 | void virtQueueSync( PVIRTIOSTATE pState, PVQUEUE pQueue);
|
---|
391 | void vringSetNotification( PVIRTIOSTATE pState, PVIRTQUEUE pVirtQueue, bool fEnabled);
|
---|
392 |
|
---|
393 |
|
---|
394 | /*
|
---|
395 | static inline int virtq_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old_idx)
|
---|
396 | return (uint16_t)(new_idx - event_idx - 1) < (uint16_t)(new_idx - old_idx);
|
---|
397 | }
|
---|
398 | // Get location of event indices (only with VIRTIO_F_EVENT_IDX)
|
---|
399 | static inline le16 *virtq_used_event(struct virtq *vq)
|
---|
400 | {
|
---|
401 | // For backwards compat, used event index is at *end* of avail ring.
|
---|
402 | return &vq->avail->ring[vq->num];
|
---|
403 | }
|
---|
404 | static inline le16 *virtq_avail_event(struct virtq *vq)
|
---|
405 | {
|
---|
406 | // For backwards compat, avail event index is at *end* of used ring.
|
---|
407 | return (le16 *)&vq->used->ring[vq->num];
|
---|
408 | }
|
---|
409 | }
|
---|
410 | */
|
---|
411 |
|
---|
412 | DECLINLINE(uint16_t) vringReadAvail(PVIRTIOSTATE pState, PVIRTQUEUE pVirtQueue)
|
---|
413 | {
|
---|
414 | uint16_t dataWord;
|
---|
415 | PDMDevHlpPhysRead(pState->CTX_SUFF(pDevIns),
|
---|
416 | pVirtQueue->pGcPhysVirtqAvail + RT_UOFFSETOF(VIRTQUEUEAVAIL, uIdx),
|
---|
417 | &dataWord, sizeof(dataWord));
|
---|
418 | return dataWord;
|
---|
419 | }
|
---|
420 |
|
---|
421 | DECLINLINE(bool) virtQueuePeek(PVIRTIOSTATE pState, PVQUEUE pQueue, PVQUEUEELEM pElem)
|
---|
422 | {
|
---|
423 | return virtQueueGet(pState, pQueue, pElem, /* fRemove */ false);
|
---|
424 | }
|
---|
425 |
|
---|
426 | DECLINLINE(bool) virtQueueIsReady(PVIRTIOSTATE pState, PVQUEUE pQueue)
|
---|
427 | {
|
---|
428 | NOREF(pState);
|
---|
429 | return !!pQueue->VirtQueue.pGcPhysVirtqAvail;
|
---|
430 | }
|
---|
431 |
|
---|
432 | DECLINLINE(bool) virtQueueIsEmpty(PVIRTIOSTATE pState, PVQUEUE pQueue)
|
---|
433 | {
|
---|
434 | return (vringReadAvail(pState, &pQueue->VirtQueue) == pQueue->uNextAvailIndex);
|
---|
435 | }
|
---|
436 |
|
---|
437 | DECLINLINE(int) virtioLock(VIRTIOSTATE *pState, int rcBusy)
|
---|
438 | {
|
---|
439 | int rc = PDMCritSectEnter(&pState->cs, rcBusy);
|
---|
440 | return rc;
|
---|
441 | }
|
---|
442 |
|
---|
443 | DECLINLINE(void) virtioUnlock(VIRTIOSTATE *pState)
|
---|
444 | {
|
---|
445 | PDMCritSectLeave(&pState->cs);
|
---|
446 | }
|
---|
447 |
|
---|
448 | #endif /* !VBOX_INCLUDED_SRC_VirtIO_Virtio_1_0_h */
|
---|