VirtualBox

source: vbox/trunk/src/VBox/Devices/VirtIO/Virtio.h@ 85672

Last change on this file since 85672 was 85121, checked in by vboxsync, 4 years ago

iprt/cdefs.h: Refactored the typedef use of DECLCALLBACK as well as DECLCALLBACKMEMBER to wrap the whole expression, similar to the DECLR?CALLBACKMEMBER macros. This allows adding a throw() at the end when compiling with the VC++ compiler to indicate that the callbacks won't throw anything, so we can stop supressing the C5039 warning about passing functions that can potential throw C++ exceptions to extern C code that can't necessarily cope with such (unwind,++). Introduced a few _EX variations that allows specifying different/no calling convention too, as that's handy when dynamically resolving host APIs. Fixed numerous places missing DECLCALLBACK and such. Left two angry @todos regarding use of CreateThread. bugref:9794

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.1 KB
Line 
1/* $Id: Virtio.h 85121 2020-07-08 19:33:26Z vboxsync $ */
2/** @file
3 * Virtio.h - Virtio Declarations
4 */
5
6/*
7 * Copyright (C) 2009-2020 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_h
19#define VBOX_INCLUDED_SRC_VirtIO_Virtio_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include <iprt/types.h>
25
26
27/** Pointer to the core shared state of a VirtIO PCI device */
28typedef struct VPCISTATE *PVPCISTATE;
29/** Pointer to the core ring-3 state of a VirtIO PCI device */
30typedef struct VPCISTATER3 *PVPCISTATER3;
31/** Pointer to the core ring-0 state of a VirtIO PCI device */
32typedef struct VPCISTATER0 *PVPCISTATER0;
33/** Pointer to the core raw-mode state of a VirtIO PCI device */
34typedef struct VPCISTATERC *PVPCISTATERC;
35
36/** Pointer to the core current context state of a VirtIO PCI device */
37typedef CTX_SUFF(PVPCISTATE) PVPCISTATECC;
38/** The core current context state of a VirtIO PCI device */
39typedef struct CTX_SUFF(VPCISTATE) VPCISTATECC;
40
41
42/** @name Saved state versions.
43 * The saved state version is changed if either common or any of specific
44 * parts are changed. That is, it is perfectly possible that the version
45 * of saved vnet state will increase as a result of change in vblk structure
46 * for example.
47 */
48#define VIRTIO_SAVEDSTATE_VERSION_3_1_BETA1 1
49#define VIRTIO_SAVEDSTATE_VERSION 2
50/** @} */
51
52#define DEVICE_PCI_VENDOR_ID 0x1AF4
53#define DEVICE_PCI_BASE_ID 0x1000
54#define DEVICE_PCI_SUBSYSTEM_VENDOR_ID 0x1AF4
55#define DEVICE_PCI_SUBSYSTEM_BASE_ID 1
56
57#define VIRTIO_MAX_NQUEUES 3
58
59#define VPCI_HOST_FEATURES 0x0
60#define VPCI_GUEST_FEATURES 0x4
61#define VPCI_QUEUE_PFN 0x8
62#define VPCI_QUEUE_NUM 0xC
63#define VPCI_QUEUE_SEL 0xE
64#define VPCI_QUEUE_NOTIFY 0x10
65#define VPCI_STATUS 0x12
66#define VPCI_ISR 0x13
67#define VPCI_CONFIG 0x14
68
69#define VPCI_ISR_QUEUE 0x1
70#define VPCI_ISR_CONFIG 0x3
71
72#define VPCI_STATUS_ACK 0x01
73#define VPCI_STATUS_DRV 0x02
74#define VPCI_STATUS_DRV_OK 0x04
75#define VPCI_STATUS_FAILED 0x80
76
77#define VPCI_F_NOTIFY_ON_EMPTY UINT32_C(0x01000000)
78#define VPCI_F_ANY_LAYOUT UINT32_C(0x08000000)
79#define VPCI_F_RING_INDIRECT_DESC UINT32_C(0x10000000)
80#define VPCI_F_RING_EVENT_IDX UINT32_C(0x20000000)
81#define VPCI_F_BAD_FEATURE UINT32_C(0x40000000)
82
83#define VRINGDESC_MAX_SIZE (2 * 1024 * 1024)
84#define VRINGDESC_F_NEXT 0x01
85#define VRINGDESC_F_WRITE 0x02
86#define VRINGDESC_F_INDIRECT 0x04
87
88typedef struct VRINGDESC
89{
90 uint64_t u64Addr;
91 uint32_t uLen;
92 uint16_t u16Flags;
93 uint16_t u16Next;
94} VRINGDESC;
95typedef VRINGDESC *PVRINGDESC;
96
97#define VRINGAVAIL_F_NO_INTERRUPT 0x01
98
99typedef struct VRINGAVAIL
100{
101 uint16_t uFlags;
102 uint16_t uNextFreeIndex;
103 uint16_t auRing[1];
104} VRINGAVAIL;
105
106typedef struct VRINGUSEDELEM
107{
108 uint32_t uId;
109 uint32_t uLen;
110} VRINGUSEDELEM;
111
112#define VRINGUSED_F_NO_NOTIFY 0x01
113
114typedef struct VRingUsed
115{
116 uint16_t uFlags;
117 uint16_t uIndex;
118 VRINGUSEDELEM aRing[1];
119} VRINGUSED;
120typedef VRINGUSED *PVRINGUSED;
121
122#define VRING_MAX_SIZE 1024
123
124typedef struct VRING
125{
126 uint16_t uSize;
127 uint16_t padding[3];
128 RTGCPHYS addrDescriptors;
129 RTGCPHYS addrAvail;
130 RTGCPHYS addrUsed;
131} VRING;
132typedef VRING *PVRING;
133
134typedef struct VQUEUE
135{
136 VRING VRing;
137 uint16_t uNextAvailIndex;
138 uint16_t uNextUsedIndex;
139 uint32_t uPageNumber;
140 char szName[16];
141} VQUEUE;
142typedef VQUEUE *PVQUEUE;
143
144/**
145 * Queue callback (consumer?).
146 *
147 * @param pDevIns The device instance.
148 * @param pQueue Pointer to the queue structure.
149 */
150typedef DECLCALLBACKTYPE(void, FNVPCIQUEUECALLBACK,(PPDMDEVINS pDevIns, PVQUEUE pQueue));
151/** Pointer to a VQUEUE callback function. */
152typedef FNVPCIQUEUECALLBACK *PFNVPCIQUEUECALLBACK;
153
154typedef struct VQUEUER3
155{
156 R3PTRTYPE(PFNVPCIQUEUECALLBACK) pfnCallback;
157} VQUEUER3;
158typedef VQUEUER3 *PVQUEUER3;
159
160typedef struct VQUEUESEG
161{
162 RTGCPHYS addr;
163 void *pv;
164 uint32_t cb;
165} VQUEUESEG;
166
167typedef struct VQUEUEELEM
168{
169 uint32_t uIndex;
170 uint32_t cIn;
171 uint32_t cOut;
172 VQUEUESEG aSegsIn[VRING_MAX_SIZE];
173 VQUEUESEG aSegsOut[VRING_MAX_SIZE];
174} VQUEUEELEM;
175typedef VQUEUEELEM *PVQUEUEELEM;
176
177
178enum VirtioDeviceType
179{
180 VIRTIO_NET_ID = 0,
181 VIRTIO_BLK_ID = 1,
182 VIRTIO_32BIT_HACK = 0x7fffffff
183};
184
185
186/**
187 * The core shared state of a VirtIO PCI device
188 */
189typedef struct VPCISTATE
190{
191 PDMCRITSECT cs; /**< Critical section - what is it protecting? */
192 /** Read-only part, never changes after initialization. */
193 char szInstance[8]; /**< Instance name, e.g. VNet#1. */
194
195 /* Read/write part, protected with critical section. */
196 /** Status LED. */
197 PDMLED led;
198
199 uint32_t uGuestFeatures;
200 uint16_t uQueueSelector; /**< An index in aQueues array. */
201 uint8_t uStatus; /**< Device Status (bits are device-specific). */
202 uint8_t uISR; /**< Interrupt Status Register. */
203
204 /** Number of queues actually used. */
205 uint32_t cQueues;
206 uint32_t u32Padding;
207 /** Shared queue data. */
208 VQUEUE Queues[VIRTIO_MAX_NQUEUES];
209
210 STAMCOUNTER StatIntsRaised;
211 STAMCOUNTER StatIntsSkipped;
212
213#ifdef VBOX_WITH_STATISTICS
214 STAMPROFILEADV StatIOReadR3;
215 STAMPROFILEADV StatIOReadR0;
216 STAMPROFILEADV StatIOReadRC;
217 STAMPROFILEADV StatIOWriteR3;
218 STAMPROFILEADV StatIOWriteR0;
219 STAMPROFILEADV StatIOWriteRC;
220 STAMPROFILE StatCsR3;
221 STAMPROFILE StatCsR0;
222 STAMPROFILE StatCsRC;
223#endif
224} VPCISTATE;
225
226
227/**
228 * The core ring-3 state of a VirtIO PCI device
229 *
230 * @implements PDMILEDPORTS
231 */
232typedef struct VPCISTATER3
233{
234 /** Status LUN: Base interface. */
235 PDMIBASE IBase;
236 /** Status LUN: LED port interface. */
237 PDMILEDPORTS ILeds;
238 /** Status LUN: LED connector (peer). */
239 R3PTRTYPE(PPDMILEDCONNECTORS) pLedsConnector;
240 /** Pointer to the shared state. */
241 R3PTRTYPE(PVPCISTATE) pShared;
242 /** Ring-3 per-queue data. */
243 VQUEUER3 Queues[VIRTIO_MAX_NQUEUES];
244} VPCISTATER3;
245
246
247/**
248 * The core ring-0 state of a VirtIO PCI device
249 */
250typedef struct VPCISTATER0
251{
252 uint64_t uUnused;
253} VPCISTATER0;
254
255
256/**
257 * The core raw-mode state of a VirtIO PCI device
258 */
259typedef struct VPCISTATERC
260{
261 uint64_t uUnused;
262} VPCISTATERC;
263
264
265/** @name VirtIO port I/O callbacks.
266 * @{ */
267typedef struct VPCIIOCALLBACKS
268{
269 DECLCALLBACKMEMBER(uint32_t, pfnGetHostFeatures,(PVPCISTATE pVPciState));
270 DECLCALLBACKMEMBER(uint32_t, pfnGetHostMinimalFeatures,(PVPCISTATE pVPciState));
271 DECLCALLBACKMEMBER(void, pfnSetHostFeatures,(PVPCISTATE pVPciState, uint32_t fFeatures));
272 DECLCALLBACKMEMBER(int, pfnGetConfig,(PVPCISTATE pVPciState, uint32_t offCfg, uint32_t cb, void *pvData));
273 DECLCALLBACKMEMBER(int, pfnSetConfig,(PVPCISTATE pVPciState, uint32_t offCfg, uint32_t cb, void *pvData));
274 DECLCALLBACKMEMBER(int, pfnReset,(PPDMDEVINS pDevIns));
275 DECLCALLBACKMEMBER(void, pfnReady,(PPDMDEVINS pDevIns));
276} VPCIIOCALLBACKS;
277/** Pointer to a const VirtIO port I/O callback structure. */
278typedef const VPCIIOCALLBACKS *PCVPCIIOCALLBACKS;
279/** @} */
280
281int vpciR3Init(PPDMDEVINS pDevIns, PVPCISTATE pThis, PVPCISTATECC pThisCC, uint16_t uDeviceId, uint16_t uClass, uint32_t cQueues);
282int vpciRZInit(PPDMDEVINS pDevIns, PVPCISTATE pThis, PVPCISTATECC pThisCC);
283int vpciR3Term(PPDMDEVINS pDevIns, PVPCISTATE pThis);
284PVQUEUE vpciR3AddQueue(PVPCISTATE pThis, PVPCISTATECC pThisCC, unsigned uSize, PFNVPCIQUEUECALLBACK pfnCallback, const char *pcszName);
285void *vpciR3QueryInterface(PVPCISTATECC pThisCC, const char *pszIID);
286void vpciR3SetWriteLed(PVPCISTATE pThis, bool fOn);
287void vpciR3SetReadLed(PVPCISTATE pThis, bool fOn);
288int vpciR3SaveExec(PCPDMDEVHLPR3 pHlp, PVPCISTATE pThis, PSSMHANDLE pSSM);
289int vpciR3LoadExec(PCPDMDEVHLPR3 pHlp, PVPCISTATE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass, uint32_t cQueues);
290void vpciR3DumpStateWorker(PVPCISTATE pThis, PCDBGFINFOHLP pHlp);
291
292void vpciReset(PPDMDEVINS pDevIns, PVPCISTATE pThis);
293int vpciRaiseInterrupt(PPDMDEVINS pDevIns, PVPCISTATE pThis, int rcBusy, uint8_t u8IntCause);
294int vpciIOPortIn(PPDMDEVINS pDevIns, PVPCISTATE pThis, RTIOPORT offPort,
295 uint32_t *pu32, unsigned cb,PCVPCIIOCALLBACKS pCallbacks);
296int vpciIOPortOut(PPDMDEVINS pDevIns, PVPCISTATE pThis, PVPCISTATECC pThisCC, RTIOPORT offPort,
297 uint32_t u32, unsigned cb, PCVPCIIOCALLBACKS pCallbacks);
298
299#define VPCI_CS
300DECLINLINE(int) vpciCsEnter(PPDMDEVINS pDevIns, PVPCISTATE pThis, int rcBusy)
301{
302#ifdef VPCI_CS
303 STAM_PROFILE_START(&pThis->CTX_SUFF(StatCs), a);
304 int rc = PDMDevHlpCritSectEnter(pDevIns, &pThis->cs, rcBusy);
305 STAM_PROFILE_STOP(&pThis->CTX_SUFF(StatCs), a);
306 return rc;
307#else
308 RT_NOREF(pDevIns, pThis, rcBusy);
309 return VINF_SUCCESS;
310#endif
311}
312
313DECLINLINE(void) vpciCsLeave(PPDMDEVINS pDevIns, PVPCISTATE pThis)
314{
315#ifdef VPCI_CS
316 PDMDevHlpCritSectLeave(pDevIns, &pThis->cs);
317#endif
318}
319
320void vringSetNotification(PPDMDEVINS pDevIns, PVRING pVRing, bool fEnabled);
321
322DECLINLINE(uint16_t) vringReadAvailIndex(PPDMDEVINS pDevIns, PVRING pVRing)
323{
324 uint16_t idx = 0;
325 PDMDevHlpPhysRead(pDevIns, pVRing->addrAvail + RT_UOFFSETOF(VRINGAVAIL, uNextFreeIndex), &idx, sizeof(idx));
326 return idx;
327}
328
329bool vqueueSkip(PPDMDEVINS pDevIns, PVPCISTATE pThis, PVQUEUE pQueue);
330bool vqueueGet(PPDMDEVINS pDevIns, PVPCISTATE pThis, PVQUEUE pQueue, PVQUEUEELEM pElem, bool fRemove = true);
331void vqueuePut(PPDMDEVINS pDevIns, PVPCISTATE pThis, PVQUEUE pQueue, PVQUEUEELEM pElem, uint32_t uLen, uint32_t uReserved = 0);
332void vqueueSync(PPDMDEVINS pDevIns, PVPCISTATE pThis, PVQUEUE pQueue);
333
334DECLINLINE(bool) vqueuePeek(PPDMDEVINS pDevIns, PVPCISTATE pThis, PVQUEUE pQueue, PVQUEUEELEM pElem)
335{
336 return vqueueGet(pDevIns, pThis, pQueue, pElem, /* fRemove */ false);
337}
338
339DECLINLINE(bool) vqueueIsReady(PVQUEUE pQueue)
340{
341 return !!pQueue->VRing.addrAvail;
342}
343
344DECLINLINE(bool) vqueueIsEmpty(PPDMDEVINS pDevIns, PVQUEUE pQueue)
345{
346 return vringReadAvailIndex(pDevIns, &pQueue->VRing) == pQueue->uNextAvailIndex;
347}
348
349#endif /* !VBOX_INCLUDED_SRC_VirtIO_Virtio_h */
350
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette