VirtualBox

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

Last change on this file since 64733 was 64387, checked in by vboxsync, 8 years ago

PDM,Devices: Some PCI device type cleanup.

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