3
* Virtio.h - Virtio Declarations
8
* Copyright (C) 2009 Sun Microsystems, Inc.
10
* This file is part of VirtualBox Open Source Edition (OSE), as
11
* available from http://www.virtualbox.org. This file is free software;
12
* you can redistribute it and/or modify it under the terms of the GNU
13
* General Public License (GPL) as published by the Free Software
14
* Foundation, in version 2 as it comes in the "COPYING" file of the
15
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19
* Clara, CA 95054 USA or visit http://www.sun.com if you need
20
* additional information or have any questions.
23
#ifndef ___VBox_Virtio_h
24
#define ___VBox_Virtio_h
26
#include <iprt/ctype.h>
28
#define VIRTIO_RELOCATE(p, o) *(RTHCUINTPTR *)&p += o
31
* The saved state version is changed if either common or any of specific
32
* parts are changed. That is, it is perfectly possible that the version
33
* of saved vnet state will increase as a result of change in vblk structure
36
#define VIRTIO_SAVEDSTATE_VERSION_3_1_BETA1 1
37
#define VIRTIO_SAVEDSTATE_VERSION 2
39
#define DEVICE_PCI_VENDOR_ID 0x1AF4
40
#define DEVICE_PCI_DEVICE_ID 0x1000
41
#define DEVICE_PCI_SUBSYSTEM_VENDOR_ID 0x1AF4
43
#define VIRTIO_MAX_NQUEUES 3
45
#define VPCI_HOST_FEATURES 0x0
46
#define VPCI_GUEST_FEATURES 0x4
47
#define VPCI_QUEUE_PFN 0x8
48
#define VPCI_QUEUE_NUM 0xC
49
#define VPCI_QUEUE_SEL 0xE
50
#define VPCI_QUEUE_NOTIFY 0x10
51
#define VPCI_STATUS 0x12
53
#define VPCI_CONFIG 0x14
55
#define VPCI_ISR_QUEUE 0x1
56
#define VPCI_ISR_CONFIG 0x3
58
#define VPCI_STATUS_ACK 0x01
59
#define VPCI_STATUS_DRV 0x02
60
#define VPCI_STATUS_DRV_OK 0x04
61
#define VPCI_STATUS_FAILED 0x80
63
#define VPCI_F_NOTIFY_ON_EMPTY 0x01000000
64
#define VPCI_F_BAD_FEATURE 0x40000000
66
#define VRINGDESC_MAX_SIZE (2 * 1024 * 1024)
67
#define VRINGDESC_F_NEXT 0x01
68
#define VRINGDESC_F_WRITE 0x02
77
typedef struct VRingDesc VRINGDESC;
78
typedef VRINGDESC *PVRINGDESC;
80
#define VRINGAVAIL_F_NO_INTERRUPT 0x01
85
uint16_t uNextFreeIndex;
88
typedef struct VRingAvail VRINGAVAIL;
95
typedef struct VRingUsedElem VRINGUSEDELEM;
97
#define VRINGUSED_F_NO_NOTIFY 0x01
103
VRINGUSEDELEM aRing[1];
105
typedef struct VRingUsed VRINGUSED;
106
typedef VRINGUSED *PVRINGUSED;
108
#define VRING_MAX_SIZE 1024
114
RTGCPHYS addrDescriptors;
118
typedef struct VRing VRING;
119
typedef VRING *PVRING;
124
uint16_t uNextAvailIndex;
125
uint16_t uNextUsedIndex;
126
uint32_t uPageNumber;
128
void (*pfnCallback)(void *pvState, struct VQueue *pQueue);
130
RTR3UINTPTR pfnCallback;
132
R3PTRTYPE(const char *) pcszName;
134
typedef struct VQueue VQUEUE;
135
typedef VQUEUE *PVQUEUE;
143
typedef struct VQueueElemSeg VQUEUESEG;
150
VQUEUESEG aSegsIn[VRING_MAX_SIZE];
151
VQUEUESEG aSegsOut[VRING_MAX_SIZE];
153
typedef struct VQueueElem VQUEUEELEM;
154
typedef VQUEUEELEM *PVQUEUEELEM;
157
enum VirtioDeviceType
161
VIRTIO_32BIT_HACK = 0x7fffffff
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. */
170
#if HC_ARCH_BITS != 64
175
PDMILEDPORTS ILeds; /**< LED interface */
176
R3PTRTYPE(PPDMILEDCONNECTORS) pLedsConnector;
178
PPDMDEVINSR3 pDevInsR3; /**< Device instance - R3. */
179
PPDMDEVINSR0 pDevInsR0; /**< Device instance - R0. */
180
PPDMDEVINSRC pDevInsRC; /**< Device instance - RC. */
182
#if HC_ARCH_BITS == 64
188
/** Base port of I/O space region. */
191
/* Read/write part, protected with critical section. */
195
uint32_t uGuestFeatures;
196
uint16_t uQueueSelector; /**< An index in aQueues array. */
197
uint8_t uStatus; /**< Device Status (bits are device-specific). */
198
uint8_t uISR; /**< Interrupt Status Register. */
200
#if HC_ARCH_BITS != 64
204
uint32_t nQueues; /**< Actual number of queues used. */
205
VQUEUE Queues[VIRTIO_MAX_NQUEUES];
207
#if defined(VBOX_WITH_STATISTICS)
208
STAMPROFILEADV StatIOReadGC;
209
STAMPROFILEADV StatIOReadHC;
210
STAMPROFILEADV StatIOWriteGC;
211
STAMPROFILEADV StatIOWriteHC;
212
STAMCOUNTER StatIntsRaised;
213
STAMCOUNTER StatIntsSkipped;
214
STAMPROFILE StatCsGC;
215
STAMPROFILE StatCsHC;
216
#endif /* VBOX_WITH_STATISTICS */
218
typedef struct VPCIState_st VPCISTATE;
219
typedef VPCISTATE *PVPCISTATE;
221
/* Callbacks *****************************************************************/
222
typedef uint32_t (*PFNGETHOSTFEATURES)(void *pState);
223
typedef uint32_t (*PFNGETHOSTMINIMALFEATURES)(void *pState);
224
typedef void (*PFNSETHOSTFEATURES)(void *pState, uint32_t uFeatures);
225
typedef int (*PFNGETCONFIG)(void *pState, uint32_t port, uint32_t cb, void *data);
226
typedef int (*PFNSETCONFIG)(void *pState, uint32_t port, uint32_t cb, void *data);
227
typedef void (*PFNRESET)(void *pState);
228
typedef void (*PFNREADY)(void *pState);
229
/*****************************************************************************/
231
int vpciRaiseInterrupt(VPCISTATE *pState, int rcBusy, uint8_t u8IntCause);
232
int vpciIOPortIn(PPDMDEVINS pDevIns,
237
PFNGETHOSTFEATURES pfnGetHostFeatures,
238
PFNGETCONFIG pfnGetConfig);
240
int vpciIOPortOut(PPDMDEVINS pDevIns,
245
PFNGETHOSTMINIMALFEATURES pfnGetHostMinimalFeatures,
246
PFNGETHOSTFEATURES pfnGetHostFeatures,
247
PFNSETHOSTFEATURES pfnSetHostFeatures,
250
PFNSETCONFIG pfnSetConfig);
252
void vpciSetWriteLed(PVPCISTATE pState, bool fOn);
253
void vpciSetReadLed(PVPCISTATE pState, bool fOn);
254
int vpciSaveExec(PVPCISTATE pState, PSSMHANDLE pSSM);
255
int vpciLoadExec(PVPCISTATE pState, PSSMHANDLE pSSM,
256
uint32_t uVersion, uint32_t uPass,
258
int vpciConstruct(PPDMDEVINS pDevIns, VPCISTATE *pState,
259
int iInstance, const char *pcszNameFmt,
260
uint16_t uSubsystemId, uint16_t uClass,
262
int vpciDestruct(VPCISTATE* pState);
263
void vpciRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta);
264
void vpciReset(PVPCISTATE pState);
265
void *vpciQueryInterface(struct PDMIBASE *pInterface,
266
PDMINTERFACE enmInterface);
267
PVQUEUE vpciAddQueue(VPCISTATE* pState, unsigned uSize,
268
void (*pfnCallback)(void *pvState, PVQUEUE pQueue),
269
const char *pcszName);
272
DECLINLINE(int) vpciCsEnter(VPCISTATE *pState, int iBusyRc)
275
STAM_PROFILE_START(&pState->CTXSUFF(StatCs), a);
276
int rc = PDMCritSectEnter(&pState->cs, iBusyRc);
277
STAM_PROFILE_STOP(&pState->CTXSUFF(StatCs), a);
284
DECLINLINE(void) vpciCsLeave(VPCISTATE *pState)
287
PDMCritSectLeave(&pState->cs);
291
void vringSetNotification(PVPCISTATE pState, PVRING pVRing, bool fEnabled);
293
DECLINLINE(uint16_t) vringReadAvailIndex(PVPCISTATE pState, PVRING pVRing)
297
PDMDevHlpPhysRead(pState->CTX_SUFF(pDevIns),
298
pVRing->addrAvail + RT_OFFSETOF(VRINGAVAIL, uNextFreeIndex),
303
bool vqueueGet(PVPCISTATE pState, PVQUEUE pQueue, PVQUEUEELEM pElem);
304
void vqueuePut(PVPCISTATE pState, PVQUEUE pQueue, PVQUEUEELEM pElem, uint32_t uLen);
305
void vqueueNotify(PVPCISTATE pState, PVQUEUE pQueue);
306
void vqueueSync(PVPCISTATE pState, PVQUEUE pQueue);
309
DECLINLINE(bool) vqueueIsReady(PVPCISTATE pState, PVQUEUE pQueue)
311
return !!pQueue->VRing.addrAvail;
314
DECLINLINE(bool) vqueueIsEmpty(PVPCISTATE pState, PVQUEUE pQueue)
316
return (vringReadAvailIndex(pState, &pQueue->VRing) == pQueue->uNextAvailIndex);
319
#endif /* ___VBox_Virtio_h */