1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
/* $Id: Virtio-solaris.h $ */
/** @file
* VirtualBox Guest Additions: Virtio Driver for Solaris, header.
*/
/*
* Copyright (C) 2010-2019 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
#ifndef GA_INCLUDED_SRC_solaris_Virtio_Virtio_solaris_h
#define GA_INCLUDED_SRC_solaris_Virtio_Virtio_solaris_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif
#include <sys/sunddi.h>
/** Release log descriptive prefix. */
#define VIRTIOLOGNAME "Virtio"
/** Buffer continues via the Next field */
#define VIRTIO_FLAGS_RING_DESC_NEXT RT_BIT(0)
/** Buffer is write-only, else is read-only. */
#define VIRTIO_FLAGS_RING_DESC_WRITE RT_BIT(1)
/** Indirect buffer (buffer contains list of buffer descriptors) */
#define VIRTIO_FLAGS_RING_DESC_INDIRECT RT_BIT(2)
/* Values from our Virtio.h */
#define VIRTIO_PCI_STATUS_ACK 0x01
#define VIRTIO_PCI_STATUS_DRV 0x02
#define VIRTIO_PCI_STATUS_DRV_OK 0x04
#define VIRTIO_PCI_STATUS_FAILED 0x80
/**
* The ring descriptor table refers to the buffers the guest is using for the
* device.
*/
struct VirtioRingDesc
{
uint64_t AddrBuf; /* Physical address of buffer. */
uint32_t cbBuf; /* Length of the buffer in bytes. */
uint16_t fFlags; /* Flags of the next buffer. */
uint16_t Next; /* Index of the next buffer. */
};
typedef struct VirtioRingDesc VIRTIORINGDESC;
typedef VIRTIORINGDESC *PVIRTIORINGDESC;
/**
* The available ring refers to what descriptors are being offered to the
* device.
*/
struct VirtioRingAvail
{
uint16_t fFlags; /* Interrupt supression flag. */
uint16_t Index; /* Index of available ring. */
uint16_t aRings[1]; /* Array of indices into descriptor table. */
};
typedef struct VirtioRingAvail VIRTIORINGAVAIL;
typedef VIRTIORINGAVAIL *PVIRTIORINGAVAIL;
/**
* The used ring refers to the buffers the device is done using them. The
* element is a pair-descriptor refers to the buffer once the device is done
* with the buffer.
*/
struct VirtioRingUsedElem
{
uint32_t Index; /* Index of start of used descriptor chain. */
uint32_t cbElem; /* Number of bytes written into the buffer. */
};
typedef struct VirtioRingUsedElem VIRTIORINGUSEDELEM;
typedef VIRTIORINGUSEDELEM *PVIRTIORINGUSEDELEM;
/**
* The Virtio Ring which contains the descriptors.
*/
struct VirtioRing
{
uint_t cDesc; /* Number of descriptors. */
PVIRTIORINGDESC pRingDesc; /* Pointer to ring descriptor. */
PVIRTIORINGAVAIL pRingAvail; /* Pointer to available ring. */
PVIRTIORINGUSEDELEM pRingUsedElem; /* Pointer to used ring element. */
};
typedef struct VirtioRing VIRTIORING;
typedef VIRTIORING *PVIRTIORING;
struct VirtioDevice;
struct VirtioQueue;
typedef void *(*PFNVIRTIOALLOC)(struct VirtioDevice *pDevice);
typedef void (*PFNVIRTIOFREE)(struct VirtioDevice *pDevice);
typedef int (*PFNVIRTIOATTACH)(struct VirtioDevice *pDevice);
typedef int (*PFNVIRTIODETACH)(struct VirtioDevice *pDevice);
typedef uint32_t (*PFNVIRTIOGETFEATURES)(struct VirtioDevice *pDevice);
typedef void (*PFNVIRTIOSETFEATURES)(struct VirtioDevice *pDevice, uint32_t fFeatures);
typedef void (*PFNVIRTIOGET)(struct VirtioDevice *pDevice, off_t off, void *pv, size_t cb);
typedef void (*PFNVIRTIOSET)(struct VirtioDevice *pDevice, off_t off, void *pv, size_t cb);
typedef void *(*PFNVIRTIOGETQUEUE)(struct VirtioDevice *pDevice, struct VirtioQueue *pQueue);
typedef void (*PFNVIRTIOPUTQUEUE)(struct VirtioDevice *pDevice, struct VirtioQueue *pQueue);
typedef int (*PFNVIRTIONOTIFYQUEUE)(struct VirtioDevice *pDevice, struct VirtioQueue *pQueue);
typedef void (*PFNVIRTIOSETSTATUS)(struct VirtioDevice *pDevice, uint8_t Status);
/**
* Virtio device operations.
*/
struct VirtioDeviceOps
{
PFNVIRTIOALLOC pfnAlloc; /* Device alloc. */
PFNVIRTIOFREE pfnFree; /* Device free. */
PFNVIRTIOATTACH pfnAttach; /* Device attach. */
PFNVIRTIODETACH pfnDetach; /* Device detach. */
};
typedef struct VirtioDeviceOps VIRTIODEVICEOPS;
typedef VIRTIODEVICEOPS *PVIRTIODEVICEOPS;
/**
* Hypervisor access operations.
*/
struct VirtioHyperOps
{
PFNVIRTIOALLOC pfnAlloc; /* Hypervisor alloc. */
PFNVIRTIOFREE pfnFree; /* Hypervisor free */
PFNVIRTIOATTACH pfnAttach; /* Hypervisor attach. */
PFNVIRTIODETACH pfnDetach; /* Hypervisor detach. */
PFNVIRTIOGETFEATURES pfnGetFeatures; /* Hypervisor get features. */
PFNVIRTIOSETFEATURES pfnSetFeatures; /* Hypervisor set features. */
PFNVIRTIONOTIFYQUEUE pfnNotifyQueue; /* Hypervisor notify queue. */
PFNVIRTIOGET pfnGet; /* Hypervisor get. */
PFNVIRTIOSET pfnSet; /* Hypervisor set. */
PFNVIRTIOGETQUEUE pfnGetQueue; /* Hypervisor get queue. */
PFNVIRTIOPUTQUEUE pfnPutQueue; /* Hypervisor put queue. */
PFNVIRTIOSETSTATUS pfnSetStatus; /* Hypervisor set status. */
};
typedef struct VirtioHyperOps VIRTIOHYPEROPS;
typedef VIRTIOHYPEROPS *PVIRTIOHYPEROPS;
/**
* Virtio Queue into which buffers are posted.
*/
struct VirtioQueue
{
VIRTIORING Ring; /* Ring buffer of this queue. */
uint16_t cBufs; /* Number of pushed, unnotified buffers. */
uint16_t FreeHeadIndex; /* Index of head of free list. */
uint16_t QueueIndex; /* Index of this queue. */
caddr_t pQueue; /* Allocated DMA region for queue. */
void *pvData; /* Queue private data. */
};
typedef struct VirtioQueue VIRTIOQUEUE;
typedef VIRTIOQUEUE *PVIRTIOQUEUE;
/**
* Virtio device descriptor, common to all Virtio devices.
*/
struct VirtioDevice
{
dev_info_t *pDip; /* OS device info. */
PVIRTIODEVICEOPS pDeviceOps; /* Device hooks. */
void *pvDevice; /* Device opaque data. */
PVIRTIOHYPEROPS pHyperOps; /* Hypervisor hooks. */
void *pvHyper; /* Hypervisor opaque data. */
uint32_t fHostFeatures; /* Features provided by the host. */
};
typedef struct VirtioDevice VIRTIODEVICE;
typedef VIRTIODEVICE *PVIRTIODEVICE;
int VirtioAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd, PVIRTIODEVICEOPS pDeviceOps, PVIRTIOHYPEROPS pHyperOps);
int VirtioDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd);
PVIRTIOQUEUE VirtioGetQueue(PVIRTIODEVICE pDevice, uint16_t Index);
void VirtioPutQueue(PVIRTIODEVICE pDevice, PVIRTIOQUEUE pQueue);
void VirtioRingInit(PVIRTIOQUEUE pQueue, uint_t cDescs, caddr_t virtBuf, ulong_t Align);
int VirtioRingPush(PVIRTIOQUEUE pQueue, paddr_t physBuf, uint32_t cbBuf, uint16_t fFlags);
size_t VirtioRingSize(uint64_t cElements, ulong_t Align);
#endif /* !GA_INCLUDED_SRC_solaris_Virtio_Virtio_solaris_h */
|