VirtualBox

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

Last change on this file since 96572 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

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