xv6, line by line
kernel/virtio.h

kernel/virtio.h

C header · 99 lines · annotated 100% · kernel · upstream

Included by 1 filekernel/virtio_disk.c
About this file

Constants and structure layouts that kernel/virtio_disk.c needs to talk to QEMU’s virtio disk. Nothing here is code; every number and every field comes from the virtio specification (version 1.1 is linked in the comment), and the driver is only correct if they match it exactly.

The file has three parts:

  1. the MMIO registers: offsets of the device’s control registers, which appear at physical address VIRTIO0 (0x10001000) through memory-mapped I/O (MMIO);
  2. the virtqueue structures: the descriptor table and the two rings that the driver and the device share in RAM;
  3. the block-device request format: the header that says “read” or “write” and which sector.

Read next: kernel/virtio_disk.c, which uses all of these.

1//
2// virtio device definitions.
3// for both the mmio interface, and virtio descriptors.
4// only tested with qemu.
5//
6// the virtio spec:
7// https://docs.oasis-open.org/virtio/virtio/v1.1/virtio-v1.1.pdf
8//
10// virtio mmio control registers, mapped starting at 0x10001000.
11// from qemu virtio_mmio.h
12// clang-format off
13#define VIRTIO_MMIO_MAGIC_VALUE 0x000 // 0x74726976
14#define VIRTIO_MMIO_VERSION 0x004 // version; should be 2
15#define VIRTIO_MMIO_DEVICE_ID 0x008 // device type; 1 is net, 2 is disk
16#define VIRTIO_MMIO_VENDOR_ID 0x00c // 0x554d4551
19#define VIRTIO_MMIO_QUEUE_SEL 0x030 // select queue, write-only
20#define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034 // max size of current queue, read-only
21#define VIRTIO_MMIO_QUEUE_NUM 0x038 // size of current queue, write-only
22#define VIRTIO_MMIO_QUEUE_READY 0x044 // ready bit
23#define VIRTIO_MMIO_QUEUE_NOTIFY 0x050 // write-only
24#define VIRTIO_MMIO_INTERRUPT_STATUS 0x060 // read-only
25#define VIRTIO_MMIO_INTERRUPT_ACK 0x064 // write-only
26#define VIRTIO_MMIO_STATUS 0x070 // read/write
27#define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080 // physical address for descriptor table, write-only
29#define VIRTIO_MMIO_DRIVER_DESC_LOW 0x090 // physical address for available ring, write-only
31#define VIRTIO_MMIO_DEVICE_DESC_LOW 0x0a0 // physical address for used ring, write-only
33// clang-format on
35// status register bits, from qemu virtio_config.h
41// device feature bits
42#define VIRTIO_BLK_F_RO 5 /* Disk is read-only */
43#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */
44#define VIRTIO_BLK_F_FLUSH 9 /* Cache flush command supported */
45#define VIRTIO_BLK_F_CONFIG_WCE 11 /* Writeback mode available in config */
46#define VIRTIO_BLK_F_MQ 12 /* support more than one vq */
51// this many virtio descriptors.
52// must be a power of two.
53#define NUM 8
55// a single descriptor, from the spec.
56struct virtq_desc {
61};
62#define VRING_DESC_F_NEXT 1 // chained with another descriptor
63#define VRING_DESC_F_WRITE 2 // device writes (vs read)
65// the (entire) avail ring, from the spec.
66struct virtq_avail {
67 uint16 flags; // always zero
68 uint16 idx; // driver will write ring[idx] next
69 uint16 ring[NUM]; // descriptor numbers of chain heads
71};
73// one entry in the "used" ring, with which the
74// device tells the driver about completed requests.
76 uint32 id; // index of start of completed descriptor chain
78};
80struct virtq_used {
81 uint16 flags; // always zero
82 uint16 idx; // device increments when it adds a ring[] entry
84};
86// these are specific to virtio block devices, e.g. disks,
87// described in Section 5.2 of the spec.
89#define VIRTIO_BLK_T_IN 0 // read the disk
90#define VIRTIO_BLK_T_OUT 1 // write the disk
92// the format of the first descriptor in a disk request.
93// to be followed by two more descriptors containing
94// the block, and a one-byte status.
96 uint32 type; // VIRTIO_BLK_T_IN or ..._OUT
99};