summaryrefslogtreecommitdiffstats
path: root/src/VBox/Additions/solaris/Virtio/Virtio-solaris.h
blob: 5f77f7dfc7faabaaccb48e2446bfb46e3bea0b77 (plain)
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 */