Skip to content

virtio.h

TIP

virtio device definitions. for both the mmio interface, and virtio descriptors. only tested with qemu. the virtio spec: https://docs.oasis-open.org/virtio/virtio/v1.1/virtio-v1.1.pdf

TIP

virtio mmio control registers, mapped starting at 0x10001000. from qemu virtio_mmio.h

#define VIRTIO_MMIO_MAGIC_VALUE		0x000
#define VIRTIO_MMIO_VERSION		0x004
#define VIRTIO_MMIO_DEVICE_ID		0x008
#define VIRTIO_MMIO_VENDOR_ID		0x00c
#define VIRTIO_MMIO_DEVICE_FEATURES	0x010
#define VIRTIO_MMIO_DRIVER_FEATURES	0x020
#define VIRTIO_MMIO_QUEUE_SEL		0x030
#define VIRTIO_MMIO_QUEUE_NUM_MAX	0x034
#define VIRTIO_MMIO_QUEUE_NUM		0x038
#define VIRTIO_MMIO_QUEUE_READY		0x044
#define VIRTIO_MMIO_QUEUE_NOTIFY	0x050
#define VIRTIO_MMIO_INTERRUPT_STATUS	0x060
#define VIRTIO_MMIO_INTERRUPT_ACK	0x064
#define VIRTIO_MMIO_STATUS		0x070
#define VIRTIO_MMIO_QUEUE_DESC_LOW	0x080
#define VIRTIO_MMIO_QUEUE_DESC_HIGH	0x084
#define VIRTIO_MMIO_DRIVER_DESC_LOW	0x090
#define VIRTIO_MMIO_DRIVER_DESC_HIGH	0x094
#define VIRTIO_MMIO_DEVICE_DESC_LOW	0x0a0
#define VIRTIO_MMIO_DEVICE_DESC_HIGH	0x0a4

TIP

status register bits, from qemu virtio_config.h

#define VIRTIO_CONFIG_S_ACKNOWLEDGE	1
#define VIRTIO_CONFIG_S_DRIVER		2
#define VIRTIO_CONFIG_S_DRIVER_OK	4
#define VIRTIO_CONFIG_S_FEATURES_OK	8

TIP

device feature bits

#define VIRTIO_BLK_F_RO              5	/* Disk is read-only */
#define VIRTIO_BLK_F_SCSI            7	/* Supports scsi command passthru */
#define VIRTIO_BLK_F_CONFIG_WCE     11	/* Writeback mode available in config */
#define VIRTIO_BLK_F_MQ             12	/* support more than one vq */
#define VIRTIO_F_ANY_LAYOUT         27
#define VIRTIO_RING_F_INDIRECT_DESC 28
#define VIRTIO_RING_F_EVENT_IDX     29

TIP

this many virtio descriptors. must be a power of two.

#define NUM 8

TIP

a single descriptor, from the spec.

struct virtq_desc {
  uint64 addr;
  uint32 len;
  uint16 flags;
  uint16 next;
};
#define VRING_DESC_F_NEXT  1
#define VRING_DESC_F_WRITE 2

TIP

the (entire) avail ring, from the spec.

struct virtq_avail {
  uint16 flags;
  uint16 idx;
  uint16 ring[NUM];
  uint16 unused;
};

TIP

one entry in the "used" ring, with which the device tells the driver about completed requests.

struct virtq_used_elem {
  uint32 id;
  uint32 len;
};

struct virtq_used {
  uint16 flags;
  uint16 idx;
  struct virtq_used_elem ring[NUM];
};

TIP

these are specific to virtio block devices, e.g. disks, described in Section 5.2 of the spec.

#define VIRTIO_BLK_T_IN  0
#define VIRTIO_BLK_T_OUT 1

TIP

the format of the first descriptor in a disk request. to be followed by two more descriptors containing the block, and a one-byte status.

struct virtio_blk_req {
  uint32 type;
  uint32 reserved;
  uint64 sector;
};