Virtio-solaris.h revision 1a9a76385f412e8c5762baadaa30afe308b1cd12
/* $Id$ */
/** @file
* VirtualBox Guest Additions: Virtio Driver for Solaris, header.
*/
/*
* Copyright (C) 2010 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 ___Virtio_solaris_h
#define ___Virtio_solaris_h
#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