VirtualBox

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

Last change on this file since 81031 was 81031, checked in by vboxsync, 5 years ago

PDM,Devices: Moving the PDMPCIDEV structures into the PDMDEVINS allocation. Preps for extending the config space to 4KB. bugref:9218

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