VirtualBox

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

Last change on this file since 26515 was 25966, checked in by vboxsync, 15 years ago

PDMIBASE refactoring; use UUID as interface IDs.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.0 KB
Line 
1/* $Id: Virtio.h 25966 2010-01-22 11:15:43Z vboxsync $ */
2/** @file
3 * Virtio.h - Virtio Declarations
4 */
5
6/*
7 * Copyright (C) 2009 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#ifndef ___VBox_Virtio_h
23#define ___VBox_Virtio_h
24
25#include <iprt/ctype.h>
26
27#define VIRTIO_RELOCATE(p, o) *(RTHCUINTPTR *)&p += o
28
29/*
30 * The saved state version is changed if either common or any of specific
31 * parts are changed. That is, it is perfectly possible that the version
32 * of saved vnet state will increase as a result of change in vblk structure
33 * for example.
34 */
35#define VIRTIO_SAVEDSTATE_VERSION_3_1_BETA1 1
36#define VIRTIO_SAVEDSTATE_VERSION 2
37
38#define DEVICE_PCI_VENDOR_ID 0x1AF4
39#define DEVICE_PCI_DEVICE_ID 0x1000
40#define DEVICE_PCI_SUBSYSTEM_VENDOR_ID 0x1AF4
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_BAD_FEATURE 0x40000000
64
65#define VRINGDESC_MAX_SIZE (2 * 1024 * 1024)
66#define VRINGDESC_F_NEXT 0x01
67#define VRINGDESC_F_WRITE 0x02
68
69struct VRingDesc
70{
71 uint64_t u64Addr;
72 uint32_t uLen;
73 uint16_t u16Flags;
74 uint16_t u16Next;
75};
76typedef struct VRingDesc VRINGDESC;
77typedef VRINGDESC *PVRINGDESC;
78
79#define VRINGAVAIL_F_NO_INTERRUPT 0x01
80
81struct VRingAvail
82{
83 uint16_t uFlags;
84 uint16_t uNextFreeIndex;
85 uint16_t auRing[1];
86};
87typedef struct VRingAvail VRINGAVAIL;
88
89struct VRingUsedElem
90{
91 uint32_t uId;
92 uint32_t uLen;
93};
94typedef struct VRingUsedElem VRINGUSEDELEM;
95
96#define VRINGUSED_F_NO_NOTIFY 0x01
97
98struct VRingUsed
99{
100 uint16_t uFlags;
101 uint16_t uIndex;
102 VRINGUSEDELEM aRing[1];
103};
104typedef struct VRingUsed VRINGUSED;
105typedef VRINGUSED *PVRINGUSED;
106
107#define VRING_MAX_SIZE 1024
108
109struct VRing
110{
111 uint16_t uSize;
112 uint16_t padding[3];
113 RTGCPHYS addrDescriptors;
114 RTGCPHYS addrAvail;
115 RTGCPHYS addrUsed;
116};
117typedef struct VRing VRING;
118typedef VRING *PVRING;
119
120struct VQueue
121{
122 VRING VRing;
123 uint16_t uNextAvailIndex;
124 uint16_t uNextUsedIndex;
125 uint32_t uPageNumber;
126#ifdef IN_RING3
127 void (*pfnCallback)(void *pvState, struct VQueue *pQueue);
128#else
129 RTR3UINTPTR pfnCallback;
130#endif
131 R3PTRTYPE(const char *) pcszName;
132};
133typedef struct VQueue VQUEUE;
134typedef VQUEUE *PVQUEUE;
135
136struct VQueueElemSeg
137{
138 RTGCPHYS addr;
139 void *pv;
140 uint32_t cb;
141};
142typedef struct VQueueElemSeg VQUEUESEG;
143
144struct VQueueElem
145{
146 uint32_t uIndex;
147 uint32_t nIn;
148 uint32_t nOut;
149 VQUEUESEG aSegsIn[VRING_MAX_SIZE];
150 VQUEUESEG aSegsOut[VRING_MAX_SIZE];
151};
152typedef struct VQueueElem VQUEUEELEM;
153typedef VQUEUEELEM *PVQUEUEELEM;
154
155
156enum VirtioDeviceType
157{
158 VIRTIO_NET_ID = 0,
159 VIRTIO_BLK_ID = 1,
160 VIRTIO_32BIT_HACK = 0x7fffffff
161};
162
163
164/**
165 * The state of the VirtIO PCI device
166 *
167 * @implements PDMILEDPORTS
168 */
169struct VPCIState_st
170{
171 PDMCRITSECT cs; /**< Critical section - what is it protecting? */
172 /* Read-only part, never changes after initialization. */
173 char szInstance[8]; /**< Instance name, e.g. VNet#1. */
174
175#if HC_ARCH_BITS != 64
176 uint32_t padding1;
177#endif
178
179 /** Status LUN: Base interface. */
180 PDMIBASE IBase;
181 /** Status LUN: LED port interface. */
182 PDMILEDPORTS ILeds;
183 /** Status LUN: LED connector (peer). */
184 R3PTRTYPE(PPDMILEDCONNECTORS) pLedsConnector;
185
186 PPDMDEVINSR3 pDevInsR3; /**< Device instance - R3. */
187 PPDMDEVINSR0 pDevInsR0; /**< Device instance - R0. */
188 PPDMDEVINSRC pDevInsRC; /**< Device instance - RC. */
189
190#if HC_ARCH_BITS == 64
191 uint32_t padding2;
192#endif
193
194 /** TODO */
195 PCIDEVICE pciDevice;
196 /** Base port of I/O space region. */
197 RTIOPORT addrIOPort;
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 StatIOReadGC;
217 STAMPROFILEADV StatIOReadHC;
218 STAMPROFILEADV StatIOWriteGC;
219 STAMPROFILEADV StatIOWriteHC;
220 STAMCOUNTER StatIntsRaised;
221 STAMCOUNTER StatIntsSkipped;
222 STAMPROFILE StatCsGC;
223 STAMPROFILE StatCsHC;
224#endif /* VBOX_WITH_STATISTICS */
225};
226typedef struct VPCIState_st VPCISTATE;
227typedef VPCISTATE *PVPCISTATE;
228
229/* Callbacks *****************************************************************/
230typedef uint32_t (*PFNGETHOSTFEATURES)(void *pState);
231typedef uint32_t (*PFNGETHOSTMINIMALFEATURES)(void *pState);
232typedef void (*PFNSETHOSTFEATURES)(void *pState, uint32_t uFeatures);
233typedef int (*PFNGETCONFIG)(void *pState, uint32_t port, uint32_t cb, void *data);
234typedef int (*PFNSETCONFIG)(void *pState, uint32_t port, uint32_t cb, void *data);
235typedef void (*PFNRESET)(void *pState);
236typedef void (*PFNREADY)(void *pState);
237/*****************************************************************************/
238
239int vpciRaiseInterrupt(VPCISTATE *pState, int rcBusy, uint8_t u8IntCause);
240int vpciIOPortIn(PPDMDEVINS pDevIns,
241 void *pvUser,
242 RTIOPORT port,
243 uint32_t *pu32,
244 unsigned cb,
245 PFNGETHOSTFEATURES pfnGetHostFeatures,
246 PFNGETCONFIG pfnGetConfig);
247
248int vpciIOPortOut(PPDMDEVINS pDevIns,
249 void *pvUser,
250 RTIOPORT port,
251 uint32_t u32,
252 unsigned cb,
253 PFNGETHOSTMINIMALFEATURES pfnGetHostMinimalFeatures,
254 PFNGETHOSTFEATURES pfnGetHostFeatures,
255 PFNSETHOSTFEATURES pfnSetHostFeatures,
256 PFNRESET pfnReset,
257 PFNREADY pfnReady,
258 PFNSETCONFIG pfnSetConfig);
259
260void vpciSetWriteLed(PVPCISTATE pState, bool fOn);
261void vpciSetReadLed(PVPCISTATE pState, bool fOn);
262int vpciSaveExec(PVPCISTATE pState, PSSMHANDLE pSSM);
263int vpciLoadExec(PVPCISTATE pState, PSSMHANDLE pSSM,
264 uint32_t uVersion, uint32_t uPass,
265 uint32_t nQueues);
266int vpciConstruct(PPDMDEVINS pDevIns, VPCISTATE *pState,
267 int iInstance, const char *pcszNameFmt,
268 uint16_t uSubsystemId, uint16_t uClass,
269 uint32_t nQueues);
270int vpciDestruct(VPCISTATE* pState);
271void vpciRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta);
272void vpciReset(PVPCISTATE pState);
273void *vpciQueryInterface(struct PDMIBASE *pInterface, const char *pszIID);
274PVQUEUE vpciAddQueue(VPCISTATE* pState, unsigned uSize,
275 void (*pfnCallback)(void *pvState, PVQUEUE pQueue),
276 const char *pcszName);
277
278#define VPCI_CS
279DECLINLINE(int) vpciCsEnter(VPCISTATE *pState, int iBusyRc)
280{
281#ifdef VPCI_CS
282 STAM_PROFILE_START(&pState->CTXSUFF(StatCs), a);
283 int rc = PDMCritSectEnter(&pState->cs, iBusyRc);
284 STAM_PROFILE_STOP(&pState->CTXSUFF(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_OFFSETOF(VRINGAVAIL, uNextFreeIndex),
306 &tmp, sizeof(tmp));
307 return tmp;
308}
309
310bool vqueueGet(PVPCISTATE pState, PVQUEUE pQueue, PVQUEUEELEM pElem);
311void vqueuePut(PVPCISTATE pState, PVQUEUE pQueue, PVQUEUEELEM pElem, uint32_t uLen);
312void vqueueNotify(PVPCISTATE pState, PVQUEUE pQueue);
313void vqueueSync(PVPCISTATE pState, PVQUEUE pQueue);
314
315
316DECLINLINE(bool) vqueueIsReady(PVPCISTATE pState, PVQUEUE pQueue)
317{
318 return !!pQueue->VRing.addrAvail;
319}
320
321DECLINLINE(bool) vqueueIsEmpty(PVPCISTATE pState, PVQUEUE pQueue)
322{
323 return (vringReadAvailIndex(pState, &pQueue->VRing) == pQueue->uNextAvailIndex);
324}
325
326#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