Skip to content
Snippets Groups Projects
Commit 142ae3b0 authored by Guy Zana's avatar Guy Zana
Browse files

Fixed windows CRLF in files

parent 2efdc3bc
No related branches found
No related tags found
No related merge requests found
#include "drivers/virtio.hh"
#include "drivers/virtio-blk.hh"
#include "debug.hh"
namespace virtio {
virtio_blk::virtio_blk()
: virtio_driver(VIRTIO_BLK_DEVICE_ID)
{
}
virtio_blk::~virtio_blk()
{
}
bool virtio_blk::Init(Device *d)
{
virtio_driver::Init(d);
add_dev_status(VIRTIO_CONFIG_S_DRIVER_OK);
return true;
}
}
#include "drivers/virtio.hh"
#include "drivers/virtio-blk.hh"
#include "debug.hh"
namespace virtio {
virtio_blk::virtio_blk()
: virtio_driver(VIRTIO_BLK_DEVICE_ID)
{
}
virtio_blk::~virtio_blk()
{
}
bool virtio_blk::Init(Device *d)
{
virtio_driver::Init(d);
add_dev_status(VIRTIO_CONFIG_S_DRIVER_OK);
return true;
}
}
#ifndef VIRTIO_BLK_DRIVER_H
#define VIRTIO_BLK_DRIVER_H
/* This header is BSD licensed so anyone can use the definitions to implement
* compatible drivers/servers.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of IBM nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. */
#include "drivers/virtio.hh"
namespace virtio {
class virtio_blk : public virtio_driver {
public:
// The feature bitmap for virtio blk
enum BlkFeatures {
VIRTIO_BLK_F_BARRIER=0, /* Does host support barriers? */
VIRTIO_BLK_F_SIZE_MAX=1, /* Indicates maximum segment size */
VIRTIO_BLK_F_SEG_MAX=2, /* Indicates maximum # of segments */
VIRTIO_BLK_F_GEOMETRY=4, /* Legacy geometry available */
VIRTIO_BLK_F_RO=5, /* Disk is read-only */
VIRTIO_BLK_F_BLK_SIZE=6, /* Block size of disk is available*/
VIRTIO_BLK_F_SCSI=7, /* Supports scsi command passthru */
VIRTIO_BLK_F_WCE=9, /* Writeback mode enabled after reset */
VIRTIO_BLK_F_TOPOLOGY=10, /* Topology information is available */
VIRTIO_BLK_F_CONFIG_WCE=11, /* Writeback mode available in config */
};
enum {
VIRTIO_BLK_DEVICE_ID=0x1001,
VIRTIO_BLK_ID_BYTES=20, /* ID string length */
/*
* Command types
*
* Usage is a bit tricky as some bits are used as flags and some are not.
*
* Rules:
* VIRTIO_BLK_T_OUT may be combined with VIRTIO_BLK_T_SCSI_CMD or
* VIRTIO_BLK_T_BARRIER. VIRTIO_BLK_T_FLUSH is a command of its own
* and may not be combined with any of the other flags.
*/
VIRTIO_BLK_T_IN=0,
VIRTIO_BLK_T_OUT=1,
/* This bit says it's a scsi command, not an actual read or write. */
VIRTIO_BLK_T_SCSI_CMD=2,
/* Cache flush command */
VIRTIO_BLK_T_FLUSH=4,
/* Get device ID command */
VIRTIO_BLK_T_GET_ID=8,
/* Barrier before this op. */
VIRTIO_BLK_T_BARRIER=0x80000000,
/* And this is the final byte of the write scatter-gather list. */
VIRTIO_BLK_S_OK=0,
VIRTIO_BLK_S_IOERR=1,
VIRTIO_BLK_S_UNSUPP=2,
};
struct virtio_blk_config {
/* The capacity (in 512-byte sectors). */
u64 capacity;
/* The maximum segment size (if VIRTIO_BLK_F_SIZE_MAX) */
u32 size_max;
/* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */
u32 seg_max;
/* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */
struct virtio_blk_geometry {
u16 cylinders;
u8 heads;
u8 sectors;
} geometry;
/* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
u32 blk_size;
/* the next 4 entries are guarded by VIRTIO_BLK_F_TOPOLOGY */
/* exponent for physical block per logical block. */
u8 physical_block_exp;
/* alignment offset in logical blocks. */
u8 alignment_offset;
/* minimum I/O size without performance penalty in logical blocks. */
u16 min_io_size;
/* optimal sustained I/O size in logical blocks. */
u32 opt_io_size;
/* writeback mode (if VIRTIO_BLK_F_CONFIG_WCE) */
u8 wce;
} __attribute__((packed));
/* This is the first element of the read scatter-gather list. */
struct virtio_blk_outhdr {
/* VIRTIO_BLK_T* */
u32 type;
/* io priority. */
u32 ioprio;
/* Sector (ie. 512 byte offset) */
u64 sector;
};
struct virtio_scsi_inhdr {
u32 errors;
u32 data_len;
u32 sense_len;
u32 residual;
};
virtio_blk();
virtual ~virtio_blk();
virtual bool Init(Device *d);
virtual u32 get_driver_features(void) { return ((1 << VIRTIO_BLK_F_SIZE_MAX)); }
private:
};
}
#endif
#ifndef VIRTIO_BLK_DRIVER_H
#define VIRTIO_BLK_DRIVER_H
/* This header is BSD licensed so anyone can use the definitions to implement
* compatible drivers/servers.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of IBM nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. */
#include "drivers/virtio.hh"
namespace virtio {
class virtio_blk : public virtio_driver {
public:
// The feature bitmap for virtio blk
enum BlkFeatures {
VIRTIO_BLK_F_BARRIER=0, /* Does host support barriers? */
VIRTIO_BLK_F_SIZE_MAX=1, /* Indicates maximum segment size */
VIRTIO_BLK_F_SEG_MAX=2, /* Indicates maximum # of segments */
VIRTIO_BLK_F_GEOMETRY=4, /* Legacy geometry available */
VIRTIO_BLK_F_RO=5, /* Disk is read-only */
VIRTIO_BLK_F_BLK_SIZE=6, /* Block size of disk is available*/
VIRTIO_BLK_F_SCSI=7, /* Supports scsi command passthru */
VIRTIO_BLK_F_WCE=9, /* Writeback mode enabled after reset */
VIRTIO_BLK_F_TOPOLOGY=10, /* Topology information is available */
VIRTIO_BLK_F_CONFIG_WCE=11, /* Writeback mode available in config */
};
enum {
VIRTIO_BLK_DEVICE_ID=0x1001,
VIRTIO_BLK_ID_BYTES=20, /* ID string length */
/*
* Command types
*
* Usage is a bit tricky as some bits are used as flags and some are not.
*
* Rules:
* VIRTIO_BLK_T_OUT may be combined with VIRTIO_BLK_T_SCSI_CMD or
* VIRTIO_BLK_T_BARRIER. VIRTIO_BLK_T_FLUSH is a command of its own
* and may not be combined with any of the other flags.
*/
VIRTIO_BLK_T_IN=0,
VIRTIO_BLK_T_OUT=1,
/* This bit says it's a scsi command, not an actual read or write. */
VIRTIO_BLK_T_SCSI_CMD=2,
/* Cache flush command */
VIRTIO_BLK_T_FLUSH=4,
/* Get device ID command */
VIRTIO_BLK_T_GET_ID=8,
/* Barrier before this op. */
VIRTIO_BLK_T_BARRIER=0x80000000,
/* And this is the final byte of the write scatter-gather list. */
VIRTIO_BLK_S_OK=0,
VIRTIO_BLK_S_IOERR=1,
VIRTIO_BLK_S_UNSUPP=2,
};
struct virtio_blk_config {
/* The capacity (in 512-byte sectors). */
u64 capacity;
/* The maximum segment size (if VIRTIO_BLK_F_SIZE_MAX) */
u32 size_max;
/* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */
u32 seg_max;
/* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */
struct virtio_blk_geometry {
u16 cylinders;
u8 heads;
u8 sectors;
} geometry;
/* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
u32 blk_size;
/* the next 4 entries are guarded by VIRTIO_BLK_F_TOPOLOGY */
/* exponent for physical block per logical block. */
u8 physical_block_exp;
/* alignment offset in logical blocks. */
u8 alignment_offset;
/* minimum I/O size without performance penalty in logical blocks. */
u16 min_io_size;
/* optimal sustained I/O size in logical blocks. */
u32 opt_io_size;
/* writeback mode (if VIRTIO_BLK_F_CONFIG_WCE) */
u8 wce;
} __attribute__((packed));
/* This is the first element of the read scatter-gather list. */
struct virtio_blk_outhdr {
/* VIRTIO_BLK_T* */
u32 type;
/* io priority. */
u32 ioprio;
/* Sector (ie. 512 byte offset) */
u64 sector;
};
struct virtio_scsi_inhdr {
u32 errors;
u32 data_len;
u32 sense_len;
u32 residual;
};
virtio_blk();
virtual ~virtio_blk();
virtual bool Init(Device *d);
virtual u32 get_driver_features(void) { return ((1 << VIRTIO_BLK_F_SIZE_MAX)); }
private:
};
}
#endif
#include "drivers/virtio.hh"
#include "drivers/virtio-net.hh"
#include "debug.hh"
namespace virtio {
virtio_net::virtio_net()
: virtio_driver(VIRTIO_NET_DEVICE_ID)
{
}
virtio_net::~virtio_net()
{
}
bool virtio_net::Init(Device *d)
{
virtio_driver::Init(d);
add_dev_status(VIRTIO_CONFIG_S_DRIVER_OK);
return true;
}
}
#include "drivers/virtio.hh"
#include "drivers/virtio-net.hh"
#include "debug.hh"
namespace virtio {
virtio_net::virtio_net()
: virtio_driver(VIRTIO_NET_DEVICE_ID)
{
}
virtio_net::~virtio_net()
{
}
bool virtio_net::Init(Device *d)
{
virtio_driver::Init(d);
add_dev_status(VIRTIO_CONFIG_S_DRIVER_OK);
return true;
}
}
#ifndef VIRTIO_NET_DRIVER_H
#define VIRTIO_NET_DRIVER_H
#include "drivers/virtio.hh"
namespace virtio {
class virtio_net : public virtio_driver {
public:
// The feature bitmap for virtio net
enum NetFeatures {
VIRTIO_NET_F_CSUM=0, /* Host handles pkts w/ partial csum */
VIRTIO_NET_F_GUEST_CSUM=1, /* Guest handles pkts w/ partial csum */
VIRTIO_NET_F_MAC=5, /* Host has given MAC address. */
VIRTIO_NET_F_GSO=6, /* Host handles pkts w/ any GSO type */
VIRTIO_NET_F_GUEST_TSO4=7, /* Guest can handle TSOv4 in. */
VIRTIO_NET_F_GUEST_TSO6=8, /* Guest can handle TSOv6 in. */
VIRTIO_NET_F_GUEST_ECN=9, /* Guest can handle TSO[6] w/ ECN in. */
VIRTIO_NET_F_GUEST_UFO=10, /* Guest can handle UFO in. */
VIRTIO_NET_F_HOST_TSO4=11, /* Host can handle TSOv4 in. */
VIRTIO_NET_F_HOST_TSO6=12, /* Host can handle TSOv6 in. */
VIRTIO_NET_F_HOST_ECN=13, /* Host can handle TSO[6] w/ ECN in. */
VIRTIO_NET_F_HOST_UFO=14, /* Host can handle UFO in. */
VIRTIO_NET_F_MRG_RXBUF=15, /* Host can merge receive buffers. */
VIRTIO_NET_F_STATUS=16, /* virtio_net_config.status available */
VIRTIO_NET_F_CTRL_VQ=17, /* Control channel available */
VIRTIO_NET_F_CTRL_RX=18, /* Control channel RX mode support */
VIRTIO_NET_F_CTRL_VLAN=19, /* Control channel VLAN filtering */
VIRTIO_NET_F_CTRL_RX_EXTRA=20, /* Extra RX mode control support */
VIRTIO_NET_F_GUEST_ANNOUNCE=21 /* Guest can announce device on the
network */
};
enum {
VIRTIO_NET_DEVICE_ID=0x1000,
};
virtio_net();
virtual ~virtio_net();
virtual bool Init(Device *d);
virtual u32 get_driver_features(void) { return ((1 << VIRTIO_NET_F_CSUM) | (1 << VIRTIO_NET_F_MAC)); }
private:
};
}
#endif
#ifndef VIRTIO_NET_DRIVER_H
#define VIRTIO_NET_DRIVER_H
#include "drivers/virtio.hh"
namespace virtio {
class virtio_net : public virtio_driver {
public:
// The feature bitmap for virtio net
enum NetFeatures {
VIRTIO_NET_F_CSUM=0, /* Host handles pkts w/ partial csum */
VIRTIO_NET_F_GUEST_CSUM=1, /* Guest handles pkts w/ partial csum */
VIRTIO_NET_F_MAC=5, /* Host has given MAC address. */
VIRTIO_NET_F_GSO=6, /* Host handles pkts w/ any GSO type */
VIRTIO_NET_F_GUEST_TSO4=7, /* Guest can handle TSOv4 in. */
VIRTIO_NET_F_GUEST_TSO6=8, /* Guest can handle TSOv6 in. */
VIRTIO_NET_F_GUEST_ECN=9, /* Guest can handle TSO[6] w/ ECN in. */
VIRTIO_NET_F_GUEST_UFO=10, /* Guest can handle UFO in. */
VIRTIO_NET_F_HOST_TSO4=11, /* Host can handle TSOv4 in. */
VIRTIO_NET_F_HOST_TSO6=12, /* Host can handle TSOv6 in. */
VIRTIO_NET_F_HOST_ECN=13, /* Host can handle TSO[6] w/ ECN in. */
VIRTIO_NET_F_HOST_UFO=14, /* Host can handle UFO in. */
VIRTIO_NET_F_MRG_RXBUF=15, /* Host can merge receive buffers. */
VIRTIO_NET_F_STATUS=16, /* virtio_net_config.status available */
VIRTIO_NET_F_CTRL_VQ=17, /* Control channel available */
VIRTIO_NET_F_CTRL_RX=18, /* Control channel RX mode support */
VIRTIO_NET_F_CTRL_VLAN=19, /* Control channel VLAN filtering */
VIRTIO_NET_F_CTRL_RX_EXTRA=20, /* Extra RX mode control support */
VIRTIO_NET_F_GUEST_ANNOUNCE=21 /* Guest can announce device on the
network */
};
enum {
VIRTIO_NET_DEVICE_ID=0x1000,
};
virtio_net();
virtual ~virtio_net();
virtual bool Init(Device *d);
virtual u32 get_driver_features(void) { return ((1 << VIRTIO_NET_F_CSUM) | (1 << VIRTIO_NET_F_MAC)); }
private:
};
}
#endif
#include <string.h>
#include "mempool.hh"
#include "drivers/virtio.hh"
#include "drivers/virtio-vring.hh"
using namespace memory;
namespace virtio {
vring::vring(unsigned int num)
{
// Alloc enough pages for the vring...
unsigned sz = VIRTIO_ALIGN(vring::get_size(num, VIRTIO_PCI_VRING_ALIGN));
_paddr = malloc(sz);
memset(_paddr, 0, sz);
// Set up pointers
_num = num;
_desc = (vring_desc *)_paddr;
_avail = (vring_avail *)(_paddr + num*sizeof(vring_desc));
_used = (vring_used *)(((unsigned long)&_avail->_ring[num] +
sizeof(u16) + VIRTIO_PCI_VRING_ALIGN-1) & ~(VIRTIO_PCI_VRING_ALIGN-1));
}
vring::~vring()
{
free(_paddr);
}
void * vring::get_paddr(void)
{
return (_paddr);
}
unsigned vring::get_size(unsigned int num, unsigned long align)
{
return (((sizeof(vring_desc) * num + sizeof(u16) * (3 + num)
+ align - 1) & ~(align - 1))
+ sizeof(u16) * 3 + sizeof(vring_used_elem) * num);
}
int vring::need_event(u16 event_idx, u16 new_idx, u16 old)
{
// Note: Xen has similar logic for notification hold-off
// in include/xen/interface/io/ring.h with req_event and req_prod
// corresponding to event_idx + 1 and new_idx respectively.
// Note also that req_event and req_prod in Xen start at 1,
// event indexes in virtio start at 0.
return ( (u16)(new_idx - event_idx - 1) < (u16)(new_idx - old) );
}
}
#include <string.h>
#include "mempool.hh"
#include "drivers/virtio.hh"
#include "drivers/virtio-vring.hh"
using namespace memory;
namespace virtio {
vring::vring(unsigned int num)
{
// Alloc enough pages for the vring...
unsigned sz = VIRTIO_ALIGN(vring::get_size(num, VIRTIO_PCI_VRING_ALIGN));
_paddr = malloc(sz);
memset(_paddr, 0, sz);
// Set up pointers
_num = num;
_desc = (vring_desc *)_paddr;
_avail = (vring_avail *)(_paddr + num*sizeof(vring_desc));
_used = (vring_used *)(((unsigned long)&_avail->_ring[num] +
sizeof(u16) + VIRTIO_PCI_VRING_ALIGN-1) & ~(VIRTIO_PCI_VRING_ALIGN-1));
}
vring::~vring()
{
free(_paddr);
}
void * vring::get_paddr(void)
{
return (_paddr);
}
unsigned vring::get_size(unsigned int num, unsigned long align)
{
return (((sizeof(vring_desc) * num + sizeof(u16) * (3 + num)
+ align - 1) & ~(align - 1))
+ sizeof(u16) * 3 + sizeof(vring_used_elem) * num);
}
int vring::need_event(u16 event_idx, u16 new_idx, u16 old)
{
// Note: Xen has similar logic for notification hold-off
// in include/xen/interface/io/ring.h with req_event and req_prod
// corresponding to event_idx + 1 and new_idx respectively.
// Note also that req_event and req_prod in Xen start at 1,
// event indexes in virtio start at 0.
return ( (u16)(new_idx - event_idx - 1) < (u16)(new_idx - old) );
}
}
#ifndef VIRTIO_VRING_H
#define VIRTIO_VRING_H
namespace virtio {
// Buffer descriptors in the ring
class vring_desc {
public:
enum {
// This marks a buffer as continuing via the next field.
VRING_DESC_F_NEXT=1,
// This marks a buffer as write-only (otherwise read-only).
VRING_DESC_F_WRITE=2,
// This means the buffer contains a list of buffer descriptors.
VRING_DESC_F_INDIRECT=4
};
u64 get_paddr(void) { return (_paddr); }
u32 get_len(void) { return (_len); }
u16 next_idx(void) { return (_next); }
// flags
bool is_chained(void) { return ((_flags & VRING_DESC_F_NEXT) == VRING_DESC_F_NEXT); };
bool is_write(void) { return ((_flags & VRING_DESC_F_WRITE) == VRING_DESC_F_WRITE); };
bool is_indirect(void) { return ((_flags & VRING_DESC_F_INDIRECT) == VRING_DESC_F_INDIRECT); };
private:
u64 _paddr;
u32 _len;
u16 _flags;
u16 _next;
};
// Guest to host
class vring_avail {
public:
enum {
// Mark that we do not need an interrupt for consuming a descriptor
// from the ring. Unrelieable so it's simply an optimization
VRING_AVAIL_F_NO_INTERRUPT=1
};
void disable_interrupt(void) { _flags |= VRING_AVAIL_F_NO_INTERRUPT; }
void enable_interrupt(void) { _flags = 0; }
u16 _flags;
// Where we put the next descriptor
u16 _idx;
// There may be no more entries than the queue size read from device
u16 _ring[];
};
class vring_used_elem {
public:
// Index of start of used vring_desc chain. (u32 for padding reasons)
u32 _id;
// Total length of the descriptor chain which was used (written to)
u32 _len;
};
// Host to guest
class vring_used {
public:
enum {
// The Host advise the Guest: don't kick me when
// you add a buffer. It's unreliable, so it's simply an
// optimization. Guest will still kick if it's out of buffers.
VRING_USED_F_NO_NOTIFY=1
};
void disable_interrupt(void) { _flags |= VRING_USED_F_NO_NOTIFY; }
void enable_interrupt(void) { _flags = 0; }
u16 _flags;
u16 _idx;
vring_used_elem _used_elements[];
};
class vring {
public:
enum {
/* We support indirect buffer descriptors */
VIRTIO_RING_F_INDIRECT_DESC = 28,
/* The Guest publishes the used index for which it expects an interrupt
* at the end of the avail ring. Host should ignore the avail->flags field. */
/* The Host publishes the avail index for which it expects a kick
* at the end of the used ring. Guest should ignore the used->flags field. */
VIRTIO_RING_F_EVENT_IDX = 29,
};
vring(unsigned int num);
virtual ~vring();
void * get_paddr(void);
static unsigned get_size(unsigned int num, unsigned long align);
// The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX
// Assuming a given event_idx value from the other size, if
// we have just incremented index from old to new_idx,
// should we trigger an event?
static int need_event(u16 event_idx, u16 new_idx, u16 old);
private:
// The physical of the physical address handed to the virtio device
void *_paddr;
// Total number of descriptors in ring
unsigned int _num;
// Flat list of chained descriptors
vring_desc *_desc;
// Available for host consumption
vring_avail *_avail;
// Available for guest consumption
vring_used *_used;
};
}
#endif // VIRTIO_VRING_H
#ifndef VIRTIO_VRING_H
#define VIRTIO_VRING_H
namespace virtio {
// Buffer descriptors in the ring
class vring_desc {
public:
enum {
// This marks a buffer as continuing via the next field.
VRING_DESC_F_NEXT=1,
// This marks a buffer as write-only (otherwise read-only).
VRING_DESC_F_WRITE=2,
// This means the buffer contains a list of buffer descriptors.
VRING_DESC_F_INDIRECT=4
};
u64 get_paddr(void) { return (_paddr); }
u32 get_len(void) { return (_len); }
u16 next_idx(void) { return (_next); }
// flags
bool is_chained(void) { return ((_flags & VRING_DESC_F_NEXT) == VRING_DESC_F_NEXT); };
bool is_write(void) { return ((_flags & VRING_DESC_F_WRITE) == VRING_DESC_F_WRITE); };
bool is_indirect(void) { return ((_flags & VRING_DESC_F_INDIRECT) == VRING_DESC_F_INDIRECT); };
private:
u64 _paddr;
u32 _len;
u16 _flags;
u16 _next;
};
// Guest to host
class vring_avail {
public:
enum {
// Mark that we do not need an interrupt for consuming a descriptor
// from the ring. Unrelieable so it's simply an optimization
VRING_AVAIL_F_NO_INTERRUPT=1
};
void disable_interrupt(void) { _flags |= VRING_AVAIL_F_NO_INTERRUPT; }
void enable_interrupt(void) { _flags = 0; }
u16 _flags;
// Where we put the next descriptor
u16 _idx;
// There may be no more entries than the queue size read from device
u16 _ring[];
};
class vring_used_elem {
public:
// Index of start of used vring_desc chain. (u32 for padding reasons)
u32 _id;
// Total length of the descriptor chain which was used (written to)
u32 _len;
};
// Host to guest
class vring_used {
public:
enum {
// The Host advise the Guest: don't kick me when
// you add a buffer. It's unreliable, so it's simply an
// optimization. Guest will still kick if it's out of buffers.
VRING_USED_F_NO_NOTIFY=1
};
void disable_interrupt(void) { _flags |= VRING_USED_F_NO_NOTIFY; }
void enable_interrupt(void) { _flags = 0; }
u16 _flags;
u16 _idx;
vring_used_elem _used_elements[];
};
class vring {
public:
enum {
/* We support indirect buffer descriptors */
VIRTIO_RING_F_INDIRECT_DESC = 28,
/* The Guest publishes the used index for which it expects an interrupt
* at the end of the avail ring. Host should ignore the avail->flags field. */
/* The Host publishes the avail index for which it expects a kick
* at the end of the used ring. Guest should ignore the used->flags field. */
VIRTIO_RING_F_EVENT_IDX = 29,
};
vring(unsigned int num);
virtual ~vring();
void * get_paddr(void);
static unsigned get_size(unsigned int num, unsigned long align);
// The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX
// Assuming a given event_idx value from the other size, if
// we have just incremented index from old to new_idx,
// should we trigger an event?
static int need_event(u16 event_idx, u16 new_idx, u16 old);
private:
// The physical of the physical address handed to the virtio device
void *_paddr;
// Total number of descriptors in ring
unsigned int _num;
// Flat list of chained descriptors
vring_desc *_desc;
// Available for host consumption
vring_avail *_avail;
// Available for guest consumption
vring_used *_used;
};
}
#endif // VIRTIO_VRING_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment