VirtualBox

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

Last change on this file since 49482 was 44856, checked in by vboxsync, 12 years ago

DevVirtioNet.cpp: Callback table for I/O port handlers instead of pushing 2-6 ffunction pointers on the stack for every port access.

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